Je cherche souvent à faire des POC pour mes tests, mon auto-formation ou pour mes TP de cours. Ces POC doivent tourner sur des vms sur ma machine avec VirtualBox.
Cependant souvent ces vms n'ont pas d'Ips publique ce qui pose des problèmes avec la génération de certificats SSL. Il existe bien sur des solutions avec xip.io ou nip.io quand on travaille sur des vhosts Apache par exemple. Pour jouer avec Traefik et des conteneurs Docker il me fallait un système dans le même genre qui fonctionne bien avec Traefik.
J'ai trouvé mon bonheur avec traefik.me.
Cet article prends en compte que l'utilisateur sait déjà utiliser docker, docker-compose et Traefik, au mieux voir nos articles précédents sur le sujet.
Mise en place de Traefik
Ma machine à comme IP 192.168.85.140 je vais donc utiliser cette IP en transformant les "." par "-" pour l'utiliser en sous-domaine de traefik.me. Donc pour Traefik je défini mon url : traefik-192-168"-85-140.traefik.me.
Voici un docker-compose :
services:
traefik:
restart: unless-stopped
image: traefik:v2.3
ports:
- "80:80"
- "443:443"
security_opt:
- no-new-privileges:true
networks:
- traefik-proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik.entrypoints=websecured"
- "traefik.http.routers.traefik.rule=Host(`traefik-192-168-85-140.traefik.me`)"
- "traefik.http.middlewares.traefik-auth.basicauth.users=admin:$$apr1$$DzLQ25C8$$/9Fh/LoGjgRYk3t0l2AwC1"
- "traefik.http.routers.traefik.service=api@internal"
- "traefik.http.routers.traefik.middlewares=hsts-headers@file, traefik-auth"
volumes:
- ./conf/traefik.yml:/etc/traefik/traefik.yml
- ./conf/config.yml:/config.yml:ro
- ./log:/log
- /var/run/docker.sock:/var/run/docker.sock
- certs:/etc/ssl/traefik
reverse-proxy-https-helper:
image: alpine
command: sh -c "cd /etc/ssl/traefik
&& wget traefik.me/cert.pem -O cert.pem
&& wget traefik.me/privkey.pem -O privkey.pem"
volumes:
- certs:/etc/ssl/traefik
networks:
- 'traefik-proxy'
labels:
traefik.enable: "false"
volumes:
certs:
networks:
traefik-proxy:
name: traefik-proxy
Le fichier traefik.yml :
api:
dashboard: true
debug: true
entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: websecured
websecured:
address: ":443"
http:
tls:
options: intermediate@file
providers:
file:
filename: /config.yml
docker:
endpoint: unix:///var/run/docker.sock
watch: true
exposedByDefault: true
defaultRule: "HostRegexp(`{{ index .Labels \"com.docker.compose.service\"}}.traefik.me`,`{{ index .Labels \"com.docker.compose.service\"}}-{dashed-ip:.*}.traefik.me`)"
log:
level: "ERROR"
filePath: "log/error.log"
format: "json"
accessLog:
filePath: "log/access.log"
format: "json"
Le fichier config.yml
http:
middlewares:
redirect-to-https:
redirectScheme:
scheme: https
hsts-headers:
headers:
frameDeny: true
sslRedirect: true
sslHost: aukfood.ovh
browserXssFilter: true
contentTypeNosniff: true
customFrameOptionsValue: SAMEORIGIN
accessControlAllowMethods:
- GET
- OPTIONS
- PUT
accessControlMaxAge: 100
addVaryHeader: true
forceSTSHeader: true
stsIncludeSubdomains: true
stsPreload: true
stsSeconds: 63072000
tls:
stores:
default:
defaultCertificate:
certFile: /etc/ssl/traefik/cert.pem
keyFile: /etc/ssl/traefik/privkey.pem
certificates:
- certFile: /etc/ssl/traefik/cert.pem
keyFile: /etc/ssl/traefik/privkey.pem
options:
intermediate:
minVersion: VersionTLS12
cipherSuites:
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 # TLS 1.2
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 # TLS 1.2
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 # TLS 1.2
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 # TLS 1.2
- TLS_AES_256_GCM_SHA384 # TLS 1.3
- TLS_CHACHA20_POLY1305_SHA256 # TLS 1.3
- TLS_FALLBACK_SCSV # TLS FALLBACK
curvePreferences:
- CurveP521
- CurveP384
sniStrict: true
modern:
minVersion: VersionTLS13
Un petit docker-compose up -d et Traefik est prêt en local avec un certificat SSL valide.
Déploiement d'un Nextcloud
Un petit exemple pour déployer un Nextcloud.
Sur la même conception de l'url que pour Traefik je crée mon url pour Nextcloud.
version: '3.7'
services:
database:
image: mariadb:10
command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: 'azertyuiop'
MYSQL_USER: 'cloud'
MYSQL_DATABASE: 'nextcloud'
MYSQL_PASSWORD: 'azertyuiop'
networks:
- 'database'
volumes:
- db:/var/lib/mysql
labels:
traefik.enable: "false"
nextcloud:
depends_on:
- database
image: nextcloud:19
restart: unless-stopped
environment:
MYSQL_HOST: 'database'
MYSQL_DATABASE: 'nextcloud'
MYSQL_USER: 'cloud'
MYSQL_PASSWORD: 'azertyuiop'
NEXTCLOUD_ADMIN_PASSWORD: 'azertyuiop'
NEXTCLOUD_ADMIN_USER: 'cldadmin'
NEXTCLOUD_TRUSTED_DOMAINS: 'nextcloud-192-168-85-140.traefik.me'
networks:
- 'traefik-proxy'
- 'database'
volumes:
- html:/var/www/html
labels:
- "traefik.enable=true"
- "traefik.docker.network=traefik-proxy"
- "traefik.http.routers.nextcloud.entrypoints=websecured"
- "traefik.http.routers.nextcloud.rule=Host(`nextcloud-192-168-85-140.traefik.me`)"
- "traefik.http.routers.nextcloud.service=nextcloud"
networks:
traefik-proxy:
external:
name: traefik-proxy
database:
volumes:
db: {}
html: {}
Nextcloud fonctionne avec un certificat SSL derrière Traefik comme si il était installé sur un serveur de prod. Tout ce qu'il me faut pour travailler correctement.
Les liens à lire
Ces articles m'ont permis de mettre au point ce POC, je remercie aussi Mathieu pour ses conseils pour la mise en place de traefik.me.
traefik.me : https://traefik.me/
Blog du barbu : https://www.grottedubarbu.fr/nextcloud-docker-traefik/
[/fusion_text][/fusion_builder_column][/fusion_builder_row][/fusion_builder_container]