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édente | |||
| commun:proxy_http [2026/08/01 14:33] – 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. Mise à jour de l' | ===== 5. Mise à jour de l' | ||
| - | Opération | + | La mise à jour de Caddy se fait **à la main**, sur le proxy. |
| <code bash> | <code bash> | ||
| cd /opt/proxy | cd /opt/proxy | ||
| - | # 1. Sauvegarder la config | + | # 1. Sauvegarder la configuration |
| sudo cp -a /opt/proxy / | sudo cp -a /opt/proxy / | ||
| - | # 2. Noter la version en cours (pour le rollback) | + | # 2. Noter la version en cours, pour pouvoir y revenir |
| docker compose exec caddy caddy version | docker compose exec caddy caddy version | ||
| Ligne 204: | Ligne 289: | ||
| docker compose pull | docker compose pull | ||
| - | # 4. Recréer le conteneur | + | # 4. Recréer le conteneur |
| docker compose up -d | docker compose up -d | ||
| - | # 5. Contrôler | + | # 5. Contrôler |
| docker compose logs --tail 40 caddy | grep -Ei " | docker compose logs --tail 40 caddy | grep -Ei " | ||
| for h in blog dav git musique nuage wiki service; do | for h in blog dav git musique nuage wiki service; do | ||
| Ligne 214: | Ligne 299: | ||
| </ | </ | ||
| - | **Rollback** : remettre | + | **Rollback.** Dans le compose, on remplace '' |
| <note tip> | <note tip> | ||
| - | Consulter le changelog Caddy avant une mise à jour de version mineure : des directives du Caddyfile | + | Avant une mise à jour, il vaut mieux lire le changelog |
| <code bash> | <code bash> | ||
| </ | </ | ||
| <note warning> | <note warning> | ||
| - | Le tag '' | + | Le tag '' |
| </ | </ | ||
| - | ===== 6. Procédure de bascule | + | ===== 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' |
| - | - Démarrer Caddy sur le NUC (échecs | + | |
| - | - Basculer | + | |
| - | - Vérifier | + | - Démarrer Caddy sur le NUC. Les challenges |
| - | - Tester chaque | + | - Sur OpenWrt, basculer |
| - | - **Rollback** : remettre l' | + | - Vérifier |
| - | - Après 48 h de stabilité : éteindre le Raspi | + | - Tester chaque |
| + | - Pour un rollback, | ||
| + | - Après 48 heures sans incident, | ||
| ===== 7. Commandes utiles ===== | ===== 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 | ||
| Ligne 247: | Ligne 334: | ||
| docker compose exec caddy caddy validate --config / | docker compose exec caddy caddy validate --config / | ||
| - | # Suivre les logs | + | # 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 ===== |
| - | * Épingler le tag Caddy sur une version exacte plutôt que '' | + | * Épingler le tag Caddy sur une version exacte plutôt que '' |
| - | * Surveillance : Grafana | + | * Mettre en place la surveillance prévue (Grafana, Prometheus, Loki, cAdvisor), qui n'est pas encore |
| - | * Sauvegarde du volume '' | + | * Sauvegarder le volume '' |
| - | * Optionnel : logwatch, rkhunter | + | * Éventuellement, installer logwatch et rkhunter. |
| - | * Créer | + | * Recréer |
commun/proxy_http.1785594794.txt.gz · Dernière modification : de francois
