O servidor e o cliente do wireguard são capazes de executar ping um no outro, mas os clientes do wireguard não conseguem executar o ping um do outro

Aug 18 2020

Estou definindo uma configuração Wireguard onde tenho as seguintes entidades:

  1. Instância de VM remota em hosts como google cloud ou amazon aws. Este é um cliente remoto para meu servidor wireguard. Vamos chamar issogcp_client

  2. Um servidor wireguard em uma máquina hospedada na minha LAN. Vamos chamar isso srvlan.

  • O encaminhamento de IPv4 é ativado neste dispositivo por sysctl.
  • Existe um Ubiquiti Edgerouter 4 entre a WAN e minha LAN. Habilitei o encaminhamento de porta e o NAT de grampo neste dispositivo. Também configurei um DNS dinâmico neste roteador.
  1. Um ou mais clientes em minha LAN, que devem ser capazes de se conectar ao cliente remoto como se fosse uma máquina em minha LAN. Como estou enfrentando o problema com meu primeiro cliente, vamos chamá-lo client1.

Na minha configuração, sou capaz de fazer ping entre srvlane nos gcp_clientdois sentidos, e entre client1e srvlantambém. Contudo. pings de gcp_clientpara client1(e vice-versa) falham.

Com base na leitura dos resultados de tcpdump -i wg0 -n icmp, fiz as seguintes observações:

  1. Pings de client1para gcp_clientalcançar, srvlanmas não são encaminhados para o roteador.
  2. Pings de gcp_clientpara client1alcançar meu roteador, que os encaminha para srvlan. No entanto, os pacotes não são encaminhados por srvlanpara client1.

A única coisa que posso concluir disso é que as regras de encaminhamento do srvlanestão de alguma forma defeituosas. Estou usando nftablespara gerenciar este dispositivo.

Esta é a minha configuração de wireguard; Os endereços IP e o número da porta foram alterados.

# 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 é o meu firewall ativado 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
        }
}

Respostas

A.B Aug 26 2020 at 00:35

Quando srvlan encaminha o tráfego encapsulado pelo WireGuard, ele o recebe do wg0 e o encaminha para ... wg0 novamente: duas vezes a mesma interface.

Portanto, você precisa anexar esta entrada à cadeia de encaminhamento do firewall inet de nftables :

                iifname "wg0" oifname "wg0" accept

Outros problemas, na entrada da cadeia :


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

Embora o protocolo funcione para IPv4, o nexthdr no protocolo IPv6 não garante que o Próximo Cabeçalho seja ICMPv6: pode haver vários Cabeçalhos de Extensão entre o Cabeçalho Fixo e o cabeçalho do protocolo da camada superior. Se esses cabeçalhos de extensão aparecerem em alguns pacotes, nexthdr ipv6-icmpeles não corresponderão mais. Use a sintaxe correta 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

Dependendo da versão nftables , ele será exibido de volta de uma forma mais simplificada.


                iifname "wg0" udp dport 50000 ct state new accept

A porta 50000 não aparece dentro da interface do WireGuard (a menos que você queira fazer um túnel do WireGuard dentro do WireGuard), mas fora (para o qual já existe uma regra). Não deveria ser necessário.


Lembre-se à medida que você adiciona mais clientes / peers WireGuard (como você fez corretamente), que não pode haver sobreposições nas entradas AllowedIPs de srvlan , pois eles determinam o cryptorouting que acontece no WireGuard para selecionar o peer adequado, após o roteamento padrão. Além disso, se gcp_client se conecta por meio de srvlan a servidores que não usam túneis WireGuard, seu endereço de LAN também deve ser adicionado aos AllowedIPs e à tabela de roteamento de gcp_client . AllowedIPs é usado para aceitar um pacote com base em sua origem (e determinar qual peer e talvez atualizar seu endpoint em caso de roaming) e para determinar para qual peer enviar um pacote com base em seu destino.