A pair of daemons and libraries to help providing valid HTTPS certificate during development phases.
In modern web, the use of HTTPS is recommended, and HTTP is on its way to deprecation.
With the increased security of HTTPS, comes a series of security techniques to increase the overall web security such as:
- HTTP Strict Transport Security HSTS
- Blocking mixed content
- Content-Security-Policy
- Referer-Policy
These features can introduce a different behaviour between production over HTTPS and local development over HTTP where some security features are ignored. Such a difference can break a working feature during development phases once deployed to production.
This server needs to be deployed on a private network, available, for example via VPN, to the eligible developers.
This server is provided a zone configured to resolve 127.0.0.01
for any sub domain, and will only serve the certificates for this zone.
This server caches the certificates to reduce Let's Encrypt usage and keep as much as possible under the rate limits.
This is an HTTP proxy that receives the certificate from the server and proxies all requests to a selected backend.
This proxy implements the same X-Forwarded-For
header as described by amazon ELB documentation
This library retrieves the certificate from the server and provides it to the node server.
- Create a DNS zone (such as local.example.com) is configured to always resolve 127.0.0.1
- Get DNS provider API keys, and export them depending on your provider
- Deploy the server on your private network
docker run -d --name local-https-dev-server tjamet/local-https-dev-server --accept-tos --email <yourEmail> --dns <DNSProvider> --domain local.example.com
--accept-tos
instructs to accept Let's Encrypt Terms Of Service--email
the account email used to retrieve of create a let's encrypt account--dns
specifies the DNS provider to use (see Supported DNS providers for more details)--domain
specifies the zone setup to resolve 127.0.0.1 When provided, all certificate domain must be within this zone
- Run either the local proxy or configure your javascript library
NAME:
local-https-dev-server - A simple HTTP server to serve certificates
USAGE:
main [global options] command [command options] [arguments...]
VERSION:
0.0.0
COMMANDS:
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
--domain value, -d value Specify the allowed domain suffix
--server value, -s value CA hostname (and optionally :port). The server certificate must be trusted in order to avoid further modifications to the client. (default: "https://acme-v02.api.letsencrypt.org/directory")
--email value, -m value Email used for registration and recovery contact.
--dns value Solve a DNS challenge using the specified provider.
--path value Directory where to store cache (let's encrypt account and certificates). (default: "~/.dev-acme")
--accept-tos, -a By setting this flag to true you indicate that you accept the current Let's Encrypt terms of service.
--port value, -p value The port the server should listen to. (default: 8080)
--help, -h show help
--version, -v print the version
The local proxy is written in go and can be run either within a container or locally.
To install the proxy, do to the releases page and download the release that matches your system.
Run the proxy in a container using the following command:
docker run -d --name local-https-dev-proxy tjamet/local-https-dev-proxy --server http://<ServerIP>:<ServerPort> --backend http://<YourBackendHost>:<YourBackendPort> --domain <subdomain>.local.example.com
NAME:
local-https-dev-proxy - A proxy to handle HTTP TLS for localhost domains
USAGE:
main [global options] command [command options] [arguments...]
VERSION:
0.0.0
COMMANDS:
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
--domain value, -d value Add a domain to serve TLS on
--server value, -s value The server serving TLS certificates over HTTP
--backend value, -b value The backend to serve requests from
--listen value, -l value The port to listen on without TLS
--tls value, -t value The TLS port to listen on (default: 0.0.0.0:443 when no listen port is provided)
--help, -h show help
--version, -v print the version
The library is available on npm as local-https-dev
and can be installed by:
npm install --save-dev local-https-dev
It exports 2 functions:
getCertificate(server, domain)
: retrieve a Promise for the certificateissuer-certificate
,certificate
andprivate-key
webpackConfigSetter(webpackConfig, certificateProviderHost, domain)
: retrieve a Promise that sets the Webpack configuration
Edit your webpack.config.js
and change the standard module.exports = webpackConfig;
for
# in case you are running webpack as a standard user you might need to add this property to allow serving from <domain>.local.example.com
webpackConfig.devServer.disableHostCheck= true
module.exports = require('local-https-dev').webpackConfigSetter(webpackConfig, '<serverURL>', '<domain>.local.example.com')
require('local-https-dev').getCertificate('<serverURL>', '<domain>.local.example.com')
.then(cert=>{
if (cert["issuer-certificate"] != null) {
# setup issuer certificate
}
if (cert["certificate"] != null) {
# setup cetificate
}
if (cert["private-key"] != null) {
# setup private key
}
})
local-https-dev is using lego Let's Encrypt client, as caddy and traefik does. lego supports several DNS providers as defined in caddy documentation:
Provider | Name to use on command line | Environment Variables to Set |
---|---|---|
Aurora DNS by PCExtreme | auroradns | AURORA_USER_ID AURORA_KEY AURORA_ENDPOINT (optional) |
Azure DNS | azure | AZURE_CLIENT_ID AZURE_CLIENT_SECRET AZURE_SUBSCRIPTION_ID AZURE_TENANT_ID |
Cloudflare | cloudflare | CLOUDFLARE_EMAIL CLOUDFLARE_API_KEY |
CloudXNS | cloudxns | CLOUDXNS_API_KEY CLOUDXNS_SECRET_KEY |
DigitalOcean | digitalocean | DO_AUTH_TOKEN |
DNSimple | dnsimple | DNSIMPLE_EMAIL DNSIMPLE_OAUTH_TOKEN |
DNS Made Easy | dnsmadeeasy | DNSMADEEASY_API_KEY DNSMADEEASY_API_SECRET DNSMADEEASY_SANDBOX (true/false) |
DNSPod | dnspod | DNSPOD_API_KEY |
DynDNS | dyn | DYN_CUSTOMER_NAME DYN_USER_NAME DYN_PASSWORD |
Gandi | gandi / gandiv5 | GANDI_API_KEY / GANDIV5_API_KEY |
GoDaddy | godaddy | GODADDY_API_KEY GODADDY_API_SECRET |
Google Cloud DNS | googlecloud | GCE_PROJECT GCE_DOMAIN GOOGLE_APPLICATION_CREDENTIALS (or GCE_SERVICE_ACCOUNT_FILE) |
Lightsail by AWS | lightsail | AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN (optional) DNS_ZONE (optional) |
Linode | linode | LINODE_API_KEY |
Namecheap | namecheap | NAMECHEAP_API_USER NAMECHEAP_API_KEY |
NS1. | ns1 | NS1_API_KEY |
Name.com | namedotcom | NAMECOM_USERNAME NAMECOM_API_TOKEN |
OVH | ovh | OVH_ENDPOINT OVH_APPLICATION_KEY OVH_APPLICATION_SECRET OVH_CONSUMER_KEY |
Open Telekom Cloud Managed DNS |
otc | OTC_DOMAIN_NAME OTC_USER_NAME OTC_PASSWORD OTC_PROJECT_NAME OTC_IDENTITY_ENDPOINT (optional) |
PowerDNS | pdns | PDNS_API_URL PDNS_API_KEY |
Rackspace | rackspace | RACKSPACE_USER RACKSPACE_API_KEY |
rfc2136 | RFC2136_NAMESERVER RFC2136_TSIG_ALGORITHM RFC2136_TSIG_KEY RFC2136_TSIG_SECRET |
|
Route53 by AWS | route53 | AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY |
Vultr | vultr | VULTR_API_KEY |