Le serveur et le client Wireguard peuvent se cingler, mais les clients Wireguard ne peuvent pas se cingler
Je mets en place une configuration Wireguard dans laquelle j'ai les entités suivantes:
Instance de VM distante sur des hôtes tels que google cloud ou amazon aws. Ceci est un client distant de mon serveur Wireguard. Appelons ça
gcp_client
Un serveur Wireguard sur une machine hébergée sur mon LAN. Permet d'appeler ça
srvlan
.
- Le transfert IPv4 est activé sur cet appareil par
sysctl
. - Il y a un Ubiquiti Edgerouter 4 entre le WAN et mon LAN. J'ai activé la redirection de port et le NAT en épingle à cheveux sur cet appareil. J'ai également mis en place un DNS dynamique sur ce routeur.
- Un ou plusieurs clients sur mon LAN, qui devraient pouvoir se connecter au client distant comme s'il s'agissait d'une machine sur mon LAN. Comme je suis confronté au problème avec mon premier client lui-même, appelons-le
client1
.
Dans ma configuration, je suis capable de cingler entre srvlan
et dans les gcp_client
deux sens, et entre client1
et srvlan
aussi. Toutefois. les pings de gcp_client
à client1
(et vice versa) échouent.
Sur la base de la lecture des résultats de tcpdump -i wg0 -n icmp
, j'ai fait les observations suivantes:
- Les pings de
client1
àgcp_client
atteindresrvlan
mais ne sont pas transmis au routeur. - Pings from
gcp_client
pourclient1
atteindre mon routeur, qui les transfère verssrvlan
. Cependant , les paquets ne sont pas transmis parsrvlan
àclient1
.
La seule chose que je peux en conclure est que les règles de transfert srvlan
sont en quelque sorte défectueuses. J'utilise nftables
pour gérer cet appareil.
Ceci est ma configuration de wireguard; les adresses IP et le numéro de port ont été modifiés.
# wg0.conf for gcp_client
[Interface]
Address = 10.0.1.2/24
ListenPort = 50000
PrivateKey = gcp_client_privkey
[Peer]
PublicKey = srvlan_pubkey
AllowedIPs = 10.0.1.0/24
Endpoint = srvlan_ddns:50000
# wg0.conf for srvlan
[Interface]
Address = 10.0.1.1/24
ListenPort = 50000
PrivateKey = srvlan_privkey
[Peer]
PublicKey = gcp_client_pubkey
AllowedIPs = 10.0.1.2/32
Endpoint = gcp_client_domainname:50000
PersistentKeepalive = 25
[Peer]
PublicKey = client1_pubkey
AllowedIPs = 10.0.1.3/32
Endpoint = client1_lanhostname:50000
PersistentKeepalive = 25 # I realise this one is unnecessary, but I had added it while testing just in case the problem got fixed.
# wg0.conf for client1
[Interface]
Address = 10.0.1.3/24
ListenPort = 50000
PrivateKey = client1_privkey
[Peer]
PublicKey = srvlan_pubkey
AllowedIPs = 10.0.1.0/24
Endpoint = srvlan_lanhostname:50000
C'est mon pare-feu activé srvlan
.
# nft list ruleset
table inet firewall {
chain inbound {
type filter hook input priority filter; policy drop;
ct state established,related accept
ct state invalid drop
iif "lo" accept
ip protocol icmp accept
ip6 nexthdr ipv6-icmp accept
ip protocol igmp accept
tcp dport 22 accept
iifname "eno1" tcp dport { 80, 443 } ct state new accept
iifname "eno1" udp dport 50000 ct state new accept
iifname "wg0" udp dport 53 ct state new accept
iifname "wg0" tcp dport { 80, 443 } ct state new accept
iifname "wg0" udp dport 50000 ct state new accept
}
chain forward {
type filter hook forward priority filter; policy drop;
ct state established,related accept
ct state invalid drop
iifname "wg0" oifname "eno1" ct state new accept
}
chain outbound {
type filter hook output priority filter; policy accept;
ct state invalid drop
}
}
table ip router {
chain prerouting {
type nat hook prerouting priority filter; policy accept;
}
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
oifname "eno1" ip saddr 10.0.1.0/24 masquerade
}
}
Réponses
Lorsque srvlan transfère le trafic tunnelé par WireGuard, il le reçoit de wg0 et l'achemine à nouveau vers ... wg0 : deux fois la même interface.
Vous devez donc ajouter cette entrée à la chaîne avant du pare-feu inet de nftables :
iifname "wg0" oifname "wg0" accept
Autres problèmes, dans la chaîne entrante :
ip protocol icmp accept ip6 nexthdr ipv6-icmp accept ip protocol igmp accept
Alors que le protocole fonctionne pour IPv4, nexthdr dans le protocole IPv6 ne garantit pas que l'en-tête suivant sera ICMPv6: il peut y avoir plusieurs en- têtes d'extension entre l'en-tête fixe et l'en-tête de protocole de la couche supérieure. Si de tels en-têtes d'extension apparaissent dans certains paquets, nexthdr ipv6-icmp
ils ne correspondent plus. Utilisez la syntaxe correcte, pour IPv4 et IPv6:
meta nfproto ipv4 meta l4proto icmp accept
meta nfproto ipv6 meta l4proto ipv6-icmp accept
meta nfproto ipv4 meta l4proto igmp accept
En fonction de la version de nftables , il sera affiché sous une forme plus simplifiée.
iifname "wg0" udp dport 50000 ct state new accept
Le port 50000 n'apparaît pas à l'intérieur de l'interface WireGuard (sauf si vous voulez tunnel WireGuard dans WireGuard), mais à l'extérieur (pour lequel il existe déjà une règle). Cela ne devrait pas être nécessaire.
Rappelez - vous que vous ajoutez des clients / pairs plus Grille de protection (comme vous l'avez fait correctement), qu'il ne peut y avoir des chevauchements dans srvlan de AllowedIPs entrées car ils déterminent le cryptorouting qui se passe dans le grillage métallique pour sélectionner pairs adéquat, après le routage standard. De plus, si gcp_client se connecte via srvlan à des serveurs n'utilisant pas de tunnels WireGuard, leur adresse LAN doit également être ajoutée à la fois aux AllowedIPs et à la table de routage de gcp_client . AllowedIPs est utilisé à la fois pour accepter un paquet en fonction de sa source (et déterminer quel pair et peut-être mettre à jour son point final en cas d'itinérance), et pour déterminer à quel pair envoyer un paquet en fonction de sa destination.