Skip to content

Latest commit

History

55 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Simple docker & nginx-based ssl-proxy

Protect any HTTP service with HTTPS!

An Nginx & Docker-based HTTPS/SSL reverse proxy.

Table of Contents

  1. Features
  2. Example
  3. Getting Started
    1. Secure Docker Registry Example
    2. Secure Rancher Server Example
    3. Docker Compose Example
  4. Arguments / Configuration

Features

  • Up-to-date Nginx & Alpine Linux.
  • Fast HTTP2 TLS-enabled reverse proxy
  • Advanced CORS Support (w/ credentials, auto hostname, smart headers)
  • Automatic WebSockets Support
  • NPN/ALPN Application-Layer Protocol Negotiation test here
  • TLS Forward Secrecy, PFS (aka Perfect Forward Secrecy).
  • Supports Optional Username & Password (stored using bcrypt at 14+ rounds)
    • Alternately an .htpasswd file can be volume mounted. (Multiple named users)
  • Great for securing a Docker Registry, Rancher server, Wordpress, etc

Example

Sample SSL Labs/Qualys SSL & TLS Report:

Here's a sample of what you can expect with default configuration.

imageimage

Getting Started

Requirements

  1. Generate a HTTPS/SSL certificate using letsencrypt.

To provide secure, proxied access to local HTTP service:

  1. Requires any working HTTP service (for UPSTREAM_TARGET.) (Supports local, in-docker, even remote).
  2. Start an instance of justsml/ssl-proxy:latest as shown below.

Secure Docker Registry Example

# Note: Small scale users can set certificates directly in the registry instance (v2+) 
docker run -d --restart=on-failure:5 \
--name docker-registry \
-v /data/registry/registry:/var/lib/registry \
registry:2.5
# Create an ssl-proxy to point at the registry's port 5000 (via UPSTREAM_TARGET option - see below.)
docker run -d --restart=on-failure:5 \
--name ssl-proxy \
-p 5000:5000 \
-e 'SERVER_NAME=hub.example.com' \
-e 'UPSTREAM_TARGET=docker-registry:5000' \
-e 'HTTPS_PORT=5000' \
-e 'USERNAME=devops' \
-e 'PASSWORD=secure' \
-e 'CERT_PUBLIC_PATH=/certs/fullchain.pem' \
-e 'CERT_PRIVATE_PATH=/certs/privkey.pem' \
-e "ADD_HEADER='Docker-Distribution-Api-Version' 'registry/2.0' always" \
-v '/certs:/certs:ro' \
--link 'docker-registry:docker-registry' \
justsml/ssl-proxy:latest
# ALT Options# Create an ssl-proxy to point at the registry's port 5000 (via UPSTREAM_TARGET option - see below.)
docker run -d --restart=on-failure:5 \
--name ssl-proxy \
-p 5000:5000 \
-e 'SERVER_NAME=hub.example.com' \
-e 'UPSTREAM_TARGET=docker-registry:5000' \
-e 'EXPIRES_DEFAULT=-1' \
-e 'HTTPS_PORT=5000' \
-e 'USERNAME=devops' \
-e 'PASSWORD=secure' \
-e 'CERT_PUBLIC_PATH=/certs/fullchain.pem' \
-e 'CERT_PRIVATE_PATH=/certs/privkey.pem' \
-e "ADD_HEADER='Docker-Distribution-Api-Version' 'registry/2.0' always" \
-v '/certs:/certs:ro' \
--link 'docker-registry:docker-registry' \
justsml/ssl-proxy:latest

Secure Rancher Server Example

# Update Cached Docker Images
docker pull rancher/server:latest
docker pull justsml/ssl-proxy:latest
# Start Rancher w/ default local port 8080
docker run -d --restart=always \
--name rancher-server \
-v /data/rancher/mysql:/var/lib/mysql \
rancher/server:latest
# Create an ssl-proxy with certs in /certs, (w/o user/pass auth) to point at the local rancher-server's port 8080
docker run -d --restart=always \
--name rancher-proxy \
-p 8080:8080 \
-e 'HTTPS_PORT=8080' \
-e 'SERVER_NAME=_' \
-e 'UPSTREAM_TARGET=rancher-server:8080' \
-e 'CERT_PUBLIC_PATH=/certs/fullchain.pem' \
-e 'CERT_PRIVATE_PATH=/certs/privkey.pem' \
-v '/certs:/certs:ro' \
--link 'rancher-server:rancher-server' \
justsml/ssl-proxy:latest

