Reverse proxy¶
HouseCairn écoute en HTTP simple et attend d’un reverse proxy qu’il termine le HTTPS devant lui. Avec l’exemple compose.yaml, il écoute sur 127.0.0.1:8000 de l’hôte.
Dans deploy/production.env, pour une instance à l’adresse housecairn.example.com :
ALLOWED_HOSTS=housecairn.example.com
CSRF_TRUSTED_ORIGINS=https://housecairn.example.com
HOUSECAIRN_BEHIND_TLS_PROXY=true
HOUSECAIRN_FORWARDED_ALLOW_IPS=192.0.2.1
HOUSECAIRN_BEHIND_TLS_PROXY=true fait que HouseCairn se fie à l’en-tête X-Forwarded-Proto : ne l’activez que si le proxy pose lui-même cet en-tête. Sans cela, HouseCairn voit du HTTP simple et redirige chaque requête vers HTTPS.
Adresse du proxy de confiance¶
HOUSECAIRN_FORWARDED_ALLOW_IPS désigne le proxy : une ou plusieurs adresses IP ou réseaux, séparés par des virgules (192.0.2.1, 192.0.2.0/24, 2001:db8::/32). Par défaut, c’est la boucle locale du conteneur lui-même, 127.0.0.1,::1.
Depuis ces adresses,
X-Forwarded-Protoindique à HouseCairn que la requête est arrivée en HTTPS, etX-Forwarded-Fordonne l’adresse du client, qui sert à limiter les tentatives de connexion par client.Depuis toute autre adresse, HouseCairn retire les en-têtes de transfert (
X-Forwarded-For,X-Forwarded-Proto,X-Forwarded-Host,Forwarded,X-Real-IP…) avant de lire la requête. Un client qui atteint le conteneur sans passer par le proxy ne peut ni se faire passer pour du HTTPS, ni choisir l’adresse sous laquelle ses tentatives de connexion sont comptées.
La valeur est l’adresse depuis laquelle HouseCairn voit le proxy se connecter, pas l’adresse publique du proxy :
Emplacement du proxy |
Valeur |
|---|---|
Sur l’hôte, avec l’exemple |
La passerelle du réseau Compose : |
Dans un conteneur du même projet Compose |
L’adresse de ce conteneur, fixée dans |
Sur une autre machine |
L’adresse de cette machine. |
Si la valeur est fausse, HouseCairn ignore les en-têtes du proxy : chaque requête est de nouveau redirigée vers HTTPS (le navigateur signale trop de redirections), et tous les clients sont comptés sous l’adresse du proxy. * fait confiance à n’importe quel pair ; ne l’utilisez que si rien d’autre que le proxy ne peut atteindre le port du conteneur.
HouseCairn lit le nom du site dans l’en-tête Host, jamais dans X-Forwarded-Host : le proxy doit transmettre Host. Caddy et Traefik le font par défaut ; nginx a besoin de proxy_set_header Host $host.
Caddy sur l’hôte¶
Caddy obtient le certificat et pose X-Forwarded-Proto et X-Forwarded-For par défaut :
housecairn.example.com {
reverse_proxy 127.0.0.1:8000
}
Gardez HOUSECAIRN_FORWARDED_ALLOW_IPS=192.0.2.1, la passerelle du réseau de l’exemple. Si vous changez la plage du réseau dans compose.yaml, changez cette valeur avec elle.
Caddy ou Traefik dans Docker Compose¶
Le proxy tourne à côté de HouseCairn, avec une adresse fixe sur un réseau qu’ils sont seuls à partager. HouseCairn ne publie aucun port : seul le proxy en publie.
services:
caddy:
image: caddy:2
restart: unless-stopped
ports: ["80:80", "443:443", "443:443/udp"]
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy-data:/data
networks:
proxy:
ipv4_address: 192.0.2.10
housecairn:
image: ghcr.io/housecairn/housecairn:X.Y.Z
restart: unless-stopped
env_file: deploy/production.env
environment:
HOUSECAIRN_FORWARDED_ALLOW_IPS: 192.0.2.10
volumes:
- housecairn-data:/data
networks: [proxy]
# Plus the hardening options of the example compose.yaml: read_only, tmpfs,
# cap_drop, security_opt, stop_grace_period.
networks:
proxy:
ipam:
config:
# A documentation range (RFC 5737): any free range works.
- subnet: 192.0.2.0/24
volumes:
housecairn-data:
caddy-data:
Avec le Caddyfile :
housecairn.example.com {
reverse_proxy housecairn:8000
}
Avec Traefik au lieu de Caddy, le réglage est le même : donnez au conteneur Traefik une adresse fixe sur le réseau partagé et mettez-la dans HOUSECAIRN_FORWARDED_ALLOW_IPS. Traefik pose X-Forwarded-Proto et X-Forwarded-For, et remplace ceux qu’envoie un client, par défaut. Les labels du service housecairn :
labels:
- traefik.enable=true
- traefik.http.routers.housecairn.rule=Host(`housecairn.example.com`)
- traefik.http.routers.housecairn.entrypoints=websecure
- traefik.http.routers.housecairn.tls.certresolver=letsencrypt
- traefik.http.services.housecairn.loadbalancer.server.port=8000
nginx¶
server {
listen 443 ssl;
server_name housecairn.example.com;
# ssl_certificate and ssl_certificate_key of your certificate.
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
$proxy_add_x_forwarded_for garde ce que le client a envoyé et ajoute l’adresse vue par nginx : HouseCairn lit la liste depuis la droite et s’arrête à la première adresse qui n’est pas un proxy de confiance, si bien que les entrées écrites par le client ne comptent pas.
HouseCairn pose ses propres en-têtes de sécurité (Content Security Policy, HSTS, X-Frame-Options) ; le proxy n’a pas besoin d’en ajouter.