NOPE LinkedIn

Catégories:
wireguard

WireGuard dans les conteneurs rootless de Podman

WireGuard dans les conteneurs rootless de Podman image

Important

Traduction d’un article du site Pro Custodibus

Le contenu de cette page est la traduction Française de l’article WireGuard in Podman Rootless Containers de Justin Ludwig

WireGuard dans les conteneurs rootless de Podman

Le mode noyau WireGuard peut fonctionner convenablement à l’intérieur de conteneurs rootless Podman. Cet article vous montrera comment, avec 10 exemples différents d’exécution de Podman rootlessly (plus 3 qui doivent être exécutés en tant que root) :

  1. Utiliser comme hub
  2. Utiliser pour le masquarade du site
  3. Utiliser pour le transfert de ports au sein d’un site
  4. Utiliser pour le transfert de ports entrants
  5. Utiliser pour le transfert de ports sortants
  6. Utiliser pour le réseau d’hôte (rootfull)
  7. Utiliser pour le réseau d’hôte avec la route par défaut (rootfull)
  8. Utiliser pour le réseau de conteneur
  9. Utiliser pour le réseau de pont
  10. Utiliser pour le réseau de pont sans masquarade
  11. Utiliser pour le réseau de pont avec WireGuard sur l’hôte (rootfull)
  12. Utiliser pour le réseau de pod
  13. Utiliser pour le transfert de ports à partir d’Internet

Différences par rapport à Docker

Mais avant tout, passons en revue quelques différences importantes entre l’exécution de WireGuard dans un conteneur “rootfull” Docker et un conteneur rootless Podman :

  1. Chargement du Module du Noyau
  2. Modifications du Pare-feu
  3. Options de Montage des Volumes
  4. Registres de Recherche Non Qualifiés
  5. Mode Réseau avec Podman Compose
  6. Liste des Paramètres du Noyau avec Podman Compose
  7. Paramètre de Transfert du Noyau

Chargement du Module du Noyau

Comme avec Docker, le hôte Podman doit avoir le module du noyau WireGuard installé. Tous les noyaux Linux depuis la version 5.6 comprennent le module WireGuard intégré, donc vous n’avez pas besoin d’installer quoi que ce soit à moins que votre hôte ne utilise un noyau Linux plus ancien que la version 5.6. Si vous utilisez un noyau plus ancien, vous pourriez être en mesure de installer le module du noyau WireGuard à partir du gestionnaire de paquets de votre distribution ; mais beaucoup plus souvent, vous devrez compiler le module du noyau WireGuard à partir des sources.

Comme avec Docker, cependant, avec Podman vous devez charger le module du noyau WireGuard en dehors de Podman. Le chargement de modules de noyau nécessite un accès root ; lorsque vous exécutez WireGuard en tant que root sur l’hôte, le module du noyau est chargé automatiquement. Mais lorsque vous exécutez WireGuard dans un conteneur Podman, si le module n’a pas déjà été chargé, WireGuard échouera à démarrer (généralement avec un message d’erreur Protocol not supported).

Vous pouvez vérifier quels modules noyau ont été chargés en exécutant la commande lsmod sur l’hôte. Si le module WireGuard a été chargé, le résultat ressemblera à ceci :

$ lsmod | grep wireguard
wireguard              94208  0
libblake2s             16384  1 wireguard
ip6_udp_tunnel         16384  1 wireguard
udp_tunnel             28672  1 wireguard
libcurve25519_generic  40960  1 wireguard

Si le module WireGuard n’a pas été chargé encore, il ne sera pas listé. Dans ce cas, vous pouvez utiliser la commande modprobe pour le charger :

$ lsmod | grep wireguard
$ sudo modprobe wireguard
$ lsmod | grep wireguard
wireguard              94208  0
...

Les modules noyau n’ont besoin d’être chargés qu’une seule fois après chaque démarrage, donc vous pourriez simplement exécuter modprobe manuellement chaque fois que vous redémarrez l’hôte Podman. Cependant, sur les hôtes avec systemd, vous pouvez plutôt lister les modules que vous souhaitez charger dans un fichier dans le répertoire /etc/modules-load.d/ de l’hôte (le fichier peut avoir n’importe quel nom ; nous utiliserons wireguard.conf pour notre exemple) :

$ echo wireguard | sudo tee /etc/modules-load.d/wireguard.conf
$ sudo systemctl restart systemd-modules-load
Note
Sur les hôtes sans systemd, le fichier /etc/modules est généralement utilisé au même titre que le répertoire /etc/modules-load.d/.

Si vous allez exécuter iptables à l’intérieur d’un conteneur Podman, comme nous le ferons avec plusieurs exemples suivants, vous aurez besoin de charger plusieurs modules noyau iptables de la même manière. Le fichier suivant /etc/modules-load.d/wireguard.conf s’assurera que le module noyau WireGuard et tous les modules iptables utilisés dans cet article的各种 exemples (sauf pour les exemples qui prennent en charge la route par défaut) sont chargés au démarrage :

# /etc/modules-load.d/wireguard.conf
# Module noyau WireGuard
wireguard
# Modules iptables pour le DNAT/SNAT de base et le masquage
iptable_nat
xt_MASQUERADE
xt_nat

Pour les exemples qui prennent en charge la route par défaut (c’est-à-dire utilisent AllowedIPs = 0.0.0.0/0), le script WireGuard exécutera plusieurs commandes iptables en arrière-plan — ce qui nécessite de charger plusieurs modules iptables différents. Le fichier suivant /etc/modules-load.d/wireguard.conf s’assurera que vous avez tous les modules iptables nécessaires pour prendre en charge la route par défaut :

# /etc/modules-load.d/wireguard.conf
# Module noyau WireGuard
wireguard
# Modules iptables pour lewg-quick route par défaut
iptable_mangle
iptable_raw
xt_addrtype
xt_comment
xt_connmark
xt_mark

MAJ 2023-12-27

Avec les dernières images de conteneur, basées sur Alpine Linux 3.19 (qui utilise le backend nftables du noyau), vous devrez charger plusieurs modules nftables du noyau au lieu des modules iptables ci-dessus. Le fichier suivant /etc/modules-load.d/wireguard.conf chargera tous les modules de noyau nécessaires pour les nouvelles images de conteneur :

# /etc/modules-load.d/wireguard.conf
# Module WireGuard
wireguard
# Modules iptables/nftables pour le DNAT/SNAT de base et la masquarade
nft_chain_nat
nft_compat
xt_nat
# Modules nftables pour la route par défaut de wg-quick
nft_ct
nft_fib_inet

Après avoir modifié ce fichier, exécutez la commande sudo systemctl restart systemd-modules-load pour vous assurer que tous les modules inclus dans le fichier sont chargés. Si cette commande génère un message d’erreur, exécutez journalctl -u systemd-modules-load pour vérifier quels modules ont échoué à charger.

Note

Dans les versions plus anciennes du noyau Linux, le module xt\_MASQUERADE avait un nom différent (par exemple, avec les noyaux RHEL 8, le module était nommé ipt\_MASQUERADE). Vous pouvez vérifier le nom correct du module en exécutant la commande suivante :

$ find /lib/modules/$(uname -r)/kernel -iname '\*masq\*'
/lib/modules/4.18.0-305.3.1.el8\_4.aarch64/kernel/net/ipv4/netfilter/ipt\_MASQUERADE.ko.xz
/lib/modules/4.18.0-305.3.1.el8\_4.aarch64/kernel/net/ipv6/netfilter/ip6t\_MASQUERADE.ko.xz
/lib/modules/4.18.0-305.3.1.el8\_4.aarch64/kernel/net/netfilter/nft\_masq.ko.xz

Dans l’exemple ci-dessus, le nom du module (IPv4) est ipt\_MASQUERADE, donc vous utiliserez ce nom à la place de xt\_MASQUERADE.

Modifications du Pare-feu

Une autre façon dont (rootless) Podman diffère de (rootfull) Docker est que lorsque Docker exécute un conteneur, il configurera automatiquement les règles iptables nécessaires pour le réseau du conteneur.

Modifier le pare-feu nécessite des droits d’administrateur, donc rootless Podman ne fait pas cela. Si vous avez un pare-feu en cours d’exécution sur l’hôte qui bloque les connexions entrantes par défaut (ce qui est recommandé), et que vous devez initier des connexions WireGuard à partir d’un hôte distant, vous devrez ouvrir manuellement le port d’écoute WireGuard pour le conteneur Podman.

Par exemple, si vous utilisez firewalld pour gérer votre pare-feu et que la zone public de firewalld protège l’interface réseau à partir de laquelle les connexions WireGuard distantes seront établies (par exemple eth0), et que votre conteneur Podman utilise un port d’écoute WireGuard de 51820, vous devrez exécuter la commande suivante pour permettre l’accès à ce port WireGuard :

$ sudo firewall-cmd --zone=public --add-port=51820/udp
success
Tip
Assurez-vous d’exécuter firewall-cmd --runtime-to-permanent après avoir apporté des modifications à votre configuration firewalld pour persister ces changements au-delà du redémarrage du système.

Options de montage de volume

Lorsque vous exécutez Podman sur un système avec SELinux activé (ce qui est la valeur par défaut pour Fedora, RHEL et de nombreux de leurs dérivés), certains volumes d’hôte montés dans un conteneur Podman nécessiteront une relabelisation avec une étiquette SELinux qui permet au conteneur d’accéder au volume. (C’est vrai aussi avec Docker, mais vous êtes plus susceptible de tomber dessus avec Podman, car Podman est souvent utilisé à la place de Docker par les mêmes distros qui activent SELinux par défaut.)

Tous les exemples de cet article utiliseront l’option Z lors du montage du répertoire de configuration WireGuard à partir de l’hôte dans le conteneur, ce qui indique à Podman d’étiqueter automatiquement le volume avec une étiquette privée et non partagée qui permet au conteneur de lire et écrire sur le volume sous SELinux :

podman run \
    ...
    --volume /srv/wg-hub/conf:/etc/wireguard​:Z \
    docker.io/procustodibus/wireguard

Recherche non qualifiée des registres

Docker utilise automatiquement docker.io comme son registre par défaut lors de la recherche d’images de conteneurs ; Podman n’a pas de registre par défaut. Si vous essayez de lancer une image avec un nom non qualifié avec Podman, vous obtiendrez une erreur similaire à celle-ci :

Erreur : le nom court "procustodibus/wireguard" n'a pas résolu en alias et aucun registre de recherche non qualifiée n'est défini dans "/etc/containers/registries.conf"

Pour corriger cela, vous pouvez ajouter docker.io à la liste des unqualified-search-registries dans votre fichier /etc/containers/registry.conf :

# /etc/containers/registries.conf
unqualified-search-registries = ["docker.io"]

Ou vous pouvez simplement qualifier le nom de l’image lors de l’exécution d’un conteneur, comme nous le ferons dans tous les exemples de cet article :

podman run \
    ...
    docker.io/​procustodibus/wireguard

Mode réseau avec Podman Compose

Avant la version 1.0.4, Podman Compose ignorait principalement les directives network_mode et networks dans les fichiers docker-compose.yml; aucune des exemples de fichiers docker-compose.yml utilisant ces directives ne fonctionnera correctement avec Podman Compose avant la version 1.0.4.

Malheureusement, comme du milieu d’octobre 2022, la version 1.0.4 de Podman Compose n’a pas encore été officiellement publiée. Pour accéder à ses corrections, vous devez exécuter la version de développement de ce dernier. Vous pouvez installer la version de développement avec la commande suivante :

$ pip3 install https://github.com/containers/podman-compose/archive/devel.tar.gz

Installez-la en tant que root (par exemple avec sudo) pour la rendre disponible à tous les utilisateurs sur votre système (au lieu de votre propre utilisateur uniquement). Si vous n’avez pas pip sur votre système, vous pouvez généralement l’installer via le package python3-pip de votre gestionnaire de paquets de distribution (et exécutez ensuite pip3 install --upgrade pip setuptools pour mettre à jour pip à sa dernière version).

Liste des Paramètres du noyau avec Podman Compose

Une autre particularité de Podman Compose est qu’il ne prend pas en charge l’utilisation de la directive sysctls avec une carte de paramètres — mais il le fait avec une liste clé=valeur. Ainsi, l’utilisation de la directive sysctls suivante dans un fichier docker-compose.yml ne fonctionnera pas :

sysctls:
  net.ipv4.conf.all.forwarding: 1

Mais cette utilisation de la directive sysctls avec Podman Compose fonctionnera :

sysctls:
- net.ipv4.conf.all.forwarding=1

Paramètre de noyau Forwarding

Et une dernière manière significative dans laquelle rootless Podman diffère de Docker est que Docker active automatiquement le paramètre de noyau net.ipv4.ip_forward (connu sous le nom de net.ipv4.conf.all.forwarding) sur l’hôte chaque fois qu’il démarre un conteneur (sauf si ce conteneur n’a pas accès au réseau du tout). Rootless Podman ne fait pas cela, donc dans les cas où vous souhaitez que WireGuard transmette des paquets et que ce paramètre n’est pas déjà activé globalement sur le système, vous devez l’activer explicitement pour le conteneur de WireGuard.

Vous pouvez le faire via le drapeau --sysctl net.ipv4.conf.all.forwarding=1 avec la commande podman run, ou via la directive sysctls ci-dessus dans un fichier docker-compose.yml. Tous les exemples de cet article qui nécessitent ce paramètre incluront le drapeau ou la directive ci-dessus.

Scénarios Concrets

Maintenant que nous avons couvert les principales différences entre Podman et Docker lors de l’utilisation de celui-ci pour exécuter un conteneur WireGuard, examinons quelques exemples concrets de l’exécution de WireGuard dans un conteneur Podman :

Utilisation en tant que Hub

WireGuard Hub dans un Conteneur Podman

Le premier exemple que nous examinerons est le lancement du hub d’une topologie WireGuard hub-and-spoke dans un conteneur Podman. Nous utiliserons la même configuration WireGuard pour ce hub que celle de “Host C” du guide Configuration Hub and Spoke WireGuard — à l’exception du fait que nous ne définirons pas le paramètre de noyau IP forwarding dans la configuration WireGuard (nous le définirons plutôt dans la configuration Podman).

Important
Pour exécuter cet exemple, assurez-vous de charger le module de noyau WireGuard sur l’hôte Podman et d’ouvrir l’accès au port UDP 51823 de l’hôte, comme décrit dans les sections Chargement du Module de Noyau et Modifications du Pare-feu au début de cet article.

Enregistrez la configuration WireGuard pour le hub dans son propre répertoire quelque part pratique sur l’hôte, comme dans le répertoire /srv/wg-hub/conf/ :

# /srv/wg-hub/conf/wg0.conf

# paramètres locaux pour Host C
[Interface]
PrivateKey = CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCGA=
Address = 10.0.0.3/32
ListenPort = 51823

# paramètres distants pour Endpoint A
[Peer]
PublicKey = /TOE4TKtAqVsePRVR+5AA43HkAK5DSntkOCO7nYq5xU=
AllowedIPs = 10.0.0.1/32

# paramètres distants pour Endpoint B
[Peer]
PublicKey = fE/wdxzl0klVp/IR8UcaoGUMjqaWi3jAd7KzHKFS6Ds=
AllowedIPs = 10.0.0.2/32

Alors vous pouvez exécuter un conteneur pour le hub avec la commande podman run suivante :

podman run \
    --cap-add NET_ADMIN \
    --name wg-hub \
    --publish 51823:51823/udp \
    --rm \
    --sysctl net.ipv4.conf.all.forwarding=1 \
    --volume /srv/wg-hub/conf:/etc/wireguard:Z \
    docker.io/procustodibus/wireguard

Ces sont les fonctions des arguments de la commande :

  1. --cap-add NET_ADMIN: Accorde au conteneur la capacité NET_ADMIN — c’est nécessaire pour démarrer une interface WireGuard à l’intérieur du conteneur.
  2. --name wg-hub: Définit le nom du conteneur sur wg-hub (vous pouvez définir ce que vous voulez ou l’omettre complètement si vous ne vous souciez pas de son nom).
  3. --publish 51823:51823/udp: Transfère le port public 51823 UDP de l’hôte au port 51823 UDP du conteneur — assurez-vous que celui-ci correspond à la configuration ListenPort dans le fichier de configuration WireGuard (le premier peut être n’importe quel port que vous souhaitez exposer publiquement). Assurez-vous également d’ouvrir l’accès au port public de l’hôte via votre pare-feu si vous voulez que les hôtes distants puissent initier des connexions WireGuard à ce conteneur.
  4. --rm: Supprime le conteneur lorsqu’il est arrêté (vous pouvez l’omettre si vous ne souhaitez pas supprimer le conteneur).
  5. --sysctl net.ipv4.conf.all.forwarding=1: Active la transmission de paquets dans le conteneur.
  6. --volume /srv/wg-hub/conf:/etc/wireguard:Z: Mappe le répertoire /srv/wg-hub/conf/ de l’hôte au répertoire /etc/wireguard/ du conteneur (vous pouvez changer le répertoire d’hôte en ce que vous voulez). L’option Z permet au conteneur d’accéder à ce répertoire même lorsque SELinux est activé.
  7. docker.io/procustodibus/wireguard: Exécute la dernière version de l’image WireGuard.

Alternativement, vous pouvez placer le fichier suivant docker-compose.yml dans le répertoire situé au-dessus du fichier de configuration WireGuard :

# /srv/wg-hub/docker-compose.yml
version: '3'
services:
  wireguard:
    image: docker.io/procustodibus/wireguard
    cap_add:
    - NET_ADMIN
    ports:
    - 51823:51823/udp
    sysctls:
    - net.ipv4.conf.all.forwarding=1
    volumes:
    - ./conf:/etc/wireguard:Z

Et ensuite démarrez un conteneur pour le hub en exécutant podman-compose up à partir du même répertoire que le fichier docker-compose.yml.

La configuration Podman pour cet exemple est très similaire à l’exemple rootfull Docker Utilisation pour le Hub de l’article original WireGuard Containers, avec les différences suivantes pour Podman :

  1. Nous avons activé explicitement le paramètre du noyau permettant la transmission des paquets.
  2. Nous avons ajouté l’option Z au volume de configuration WireGuard.
  3. Nous avons qualifié le nom de l’image avec le registre docker.io.

Utilisation pour le Masquarading Site

Masquarading Point-to-Site WireGuard à partir d’un conteneur Docker

Voici la traduction en français du texte technique Markdown que vous avez fourni :

Ensuite, examinons comment utiliser un conteneur Podman pour fournir une connectivité au réseau local (LAN) de l’hôte Podman à partir d’autres points de terminaison WireGuard distants, dans une topologie point-to-site (avec masquage). Nous utiliserons la même configuration WireGuard pour le conteneur que “Host β” du guide Configuration de point à site WireGuard — avec deux exceptions :

  1. Nous ne définirons pas le paramètre de noyau “IP forwarding” dans la configuration WireGuard (nous le définirons plutôt dans la configuration Podman).
  2. Nous pouvons simplifier les règles iptables du conteneur à une seule ligne (pour masquerer tous les paquets transférés, sauf ceux envoyés par son interface WireGuard).
Important
Pour exécuter cet exemple, assurez-vous de charger les modules noyau WireGuard et iptables sur l’hôte Podman et d’ouvrir l’accès au port UDP 51822 de l’hôte, comme décrit dans les sections Chargement des modules noyau et Modifications du pare-feu au début de cet article.

Enregistrez la configuration WireGuard pour Host β dans son propre répertoire quelque part pratique sur l’hôte, comme dans le répertoire /srv/wg-p2s/conf/ :

# /srv/wg-p2s/conf/wg0.conf

# paramètres locaux pour Host β
[Interface]
PrivateKey = ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBFA=
Address = 10.0.0.2/32
ListenPort = 51822

# masquage IP
PreUp = iptables -t nat -A POSTROUTING ! -o %i -j MASQUERADE

# paramètres distants pour le Point de terminaison A
[Peer]
PublicKey = /TOE4TKtAqVsePRVR+5AA43HkAK5DSntkOCO7nYq5xU=
AllowedIPs = 10.0.0.1/32

Vous pouvez exécuter un conteneur pour cette interface WireGuard avec la commande podman run suivante :

podman run \
    --cap-add NET_ADMIN \
    --cap-add NET_RAW \
    --publish 51822:51822/udp \
    --name wg-p2s \
    --rm \
    --sysctl net.ipv4.conf.all.forwarding=1 \
    --volume /srv/wg-p2s/conf:/etc/wireguard:Z \
    docker.io/procustodibus/wireguard

Alternativement, vous pouvez placer le fichier suivant docker-compose.yml dans le répertoire situé au-dessus du fichier de configuration WireGuard :

# /srv/wg-p2s/docker-compose.yml
version: '3'
services:
  wireguard:
    image: docker.io/procustodibus/wireguard
    cap_add:
    - NET_ADMIN
    - NET_RAW
    ports:
    - 51822:51822/udp
    sysctls:
    - net.ipv4.conf.all.forwarding=1
    volumes:
    - ./conf:/etc/wireguard:Z

Et ensuite démarrer le conteneur en exécutant podman-compose up à partir du même répertoire que le fichier docker-compose.yml.

La configuration Podman pour cet exemple est très similaire à l’exemple rootfull Docker Utilisation pour le masquage de site de l’article original WireGuard Containers, avec les différences suivantes pour Podman :

  1. Nous avons accordé la capacité NET_RAW (pour exécuter iptables dans un conteneur sans privilèges root).
  2. Nous avons activement activé le paramètre de noyau packet forwarding.
  3. Nous avons ajouté l’option Z au volume de configuration WireGuard.
  4. Nous avons qualifié le nom de l’image avec le registre docker.io.

Utilisation pour le transfert de ports du site

Transfert de ports du site WireGuard à partir d’un conteneur Docker

Vous pouvez également utiliser un conteneur Podman pour fournir la connectivité à partir du LAN (Réseau local) du hôte Podman vers d’autres points distants WireGuard, inversant le topologie conventionnelle point-to-site en transférant le trafic pour des services spécifiques du « site » au « point ». Nous utiliserons la même configuration WireGuard pour le conteneur dans ce scénario que celle de « Host β » du guide WireGuard Point to Site With Port Forwarding — à l’exception du fait que nous ne définirons pas le paramètre de noyau IP forwarding dans la configuration WireGuard (nous le définirons plutôt dans la configuration Podman).

Important
Pour exécuter cet exemple, assurez-vous de charger les modules de noyau WireGuard et iptables sur le hôte Podman et d’ouvrir l’accès au port UDP 51822 du hôte, comme décrit dans les sections Chargement des modules de noyau et Modifications du pare-feu au début de cet article.

Sauvegardez la configuration WireGuard pour le site dans son propre répertoire quelque part pratique sur l’hôte, comme dans le répertoire /srv/wg-fwd/conf/ :

# /srv/wg-fwd/conf/wg0.conf

# paramètres locaux pour l'Hôte β
[Interface]
PrivateKey = ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBFA=
Address = 10.0.0.2/32
ListenPort = 51822

# transfert de port
PreUp = iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 10.0.0.1

# paramètres distants pour le Point de terminaison A
[Peer]
PublicKey = /TOE4TKtAqVsePRVR+5AA43HkAK5DSntkOCO7nYq5xU=
AllowedIPs = 10.0.0.1/32

Comme dans ce scénario, nous transférons le port 80 de l’hôte, qui est un “port privilégié” (comme tous les ports inférieurs à 1024), nous aurions normalement besoin d’utiliser root sur l’hôte pour exécuter un conteneur avec cette configuration WireGuard. Nous pouvons néanmoins y parvenir avec Podman sans privilèges, cependant, en ajustant cette restriction. La méthode la plus simple consiste à modifier la définition des ports privilégiés ; exécutez la commande suivante en tant que root :

$ sudo sysctl -w net.ipv4.ip_unprivileged_port_start=0
Note
Cela ne change que temporairement la définition du port privilégié — pour le rendre permanent, ajoutez le paramètre de noyau mentionné ci-dessus à un fichier dans votre répertoire /etc/sysctl.d/ (ou au fichier /etc/sysctl.conf). Consultez également les réponses à la question Allow non-root process to bind to port 80 and 443? sur Super User pour plusieurs façons alternatives d’exécuter une commande sans privilèges qui peut écouter des ports privilégiés.

De plus, si vous avez un pare-feu configuré sur l’hôte, vous devrez l’ajuster pour permettre l’accès au port 80 depuis le LAN. Consultez la section « Point to Site » de la Guide sur l’utilisation de WireGuard avec UFW, la Guide sur l’utilisation de WireGuard avec Firewalld ou la Guide sur l’utilisation de WireGuard avec Nftables (ou la section « Configurer le pare-feu sur l’hôte β » du WireGuard Point to Site Avec Port Forwarding) pour des exemples de comment procéder.

Note
Ceci est en plus de permettre l’accès à travers votre pare-feu au port d’écoute WireGuard (51822 dans cet exemple), comme décrit dans la section Modifications du Pare-feu.

Exécutez ensuite le conteneur Podman pour cette configuration WireGuard avec la commande podman run suivante :

podman run \
    --cap-add NET_ADMIN \
    --cap-add NET_RAW \
    --name wg-fwd \
    --network slirp4netns:port_handler=slirp4netns \
    --publish 80:80 \
    --publish 51822:51822/udp \
    --rm \
    --sysctl net.ipv4.conf.all.forwarding=1 \
    --volume /srv/wg-fwd/conf:/etc/wireguard:Z \
    docker.io/procustodibus/wireguard

Alternativement, vous pouvez placer le fichier suivant docker-compose.yml dans le répertoire situé au-dessus du fichier de configuration WireGuard :

# /srv/wg-fwd/docker-compose.yml
version: '3'
services:
  wireguard:
    image: docker.io/procustodibus/wireguard
    cap_add:
    - NET_ADMIN
    - NET_RAW
    network_mode: slirp4netns:port_handler=slirp4netns
    ports:
    - 80:80
    - 51822:51822/udp
    sysctls:
    - net.ipv4.conf.all.forwarding=1
    volumes:
    - ./conf:/etc/wireguard:Z

Et ensuite démarrez le conteneur en exécutant podman-compose up depuis le même répertoire que le fichier docker-compose.yml.

Note
Cet exemple nécessite Podman Compose version 1.0.4 ou plus récente (consultez la section Mode de réseau avec Podman Compose).

La configuration Podman pour cet exemple est très similaire à l’exemple rootfull Docker Utilisation pour le transfert de ports au site de l’article original WireGuard Containers, avec les différences suivantes pour Podman :

  1. Nous avons accordé la capacité NET_RAW (pour exécuter iptables dans un conteneur sans privilèges root).
  2. Nous avons défini slirp4netns comme gestionnaire de transfert de ports (pour permettre le transfert de ports depuis l’hôte vers une destination en dehors du conteneur).
  3. Nous avons activé explicitement le paramètre de noyau pour la transmission des paquets.
  4. Nous avons ajouté l’option Z au volume de configuration WireGuard.
  5. Nous avons qualifié le nom de l’image avec le registre docker.io.

Utilisation pour le transfert de ports entrants

Transfert de ports entrants WireGuard à partir du conteneur Docker

Vous pouvez également utiliser le transfert de ports avec un conteneur Podman de manière qui rend l’hôte Podman un proxy public pour certains services privés connectés via une topologie point-to-point WireGuard (ou topologie hub-and-spoke).

Pour cet exemple, nous utiliserons un réseau point à point entre le Point de terminaison A et le Point de terminaison B, similaire au configuré dans la Configuration WireGuard Point to Point guide, mais où Endpoint A n’est pas une station de travail utilisateur finale, mais en fait un serveur dans un datacenter avec un port TCP public 80 exposé. Endpoint B est un serveur web dans un autre datacenter, avec uniquement sa porte UDP WireGuard 51822 exposée.

Important
Pour exécuter cet exemple, assurez-vous de charger les modules noyau WireGuard et iptables sur l’hôte Podman, comme décrit dans la section Chargement des Modules Noyau au début de cet article.

Nous ajouterons quelques règles iptables à la configuration WireGuard pour Endpoint A, mais sinon nous utiliserons la même configuration qu’au WireGuard Point to Point Configuration guide. Enregistrez ce fichier de configuration dans son propre répertoire quelque part pratique sur l’hôte, comme dans le répertoire /srv/wg-ifw/conf/ :

# /srv/wg-ifw/conf/wg0.conf

# paramètres locaux pour Endpoint A
[Interface]
PrivateKey = AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEE=
Address = 10.0.0.1/32
ListenPort = 51821

# redirrection de ports
PreUp = iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 10.0.0.2
PreUp = iptables -t nat -A POSTROUTING -p tcp --dport 80 -j MASQUERADE

# paramètres distants pour le Point de terminaison B
[Peer]
PublicKey = fE/wdxzl0klVp/IR8UcaoGUMjqaWi3jAd7KzHKFS6Ds=
Endpoint = 203.0.113.2:51822
AllowedIPs = 10.0.0.2/32

La première règle iptables ci-dessus transférera les paquets que le conteneur reçoit au port TCP `80` vers le Point de terminaison B. La deuxième règle iptables masquera ces paquets comme s'ils provenaient du conteneur lui-même, afin que le Point de terminaison B envoie des réponses à travers le Point de terminaison A.









    
    





    
    


Tip
Vous pouvez omettre la règle iptables de masquage si vous utilisez plutôt l’un des plusieurs stratégies d’routing alternatives sur le Point de terminaison B couvertes dans l’article Port Forwarding WireGuard à partir de l’Internet.
De plus, car nous transférons ici le port `80` du hôte, qui est un "port privilégié" (comme tous les ports inférieurs à `1024`), nous aurions normalement besoin de root sur le hôte pour exécuter un conteneur avec cette configuration WireGuard. Nous pouvons néanmoins l'exécuter avec Podman sans privilèges, cependant, en ajustant cette restriction. La méthode la plus simple consiste à modifier la définition des ports privilégiés ; exécutez la commande suivante en tant que root : ```bash $ sudo sysctl -w net.ipv4.ip_unprivileged_port_start=0
Note
Cela ne change temporairement que la définition du port privilégié — pour le rendre permanent, ajoutez le paramètre de noyau ci-dessus à un fichier dans votre répertoire /etc/sysctl.d/ (ou au fichier /etc/sysctl.conf). Consultez également les réponses à la question Allow non-root process to bind to port 80 and 443? sur Super User pour plusieurs façons alternatives d’exécuter une commande sans privilèges qui peut écouter des ports privilégiés.

Et également, si vous avez un pare-feu configuré sur l’hôte, vous devrez l’ajuster pour permettre l’accès au port 80 à partir de son interface réseau publique. Si vous utilisez firewalld pour gérer votre pare-feu, vous pouvez probablement simplement ajouter le port 80 à sa zone public :

$ sudo firewall-cmd --zone=public --add-port=80/tcp
success
Note
Cela s’ajoute à l’autorisation de passer par votre pare-feu au port d’écoute WireGuard (51822 dans cet exemple), comme décrit dans la section Modifications du Pare-feu.

Ensuite, exécutez un conteneur pour cette configuration WireGuard avec la commande podman run suivante :

podman run \
    --cap-add NET_ADMIN \
    --cap-add NET_RAW \
    --publish 80:80 \
    --publish 51821:51821/udp \
    --name wg-ifw \
    --network slirp4netns:port_handler=slirp4netns \
    --rm \
    --sysctl net.ipv4.conf.all.forwarding=1 \
    --volume /srv/wg-ifw/conf:/etc/wireguard:Z \
    docker.io/procustodibus/wireguard

Alternativement, vous pouvez placer le fichier docker-compose.yml suivant dans le répertoire situé au-dessus du fichier de configuration WireGuard :

# /srv/wg-ifw/docker-compose.yml
version: '3'
services:
  wireguard:
    image: docker.io/procustodibus/wireguard
    cap_add:
    - NET_ADMIN
    - NET_RAW
    ports:
    - 80:80
    - 51821:51821/udp
    network_mode: slirp4netns:port_handler=slirp4netns
    sysctls:
    - net.ipv4.conf.all.forwarding=1
    volumes:
    - ./conf:/etc/wireguard:Z

Et ensuite démarrez le conteneur en exécutant podman-compose up à partir du même répertoire que le fichier docker-compose.yml.

Note
Cet exemple nécessite Podman Compose version 1.0.4 ou plus récente (voir la section Mode de réseau avec Podman Compose).

La configuration Podman pour cet exemple est très similaire à l’exemple rootfull Docker Utilisation pour le transfert d’entrées sortantes de l’article original WireGuard Containers, avec les différences suivantes pour Podman :

  1. Nous avons accordé la capacité NET_RAW (pour exécuter iptables dans un conteneur sans privilèges root).
  2. Nous avons défini slirp4netns comme le gestionnaire de transfert de ports (pour permettre le transfert de ports du hôte à une destination en dehors du conteneur).
  3. Nous avons activé explicitement le paramètre du noyau pour l’encapsulation des paquets.
  4. Nous avons ajouté l’option Z au volume de configuration WireGuard.
  5. Nous avons qualifié le nom de l’image avec le registre docker.io.

Utilisation pour le Transfert de Ports Sortants

Transfert de ports sortants WireGuard à partir d’un conteneur Docker

Vous pouvez également utiliser le transfert de ports avec un conteneur Podman de manière qui rend le hôte Podman un proxy privé pour certains services publics connectés via une topologie de réseau point-à-point WireGuard (ou topologie hub-and-spoke).

Pour cet exemple, nous utiliserons à nouveau un réseau point-à-point entre le Point de terminaison A et le Point de terminaison B, similaire au celui montré par la Configuration de WireGuard Point-to-Point mais où plutôt que le Point de terminaison B héberger un serveur web lui-même, il ne fait qu’encadrer le trafic encadré sur le port TCP 80 vers un autre serveur web externe.

Important
Pour exécuter cet exemple, assurez-vous de charger les modules noyau WireGuard et iptables sur l’hôte Podman, et d’ouvrir l’accès au port UDP 51822 de l’hôte, comme décrit dans les sections Chargement des Modules Noyau et Modifications du Pare-feu à la début de cet article.

Nous ajouterons quelques règles iptables à la configuration WireGuard pour le Point de terminaison B, mais sinon nous utiliserons la même configuration pour lui que dans le guide Configuration WireGuard Point à Point. Enregistrez ce fichier de configuration dans un répertoire convenable sur l’hôte, comme dans le répertoire /srv/wg-ofw/conf/ :

# /srv/wg-ofw/conf/wg0.conf
# paramètres locaux pour le Point de terminaison B
[Interface]
PrivateKey = ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBFA=
Address = 10.0.0.2/32
ListenPort = 51822

# transfert
PreUp = iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.0.2.3
PreUp = iptables -t nat -A POSTROUTING -p tcp --dport 80 -j MASQUERADE

# paramètres distants pour le Point de terminaison A
[Peer]
PublicKey = /TOE4TKtAqVsePRVR+5AA43HkAK5DSntkOCO7nYq5xU=
AllowedIPs = 10.0.0.1/32

La première règle iptables ci-dessus transférera les paquets que le conteneur reçoit via le tunnel WireGuard au port TCP 80 vers l’adresse IP du serveur web de 192.0.2.3. La deuxième règle iptables masquera ces paquets comme s’ils provenaient directement du conteneur lui-même, afin que (en complément de la masquerade fournie par le hôte Podman pour le conteneur) le serveur web externe envoie les réponses à travers Endpoint B (où le hôte Podman renverra ces réponses au conteneur, pour qu’il les transfère ensuite vers Endpoint A).

Note
Contrairement aux exemples précédents Utilisation pour le transfert de ports du site et Utilisation pour le transfert de ports entrants, nous *n’avons pas besoin* d’ajuster les restrictions de port privilégié sur l’hôte, ni d’ajuster le pare-feu de l’hôte pour le port transféré, car ce scénario ne manipule pas les paquets envoyés au port 80 sur l’*hôte lui-même* — seulement les paquets du port 80 qui ont été tunnelisés dans le conteneur.

Exécutez un conteneur pour cette configuration WireGuard avec la commande suivante :

podman run \
    --cap-add NET_ADMIN \
    --cap-add NET_RAW \
    --publish 51822:51822/udp \
    --name wg-ofw \
    --rm \
    --sysctl net.ipv4.conf.all.forwarding=1 \
    --volume /srv/wg-ofw/conf:/etc/wireguard:Z \
    docker.io/procustodibus/wireguard

Alternativement, vous pouvez placer le fichier suivant docker-compose.yml dans le répertoire situé au-dessus du fichier de configuration WireGuard :

# /srv/wg-ofw/docker-compose.yml
version: '3'
services:
  wireguard:
    image: docker.io/procustodibus/wireguard
    cap_add:
    - NET_ADMIN
    - NET_RAW
    ports:
    - 51822:51822/udp
    sysctls:
    - net.ipv4.conf.all.forwarding=1
    volumes:
    - ./conf:/etc/wireguard:Z

Et ensuite démarrez le conteneur en exécutant podman-compose up à partir du même répertoire que le fichier docker-compose.yml.

La configuration Podman pour cet exemple est très similaire à l’exemple rootfull Docker Utilisation pour la redirection de ports sortants de l’article original WireGuard Containers, avec les différences suivantes pour Podman :

  1. Nous avons accordé la capacité NET_RAW (pour exécuter iptables dans un conteneur sans privilèges root).
  2. Nous avons activement activé le paramètre de noyau permettant le transfert de paquets.
  3. Nous avons ajouté l’option Z au volume de configuration WireGuard.
  4. Nous avons qualifié le nom de l’image avec le registre docker.io.

Utilisation pour le réseau d’hôte

WireGuard Podman Host Network

Vous pouvez utiliser un conteneur Podman pour fournir l’accès au réseau WireGuard du hôte Podman lui-même, si vous souhaitez utiliser le hôte lui-même comme un point régulier dans une topologie point-to-point ou point-to-site, ou en tant qu’élément générique d’une topologie hub-and-spoke. Cependant, dans ce scénario, vous devez exécuter le conteneur en tant que root, afin de configurer l’interface WireGuard à l’intérieur de l’espace de noms réseau racine du hôte.

Important
Pour exécuter cet exemple, assurez-vous de charger le module noyau WireGuard sur le hôte Podman comme décrit dans la section Chargement du Module Noyau au début de cet article.

Pour cet exemple, nous utiliserons exactement la même configuration WireGuard que “Endpoint A” du guide Configuration Point-to-Point WireGuard. Enregistrez la configuration WireGuard pour le conteneur dans son propre répertoire quelque part pratique sur le hôte, comme dans le répertoire /srv/wg-host/conf/ :

# /srv/wg-host/conf/wg0.conf

# paramètres locaux pour Endpoint A
[Interface]
PrivateKey = AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEE=
Address = 10.0.0.1/32
ListenPort = 51821

# paramètres distants pour le Point de terminaison B
[Peer]
PublicKey = fE/wdxzl0klVp/IR8UcaoGUMjqaWi3jAd7KzHKFS6Ds=
Endpoint = 203.0.113.2:51822
AllowedIPs = 10.0.0.2/32

Vous pouvez ensuite exécuter un conteneur pour cette configuration WireGuard avec la commande podman run suivante :

sudo podman run \
    --cap-add NET_ADMIN \
    --name wg-host \
    --network host \
    --rm \
    --volume /srv/wg-host/conf:/etc/wireguard:Z \
    docker.io/procustodibus/wireguard

Lorsque vous exécutez le conteneur de cette manière, avec l’indicateur --network host, il exposera le réseau WireGuard au reste des processus sur l’hôte Podman. Ainsi, si, par exemple, vous avez un serveur HTTP en cours d’exécution sur le Point de terminaison B (10.0.0.2) dans le réseau WireGuard (comme nous le faisons dans le scénario pour la Configuration WireGuard Point à Point guide), vous pourrez accéder à ce serveur web depuis l’hôte Podman en utilisant cURL (ou tout navigateur Web) comme suit :

$ curl 10.0.0.2:80
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
...

Alternativement, vous pouvez exécuter le conteneur WireGuard avec la commande podman-compose si vous placez le fichier suivant docker-compose.yml dans le répertoire situé au-dessus du fichier de configuration WireGuard :

# /srv/wg-host/docker-compose.yml
version: '3'
services:
  wireguard:
    image: docker.io/procustodibus/wireguard
    cap_add:
    - NET_ADMIN
    network_mode: host
    volumes:
    - ./conf:/etc/wireguard:Z

Et ensuite, démarrez le conteneur en exécutant sudo podman-compose up à partir du même répertoire que le fichier docker-compose.yml.

Note
Cet exemple nécessite Podman Compose version 1.0.4 ou plus tard (voir la section Mode de réseau avec Podman Compose).

La configuration Podman pour cet exemple est très similaire à l’exemple Docker Utiliser le mode réseau d’hôte de l’article original WireGuard Containers, avec les différences suivantes pour Podman :

  1. Nous avons ajouté l’option Z au volume de configuration WireGuard.
  2. Nous avons qualifié le nom de l’image avec le registre docker.io.

Utiliser le mode réseau d’hôte avec la route par défaut

WireGuard Podman Host Network With Default Route

Vous pouvez également utiliser un conteneur Podman pour fournir un accès à Internet au hôte lui-même via le réseau WireGuard du conteneur. Cependant, dans ce scénario, vous devez également exécuter le conteneur en tant que root, afin qu’il puisse configurer l’interface WireGuard à l’intérieur de l’espace de noms réseau racine du hôte.

Important
Pour exécuter cet exemple, assurez-vous de charger les modules noyau WireGuard et iptables sur l’hôte Podman comme décrit dans la section Chargement des Modules Noyau au début de cet article.

Pour cet exemple, nous utiliserons une configuration WireGuard similaire à “Point A” du guide Configuration Point à Site WireGuard. Enregistrez la configuration WireGuard pour le conteneur dans son propre répertoire quelque part pratique sur l’hôte, comme dans le répertoire /srv/wg-host-internet/conf/ :

# /srv/wg-host-internet/conf/wg0.conf

# paramètres locaux pour Endpoint A
[Interface]
PrivateKey = AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEE=
Address = 10.0.0.1/32
ListenPort = 51821

# paramètres distants pour Host β
[Peer]
PublicKey = fE/wdxzl0klVp/IR8UcaoGUMjqaWi3jAd7KzHKFS6Ds=
Endpoint = 203.0.113.2:51822
AllowedIPs = 0.0.0.0/0

La seule différence entre cet exemple et le scénario du guide Configuration Point à Site WireGuard est que dans cet exemple, l’Internet est le “site” auquel Host β fournira l’accès, plutôt que simplement le réseau local de Host β. Ainsi, nous avons modifié la configuration WireGuard d’Endpoint A en changeant la valeur de AllowedIPs à 0.0.0.0/0 (l’espace d’adressage IPv4 entier).

Ce paramètre AllowedIPs déclenchera le script WireGuard utilisé dans le conteneur Podman pour prendre en charge la route par défaut de l’hôte, envoyant tout le trafic non local de l’hôte à travers le tunnel WireGuard. Cela nécessite également d’activer le paramètre ipv4.conf.all.src_valid_mark du noyau à l’extérieur du conteneur :

$ sudo sysctl -w net.ipv4.conf.all.src_valid_mark=1
Note
Ce paramètre est temporairement activé — pour le rendre permanent, ajoutez-le à un fichier dans votre répertoire /etc/sysctl.d/ (ou à votre fichier /etc/sysctl.conf).

Avec ce paramètre de noyau défini, vous pouvez exécuter le conteneur WireGuard en tant que root avec la commande podman run suivante :

sudo podman run \
    --cap-add NET_ADMIN \
    --cap-add NET_RAW \
    --name wg-host-internet \
    --network host \
    --rm \
    --volume /srv/wg-host-internet/conf:/etc/wireguard:Z \
    docker.io/procustodibus/wireguard

L’hôte enverra maintenant tout son trafic Internet à travers le tunnel WireGuard. Si vous exécutez la commande suivante sur l’Endpoint A, cela démontrera qu’il utilise désormais l’adresse IP de Host β pour accéder à Internet :

$ curl icanhazip.com
203.0.113.2

Alternativement, vous pouvez exécuter le conteneur WireGuard via la commande podman-compose si vous placez le fichier suivant docker-compose.yml dans le répertoire au-dessus du fichier de configuration WireGuard :

# /srv/wg-host-internet/docker-compose.yml
version: '3'
services:
  wireguard:
    image: docker.io/procustodibus/wireguard
    cap_add:
    - NET_ADMIN
    - NET_RAW
    network_mode: host
    volumes:
    - ./conf:/etc/wireguard:Z

Et démarrez le conteneur en exécutant sudo podman-compose up à partir du même répertoire que le fichier docker-compose.yml.

Note
Cet exemple nécessite Podman Compose version 1.0.4 ou plus tard (consultez la section Mode de réseau avec Podman Compose).

Utilisation pour le réseau de conteneur

WireGuard Podman Container Network

Vous pouvez également utiliser un conteneur Podman pour fournir l’accès à un réseau WireGuard pour d’autres conteneurs sélectionnés sur l’hôte Podman. La méthode la plus simple consiste à exécuter les autres conteneurs dans le namespace de réseau du premier conteneur.

Important
Pour exécuter cet exemple, assurez-vous de charger le module noyau WireGuard sur l’hôte Podman et d’ouvrir l’accès au port UDP 51822 de l’hôte, comme décrit dans les sections Chargement du module noyau et Modifications du pare-feu au début de cet article.

Pour cet exemple, nous utiliserons exactement la même configuration de WireGuard que “Endpoint B” du guide WireGuard Point to Point Configuration. Enregistrez la configuration de WireGuard pour le conteneur dans son propre répertoire quelque part pratique sur l’hôte, comme dans le répertoire /srv/wg-point/conf/ :

# /srv/wg-point/conf/wg0.conf

# paramètres locaux pour Endpoint B
[Interface]
PrivateKey = ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBFA=
Address = 10.0.0.2/32
ListenPort = 51822

# paramètres distants pour Endpoint A
[Peer]
PublicKey = /TOE4TKtAqVsePRVR+5AA43HkAK5DSntkOCO7nYq5xU=
AllowedIPs = 10.0.0.1/32

Exécutez un conteneur pour cette configuration de WireGuard avec la commande podman run suivante :

podman run \
    --cap-add NET_ADMIN \
    --publish 51822:51822/udp \
    --name wg-point \
    --rm \
    --volume /srv/wg-point/conf:/etc/wireguard:Z \
    docker.io/procustodibus/wireguard

Et avec ce conteneur en cours d’exécution (auquel nous avons donné le nom arbitraire “wg-point”), utilisez l’indicateur --network container:wg-point pour exécuter chaque conteneur frère auquel vous souhaitez partager le réseau WireGuard, comme suit :

podman run \
    --name example-web-server \
    --network container:wg-point \
    --rm \
    docker.io/nginx

Le conteneur example-web-server démarrera un serveur web générique nginx, qui écoute sur le port TCP 80 dans son propre espace de réseau du conteneur WireGuard. Cela vous permet d’accéder au serveur web à partir du réseau WireGuard en utilisant l’adresse IP WireGuard du conteneur WireGuard (10.0.0.2). Par exemple, nous pouvons y accéder comme suit avec cURL depuis le Point de terminaison A :

$ curl 10.0.0.2:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...

Alternativement, vous pouvez exécuter le conteneur WireGuard en même temps que ses frères et sœurs en utilisant la commande podman-compose si vous placez le fichier suivant docker-compose.yml dans le répertoire situé au-dessus du fichier de configuration WireGuard :

# /srv/wg-point/docker-compose.yml
version: '3'
services:
  wireguard:
    image: docker.io/procustodibus/wireguard
    cap_add:
    - NET_ADMIN
    ports:
    - 51822:51822/udp
    volumes:
    - ./conf:/etc/wireguard:Z
  example-web-server:
    image: docker.io/nginx
    network_mode: 'service:wireguard'

Ensuite, démarrez les conteneurs en exécutant podman-compose up à partir du même répertoire que le fichier docker-compose.yml.

Note
Ce exemple nécessite Podman Compose version 1.0.4 ou plus récente (voir la section Mode de réseau avec Podman Compose).

La configuration de Podman pour cet exemple est similaire à l’exemple Docker Utiliser pour le réseau conteneur de l’article original WireGuard Containers — mais nous avons inversé les rôles entre le Point de terminaison A et le Point de terminaison B pour correspondre aux exemples Utiliser pour le réseau pont et Utiliser pour le réseau Pod plus tard dans cet article. Si nous avions gardé les rôles identiques, les seules différences entre cet exemple de Podman et l’exemple Docker de l’autre article seraient que, pour Podman :

  1. Nous avons ajouté l’option Z au volume de configuration WireGuard.
  2. Nous avons qualifié le nom de l’image avec le registraire docker.io.

Utiliser pour le réseau pont

Accès à distance via conteneur WireGuard

Une autre façon pour un conteneur Podman d’offrir un accès WireGuard aux autres conteneurs est de les attacher tous au même réseau pont. Cela crée essentiellement une topologie point-to-site WireGuard, où le “site” est le réseau pont du conteneur, au lieu du LAN de l’hôte.

Nous utiliserons en fait la même configuration WireGuard pour le conteneur Podman dans cet exemple que celle utilisée par “Hôte β” dans le guide Configuration point-to-site WireGuard — avec deux exceptions :

  1. Nous ne configurons pas le paramètre de noyau “IP forwarding” dans la configuration de WireGuard (nous le configurons à la place dans la configuration de Podman).
  2. Nous pouvons simplifier les règles iptables du conteneur en une seule ligne (pour masquerer tous les paquets transférés, sauf ceux envoyés via son interface WireGuard).
Important
Pour exécuter cet exemple, assurez-vous de charger les modules noyau WireGuard et iptables sur l’hôte Podman et d’ouvrir l’accès au port UDP 51822 de l’hôte, comme décrit dans les sections Chargement des Modules Noyau et Modifications du Pare-feu à la début de cet article.

Enregistrez la configuration WireGuard pour le Point de terminaison B dans son propre répertoire quelque part pratique sur l’hôte, comme dans le répertoire /srv/wg-net-masq/wg-server/ :

# /srv/wg-net-masq/wg-server/wg0.conf

# paramètres locaux pour le Point de terminaison B
[Interface]
PrivateKey = ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBFA=
Address = 10.0.0.2/32
ListenPort = 51822

# masquage IP
PreUp = iptables -t nat -A POSTROUTING ! -o %i -j MASQUERADE

# paramètres distants pour le Point de terminaison A
[Peer]
PublicKey = /TOE4TKtAqVsePRVR+5AA43HkAK5DSntkOCO7nYq5xU=
AllowedIPs = 10.0.0.1/32

Ensuite, créez le réseau de pont pour les conteneurs en exécutant la commande suivante :

$ podman network create \
    --subnet 192.168.123.0/24 \
    wg-network

Vous pouvez utiliser un sous-réseau différent que 192.168.123.0/24 si vous le souhaitez, et un nom différent que wg-network — juste assurez-vous de mettre à jour la configuration pour les conteneurs en conséquence.

Enfin, démarrez le conteneur WireGuard ainsi que d’autres conteneurs que vous souhaitez exposer via WireGuard. Pour chaque conteneur, spécifiez le nom du réseau que nous venons de créer et une adresse IP disponible dans le réseau :

$ podman run \
    --cap-add NET_ADMIN \
    --cap-add NET_RAW \
    --name wg-server \
    --network wg-network \
    --ip 192.168.123.123 \
    --publish 51822:51822/udp \
    --rm \
    --sysctl net.ipv4.conf.all.forwarding=1 \
    --volume /srv/wg-net-masq/conf:/etc/wireguard:Z \
    docker.io/procustodibus/wireguard
$ podman run \
    --name example-web-server \
    --network wg-network \
    --ip 192.168.123.2 \
    --rm \
    docker.io/nginx

L’ordre dans lequel vous démarrez les conteneurs ne compte pas. Si vous aviez précédemment démarré un conteneur que vous souhaitez maintenant exposer via WireGuard, vous pouvez le connecter au réseau de pont avec la commande suivante :

$ podman network connect \
    --ip 192.168.123.2 \
    wg-network \
    example-web-server

Sur Endpoint A (l’hôte distant), assurez-vous d’inclure le sous-réseau du réseau de pont dans la configuration de WireGuard d’Endpoint A :

# /etc/wireguard/wg0.conf

# paramètres locaux pour Endpoint A
[Interface]
PrivateKey = AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEE=
Address = 10.0.0.1/32
ListenPort = 51821

# paramètres distants pour le Point de terminaison B
[Peer]
PublicKey = fE/wdxzl0klVp/IR8UcaoGUMjqaWi3jAd7KzHKFS6Ds=
Endpoint = 203.0.113.2:51822
AllowedIPs = 192.168.123.0/24

Alors, vous pourrez accéder aux conteneurs sur le Point de terminaison B depuis le Point de terminaison A en utilisant leur adresse IP sur le réseau pont. Par exemple, nous pouvons accéder au conteneur example-web-server depuis le Point de terminaison A en utilisant son adresse réseau pont de 192.168.123.2 :

$ curl 192.168.123.2:80
<!DOCTYPE html>
<html>
<head>
<title>Bienvenue sur nginx!</title>
...

Alternativement, vous pouvez utiliser Podman Compose pour configurer le réseau pont et les conteneurs. Par exemple, en utilisant la syntaxe Docker Compose version 3.5+, vous pouvez créer un wg-network similaire au-dessus et connecter des conteneurs wg-server et example-web-server similaires à celui-ci :

# /srv/wg-net-masq/docker-compose.yml
version: '3.5'

networks:
  wg-network:
    ipam:
      config:
      - subnet: 192.168.123.0/24

services:
  wg-server:
    image: docker.io/procustodibus/wireguard
    cap_add:
    - NET_ADMIN
    - NET_RAW
    networks:
      wg-network:
        ipv4_address: 192.168.123.123
    ports:
    - 51822:51822/udp
    sysctls:
    - net.ipv4.conf.all.forwarding=1
    volumes:
    - ./conf:/etc/wireguard:Z

  example-web-server:
    image: docker.io/nginx
    networks:
      wg-network:
        ipv4_address: 192.168.123.2

Démarrez le réseau et les conteneurs en exécutant podman-compose up depuis le même répertoire que le fichier docker-compose.yml.

Note
Cet exemple nécessite Podman Compose version 1.0.4 ou plus récente (consultez la section Mode de réseau avec Podman Compose).

La configuration Podman pour cet exemple est très similaire à l’exemple rootfull Docker WireGuard dans un conteneur de l’article Accès distant avec WireGuard aux conteneurs Docker, avec les différences suivantes pour le conteneur WireGuard Podman :

  1. Nous avons accordé la capacité NET_RAW (pour exécuter iptables dans un conteneur sans privilèges).
  2. Nous avons activé explicitement le paramètre de noyau packet forwarding.
  3. Nous avons ajouté l’option Z au volume de configuration WireGuard.
  4. Nous avons qualifié le nom de l’image avec le registre docker.io.

Utilisation pour un réseau Bridge sans masquarade

Accès distant avec WireGuard sans masquarade

Un inconvénient du scénario Utilisation pour un réseau Bridge mentionné ci-dessus est qu’il a fallu ajouter une règle iptables de masquarade au conteneur WireGuard. Cela signifie que le trafic transféré vers les autres conteneurs sur le réseau bridge à partir du réseau WireGuard apparaîtra avoir l’adresse IP propre du conteneur WireGuard comme source (192.168.123.123), au lieu des adresses sources originales du trafic.

Pour maintenir les adresses sources originales du trafic, il faudrait ajouter manuellement une route (ou plusieurs routes) à l’espace de réseau de chaque conteneur auquel le conteneur WireGuard transfère le trafic. Dans le scénario ci-dessus, nous avons attribué à la machine virtuelle WireGuard une adresse IP de 192.168.123.123, et la configuration de WireGuard du conteneur est configurée pour permettre uniquement les paquets provenant de 10.0.0.1/32 (Point de terminaison A) ; donc, dans ce scénario, nous devrions ajouter la route suivante au conteneur example-web-server :

ip route add 10.0.0.1/32 via 192.168.123.123

Si la configuration de WireGuard du conteneur WireGuard contenait plusieurs blocs d’adresses AllowedIPs, nous devrions ajouter une route pour chaque bloc. Par exemple, si la configuration contenait ce qui suit :

AllowedIPs = 10.0.0.1/32
AllowedIPs = 10.1.2.3/32, 10.1.2.99/32
AllowedIPs = 192.168.234.0/24

Nous devrions ajouter quatre routes, une pour chaque bloc d’adresses :

ip route add 10.0.0.1/32 via 192.168.123.123
ip route add 10.1.2.3/32 via 192.168.123.123
ip route add 10.1.2.99/32 via 192.168.123.123
ip route add 192.168.234.0/24 via 192.168.123.123

Pour ajouter des routes au conteneur, vous devez exécuter la commande ip route add soit a) depuis l’hôte en utilisant le namespace du conteneur, soit b) à l’intérieur du conteneur lui-même. Pour ajouter des routes depuis l’hôte, utilisez la commande nsenter comme décrit dans la section Ajouter la Route depuis l’Hôte de l’article WireGuard Accès à Distance aux Conteneurs Docker.

Pour ajouter des routes à partir d’un conteneur Podman sans privilèges root, vous devez :

  1. Installer le package iproute2 dans le conteneur (ou, idéalement, l’image du conteneur).
  2. Démarrer le conteneur avec la capacité NET_ADMIN.
  3. Exécuter la commande ip route add à partir du conteneur.

La façon dont vous faites cela dépend généralement de l’image du conteneur, mais en général cela signifie que vous devez :

  1. Créer une image personnalisée avec un Dockerfile personnalisé dans lequel vous installez le package iproute2.
  2. Exécuter l’image avec un script personnalisé (et avec le drapeau --cap-add NET_ADMIN).
  3. En tant que première partie du script, exécuter la commande ip route add.
  4. En tant que deuxième partie du script, exécuter la commande par défaut de l’image de base originale.

Pour notre exemple de serveur web, nous créons une image Docker personnalisée comme suit (placée dans son propre répertoire quelque part pratique sur l’hôte, comme le répertoire /srv/wg-net-route/example-web-server/), qui remplace l’image de base nginx pour installer le package iproute2 :

# /srv/wg-net-route/example-web-server/Dockerfile
FROM docker.io/nginx
RUN apt-get update && apt-get install -y iproute2

Ensuite, nous créons un script de commande personnalisé (placé à /srv/wg-net-route/example-web-server/command.sh) qui d’abord exécute la commande ip route add, puis lance la commande pour démarrer nginx :

#!/bin/sh -e
# /srv/wg-net-route/example-web-server/command.sh
ip route add 10.0.0.1/32 via 192.168.123.123
nginx -g 'daemon off;'

Et nous construisons l’image personnalisée comme suit, en lui affectant une étiquette de custom-nginx :

podman build \
    --tag custom-nginx \
    /srv/wg-net-route/example-web-server

Ensuite, nous sauvegardons la configuration WireGuard pour le Point de terminaison B dans un autre répertoire sur l’hôte (comme /srv/wg-net-route/wg-server/):

# /srv/wg-net-route/wg-server/wg0.conf

# paramètres locaux pour le Point de terminaison B
[Interface]
PrivateKey = ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBFA=
Address = 10.0.0.2/32
ListenPort = 51822

# paramètres distants pour le Point de terminaison A
[Peer]
PublicKey = /TOE4TKtAqVsePRVR+5AA43HkAK5DSntkOCO7nYq5xU=
AllowedIPs = 10.0.0.1/32

La configuration WireGuard devrait être la même que pour l’exemple Utilisation pour le réseau de conteneur ci-dessus, simplement sans la règle iptables masquand les adresses IP.

Important
Pour exécuter cet exemple, assurez-vous de charger le module noyau WireGuard sur l’hôte Podman et d’ouvrir l’accès au port UDP 51822 de l’hôte, comme décrit dans les sections Chargement du Module Noyau et Modifications du Pare-feu à la fin de cet article.

Ensuite, nous créons le réseau de pont pour les conteneurs en exécutant la commande suivante :

$ podman network create \
    --subnet 192.168.123.0/24 \
    wg-network

Et démarrons le conteneur WireGuard, l’attaching au réseau de pont :

$ podman run \
    --cap-add NET_ADMIN \
    --name wg-server \
    --network wg-network \
    --ip 192.168.123.123 \
    --publish 51822:51822/udp \
    --rm \
    --sysctl net.ipv4.conf.all.forwarding=1 \
    --volume /srv/wg-net-route/wg-server:/etc/wireguard:Z \
    docker.io/procustodibus/wireguard

Contrairement au scénario Utilisation pour le Réseau de Conteneurs, nous n’avons pas besoin d’ajouter la capacité NET_RAW au conteneur WireGuard, car nous ne devons pas exécuter de règles iptables à l’intérieur de celui-ci.

Enfin, nous pouvons exécuter un conteneur avec l’image nginx personnalisée que nous avons construite ci-dessus, en l’attaching au même réseau de pont :

$ podman run \
    --cap-add NET_ADMIN \
    --name example-web-server \
    --network wg-network \
    --ip 192.168.123.2 \
    --rm \
    --volume /srv/wg-net-route/example-web-server:/custom:Z \
    custom-nginx \
    /custom/command.sh

Comme ce conteneur exécutera la commande ip route add, il doit être accordé la capacité NET_ADMIN. Et car nous le faisons via le script personnalisé command.sh que nous avons écrit ci-dessus, nous devons également monter ce script dans le répertoire /custom/ du conteneur (ou à un autre point de montage convivial au sein du conteneur).

Avec cette route ajoutée, nous pouvons tester le tunnel WireGuard en essayant d’accéder au conteneur personnalisé par son adresse sur le réseau pont (192.168.123.2) depuis Endpoint A :

$ curl 192.168.123.2:80
<!DOCTYPE html>
<html>
<head>
<title>Bienvenue sur nginx!</title>
...

Alternativement, vous pouvez utiliser Podman Compose pour construire l’image personnalisée et la exécuter dans un réseau pont avec le conteneur WireGuard. Par exemple, en utilisant la syntaxe Docker Compose version 3.5+, vous pouvez créer un wg-network similaire au-dessus et connecter des conteneurs wg-server et example-web-server similaires à celui-ci :

# /srv/wg-net-route/docker-compose.yml
version: '3.5'

networks:
  wg-network:
    ipam:
      config:
      - subnet: 192.168.123.0/24

services:
  wg-server:
    image: docker.io/procustodibus/wireguard
    cap_add:
    - NET_ADMIN
    networks:
      wg-network:
        ipv4_address: 192.168.123.123
    ports:
    - 51822:51822/udp
    sysctls:
    - net.ipv4.conf.all.forwarding=1
    volumes:
    - ./wg-server:/etc/wireguard:Z

```yaml
example-web-server:
    build: example-web-server
    cap_add:
    - NET_ADMIN
    command: /custom/command.sh
    networks:
      wg-network:
        ipv4_address: 192.168.123.2
    volumes:
    - ./example-web-server:/custom:Z

Démarrez le réseau et les conteneurs en exécutant podman-compose up à partir du même répertoire que le fichier docker-compose.yml.

Note
Cette example nécessite Podman Compose version 1.0.4 ou plus récente (voir la section Mode de réseau avec Podman Compose).

La configuration Podman pour cette example est très similaire à l’exemple rootfull Docker WireGuard dans un conteneur sans masquage de l’article Accès distant avec WireGuard aux conteneurs Docker, avec les différences suivantes pour le conteneur WireGuard Podman :

  1. Nous avons activé explicitement le paramètre de noyau de transfert des paquets.
  2. Nous avons ajouté l’option Z au volume de configuration WireGuard.
  3. Nous avons qualifié le nom de l’image avec le registre docker.io.

Utilisation pour un réseau Bridge avec WireGuard sur l’Hôte

Accès distant avec WireGuard via l&rsquo;Hôte

Si vous exécutez WireGuard sur l’hôte Podman lui-même, au lieu de le faire dans un conteneur, vous pouvez également permettre aux points de terminaison distants du réseau WireGuard d’accéder aux conteneurs Podman sur un réseau pont — tant que vous exécutez ces conteneurs (et le réseau pont lui-même) en tant que root.

Important
Pour exécuter cet exemple, assurez-vous d’ouvrir l’accès au port UDP 51822 de l’hôte, comme décrit dans la section Modifications du pare-feu à la début de cet article.

Enregistrez la configuration WireGuard pour l’hôte dans le répertoire /etc/wireguard/ :

# /etc/wireguard/wg0.conf

# paramètres locaux pour Endpoint B
[Interface]
PrivateKey = ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBFA=
Address = 10.0.0.2/32
ListenPort = 51822

# paramètres distants pour Endpoint A
[Peer]
PublicKey = /TOE4TKtAqVsePRVR+5AA43HkAK5DSntkOCO7nYq5xU=
AllowedIPs = 10.0.0.1/32

Comme WireGuard s’exécutera dans l’espace de noms racine de l’hôte, nous ne nécessitons pas d’ règles iptables de masquage dans ce scénario. Démarrez l’interface WireGuard en exécutant la commande suivante sur l’hôte :

$ sudo wg-quick up wg0

Ensuite, créez le réseau pont pour les conteneurs à utiliser en exécutant la commande suivante en tant que root :

$ sudo podman network create \
    --subnet 192.168.123.0/24 \
    wg-network

Enfin, redémarrez les conteneurs que vous souhaitez exposer via WireGuard en tant que root. Pour chaque conteneur, spécifiez le nom du réseau que nous venons de créer et une adresse IP disponible dans le réseau :

$ sudo podman run \
    --name example-web-server \
    --network wg-network \
    --ip 192.168.123.2 \
    --rm \
    docker.io/nginx

Si vous n’avez pas de pare-feu configuré sur l’hôte, vous pourrez accéder immédiatement au conteneur example-web-server depuis le Point de terminaison A. Cependant, si vous avez un pare-feu sur l’hôte, vous devrez ajuster le pare-feu pour permettre à l’interface WireGuard de l’hôte (wg0) d’accéder au réseau Podman wg-network (192.168.123.0/24).

Note
Ceci est en plus de la permission d’accès via votre pare-feu à le port d’écoute WireGuard (51822 dans cet exemple), comme décrit dans la section Modifications du Pare-feu.

Si vous utilisez firewalld pour gérer votre pare-feu, la méthode la plus simple est d’ajouter simplement l’interface WireGuard au groupe trusted de firewalld :

$ sudo firewall-cmd --zone=trusted --add-interface=wg0
success

Sinon, si vous utilisez nftables ou iptables directement, vous devrez probablement ajouter une règle comme iifname wg0 ip daddr 192.168.123.0/24 accept à la chaîne forward de votre table filter (pour nftables), ou quelque chose comme -A FORWARD -i wg0 -d 192.168.123.0/24 -j ACCEPT pour iptables.

Avec le pare-feu ajusté, vous pourrez maintenant accéder au conteneur example-web-server depuis le Point de terminaison A en utilisant son adresse réseau de pont 192.168.123.2 :

$ curl 192.168.123.2:80
<!DOCTYPE html>
<html>
<head>
<title>Bienvenue sur nginx!</title>
...

Alternativement, vous pouvez utiliser Podman Compose pour configurer le réseau de pont et les conteneurs. Par exemple, en utilisant la syntaxe Docker Compose version 3.5+, vous pouvez créer un wg-network similaire à celui-ci et connecter un conteneur example-web-server similaire à ce réseau :

# /srv/wg-net-host/docker-compose.yml
version: '3.5'

networks:
  wg-network:
    ipam:
      config:
      - subnet: 192.168.123.0/24

  example-web-server:
    image: docker.io/nginx
    networks:
      wg-network:
        ipv4_address: 192.168.123.2

Démarrez le réseau et les conteneurs en exécutant sudo podman-compose up depuis le même répertoire que le fichier docker-compose.yml.

Note
Cet exemple nécessite Podman Compose version 1.0.4 ou plus récente (consultez la section Mode de réseau avec Podman Compose).

La configuration Podman pour cet exemple est très similaire à l’exemple Docker WireGuard sur le Hôte de l’article Accès distant avec WireGuard aux conteneurs Docker. La seule différence réelle est que Docker ajoute quelques règles de pare-feu plus restrictives que Podman (lorsque firewalld n’est pas utilisé).

Utilisation pour le réseau Pod

Accès distant via Pod avec WireGuard

Avec Podman, la façon la plus idiomatique d’utiliser un conteneur Podman pour fournir l’accès à d’autres conteneurs sélectionnés à un réseau WireGuard est de les exécuter ensemble dans le même pod. Cela permet à tous les conteneurs de partager le même espace de noms réseau.

Important
Pour exécuter cet exemple, assurez-vous de charger le module noyau WireGuard sur l’hôte Podman et d’ouvrir l’accès au port UDP 51822 du hôte, comme décrit dans les sections Chargement du Module Noyau et Modifications du Pare-feu à la fin de cet article.

Pour cet exemple, nous utiliserons exactement la même configuration WireGuard que “Point B” de l’article Configuration Point à Point avec WireGuard. Enregistrez la configuration WireGuard pour le conteneur dans son propre répertoire quelque part pratique sur le hôte, comme dans le répertoire /srv/wg-pod/conf/ :

# /srv/wg-pod/conf/wg0.conf

# paramètres locaux pour Endpoint B
[Interface]
PrivateKey = ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBFA=
Address = 10.0.0.2/32
ListenPort = 51822

# paramètres distants pour le Point de terminaison A
[Peer]
PublicKey = /TOE4TKtAqVsePRVR+5AA43HkAK5DSntkOCO7nYq5xU=
AllowedIPs = 10.0.0.1/32

Créez ensuite un nouveau pod avec la commande podman pod create, publiant le port d’écoute du conteneur WireGuard (51822), et en donnant au pod un nom arbitraire comme wg-pod :

podman pod create \
    --publish 51822:51822/udp \
    --name wg-pod

Ensuite, créez le conteneur WireGuard pour le pod avec la commande suivante podman create :

podman create \
    --cap-add NET_ADMIN \
    --name wg-server \
    --pod wg-pod \
    --rm \
    --volume /srv/wg-pod/conf:/etc/wireguard:Z \
    docker.io/procustodibus/wireguard

Remarquez que avec cette commande, nous avons utilisé le drapeau --pod pour spécifier le pod dans lequel exécuter le conteneur et n’avons pas inclus de drapeau --publish pour le port d’écoute WireGuard (puisqu’il doit être publié pour le pod lui-même, et non le conteneur).

Ajoutez ensuite au pod les autres conteneurs avec lesquels vous souhaitez partager le réseau WireGuard :

podman create \
    --name example-web-server \
    --pod wg-pod \
    --rm \
    docker.io/nginx

Enfin, démarrez le pod :

podman pod start wg-pod

Le conteneur example-web-server démarrera un serveur Web nginx générique, qui écoute sur le port TCP 80 dans l’espace de réseau du pod. Cela vous permet d’accéder au serveur Web à partir du réseau WireGuard en utilisant l’adresse IP WireGuard du conteneur WireGuard (10.0.0.2). Par exemple, nous pouvons y accéder comme suit avec cURL depuis le Point de terminaison A :

$ curl 10.0.0.2:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...

Notez que il n’y a pas de moyen équivalent d’exécuter des conteneurs dans un pod en utilisant Docker, Docker Compose ou Podman Compose. Cependant, cette technique est similaire à l’exécution de plusieurs conteneurs dans le même réseau de conteneur, comme décrit dans l’exemple Utilisation pour le Réseau de Conteneur ci-dessus.

Utilisation pour la Redirection de Port depuis Internet

Redirection de Port à partir d&rsquo;Internet avec Podman et WireGuard

Notre dernier exemple vous montrera comment utiliser un conteneur Podman comme cible de la redirection de port via WireGuard depuis l’Internet — sans masquerade. Nous répliquerons en effet le serveur privé de l’article Redirection de Port à partir d’Internet avec WireGuard , mais en exécutant le serveur WireGuard et le serveur Web du serveur privé comme deux conteneurs Podman dans le même pod.

Dans cet exemple, nous appellerons le serveur public “Point de terminaison A” et le serveur privé “Point de terminaison B”, pour une cohérence avec la section Utilisation pour le transfert d’entrées de port de cet article. Cette section montre comment exécuter WireGuard dans un conteneur Podman sur le serveur public d’une situation similaire (bien que celle-ci utilise la masquerade); cette section montre comment exécuter WireGuard dans un conteneur Podman sur le serveur privé (et dans une situation où le serveur public ne fournit pas de masquerade).

Important
Pour exécuter cet exemple, assurez-vous d’ charger les modules noyau WireGuard et iptables sur l’hôte Podman et d’ouvrir l’accès au port UDP 51822 de l’hôte, comme décrit dans la section Chargement des modules noyau et Modifications du pare-feu à la début de cet article.

Afin d’éviter le besoin de masquerade sur le serveur public (Point de terminaison A), nous utiliserons la configuration suivante de WireGuard sur le serveur privé (Point de terminaison B), avec sa configuration AllowedIPs définie pour l’ensemble de l’espace d’adressage IPv4 (0.0.0.0/0). Enregistrez la configuration de WireGuard pour le conteneur dans son propre répertoire quelque part pratique sur l’hôte, comme dans le répertoire /srv/wg-internet/conf/ :

# /srv/wg-internet/conf/wg0.conf

# paramètres locaux pour Point de terminaison B
[Interface]
PrivateKey = ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBFA=
Address = 10.0.0.2/32
ListenPort = 51822

# paramètres distants pour le Point de terminaison A
[Peer]
PublicKey = /TOE4TKtAqVsePRVR+5AA43HkAK5DSntkOCO7nYq5xU=
Endpoint = 198.51.100.1:51821
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

Ceci est la même technique présentée dans la section Route par défaut de l’article Port forwarding from the Internet with WireGuard ; mais en exécutant WireGuard dans un pod, WireGuard prendra le relais sur la route par défaut juste pour le pod, au lieu de l’ensemble du hôte.

Ensuite, créez le pod avec la commande suivante podman pod create, publiant le port d’écoute du conteneur WireGuard (51822), et en donnant au pod un nom arbitraire comme wg-pod :

podman pod create \
    --publish 51822:51822/udp \
    --name wg-pod

Ensuite, créez le conteneur WireGuard pour le pod avec la commande suivante podman create :

podman create \
    --cap-add NET_ADMIN \
    --cap-add NET_RAW \
    --name wg-server \
    --pod wg-pod \
    --rm \
    --sysctl net.ipv4.conf.all.src_valid_mark=1 \
    --volume /srv/wg-internet/conf:/etc/wireguard:Z \
    docker.io/procustodibus/wireguard

Remarquez que pour cette commande, comparée à l’exemple Utilisation pour le réseau des pods ci-dessus, nous avons ajouté la capacité NET_RAW, et activé le paramètre de noyau ipv4.conf.all.src_valid_mark. Ces éléments sont nécessaires pour permettre le travail supplémentaire que fait le script WireGuard lors de la configuration de la route par défaut (déclenchée par l’option AllowedIPs = 0.0.0.0/0 dans notre configuration WireGuard ci-dessus).

Ensuite, ajoutez les autres conteneurs (ou conteneurs) qui serviront comme cible du transfert de ports. Dans ce cas, nous allons exécuter un serveur web générique :

podman create \
    --name example-web-server \
    --pod wg-pod \
    --rm \
    docker.io/nginx

Enfin, démarrez le pod :

podman pod start wg-pod

Avec le serveur public configuré pour transférer le port TCP 80 vers le point de terminaison B comme montré par l’article Transfert de ports WireGuard depuis Internet (ou configuré avec Podman comme montré dans la section Utilisation pour le transfert de ports entrants ci-dessus, mais sans la règle iptables masquant), vous pouvez accéder au serveur web générique en cours d’exécution dans le pod à l’aide de l’adresse IP publique du serveur public :

$ curl 198.51.100.1:80
<!DOCTYPE html>
<html>
<head>
<title>Bienvenue sur nginx!</title>
...

Dépannage

Erreur Non Supportée

Si vous rencontrez une erreur not supported lors du démarrage du conteneur WireGuard, comme la suivante :

[#] ip link add wg0 type wireguard
Erreur : Type de dispositif inconnu.
Impossible d'accéder à l'interface : Protocole non pris en charge

Cela signifie que vous n’avez pas le module noyau WireGuard installé sur l’hôte, ou que le module n’a pas encore été chargé. Assurez-vous de suivre les instructions Chargement du Module Noyau au début de cet article.

Impossible d’Initialiser iptables

Si vous rencontrez une erreur can’t initialize iptables lorsque le conteneur WireGuard démarre, comme ceci :

iptables v1.8.8 (legacy): can't initialize iptables table `nat': Permission denied (you must be root)
Peut-être que iptables ou votre noyau doivent être mis à jour.

Ou comme ceci :

iptables v1.8.8 (legacy): can't initialize iptables table `nat': Table does not exist (do you need to insmod?)

Cela signifie que vous n’avez pas chargé les modules noyau iptables nécessaires, ou que vous n’avez pas accordé au conteneur la capacité NET_RAW. Assurez-vous de suivre les instructions Chargement du Module Noyau au début de l’article (et accordez le conteneur la capacité NET_RAW).

Mise à jour 2023-12-27

Avec les dernières images de conteneurs, basées sur Alpine Linux 3.19 (qui utilise le backend nftables du noyau), vous pourriez rencontrer des messages d’erreur comme suit :

iptables: Failed to initialize nft: Protocol not supported

Ou comme ceci :

Avertissement : Extension MASQUERADE révision 0 non prise en charge, module du noyau manquant ?
iptables v1.8.10 (nf_tables): RULE_APPEND a échoué (Aucun fichier ou répertoire tel que cela) : règle dans la chaîne POSTROUTING

Ou comme ceci :

Avertissement : Extension DNAT révision 0 non prise en charge, module du noyau manquant ?
iptables v1.8.10 (nf_tables): CHAIN_ADD a échoué (Aucun fichier ou répertoire tel que cela) : chaîne PREROUTING

Ou comme ceci :

mnl.c:61 : Impossible d'initialiser le socket Netlink : Protocole non pris en charge

Ou comme ceci :

[#] nft -f /dev/fd/63
/dev/fd/63:5:1-96 : Erreur : Ne peut pas traiter la règle : Aucun fichier ou répertoire tel que cela

Si ce n’est pas le cas, vous devez charger les modules du noyau nftables comme indiqué dans les instructions Chargement des modules du noyau au début de l’article.

Erreur provenant de slirp4netns

Si vous rencontrez une erreur de slirp4netns lors du démarrage du conteneur WireGuard, comme suit :

Erreur : erreur de slirp4netns lors de la configuration de la redirection de port : map[desc:bad request: add_hostfwd: slirp_add_hostfwd a échoué]

Cela signifie que vous essayez d’exposer un port privilégié pour un conteneur sans privilèges. Soit diminuez le paramètre net.ipv4.ip_unprivileged_port_start du noyau à (ou en dessous) le port que vous essayez d’exposer, soit suivez l’une des autres suggestions de la question Permettre à un processus non-root de lier au port 80 et 443 ? sur le site Super User.

Erreur lors du paramétrage de src_valid_mark

Si vous voyez une erreur concernant le paramètre de noyau net.ipv4.conf.all.src_valid_mark lors du démarrage du conteneur WireGuard, comme celle-ci :

sysctl: error setting key 'net.ipv4.conf.all.src_valid_mark': Read-only file system

Cela signifie que vous avez configuré WireGuard pour prendre en charge la route par défaut (par exemple via AllowedIPs = 0.0.0.0/0 ou AllowedIPs = ::/0), mais manquez de certains pré-conditions nécessaires du script wg-quick qui lui permettent de le faire. Assurez-vous que vous :

  1. Activez le paramètre de noyau net.ipv4.conf.all.src_valid_mark.
  2. Accordez au conteneur WireGuard la capacité NET_RAW.
  3. Chargez tous les modules de noyau suivants :
# Module WireGuard
wireguard
# Modules iptables pour la route par défaut de wg-quick
iptable_mangle
iptable_raw
xt_addrtype
xt_comment
xt_connmark
xt_mark

Mise à jour 2023-12-27

Avec les dernières images de conteneur, basées sur Alpine Linux 3.19 (qui utilise le backend nftables du noyau), vous devrez charger plusieurs modules nftables au lieu des modules iptables. Chargez ces modules pour utiliser WireGuard pour la route par défaut :

# Module WireGuard
wireguard
# Modules nftables pour la route par défaut de wg-quick
nft_ct
nft_fib_inet

Suivez l’exemple Utiliser pour le réseau d’hôte avec une route par défaut lors de l’exécution d’un conteneur WireGuard rootfull, et l’exemple Utiliser pour le transfert de ports à partir d’Internet lors de l’exécution d’un conteneur WireGuard sans privilèges.

Outils de diagnostic

Pour diagnostiquer d’autres problèmes, vous pouvez accéder à un conteneur Podman en utilisant la commande podman exec, comme suit pour un conteneur nommé wg-point :

$ podman exec -it wg-point sh
/ #

Pour les conteneurs Podman qui ont été démarrés via la commande podman-compose up, vous pouvez y accéder en utilisant la commande podman-compose exec à partir du même répertoire que leur fichier docker-compose.yml ; comme suit pour un service nommé wg-server :

$ podman-compose exec wg-server sh
/ #

Vous pouvez également utiliser l’outil nsenter pour exécuter des outils de diagnostic installés sur l’hôte à partir de l’espace de réseau d’un conteneur Podman. D’abord, utilisez la commande podman container inspect pour identifier le PID (Process ID) du conteneur, comme suit pour un conteneur nommé wg-point :

$ podman container inspect wg-point -f '{{.State.Pid}}'
12345

Ensuite, utilisez la commande nsenter -t [PID] -n [PROGRAM COMMAND] pour exécuter tout programme installé sur l’hôte, comme tcpdump :

$ sudo nsenter -t 12345 -n tcpdump -niany tcp port 80
tcpdump: sortie verbale supprimée, utilisez -v ou -vv pour un décodage complet du protocole
écoute sur tout, type de liaison LINUX_SLL (Linux cooked v1), taille de capture 262144 octets
15:49:52.374483 IP 198.51.100.1.48764 > 10.0.2.100.80: Flags [S], seq 836029496, win 62727, options [mss 8961,sackOK,TS val 427845568 ecr 0,nop,wscale 6], length 0
15:49:52.374508 IP 198.51.100.1.48764 > 10.0.0.1.80: Flags [S], seq 836029496, win 62727, options [mss 8961,sackOK,TS val 427845568 ecr 0,nop,wscale 6], length 0
...

Voir les sections Se Connecter au Conteneur WireGuard et Exécuter des Outils Diagnostiques dans l’espace de noms WireGuard de l’article original Conteneurs WireGuard pour d’autres exemples.

10/19/2022

(mis à jour 12/27/2023)

par Justin Ludwig