La mise en réseau de nos serveurs est nécessaire, notamment pour l’utilisation du serveur NFS (qui nécessite d’importantes précautions de sécurité) ou du serveur syslog-ng pour la centralisation des journaux.
Notre hébergeur PulseHeberg intègre dans l’interface de gestion des serveurs un système de pare-feu configurable.
Tous nos serveurs ont un pare-feu configuré pour bloquer tous les ports par défaut et autoriser le trafic ICMP. Les ports nécessaires au fonctionnement des services sont manuellement autorisés.
Quelques ports font l’objet de règles spécifiques :
Un lien WireGuard connecte nos serveurs en production, à l’exception de notre machine dédiée à la supervision et aux sauvegardes.
Ce lien est configuré avec systemd-networkd. Le serveur de stockage, Antigone, agit comme serveur WireGuard principal.
La configuration est inspirée de plusieurs tutoriels, dont celui sur le blog d’elou.world ou de shibumi.dev. Nous n’utilisons pas wg-quick
.
Le serveur est configuré comme suit, avec les IPs fictives définies ci-dessous :
192.0.2.0/24
192.0.2.1
192.0.2.2
192.0.2.3
(machine supprimée)192.0.2.4
Tous les fichiers de configuration présentés ci-dessous se situent dans le dossier /etc/systemd/network/
et doivent appartenir au compte et au groupe systemd-network
avec la permission 600
.
Contenu du fichier /etc/systemd/network/80-wg0.netdev
sur Antigone :
[NetDev]
Name = wg0
Kind = wireguard
Description = WireGuard VPN
[WireGuard]
ListenPort = 51820
PrivateKey = <CLÉ PRIVÉE ANTIGONE>
[WireGuardPeer]
PublicKey = <CLÉ PUBLIQUE BALEARICA>
PresharedKey = <CLÉ PARTAGÉE BALEARICA-ANTIGONE>
AllowedIPs = 192.0.2.2/32
[WireGuardPeer]
PublicKey = <CLÉ PUBLIQUE SIALIA>
PresharedKey = <CLÉ PARTAGÉE SIALIA-ANTIGONE>
AllowedIPs = 192.0.2.3/32
Contenu du fichier /etc/systemd/network/85-wg0.network
:
[Match]
Name = wg0
[Network]
Address = 192.0.2.1/32
[RoutingPolicyRule]
From = 198.51.100.0/24
[Route]
Gateway = 192.0.2.1
Destination = 192.0.2.0/24
[Route]
Destination = 0.0.0.0/0
Type = blackhole
Metric = 1
Voici la configuration de Balearica, client Wireguard dans notre topologie. La configuration de Sialia est similaire.
Contenu du fichier /etc/systemd/network/80-wg0.netdev
sur Balearica :
[NetDev]
Name = wg0
Kind = wireguard
Description = WireGuard VPN
[WireGuard]
PrivateKey = <CLÉ PRIVÉE BALEARICA>
[WireGuardPeer]
PublicKey = <CLÉ PUBLIQUE ANTIGONE>
PresharedKey = <CLÉ PARTAGÉE BALEARICA-ANTIGONE>
AllowedIPs = 192.0.2.0/24
Endpoint = <IP PUBLIQUE ANTIGONE>:51820
PersistentKeepalive=25
Contenu du fichier /etc/systemd/network/85-wg0.network
:
[Match]
Name = wg0
[Network]
Address = 192.0.2.2/32
[Route]
Gateway = 192.0.2.1
Destination = 192.0.2.0/24
GatewayOnlink = true
wg genpsk
pour générer une clé partagée pour chaque lien entre vos machines.wg genkey
pour générer une nouvelle clé privée pour une machine, puis wg pubkey
(avec une clé privée transmise en entrée standard) pour afficher la clé publique associée.systemd-networkd
s’il n’est pas activé par défaut : systemctl enable --now systemd-networkd
.
Astuces :
systemctl restart systemd-networkd && networkctl reload && networkctl reconfigure wg0 && networkctl forcerenew wg0
.wg show
affiche la liste des pairs WireGuard connectés et l’état de la connexion.Quelques règles iptables sont appliquées au démarrage de chacune de nos machines.
Les connexions internes avec le serveur de stockage sont coupées afin d’empêcher les conteneurs d’accéder au serveur NFS, qui ne demande pas d’authentification « by design ».
Voici le script utilisé, avec des IPs fictives définies ci-dessous :
192.0.2.0/24
192.0.2.1
198.51.100.1
#!/bin/bash
# Prevent all containers to reach the storage machine.
iptables -I DOCKER-USER -i wg0 -s 192.0.2.1 -j DROP
# Make an exception for our reverse-proxy on the syslog-ng port only.
iptables -I DOCKER-USER -i wg0 -d 198.51.100.1 -s 192.0.2.1 -p tcp --sport 514 -j ACCEPT
# Create the missing DOCKER-USER chain
# https://github.com/docker/for-linux/issues/1248
ip6tables -N DOCKER-USER
rp6tables -I FORWARD -j DOCKER-USER
En production, chacun de nos conteneurs est isolé dans un sous-réseau virtuel (créé avec Docker), dédié au service auquel il appartient.
Pour des raisons de sécurité, nous n’utilisons pas le réseau par défaut bridge
et le paramètre icc
(inter-container communication) est désactivé globalement sur Docker, et activé manuellement pour chaque sous-réseau.
Certains conteneurs, comme le reverse-proxy, le serveur PostgreSQL ou le résolveur DNS sont connectés à multiples sous réseaux en même temps. Chaque adresse IP est statiquement affectée.