Le serveur et le client Wireguard peuvent se cingler, mais les clients Wireguard ne peuvent pas se cingler

Aug 18 2020

Je mets en place une configuration Wireguard dans laquelle j'ai les entités suivantes:

  1. 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 çagcp_client

  2. 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.
  1. 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 srvlanet dans les gcp_clientdeux sens, et entre client1et srvlanaussi. 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:

  1. Les pings de client1à gcp_clientatteindre srvlanmais ne sont pas transmis au routeur.
  2. Pings from gcp_clientpour client1atteindre mon routeur, qui les transfère vers srvlan. Cependant , les paquets ne sont pas transmis par srvlanà client1.

La seule chose que je peux en conclure est que les règles de transfert srvlansont en quelque sorte défectueuses. J'utilise nftablespour 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

A.B Aug 26 2020 at 00:35

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-icmpils 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.