Eu tenho um servidor lanserver
rodando na minha LAN privada que está conectado a um servidor público publicserver
usando o Wireguard. publicserver
encaminha conexões TCP para certas portas lanserver
através da conexão Wireguard usando uma DNAT
regra iptables.
Em lanserver
, o Wireguard é configurado como uma conexão do NetworkManager. Ele está roteando todo o tráfego da Internet através do Wireguard usando AllowedIPs = 0.0.0.0/0, ::/0
. Isso faz com que as seguintes regras de ip sejam configuradas em lanserver
:
[root@lanserver ~]# ip rule show
0: from all lookup local
31100: from all lookup main suppress_prefixlength 0
31101: not from all fwmark 0xcb2e lookup 52014
32766: from all lookup main
32767: from all lookup default
[root@lanserver ~]# ip route show table 52014
default dev wg0 proto static scope link metric 50
Esta configuração funciona corretamente. Uma conexão TCP de entrada publicserver
é encaminhada para lanserver
usar a regra iptables. A resposta é enviada de volta publicserver
porque a regra de ip 31101
corresponde a ela.
Há uma exceção: quando tento abrir uma conexão TCP publicserver
usando IPv6 do meu computador pessoal pc
, que também está dentro da minha LAN privada, não funciona. O problema parece ser que ambos pc
e lanserver
têm um endereço IPv6 na mesma sub-rede pública. publicserver
encaminha a conexão para lanserver
com sucesso, mas a resposta não é roteada de volta pela conexão Wireguard, mas diretamente para pc
devido à regra de ip 31100
.
Como posso garantir que todas as respostas para conexões recebidas pela interface Wireguard lanserver
também sejam enviadas de volta pela interface Wireguard, independentemente de seu IP de origem estar em uma sub-rede local?
Posso pensar em soluções nas seguintes direções:
- Desative o IPv6
lanserver
, fazendo com que ele não esteja na mesma sub-rede que opc
. Não é uma solução muito boa. - Use
SNAT
parapublicserver
o encaminhamento de porta. Não é uma solução aceitável, pois alguns dos serviços por trás das portas encaminhadas precisam conhecer o verdadeiro IP de origem. - Mencione explicitamente a sub-rede IPv6 local no
AllowedIPs
peer do Wireguard. Isso não funciona porque a sub-rede IPv6 muda a cada 24 horas. - Adicione uma regra de IP personalizada que de alguma forma corresponda a todas as conexões recebidas
wg0
e use a tabela de roteamento52014
para elas. Não sei exatamente como especificar essa regra. Além disso, o problema é que o número da tabela de roteamento muda toda vez que a conexão Wireguard é reiniciada. O lugar certo para criar tal regra provavelmente seria oPostUp
script, mas o NetworkManager parece não permitir a especificação de um.
Depois de experimentar diferentes opções, decidi parar de usar o NetworkManager e usar o wg-quick diretamente. No Fedora Server, isso foi bem fácil e eu só tive que remover a conexão do NetworkManager usando
nmcli con del wg0
e habilitar o serviço wg-quick usandosystemctl enable --now wg-quick@wg0
(que lê a configuração do/etc/wireguard/wg0.conf
). Mudar para wg-quick tem as seguintes vantagens:PostUp
comandos personalizados para configurar uma configuração de roteamento mais complexa51820
, embora eu não tenha encontrado nenhuma documentação sobre isso. Isso facilita a configuração de regras de IP personalizadas.Em seguida, usei o
PostUp
comando inwg0.conf
para configurar regras de ip adicionais que garantiriam que qualquer tráfego do Wireguard também respondesse por meio do Wireguard. Existem duas opções para conseguir isso:Opção 1: correspondência de IP de origem
As regras de ip correspondem aos pacotes do Wireguard com base em seus endereços IP de origem (que são definidos automaticamente para o endereço IP no qual a solicitação foi recebida originalmente):
Opção 2: fwmark
Algumas regras do iptables são configuradas para definir um
mark
pacote on que chega através dewg0
:Então isso
mark
é correspondido pela regra de IP:Mais detalhes sobre esta solução podem ser encontrados aqui .