Skip to content

Instantly share code, notes, and snippets.

@darth-veitcher
Created September 9, 2019 13:26
Show Gist options
  • Star 32 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save darth-veitcher/93acda9617bab3e1de0264cebf4637fc to your computer and use it in GitHub Desktop.
Save darth-veitcher/93acda9617bab3e1de0264cebf4637fc to your computer and use it in GitHub Desktop.
Traefik v2.0 with Cloudflare Wildcard and OpenVPN
version: "3"
services:
traefik:
image: "traefik:v2.0"
container_name: "traefik"
command:
# Globals
- "--log.level=DEBUG"
- "--api=true"
- "--global.sendAnonymousUsage=false"
# Docker
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.endpoint=unix:///var/run/docker.sock"
# Entrypoints
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
# LetsEncrypt
# - "--certificatesresolvers.mydnschallenge.acme.caServer=https://acme-staging-v02.api.letsencrypt.org/directory"
- "--certificatesresolvers.mydnschallenge.acme.email=${CF_API_EMAIL}"
- "--certificatesresolvers.mydnschallenge.acme.dnschallenge.provider=cloudflare"
- "--certificatesresolvers.mydnschallenge.acme.storage=/etc/traefik/acme.json"
ports:
- "80:80"
- "443:443"
environment:
- CF_API_EMAIL=${CF_API_EMAIL}
- CF_API_KEY=${CF_API_KEY}
volumes:
- "/etc/traefik/acme.json:/etc/traefik/acme.json"
- "/var/run/docker.sock:/var/run/docker.sock:ro"
labels:
# API
- "traefik.enable=true"
- "traefik.http.routers.traefik.rule=Host(`traefik.mydomain.fyi`)"
- "traefik.http.services.traefik.loadbalancer.server.port=8080"
- "traefik.http.services.traefik.loadbalancer.server.scheme=http"
# Wildcard cert
- "traefik.http.routers.traefik.tls.domains[0].main=mydomain.fyi"
- "traefik.http.routers.traefik.tls.domains[0].sans=*.mydomain.fyi"
- "traefik.http.routers.traefik.tls.certresolver=mydnschallenge"
# Global http-->https
- "traefik.http.routers.http-catchall.rule=hostregexp(`{host:[a-z-.]+}`)"
- "traefik.http.routers.http-catchall.entrypoints=web"
- "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
whoami:
image: "containous/whoami"
container_name: "whoami"
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.mydomain.fyi`)"
- "traefik.http.routers.whoami.entrypoints=websecure"
- "traefik.http.routers.whoami.tls.certresolver=mydnschallenge"
ovpn:
image: "kylemanna/openvpn"
container_name: "ovpn"
volumes:
- "/opt/docker/ovpn:/etc/openvpn"
cap_add:
- NET_ADMIN
labels:
- "traefik.enable=true"
- "traefik.tcp.routers.ovpn.rule=HostSNI(`*`)"
- "traefik.tcp.routers.ovpn.entrypoints=websecure"
- "traefik.tcp.routers.ovpn.tls=false"
- "traefik.tcp.routers.ovpn.service=ovpn"
- "traefik.tcp.services.ovpn.loadbalancer.server.port=1194"
@darth-veitcher
Copy link
Author

TCP router for OpenVPN image above allows to listen on port 443 and route VPN into there as well as catering for HTTPS on the same port.

@darth-veitcher
Copy link
Author

NB: OpenVPN needs to be run in TCP as opposed to UDP. See docs for details.

The below snippet assumes running on CoreOS

# Set up the storage volume and fqdn
VPN_HOST="vpn.mydomain.fyi"
OVPN_DATA="/opt/docker/ovpn"

# Create folder structure (CoreOS will keep /opt)
sudo mkdir -p $OVPN_DATA
sudo chown -R core:core /opt/docker

# Initialise the container and specify TCP on the SSL port
docker run -v $OVPN_DATA:/etc/openvpn --rm kylemanna/openvpn ovpn_genconfig -u tcp://$VPN_HOST:443

# Initialise the PKI
docker run -v $OVPN_DATA:/etc/openvpn --rm -it kylemanna/openvpn ovpn_initpki

Now can generate client certs and connect

# Generate a client certificate without a passphrase
CLIENTNAME=darthveitcher
docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm -it kylemanna/openvpn easyrsa build-client-full $CLIENTNAME nopass

# Retrieve the client configuration with embedded certificates
docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm kylemanna/openvpn ovpn_getclient $CLIENTNAME > $CLIENTNAME.ovpn

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment