new post
This commit is contained in:
parent
24160cee23
commit
d5afd8bb26
1 changed files with 168 additions and 0 deletions
168
posts/2022/2022-03-06-https-local.md
Normal file
168
posts/2022/2022-03-06-https-local.md
Normal file
|
@ -0,0 +1,168 @@
|
|||
<!-- title: Tester en local avec HTTPS -->
|
||||
<!-- category: Hébergement Containers -->
|
||||
|
||||
Mes services sont hébergés sur un serveur de containers propulsé par docker compose. L'exposition des services HTTP et HTTPS est géré par le *reverse-proxy* [Traefik](https://traefik.io/traefik/) qui s'occupe aussi de renouveler les certificats SSL délivrés par Let's Encrypt ; pour cela il s'interface avec la plupart des *registrars* (les entités qui gère les noms de domaine). Cela permet de bénéficier de la méthode **dnsprovider** et de demander un certificat *wildcard* (*.mondomaine.fr) plutôt que des certificats pour chaque hôte du domaine (soit chaque container exposé).
|
||||
|
||||
Un serveur à base de containers est facilement portable d'une machine à l'autre et on en vient vite à monter un environnement de test local sur sa machine pour tester / valider avant de déployer sur le serveur. Ce qui est plus *touchy* c'est de se placer dans des configurations similaires au serveur en production et notamment d'avoir du HTTPS.
|
||||
|
||||
Après avoir considéré la complication à gérer des certificats auto-signés, j'ai opté pour une solution basée sur la résolution de noms fournie par [Traefik.me](https://traefik.me/). Cette géniale idée permet de résoudre n'importe quel nom de machine du domaine **traefik.me** en **localhost**. Contrairement à ce que le nom du site laisse supposer, ce n'est pas une solution officielle fournie par Traefik mais je crois que [son auteur Pyrou](https://github.com/pyrou) est un utilisateur (et peut-être un fan) de Traefik. En tout cas on peut mettre en œuvre traefik.me avec n'importe quelle autre solution de *reverse-proxy*, les certificats PEM à jour sont fournis sur la page d'accueil du site.
|
||||
|
||||
Voici donc ma configuration locale pour résoudre les nom de mes containers en HTTPS sur le domaine traefik.me :
|
||||
|
||||
|
||||
Fichier **docker-compose.traefik-local.yml** :
|
||||
|
||||
```yaml
|
||||
services:
|
||||
traefik-local:
|
||||
container_name: traefik-local
|
||||
image: traefik:v2.5.3
|
||||
profiles: ["testing"]
|
||||
ports:
|
||||
- 80:80
|
||||
- 443:443
|
||||
- 8080:8080
|
||||
expose:
|
||||
- 8080
|
||||
labels:
|
||||
- traefik.enable=true
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
- traefik.yml:/etc/traefik/traefik.yml
|
||||
- tls.yml:/etc/traefik/tls.yml
|
||||
- certs:/etc/ssl/traefik
|
||||
|
||||
traefik-reverse-proxy-https-helper:
|
||||
container_name: traefik-reverse-proxy-https-helper
|
||||
image: alpine
|
||||
profiles: ["testing"]
|
||||
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
|
||||
|
||||
volumes:
|
||||
certs:
|
||||
```
|
||||
|
||||
Fichier **tls.yml** :
|
||||
|
||||
```yaml
|
||||
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
|
||||
```
|
||||
|
||||
Fichier **traefik.yml** :
|
||||
|
||||
```yaml
|
||||
logLevel: INFO
|
||||
|
||||
api:
|
||||
insecure: true
|
||||
dashboard: true
|
||||
|
||||
entryPoints:
|
||||
http:
|
||||
address: ":80"
|
||||
https:
|
||||
address: ":443"
|
||||
|
||||
providers:
|
||||
file:
|
||||
filename: /etc/traefik/tls.yml
|
||||
docker:
|
||||
endpoint: unix:///var/run/docker.sock
|
||||
watch: true
|
||||
exposedByDefault: false
|
||||
defaultRule: "HostRegexp(`{{ index .Labels \"com.docker.compose.service\"}}.traefik.me`,`{{ index .Labels \"com.docker.compose.service\"}}-{dashed-ip:.*}.traefik.me`)"
|
||||
|
||||
http:
|
||||
# global redirect to https
|
||||
routers:
|
||||
http-catchall:
|
||||
rule: "hostregexp(`{host:.+}`)"
|
||||
entrypoints:
|
||||
- http
|
||||
middlewares:
|
||||
- redirect-to-https
|
||||
|
||||
# middleware redirect
|
||||
middlewares:
|
||||
redirect-to-https:
|
||||
redirectscheme:
|
||||
scheme: https
|
||||
permanent: true
|
||||
```
|
||||
|
||||
On notera le container compagnon "traefik-reverse-proxy-https-helper" qui s'occupe de rapatrier une version à jour des certificats et de les stocker sur le volume **certs** partagé avec le container "traefik-local".
|
||||
|
||||
La configuration de traefik pour le serveur est classique. Dans mon cas elle s'interface avec le registrar infomaniak qui me loue mon nom de domaine.
|
||||
|
||||
Fichier **docker-compose.traefik-infomaniak.yml** :
|
||||
|
||||
```yaml
|
||||
services:
|
||||
traefik-infomaniak:
|
||||
container_name: traefik-infomaniak
|
||||
image: traefik:v2.5.3
|
||||
profiles: ["production"]
|
||||
command:
|
||||
- --providers.docker=true
|
||||
- --providers.docker.exposedbydefault=false
|
||||
- --api.dashboard=false
|
||||
- --entrypoints.http.address=:80
|
||||
- --entrypoints.https.address=:443
|
||||
- --certificatesresolvers.letsencrypt.acme.email=${LETSENCRYPT_EMAIL}
|
||||
- --certificatesresolvers.letsencrypt.acme.storage=/acme.json
|
||||
- --certificatesResolvers.letsencrypt.acme.dnsChallenge=true
|
||||
- --certificatesresolvers.letsencrypt.acme.dnschallenge.provider=infomaniak
|
||||
environment:
|
||||
- INFOMANIAK_ACCESS_TOKEN=${LETSENCRYPT_DNSPROVIDER_TOKEN}
|
||||
labels:
|
||||
- traefik.enable=true
|
||||
- traefik.http.routers.api.entrypoints=http
|
||||
- traefik.http.routers.api.entrypoints=https
|
||||
- traefik.http.routers.api.service=api@internal
|
||||
# middleware auth
|
||||
- traefik.http.routers.api.middlewares=auth
|
||||
- traefik.http.middlewares.auth.basicauth.users=${BASIC_AUTH}
|
||||
# request widlcard certificate
|
||||
- traefik.http.routers.api.tls.certresolver=letsencrypt
|
||||
- traefik.http.routers.api.tls.domains[0].main=${DOMAIN}
|
||||
- traefik.http.routers.api.tls.domains[0].sans=*.${DOMAIN}
|
||||
# global redirect to https
|
||||
- traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)
|
||||
- traefik.http.routers.http-catchall.entrypoints=http
|
||||
- traefik.http.routers.http-catchall.middlewares=redirect-to-https
|
||||
# middleware redirect
|
||||
- traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https
|
||||
- traefik.http.middlewares.redirect-to-https.redirectscheme.permanent=true
|
||||
ports:
|
||||
- 80:80
|
||||
- 443:443
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
- acme.json:/acme.json
|
||||
```
|
||||
|
||||
Le support des profils de docker-compose permet de choisir la bonne configuration au démarrage des containers.
|
||||
|
||||
En mode "production" sur le serveur :
|
||||
|
||||
docker-compose --env-file .env --profile production up -d
|
||||
|
||||
En mode "test" sur la machine locale :
|
||||
|
||||
docker-compose --env-file .env --profile testing up
|
||||
|
||||
Les configurations docker-compose de l'article sont un peu simplifiées pour faciliter la compréhension. Les sources complètes [sont sur GitHub](https://github.com/kianby/selfhosting).
|
Loading…
Add table
Reference in a new issue