El servidor y el cliente de Wireguard pueden hacer ping entre sí, pero los clientes de Wireguard no pueden hacer ping entre sí
Estoy configurando una configuración de Wireguard donde tengo las siguientes entidades:
Instancia de VM remota en hosts como google cloud o amazon aws. Este es un cliente remoto para mi servidor wireguard. Vamos a llamar a esto
gcp_client
Un servidor wireguard en una máquina alojada en mi LAN. Llamemos a esto
srvlan
.
- El reenvío de IPv4 está habilitado en este dispositivo mediante
sysctl
. - Hay un Ubiquiti Edgerouter 4 entre la WAN y mi LAN. He habilitado el reenvío de puertos y NAT de horquilla en este dispositivo. También configuré un DNS dinámico en este enrutador.
- Uno o más clientes en mi LAN, que deberían poder conectarse al cliente remoto como si fuera una máquina en mi LAN. Como estoy enfrentando el problema con mi primer cliente, llamémoslo
client1
.
En mi configuración, puedo hacer ping entre srvlan
y en gcp_client
ambos sentidos, y entre client1
y srvlan
también. Sin embargo. los pings de gcp_client
a client1
(y viceversa) fallan.
Basándome en leer los resultados de tcpdump -i wg0 -n icmp
, hice las siguientes observaciones:
- Hace ping desde
client1
paragcp_client
llegarsrvlan
pero no se reenvía al enrutador. - Hace ping desde
gcp_client
paraclient1
llegar a mi enrutador, que los reenvía asrvlan
. Sin embargo, los paquetes no se reenvíansrvlan
aclient1
.
Lo único que puedo concluir de esto es que las reglas de reenvío srvlan
son de alguna manera defectuosas. Estoy usando nftables
para administrar este dispositivo.
Esta es mi configuración de protección de cables; Se han cambiado las direcciones IP y el número de puerto.
# 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
Este es mi firewall encendido 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
}
}
Respuestas
Cuando srvlan reenvía tráfico de túnel WireGuard, lo recibe de wg0 y lo enruta a ... wg0 nuevamente: dos veces la misma interfaz.
Por lo tanto, debe agregar esta entrada a la cadena de avance del firewall inet de nftables :
iifname "wg0" oifname "wg0" accept
Otros problemas, en la cadena entrante :
ip protocol icmp accept ip6 nexthdr ipv6-icmp accept ip protocol igmp accept
Si bien el protocolo funciona para IPv4, nexthdr en el protocolo IPv6 no garantiza que el siguiente encabezado sea ICMPv6: puede haber varios encabezados de extensión entre el encabezado fijo y el encabezado del protocolo de capa superior. Si tales encabezados de extensión aparecen en algunos paquetes, entonces nexthdr ipv6-icmp
ya no coincidirán. Utilice la sintaxis correcta para 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
Dependiendo de la versión de nftables , se mostrará de nuevo en una forma más simplificada.
iifname "wg0" udp dport 50000 ct state new accept
El puerto 50000 no aparece dentro de la interfaz WireGuard (a menos que desee tunelizar WireGuard dentro de WireGuard), sino afuera (para lo cual ya existe una regla). No debería ser necesario.
Recuerde a medida que agrega más clientes / pares de WireGuard (como lo hizo correctamente), que no puede haber superposiciones en las entradas de IPs permitidas de srvlan ya que determinan el enrutamiento criptográfico que ocurre en WireGuard para seleccionar el par adecuado, después del enrutamiento estándar. Además, si gcp_client se conecta a través de srvlan a servidores que no usan túneles WireGuard, entonces su dirección LAN también debe agregarse tanto a los IP permitidos como a la tabla de enrutamiento de gcp_client . AllowIPs se utiliza tanto para aceptar un paquete según su origen (y determinar qué par y tal vez actualizar su punto final en caso de itinerancia), como para determinar a qué par enviar un paquete según su destino.