Il server e il client Wireguard possono eseguire il ping a vicenda, ma i client Wireguard non possono eseguire il ping a vicenda

Aug 18 2020

Sto impostando una configurazione Wireguard in cui ho le seguenti entità:

  1. Istanza VM remota su host come google cloud o amazon aws. Questo è un client remoto per il mio server wireguard. Chiamiamolo questogcp_client

  2. Un server wireguard su una macchina ospitata sulla mia LAN. Chiamiamolo srvlan.

  • L'inoltro IPv4 è abilitato su questo dispositivo da sysctl.
  • C'è un Ubiquiti Edgerouter 4 tra la WAN e la mia LAN. Ho abilitato il port forwarding e il NAT hairpin su questo dispositivo. Ho anche impostato un DNS dinamico su questo router.
  1. Uno o più client sulla mia LAN, che dovrebbero essere in grado di connettersi al client remoto come se fosse una macchina sulla mia LAN. Dato che sto affrontando il problema con il mio primo cliente stesso, chiamiamolo client1.

Nella mia configurazione, sono in grado di eseguire il ping tra srvlane in gcp_cliententrambi i modi, e anche tra client1e srvlan. Però. i ping da gcp_clienta client1(e viceversa) falliscono.

Sulla base della lettura dei risultati di tcpdump -i wg0 -n icmp, ho formulato le seguenti osservazioni:

  1. Ping da client1a gcp_clientraggiungere srvlanma non vengono inoltrati al router.
  2. Ping da gcp_clientper client1raggiungere il mio router, che li inoltra a srvlan. Tuttavia i pacchetti non vengono inoltrati da srvlana client1.

L'unica cosa che posso concludere da questo è che le regole di inoltro srvlansono in qualche modo difettose. Sto usando nftablesper gestire questo dispositivo.

Questa è la mia configurazione di wireguard; gli indirizzi ip e il numero di porta sono stati modificati.

# 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

Questo è il mio firewall attivo 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
        }
}

Risposte

A.B Aug 26 2020 at 00:35

Quando srvlan inoltra il traffico con tunnel WireGuard, lo riceve da wg0 e lo indirizza nuovamente a ... wg0 : due volte la stessa interfaccia.

Quindi è necessario aggiungere questa voce alla catena di inoltro del firewall inet di nftables :

                iifname "wg0" oifname "wg0" accept

Altri problemi, nella catena in entrata :


                ip protocol icmp accept
                ip6 nexthdr ipv6-icmp accept
                ip protocol igmp accept

Sebbene il protocollo funzioni per IPv4, nexthdr nel protocollo IPv6 non garantisce che l'intestazione successiva sarà ICMPv6: possono esserci diversi intestazioni di estensione tra l'intestazione fissa e l'intestazione del protocollo di livello superiore. Se tali intestazioni di estensione compaiono in alcuni pacchetti, nexthdr ipv6-icmpnon corrisponderanno più. Usa la sintassi corretta, per IPv4 e IPv6:

                meta nfproto ipv4 meta l4proto icmp accept
                meta nfproto ipv6 meta l4proto ipv6-icmp accept
                meta nfproto ipv4 meta l4proto igmp accept

A seconda della versione di nftables , verrà visualizzato di nuovo in una forma più semplificata.


                iifname "wg0" udp dport 50000 ct state new accept

La porta 50000 non viene visualizzata all'interno dell'interfaccia WireGuard (a meno che non si desideri eseguire il tunneling di WireGuard all'interno di WireGuard), ma all'esterno (per il quale esiste già una regola). Non dovrebbe essere necessario.


Ricordate come si aggiungono più Wireguard clienti / peers (come avete fatto correttamente), che non ci può essere sovrapposizioni in srvlan s' AllowedIPs voci poiché determinano il cryptorouting che accade in Gabbia di protezione per selezionare il peer adeguata, dopo il percorso standard. Inoltre, se gcp_client si connette tramite srvlan a server che non utilizzano i tunnel WireGuard, anche il loro indirizzo LAN deve essere aggiunto sia a AllowedIPs che alla tabella di routing di gcp_client . AllowedIPs viene utilizzato sia per accettare un pacchetto in base alla sua origine (e determinare quale peer e forse aggiornare il suo endpoint in caso di roaming), sia per determinare a quale peer inviare un pacchetto in base alla sua destinazione.