0.0.0 • Published 6 years ago

local-https-dev v0.0.0

Weekly downloads
2
License
Apache-2.0
Repository
github
Last release
6 years ago

Local development using https

A pair of daemons and libraries to help providing valid HTTPS certificate during development phases.

Motivation

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:

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.

System description

Certificate server

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.

Local proxy

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

Javascript library

This library retrieves the certificate from the server and provides it to the node server.

Usage

  1. Create a DNS zone (such as local.example.com) is configured to always resolve 127.0.0.1
  2. Get DNS provider API keys, and export them depending on your provider
  3. 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
  1. Run either the local proxy or configure your javascript library

Server help

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

Using local proxy

The local proxy is written in go and can be run either within a container or locally.

Install

To install the proxy, do to the releases page and download the release that matches your system.

Run

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

proxy help

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

Using javascript library

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 certificate issuer-certificate, certificate and private-key
  • webpackConfigSetter(webpackConfig, certificateProviderHost, domain): retrieve a Promise that sets the Webpack configuration

Using 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')

Using certificate promise

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
            }
        })

Supported DNS Providers

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: