Il server e il client Wireguard possono eseguire il ping a vicenda, ma i client Wireguard non possono eseguire il ping a vicenda
Sto impostando una configurazione Wireguard in cui ho le seguenti entità:
Istanza VM remota su host come google cloud o amazon aws. Questo è un client remoto per il mio server wireguard. Chiamiamolo questo
gcp_client
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.
- 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 srvlan
e in gcp_client
entrambi i modi, e anche tra client1
e srvlan
. Però. i ping da gcp_client
a client1
(e viceversa) falliscono.
Sulla base della lettura dei risultati di tcpdump -i wg0 -n icmp
, ho formulato le seguenti osservazioni:
- Ping da
client1
agcp_client
raggiungeresrvlan
ma non vengono inoltrati al router. - Ping da
gcp_client
perclient1
raggiungere il mio router, che li inoltra asrvlan
. Tuttavia i pacchetti non vengono inoltrati dasrvlan
aclient1
.
L'unica cosa che posso concludere da questo è che le regole di inoltro srvlan
sono in qualche modo difettose. Sto usando nftables
per 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
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-icmp
non 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.