Docker Compose Example

version: '2'services:
ssl-proxy:
image: justsml/ssl-proxy:latestenvironment:
- HTTPS_PORT=8080
- SERVER_NAME=rancher.example.com
- UPSTREAM_TARGET=rancher-server:8080
- CERT_PUBLIC_PATH=/certs/fullchain.pem
- CERT_PRIVATE_PATH=/certs/privkey.pemvolumes:
- /certs:/certs:rolinks:
- 'rancher-server:rancher-server'ports: [ '8080:8080' ]rancher-server:
image: rancher/server:latestexpose: [ '8080' ]volumes:
- /data/rancher/mysql:/var/lib/mysql

Arguments

NameDefault/ReqdNotes
CERT_AUTOOptionalSet to true to automatically request certificate for $SERVER_NAME - caution: don't exceed let's encrypts API limits.
CERT_PUBLIC_PATHReqd. PEM fileBind-mount certificate files to container path /certs - Or override path w/ this var.
CERT_PRIVATE_PATHReqd. PEM fileBind-mount certificate files to container path /certs - Or override path w/ this var.
SERVER_NAMERequiredPrimary domain name. Not restricting.
UPSTREAM_TARGETRequiredHTTP target host:port. Typically an internally routable address. e.g. localhost:9090 or rancher-server:8080
HTTPS_PORT443/RequiredNeeded for URL rewriting.
ALLOW_RC4Not setBackwards Compatible Option Required for Java 6 or WinXP/IE8
EXPIRES_DEFAULTNot setSet to apply a default expiration value for nginx location /. Useful for app & caching proxies. (For app use -1 and for caching proxy something like 6h)
USERNAMEadminBoth PASSWORD and USERNAME must be set in order to use Basic authorization
PASSWORDBoth PASSWORD and USERNAME must be set in order to use Basic authorization
PASSWD_PATH/etc/nginx/.htpasswdAlternate auth support (don't combine with USERNAME/PASSWORD) Bind-mount a custom path to /etc/nginx/.htpasswd
ADD_HEADERNot setUseful for tagging routes in your infrastructure.

===================


Contributing / Dev Notes

WORK IN PROGRESS:

  1. HTTPS -> HTTPS proxying support. AKA End-to-end TLS. (skipped due to underwhelming performance and extra complexity in the bash startup script.)
  2. Better CORS support: multi host name
  3. haproxy alt version
# Publish 'latest' version
docker build -t ssl-proxy:latest .
docker tag ssl-proxy:latest justsml/ssl-proxy:latest
docker push justsml/ssl-proxy:latest
# Push a tagged version:# docker tag ssl-proxy:latest justsml/ssl-proxy:v1.0.1# docker push justsml/ssl-proxy:v1.0.1# Remember to docker pull on servers
docker pull justsml/ssl-proxy:latest
# Local testing:
docker build -t ssl-proxy:latest .
docker rm -f TEST-ssl-proxy
docker run --rm \
--name TEST-ssl-proxy \
-v ~/certs/xray:/certs \
-p 5000:5000 \
-e 'HTTPS_PORT=5000' \
-e 'USERNAME=devops' \
-e 'PASSWORD=secure' \
-e 'SERVER_NAME=hub.example.com' \
-e 'UPSTREAM_TARGET=www.google.com:80' \
-e 'CERT_PUBLIC_PATH=/certs/fullchain.pem' \
-e 'CERT_PRIVATE_PATH=/certs/privkey.pem' \
ssl-proxy:latest

About

Docker https/ssl reverse proxy w/ nginx. Supports: Auto request letsencrypt cert, CORS, HTTP Auth, Real-time/Low Latency...

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages