Passage du port WireGuard depuis Internet
{< admonitionblock style=“important” >} Traduction d’un article du site Pro Custodibus
Le contenu de cette page est la traduction Française de l’article WireGuard Port Forwarding From the Internet de Justin Ludwig
{< /admonitionblock >}
Portage WireGuard à partir de l’Internet
Quand vous avez un serveur privé qui ne peut pas être accédé publiquement depuis Internet (par exemple, en raison du NAT), mais que vous voulez exposer un service exécutant sur celui-ci au trafic public d’Internet, vous pouvez le faire via WireGuard — à condition de posséder un autre serveur qui est accessible publiquement depuis Internet. Cet article vous montrera comment.
La mise en place d’une connexion WireGuard entre deux serveurs et la transmission du trafic d’un à l’autre est généralement assez simple. La partie qui peut être difficile est la retour de trafic. Par exemple, supposons que vous ayez une application Web fonctionnant sur le port 8080 d’un serveur privé situé derrière un NAT (Network Address Translation) à un site, et que vous souhaitiez la rendre accessible au public Internet par le port 2000 d’un serveur public ayant du nom de domaine public.example.com :
Sur ce serveur privé, afin que l’application Web fonctionne correctement, elle doit pouvoir accéder à un serveur de base de données et à une file d’attente de messages sur un autre réseau interne auquel il est connecté ; et vous devez également pouvoir y accéder depuis un deuxième réseau interne pour la gestion via SSH. Ainsi, le serveur privé ne peut pas simplement envoyer tout son trafic via sa connexion WireGuard au serveur public — il doit envoyer uniquement par sélection les trafics qui constituent des réponses de l’application Web à l’origine du trafic public transféré.
Il existe plusieurs techniques différentes que vous pouvez utiliser pour envoyer le trafic de retour à travers la connexion WireGuard depuis le serveur privé au serveur public. La technique que vous devez utiliser dépend de ce que le serveur privé doit accéder en dehors de sa connexion WireGuard. Voici les principales techniques :
- Connexion de base
- Masquage
- Routes statiques
- Route par défaut
- Route par défaut avec des exceptions
- Mouvements du trafic selon des politiques
Connexion de base
La connexion WireGuard de base entre les deux serveurs est similaire à celle de la configuration du guide “WireGuard Point to Site avec redirection de ports”.
Pour cet exemple, nous allons configurer WireGuard sur notre serveur privé comme suit, en utilisant l’adresse IP publique du serveur public 203.0.113.2 pour démarrer une connexion WireGuard avec le serveur public ; et en utilisant une configuration PersistentKeepalive pour maintenir la connexion active à travers la porteuse NAT devant le serveur privé :
# /etc/wireguard/wg0.conf
# paramètres locaux du serveur privé
[Interface]
PrivateKey = AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEE=
Address = 10.0.0.1
# paramètres distants pour le serveur public
[Peer]
PublicKey = fE/wdxzl0klVp/IR8UcaoGUMjqaWi3jAd7KzHKFS6Ds=
Endpoint = 203.0.113.2:51822
AllowedIPs = 10.0.0.2
PersistentKeepalive = 25
Ces paramètres sont similaires à “Point A” de la section “WireGuard Point to Site avec redirection de ports”.
Sur le serveur public, nous devons activer le forwarding des paquets. Nous devons également ajouter une règle de pare-feu pour configurer la redirection de ports (aussi connue sous le nom de DNAT, Translation d’adresse réseau de destination) qui traduit l’adresse de destination des paquets envoyés vers le port TCP 2000 du serveur public en celui du port TCP 8080 sur le serveur privé (10.0.0.1). Nous ferons cela via les commandes PreUp dans sa configuration WireGuard (pour faciliter la prise en charge) :
# /etc/wireguard/wg0.conf
# paramètres locaux du serveur public
[Interface]
PrivateKey = ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBFA=
Address = 10.0.0.2
ListenPort = 51822
# forwarding des paquets
PreUp = sysctl -w net.ipv4.ip_forward=1
# port forwarding
PreUp = iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 2000 -j DNAT --to-destination 10.0.0.1:8080
PostDown = iptables -t nat -D PREROUTING -i eth0 -p tcp --dport 2000 -j DNAT --to-destination 10.0.0.1:8080
# remote settings for the private server
[Peer]
PublicKey = /TOE4TKtAqVsePRVR+5AA43HkAK5DSntkOCO7nYq5xU=
AllowedIPs = 10.0.0.1
Ces paramètres sont similaires à « Host β » du guide WireGuard Point to Site With Port Forwarding.
|
Note
|
Si vous utilisez nftables au lieu de iptables sur votre serveur public, au lieu de lancer la commande iptables précédente pour configurer le port forwarding, vous ajouteriez une règle comme tcp dport 2000 dnat ip to 10.0.0.1:8080 à un chaîne natuer prerouting dans votre configuration nftables. Voici un exemple complet de fichier de configuration nftables qui fait cela :
#!/usr/sbin/nft -f
flush ruleset
define pub_iface = "eth0"
define wg_iface = "wg0"
define wg_port = 51822
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
```markdown
# accept all loopback packets
iif "lo" accept
# accept all icmp/icmpv6 packets
meta l4proto { icmp, ipv6-icmp } accept
# accept all packets that are part of an already-established connection
ct state vmap { invalid : drop, established : accept, related : accept }
# drop new connections over rate limit
ct state new limit rate over 1/second burst 10 packets drop
# accept all DHCPv6 packets received at a link-local address
ip6 daddr fe80::/64 udp dport dhcpv6-client accept
# accept all SSH packets received on a public interface
iifname $pub_iface tcp dport ssh accept
# accept all WireGuard packets received on a public interface
iifname $pub_iface udp dport $wg_port accept
# reject with polite "port unreachable" icmp response
reject
}
chain forward {
type filter hook forward priority 0; policy drop;
# forward all packets that are part of an already-established connection
ct state vmap { invalid : drop, established : accept, related : accept }
# forward any incoming packets from a public interface that will go out through WireGuard
iifname $pub_iface oifname $wg_iface accept
# reject with polite "host unreachable" icmp response
reject with icmpx type host-unreachable
}
}
table inet nat {
chain prerouting {
type nat hook prerouting priority -100; policy accept;
# rewrite destination address of TCP port 2000 packets to port 8080 on 10.0.0.1
iifname $pub_iface tcp dport 2000 dnat ip to 10.0.0.1:8080
}
}
Voir la section Point à Site avec Redirection de Ports du guide de configuration WireGuard Nftables pour une explication complète de ces règles de pare-feu.
Cette configuration donnera une connectivité de base entre le serveur privé et le serveur public (essayez-le en lançant curl 10.0.0.1:8080 sur le serveur public — vous devriez voir la sortie de l’application web sur le serveur privé). Cela ne permettra pas de transférer aucun trafic Internet entre les deux serveurs, cependant. Pour cela, vous devez ajouterl’une des techniques suivantes.
Masquage
La manière la plus simple d’autoriser le retour du trafic en l’envoyant du nouveau côté du serveur privé vers le serveur public est d’utiliser le SNAT (Source Network Address Translation) sur le serveur public pour traduire les adresses sources des paquets transférés afin qu’elles utilisent l’adresse IP propre au serveur public. Lorsque le SNAT est utilisé de cette manière, il est appelé “masquage” (dans cet exemple, le serveur public masque l’identité des paquets de l’internet avec son propre identité).
Comme le serveur privé reçoit les ces paquets transférés avec leur adresse source déjà réécrite pour utiliser l’adresse IP WireGuard du serveur public, aucune modification de routing n’est nécessaire sur le serveur privé — le serveur privé sait qu’il peut répondre à ces paquets en envoyant le trafic directement au serveur public. Le pare-feu du serveur public s’occupe de se souvenir des sources originales du trafic et de réécrire les destinations des paquets de réponse pour les remettre à l’adresse IP source originale.
Pour appliquer le masquage avec iptables, ajoutez les commandes suivantes PreUp et PostDown au fichier de configuration WireGuard du serveur public :
# /etc/wireguard/wg0.conf
# paramètres locaux pour le serveur public
[Interface]
PrivateKey = ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBFA=
Address = 10.0.0.2
ListenPort = 51822
# transfert de paquets
PreUp = sysctl -w net.ipv4.ip_forward=1
# redéfinition du port
PreUp = iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 2000 -j DNAT --to-destination 10.0.0.1:8080
PostDown = iptables -t nat -D PREROUTING -i eth0 -p tcp --dport 2000 -j DNAT --to-destination 10.0.0.1:8080
masquage de paquets
PreUp = iptables -t nat -A POSTROUTING -o wg0 -j MASQUERADE PostDown = iptables -t nat -D POSTROUTING -o wg0 -j MASQUERADE
paramètres distants pour le serveur privé
[Peer] PublicKey = /TOE4TKtAqVsePRVR+5AA43HkAK5DSntkOCO7nYq5xU= AllowedIPs = 10.0.0.1
ou si vous utilisez plutôt nftables à la place d'iptables, ajoutez la chaîne `nat postrouting` suivante au fichier de configuration nftables du service public :
```bash
#!/usr/sbin/nft -f
flush ruleset
# ...
table inet nat {
chain prerouting {
type nat hook prerouting priority -100; policy accept;
# redirige l'adresse de destination des paquets TCP sur le port 2000 vers le port 8080 sur 10.0.0.1
iifname $pub_iface tcp dport 2000 dnat ip to 10.0.0.1:8080
}
chain postrouting {
type nat hook postrouting priority 100; policy accept;
# masquerade tous les paquets sortants par le biais de WireGuard
oifname $wg_iface masquerade
}
}
Le désavantage du masquage est que cela cache l’adresse IP source originale des clients utilisant l’application web elle-même — tout le trafic reçu par le serveur privé utilisera l’adresse IP WireGuard du serveur public (10.0.0.2) comme adresse source. Mais vous devriez maintenant être capable de vous connecter à l’application web sur le serveur privé depuis tout appareil à travers Internet, en utilisant le nom d’hôte et le port du serveur public (par exemple curl public.example.com:2000).
Achemins statiques
Si vous avez l’information en advance que votre trafic Internet proviendra de quelques-unes, des réseaux d’adresses IP statiques (comme l’exemple 198.51.100.87 et la plage d’adresses IP depuis 192.0.2.144 jusqu’à 192.0.2.147), une autre option que vous pouvez utiliser est de définir simplement des routes statiques pour ces adresses IP sur le serveur privé, afin que celui-ci envoie toujours le trafic vers ces adresses par le biais du serveur public. C’est la même approche utilisée dans l’article WireGuard Point to Site With Port Forwarding (en français : WireGuard Point à Site avec le passage de port), où nous savons que tout le trafic proviendra du sous-réseau B (192.168.200.0/24 dans cet article).
Tout ce dont vous avez besoin dans ce cas est d’ajouter l’adresse IP statique au paramètre AllowedIPs dans la configuration WireGuard pour le serveur privé :
# /etc/wireguard/wg0.conf
# paramètres locaux du serveur privé
[Interface]
PrivateKey = AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEE=
Address = 10.0.0.1
# paramètres distants du serveur public
[Peer]
PublicKey = fE/wdxzl0klVp/IR8UcaoGUMjqaWi3jAd7KzHKFS6Ds=
Endpoint = 203.0.113.2:51822
AllowedIPs = 10.0.0.2, 198.51.100.87, 192.0.2.144/30
PersistentKeepalive = 25
En faisant cela, vous pourrez vous connecter à l’application web sur le serveur privé en utilisant le nom d’hôte et le port du serveur public (par exemple curl public.example.com:2000) depuis un tout autre hôte qui utilise une des adresses IP publiques de ses réseaux Интернет comme adresse publique (comme 192.0.2.145). L’application web sur le serveur privé verra l’adresse IP source d’origine (par exemple 192.0.2.145), mais sera toujours en mesure d’envoyer correctement les réponses par le biais du serveur public.
Route par défaut
Si le serveur privé ne nécessite pas vraiment d’accéder à une base de données et à une file d’attente de messages distinctes (ou s’il pouvait les accéder via WireGuard), et que vous n’aviez pas besoin de vous connecter au serveur privé par SSH pour l’administration (ou qu’il suffisait de vous y connecter via WireGuard), vous pourriez laisser WireGuard prendre le relais du routeur par défaut du serveur privé — et envoyer tout son trafic par défaut à travers WireGuard vers le serveur public.
Dans ce cas, il suffirait simplement de définir l’option AllowedIPs du service WireGuard sur le serveur privé à 0.0.0.0/0:
# /etc/wireguard/wg0.conf
# paramètres locaux pour le serveur privé
[Interface]
PrivateKey = AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEE=
Address = 10.0.0.1
# paramètres distants pour le serveur public
[Peer]
PublicKey = fE/wdxzl0klVp/IR8UcaoGUMjqaWi3jAd7KzHKFS6Ds=
Endpoint = 203.0.113.2:51822
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
Si vous faisiez cela, vous pourriez vous connecter à l’application web sur le serveur privé depuis tout hôte de l’internet, en utilisant le nom d’hôte et le port du serveur public (par exemple curl public.example.com:2000). L’application web sur le serveur privé verrait l’adresse IP source originale et enverrait des réponses (ainsi que tout son autre trafic) à travers sa connexion WireGuard vers le serveur public.
|
Tip
|
Route par défaut avec des exceptions
Si vous savez à l’avance que le trafic interne du serveur privé est limité à quelques sous-réseaux uniquement, vous pouvez laisser WireGuard prendre le contrôle de la route par défaut du serveur privé et ajouter quelques routes statiques pour votre trafic interne en tant qu’exceptions. C’est l’inverse de l’option Routes statiques décrite ci-dessus — au lieu d’énumérer les adresses IP ou les plages que vous toujours souhaitez envoyer via le tunnel WireGuard, vous énumérez les adresses IP ou les plages que vous jamais ne voulez pas envoyer via le tunnel WireGuard.
Ce qui suit est parfait pour le scénario d’exemple où la base de données et la file d’attente de messages utilisées par le serveur privé sont sur le sous-réseau 10.11.12.0/24, et l’accès SSH n’est autorisé que depuis le sous-réseau 192.168.99.0/24. Dans ce cas, vous définiriez la configuration WireGuard du serveur privé pour utiliser une valeur AllowedIPs de 0.0.0.0/0, et vous ajouteriez des routes explicites sur le serveur privé pour ces réseaux internes — ce qui peut également être fait via son fichier de configuration WireGuard :
# /etc/wireguard/wg0.conf
# paramètres locaux du serveur privé
[Interface]
PrivateKey = AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEE=
Address = 10.0.0.1
# route statique pour la base de données et la file d'attente de messages
PreUp = ip route add 10.11.12.0/24 via 192.168.1.1 dev eth0
PostDown = ip route del 10.11.12.0/24 via 192.168.1.1 dev eth0
# route statique pour l'accès SSH
PreUp = ip route add 192.168.99.0/24 via 192.168.1.1 dev eth0
PostDown = ip route del 192.168.99.0/24 via 192.168.1.1 dev eth0
# paramètres distants du serveur public
[Peer]
PublicKey = fE/wdxzl0klVp/IR8UcaoGUMjqaWi3jAd7KzHKFS6Ds=
Endpoint = 203.0.113.2:51822
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
Assurez-vous d’utiliser la passerelle réseau et l’interface réseau réelles du serveur privé au lieu de 192.168.1.1 et eth0. Vous pouvez déterminer les paramètres de votre passerelle réseau en exécutant la commande ip route — la ligne commençant par default montre votre passerelle réseau :
$ ip route
default via 192.168.1.1 dev eth0 proto dhcp src 192.168.1.11 metric 100
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.11 metric 100
Si vous utilisez cette approche, vous pourrez vous connecter à l’application web sur le serveur privé depuis n’importe quel hôte d’Internet, en utilisant le nom d’hôte et le port du serveur public (par exemple curl public.example.com:2000). L’application web sur le serveur privé verra l’adresse IP source originale de toutes les communications réseau Internet, mais elle pourra toujours envoyer correctement les réponses via le serveur public.
Routeur de stratégie
L’option finale est d’utiliser le routage par stratégie. C’est également une bonne adaptation pour le scénario d’exemple. Généralement, la manière dont vous utilisez le routage par stratégie avec WireGuard se fait en combinant trois choses :
- Ajoutez un paramètre
Tableà la section[Interface]de votre configuration de WireGuard. Cela indique wq-quick d’ajouter des routes à une table personnalisée plutôt que à sa table de routage principale. - Ajoutez vos règles de stratégie personnalisées via la commande
ip rule addpour diriger le trafic sélectionné pour utiliser la table personnalisée. - Définissez
AllowedIPs = 0.0.0.0/0pour l’un des pairs dans votre configuration de WireGuard. Cela assurera que tout le trafic dirigé pour utiliser la table de routage personnalisée (et ne correspondant pas auxAllowedIPsd’un autre peer) soit envoyé à ce peer.
Pour retourner tous les traitements sur le serveur privé qui ont initialement entré par son interface de WireGuard via celle-ci, utilisez ceci pour la configuration du serveur privé de WireGuard :
# /etc/wireguard/wg0.conf
# paramètres locaux pour le serveur privé
[Interface]
PrivateKey = AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEE=
Address = 10.0.0.1
Table = 123
PreUp = ip rule add from 10.0.0.1 table 123 priority 456
PostDown = ip rule del from 10.0.0.1 table 123 priority 456
# paramètres distants pour le serveur public
[Peer]
PublicKey = fE/wdxzl0klVp/IR8UcaoGUMjqaWi3jAd7KzHKFS6Ds=
Endpoint = 203.0.113.2:51822
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
Le règle de politique mentionnée fonctionne car le trafic de retour utilisera l’adresse IP source des paquets de réponse identique à celle utilisée pour l’adresse destination des paquets originaux. L’adresse destination des paquets转发从公网服务器到私网服务器的所有都被公网服务器翻译成 10.0.0.1;因此,由私网服务器生成的应答 packets 将使用 10.0.0.1 作为源 address。上述政策规则匹配这些 packets,并确保它们通过自定义的 123 路由表进行路由;而 wg-quick 设置此表的默认路由使用 WireGuard 接口。
|
Tip
|
Voici comment vous pouvez faire référence à une table de routage personnalisée par nom plutôt que par numéro :
Ajoutez une entrée pour elle dans le fichier /etc/iproute2/rt_tables. Par exemple, vous pouvez définir $ echo ‘123 foo’ | sudo tee -a /etc/iproute2/rt_tables Vous pouvez ensuite faire référence à la table Table = foo PreUp = ip rule add from 10.0.0.1 table foo priority 456 PostDown = ip rule del from 10.0.0.1 table foo priority 456 |
Avec cette approche, vous pourrez vous connecter à l’application web sur le serveur privé depuis n’importe quel hôte sur Internet, en utilisant le nom d’hôte et le port du serveur public (par exemple, curl public.example.com:2000). L’application web sur le serveur privé vera l’adresse IP source originale, mais elle pourra également envoyer correctement des réponses à travers le serveur public. Toutes les autres communications du serveur privé, y compris celles provenant du serveur privé lui-même, continueront d’utiliser la table de routage principale du serveur, sans être affectées par votre configuration WireGuard.
Techniques supplémentaires
Consultez l’article Port Forwarding avec WireGuard à partir de l’Internet vers d’autres réseaux pour quelques exemples avancés de l’utilisation de ces techniques. Cet article couvre également la technique Marquage de connexion, qui peut être nécessaire lorsque vous transmettez des connexions vers conteneurs Docker ou par plusieurs hops vers d’autres serveurs internes (ou à tout moment où la décision de routage appropriée pour les paquets de retour ne peut être prise que par retenir quelque chose au sujet de leurs paquets entrants originaux ou connexion).
9/1/2022
par Justin Ludwig
by Justin Ludwig translated by: Patrice Le Guyader
