commun:proxy_http
Différences
Ci-dessous, les différences entre deux révisions de la page.
| Les deux révisions précédentesRévision précédenteProchaine révision | Révision précédente | ||
| commun:proxy_http [2026/06/27 07:46] – [6. Commandes utiles] francois | commun:proxy_http [2026/09/20 08:47] (Version actuelle) – francois | ||
|---|---|---|---|
| Ligne 1: | Ligne 1: | ||
| ====== Migration proxy HTTP : Raspi → NUC ====== | ====== Migration proxy HTTP : Raspi → NUC ====== | ||
| - | Migration du reverse proxy depuis | + | Cette page décrit le reverse proxy de la maison. Il tournait auparavant sur un Raspberry Pi (Arch Linux, Apache et Certbot). Il tourne maintenant sur un NUC sous Debian 13, avec le logiciel Caddy dans un conteneur |
| - | **Objectifs** : maintenabilité, robustesse, open-source, | + | Le changement visait une machine plus simple à entretenir, plus fiable, entièrement en logiciels libres et plus facile à surveiller. |
| ===== 1. Système ===== | ===== 1. Système ===== | ||
| Ligne 9: | Ligne 9: | ||
| ==== Distribution ==== | ==== Distribution ==== | ||
| - | * **Debian 13 "Trixie"** (stable depuis le 09/08/2025, support | + | Le NUC fonctionne sous **Debian 13 « Trixie |
| - | * Installation | + | |
| - | * Noyau : '' | + | Le noyau est installé par le paquet |
| - | * Bootloader : **GRUB** (défaut Debian, | + | |
| ==== Partitionnement ==== | ==== Partitionnement ==== | ||
| - | Disque | + | Le disque est un NVMe de 250 Go, non chiffré. Il est découpé en trois partitions : |
| ^ Partition ^ Taille ^ FS ^ Montage ^ | ^ Partition ^ Taille ^ FS ^ Montage ^ | ||
| Ligne 23: | Ligne 22: | ||
| | nvme0n1p3 | ~248 Go | LVM (PV) | — | | | nvme0n1p3 | ~248 Go | LVM (PV) | — | | ||
| - | VG '' | + | La troisième partition est un volume physique LVM. Elle porte le groupe de volumes |
| ^ LV ^ Taille ^ FS ^ Montage ^ | ^ LV ^ Taille ^ FS ^ Montage ^ | ||
| Ligne 30: | Ligne 29: | ||
| | lv-var | 35 Go | ext4 | /var | | | lv-var | 35 Go | ext4 | /var | | ||
| | lv-opt | 60 Go | ext4 | /opt | | | lv-opt | 60 Go | ext4 | /opt | | ||
| - | | //(libre)// | ~93 Go | — | réserve | + | | //(libre)// | ~93 Go | — | réserve | |
| + | |||
| + | Environ 93 Go restent non alloués dans le VG, pour étendre un LV le jour où il sera plein. | ||
| <note tip> | <note tip> | ||
| - | Extension | + | Un LV s' |
| <code bash> | <code bash> | ||
| lvextend -L +20G / | lvextend -L +20G / | ||
| Ligne 44: | Ligne 45: | ||
| ==== Adressage ==== | ==== Adressage ==== | ||
| - | * Routeur : **OpenWrt** ('' | + | Le routeur est un OpenWrt |
| - | | + | |
| - | | + | Le NUC a toujours l' |
| + | |||
| + | Cette adresse | ||
| ==== Gestion réseau ==== | ==== Gestion réseau ==== | ||
| - | * Interface | + | L' |
| - | * Renouvellement | + | |
| + | Pour renouveler le bail DHCP : | ||
| + | <code bash> | ||
| <note warning> | <note warning> | ||
| - | **Piège rencontré** | + | **Piège rencontré.** Une réservation DHCP ne prend pas effet tant qu'une autre machine |
| <code bash> | <code bash> | ||
| # Sur OpenWrt | # Sur OpenWrt | ||
| Ligne 65: | Ligne 70: | ||
| ==== Pare-feu (UFW) ==== | ==== Pare-feu (UFW) ==== | ||
| + | |||
| + | La politique par défaut refuse le trafic entrant et autorise le trafic sortant. Les ouvertures sont les suivantes : | ||
| <code bash> | <code bash> | ||
| ufw default deny incoming | ufw default deny incoming | ||
| ufw default allow outgoing | ufw default allow outgoing | ||
| - | ufw allow 22/ | + | ufw allow from 192.168.1.0/ |
| - | ufw allow 80/ | + | ufw allow from 192.168.115.0/24 to any port 22 proto tcp |
| + | ufw allow from 10.1.100.0/ | ||
| + | ufw allow 80/ | ||
| ufw allow 443/ | ufw allow 443/ | ||
| ufw allow 443/ | ufw allow 443/ | ||
| ufw enable | ufw enable | ||
| + | </ | ||
| + | |||
| + | SSH n'est joignable que depuis les réseaux internes (LAN1, WiFi, VPN). Le port est fermé côté Internet, en IPv4 comme en IPv6. | ||
| + | |||
| + | Les règles sur les ports 80 et 443 sont là pour la lisibilité. En pratique, Docker publie lui-même ces ports par ses propres règles iptables, en amont d'UFW. | ||
| + | |||
| + | ==== Cloisonnement sortant de Caddy ==== | ||
| + | |||
| + | Le proxy est la seule machine de la maison directement exposée à Internet. Si Caddy était compromis, l' | ||
| + | |||
| + | Ce filtrage ne peut pas s' | ||
| + | |||
| + | Les règles sont écrites à la fin du fichier ''/ | ||
| + | |||
| + | < | ||
| + | # BEGIN CADDY EGRESS | ||
| + | *filter | ||
| + | : | ||
| + | -A DOCKER-USER -m conntrack --ctstate ESTABLISHED, | ||
| + | -A DOCKER-USER -s 172.18.0.0/ | ||
| + | -A DOCKER-USER -s 172.18.0.0/ | ||
| + | -A DOCKER-USER -s 172.18.0.0/ | ||
| + | -A DOCKER-USER -s 172.18.0.0/ | ||
| + | -A DOCKER-USER -s 172.18.0.0/ | ||
| + | -A DOCKER-USER -s 172.18.0.0/ | ||
| + | COMMIT | ||
| + | # END CADDY EGRESS | ||
| + | </ | ||
| + | |||
| + | Les règles se lisent de haut en bas, et la première qui correspond s' | ||
| + | |||
| + | ^ Destination ^ Port ^ Service ^ | ||
| + | | cahute (.9) | 443 | Apache : blog, dav, musique, nuage, wiki | | ||
| + | | cahute (.9) | 3000 | Gitea | | ||
| + | | cahute (.9) | 3001 | Uptime-Kuma | | ||
| + | | cahute (.9) | 3002 | Homepage | | ||
| + | | cahute (.9) | 8888 | Dozzle | | ||
| + | | cahute (.9) | 17170 | LLDAP (interface web) | | ||
| + | | homeassistant (.67) | 8123 | Home Assistant | | ||
| + | | routeur (.90) | 53 | DNS local | | ||
| + | |||
| + | Internet reste accessible au conteneur. Il en a besoin pour ACME et pour joindre le DNS de secours '' | ||
| + | |||
| + | Trois conséquences sont à connaître : | ||
| + | |||
| + | * Un '' | ||
| + | * Les règles filtrent par IP, pas par nom. Home Assistant doit donc garder l' | ||
| + | * La source '' | ||
| + | |||
| + | <code bash> | ||
| + | # Recharger après une modification du bloc | ||
| + | sudo ufw reload | ||
| + | |||
| + | # Afficher la chaîne telle qu' | ||
| + | sudo iptables -S DOCKER-USER | ||
| + | |||
| + | # Vérifier que le blocage fonctionne : Cockpit (port 9090) n'est pas autorisé, | ||
| + | # la commande doit échouer au bout de 3 secondes | ||
| + | docker exec proxy-caddy-1 wget -T 3 -qO- http:// | ||
| </ | </ | ||
| ==== Fail2ban ==== | ==== Fail2ban ==== | ||
| - | ''/ | + | Fail2ban surveille les tentatives de connexion SSH. Une adresse qui échoue cinq fois en dix minutes est bannie pendant une heure. Le réglage se trouve dans ''/ |
| < | < | ||
| [DEFAULT] | [DEFAULT] | ||
| Ligne 91: | Ligne 160: | ||
| ==== SSH durci ==== | ==== SSH durci ==== | ||
| - | * Clé SSH (ed25519) | + | La connexion |
| - | * '' | + | |
| - | | + | La clé a été copiée sur le NUC avec '' |
| ==== Mises à jour automatiques ==== | ==== Mises à jour automatiques ==== | ||
| - | * '' | + | Le paquet |
| ===== 4. Stack proxy ===== | ===== 4. Stack proxy ===== | ||
| Ligne 103: | Ligne 172: | ||
| ==== Docker ==== | ==== Docker ==== | ||
| - | * Docker 29 + Compose v5 (install via '' | + | Le NUC utilise |
| - | * Projet | + | |
| ==== Caddy ==== | ==== Caddy ==== | ||
| - | Reverse | + | Caddy fait office de reverse |
| + | |||
| + | Le conteneur est décrit dans ''/ | ||
| - | ''/ | ||
| <code yaml> | <code yaml> | ||
| services: | services: | ||
| Ligne 117: | Ligne 186: | ||
| restart: unless-stopped | restart: unless-stopped | ||
| dns: | dns: | ||
| - | - 192.168.1.90 | + | - 192.168.1.90 |
| - 1.1.1.1 | - 1.1.1.1 | ||
| ports: | ports: | ||
| Ligne 131: | Ligne 200: | ||
| caddy_data: | caddy_data: | ||
| caddy_config: | caddy_config: | ||
| + | |||
| + | networks: | ||
| + | default: | ||
| + | ipam: | ||
| + | config: | ||
| + | - subnet: 172.18.0.0/ | ||
| </ | </ | ||
| + | |||
| + | < | ||
| + | **Pourquoi figer le sous-réseau.** Sans le bloc '' | ||
| + | </ | ||
| <note important> | <note important> | ||
| - | **Deux pièges | + | **Deux pièges rencontrés |
| - | - Le résolveur interne Docker ('' | + | |
| - | - En forçant | + | Au début, le résolveur interne |
| + | |||
| + | Ensuite, avec un DNS public | ||
| </ | </ | ||
| ==== Caddyfile ==== | ==== Caddyfile ==== | ||
| - | | + | La configuration des vhosts se trouve dans '' |
| - | Modèle d'un vhost (cas proxy HTTPS→HTTPS vers cahute) : | ||
| < | < | ||
| blog.beafrancois.fr { | blog.beafrancois.fr { | ||
| Ligne 158: | Ligne 238: | ||
| <note tip> | <note tip> | ||
| - | **'' | + | La directive |
| - | **'' | + | La directive |
| </ | </ | ||
| Ligne 166: | Ligne 246: | ||
| ^ Domaine ^ Backend ^ Particularité ^ | ^ Domaine ^ Backend ^ Particularité ^ | ||
| - | | blog | cahute/blog | redir → /blog/ | | + | | blog | cahute/blog | redirection de / vers /blog/ | |
| - | | dav | cahute/ | + | | dav | cahute/ |
| | git | cahute:3000 | — | | | git | cahute:3000 | — | | ||
| - | | musique | cahute/ | + | | musique | cahute/ |
| - | | nuage | cahute/ | + | | nuage | cahute/ |
| - | | wiki | cahute/ | + | | wiki | cahute/ |
| - | | service | homeassistant: | + | | service | homeassistant: |
| - | < | + | Le vhost '' |
| + | |||
| + | <note warning> | ||
| + | Un nouveau vhost qui pointe vers une adresse ou un port absent du bloc '' | ||
| + | </ | ||
| ==== Limite de taille des logs ==== | ==== Limite de taille des logs ==== | ||
| - | ''/ | + | Les logs des conteneurs sont limités à cinq fichiers de 50 Mo chacun, pour ne pas remplir le disque. Le réglage est dans ''/ |
| <code json> | <code json> | ||
| { | { | ||
| Ligne 186: | Ligne 271: | ||
| </ | </ | ||
| - | ''/ | + | Le journal systemd est limité à 2 Go par la ligne '' |
| - | ===== 5. Procédure | + | ===== 5. Mise à jour de l' |
| - | - Baisser le TTL DNS à 60s (J-24h) | + | La mise à jour de Caddy se fait **à la main**, sur le proxy. Aucun outil ne met à jour le conteneur automatiquement |
| - | - Démarrer | + | |
| - | - Basculer la réservation DHCP / redirection routeur vers le NUC | + | |
| - | - Vérifier l' | + | |
| - | - Tester chaque service ('' | + | |
| - | - **Rollback** : remettre | + | |
| - | - Après 48 h de stabilité : éteindre le Raspi | + | |
| - | ===== 6. Commandes utiles ===== | + | <code bash> |
| + | cd / | ||
| + | |||
| + | # 1. Sauvegarder la configuration avant de toucher à quoi que ce soit | ||
| + | sudo cp -a /opt/proxy / | ||
| + | |||
| + | # 2. Noter la version en cours, pour pouvoir y revenir | ||
| + | docker compose exec caddy caddy version | ||
| + | |||
| + | # 3. Télécharger la nouvelle image | ||
| + | docker compose pull | ||
| + | |||
| + | # 4. Recréer le conteneur avec cette image | ||
| + | docker compose up -d | ||
| + | |||
| + | # 5. Contrôler les logs, puis chaque vhost | ||
| + | docker compose logs --tail 40 caddy | grep -Ei " | ||
| + | for h in blog dav git musique nuage wiki service; do | ||
| + | echo -n "$h : "; curl -sI -o /dev/null -w ' | ||
| + | done | ||
| + | </ | ||
| + | |||
| + | **Rollback.** Dans le compose, on remplace '' | ||
| + | |||
| + | <note tip> | ||
| + | Avant une mise à jour, il vaut mieux lire le changelog de Caddy, car des directives du Caddyfile changent parfois. En cas de doute, on peut vérifier la configuration avant de recréer le conteneur : | ||
| + | <code bash> | ||
| + | </ | ||
| + | |||
| + | <note warning> | ||
| + | Le tag '' | ||
| + | </ | ||
| + | |||
| + | ===== 6. Procédure de bascule ===== | ||
| + | |||
| + | Cette procédure est celle qui a servi à passer du Raspberry Pi au NUC. À chaque étape, il restait possible de revenir à l' | ||
| + | |||
| + | - La veille, abaisser le TTL DNS à 60 secondes, pour qu'un changement se propage rapidement. | ||
| + | - Démarrer Caddy sur le NUC. Les challenges ACME échouent tant qu'il ne reçoit pas le trafic, c'est normal. | ||
| + | - Sur OpenWrt, basculer la réservation DHCP vers le NUC, ou pointer vers lui la redirection de ports. | ||
| + | - Vérifier que les certificats sont obtenus : <code bash> | ||
| + | - Tester chaque vhost avec '' | ||
| + | - Pour un rollback, remettre l' | ||
| + | - Après 48 heures sans incident, éteindre le Raspberry Pi. | ||
| + | |||
| + | ===== 7. Commandes utiles ===== | ||
| <code bash> | <code bash> | ||
| - | # Recharger la config après modif du Caddyfile | + | # Prendre en compte une modification |
| docker compose exec caddy caddy reload --config / | docker compose exec caddy caddy reload --config / | ||
| - | # Recharger la config après modif du Caddyfile | + | # Même chose en redémarrant le conteneur |
| docker compose restart caddy | docker compose restart caddy | ||
| - | # Suivre les logs | + | # Vérifier la syntaxe du Caddyfile sans l' |
| + | docker compose exec caddy caddy validate --config / | ||
| + | |||
| + | # Suivre les logs en direct | ||
| docker compose logs -f caddy | docker compose logs -f caddy | ||
| - | # État des conteneurs | + | # État du conteneur |
| docker compose ps | docker compose ps | ||
| - | # Espace | + | # Chaîne DOCKER-USER telle qu' |
| + | sudo iptables -S DOCKER-USER | ||
| + | |||
| + | # Place disponible sur le disque | ||
| df -h && vgs && lvs | df -h && vgs && lvs | ||
| </ | </ | ||
| - | ===== TODO / pistes | + | ===== Ce qui reste à faire ===== |
| - | * Surveillance : Grafana | + | * Épingler le tag Caddy sur une version exacte plutôt que '' |
| - | * Sauvegarde du volume '' | + | * Mettre en place la surveillance prévue (Grafana, Prometheus, Loki, cAdvisor), qui n'est pas encore |
| - | * Optionnel : logwatch, rkhunter | + | * Sauvegarder le volume '' |
| - | * Créer | + | * Éventuellement, installer logwatch et rkhunter. |
| + | * Recréer | ||
commun/proxy_http.1782546364.txt.gz · Dernière modification : de francois
