iptables: Como encaminhar a porta UDP e TCP para o servidor por trás da conexão VPN wireguard

iptables: Como encaminhar a porta UDP e TCP para o servidor por trás da conexão VPN wireguard

Então eu tenho um servidor VPS (KVM) rodando Debian bullseye com um IP público. Esse servidor também está executando um servidor wireguard. Em casa tenho outro servidor (atrás do NAT) com um cliente wireguard que está conectado ao meu VPS. O túnel está funcionando, o que significa que posso me comunicar corretamente pela VPN wireguard.

+----------------------------------+             +-------------------------------
| Homeserver (behind NAT)          |             | VPS (KVM) with public IP     |
| 192.168.1.10                     |             | 1.2.3.4                      |
|         +------------------------|             |--------------------+         |
|         | wg-homeserver          | - - - - - - | wg-vps             |         |
|         | 192.168.200.2          |             | 192.168.200.1      |         |
|         +------------------------|             |--------------------+         |
|                                  |             |                              |
+----------------------------------+             +------------------------------+

Meu servidor doméstico executa vários contêineres docker que escutam nas portas (em todos os endereços IP), o que significa que essas portas são acessíveis em 192.168.1.0/24. Agora preciso encaminhar uma porta TCP e uma porta UDP no endereço IP público do meu VPS e encaminhar o tráfego pelo link wireguard para as mesmas portas no meu servidor doméstico:

1.2.3.4:10000/tcp -> 192.168.200.2:10000/tcp
1.2.3.4:10001/udp -> 192.168.200.2:10001/udp

O encaminhamento de IP está habilitado em ambas as máquinas, o que significa que cat /proc/sys/net/ipv4/ip_forwardmostra 1.

Para encaminhar a porta TCP, tenho estas regras:

iptables -A FORWARD -d 192.168.200.2/32 -i wg-vps -p tcp --dport 10000 -j ACCEPT
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 10000 -j DNAT --to-destination 192.168.200.2:10000

Quando tento, ssh -p 10000 1.2.3.4não vejo nenhum pacote sendo registrado por wireguard -i wg-vps. Tentei várias outras coisas, mas não consegui descobrir o que estou fazendo de errado ou faltando.

Enfim, quanto à porta UDP criei esta regra, com um pouco mais de sucesso:

iptables -t nat -A PREROUTING -d 1.2.3.4/32 -i eth0 -p udp --dport 10001 -j DNAT --to-destination 192.168.200.2:10001

É assim que envio meu pacote de teste UDP:

echo -n test | nc -4 -u 1.2.3.4 10001

Quando faço isso, posso ver tcpdump -i wg-vpsno meu log VPS isto ( 4.5.6.7sendo meu endereço IP público):

11:35:47.497622 IP 4.5.6.7.43357 > 192.168.200.2.10001: UDP, length 4

Parece que ele está tentando fazer a coisa certa e pegar o pacote, atualizar o destino para 192.168.200.2e colocá-lo na interface wireguard wg-vps. Mas tcpdump -i wg-homeserverno meu servidor doméstico nunca mostra esse pacote chegando.

Na verdade, percebi que quando estou watch ip -s link show wg-homeserverno meu Homeserver, toda vez que envio um pacote udp para aquela porta, os erros de RX aumentam em um. Entãoalgochega até lá, mas seja lá o que for, não está aparecendo tcpdumpe parece ter caído em algum lugar abaixo. O que é estranho porque tanto o UDP quanto o TCP no link wireguard funcionam bem em ambas as direções.

Pelo que entendi, tcpdumpmostra pacotes anteriores ao iptables, então meu palpite é que, mesmo que o pacote pareça ter sido gravado na interface wireguard, ele será descartado em algum lugar.

ATUALIZAR: Ok, então encontrei uma maneira de ativar o log wireguard:

echo module wireguard +p > /sys/kernel/debug/dynamic_debug/control

E ao rastrear os logs, dmesg --followparece que o wireguard está descartando o pacote por este motivo:

wireguard: wg-homeserver: Packet has unallowed src IP (4.5.6.7) from peer 20 (xxxxxx)

Então, acho que isso significa que ele não gosta do fato de o endereço de origem ser o original de onde veio a solicitação. Não quero fazer SNAT, então acho que só preciso ensiná-lo de alguma forma que deve permitir qualquer endereço de origem.

Qual é a AllowedIPsconfiguração na [Peer]seção da minha configuração do wireguard. Isso resolve o problema:

AllowedIPs = 0.0.0.0/0, ::0/0

Antes disso eu havia colocado as máscaras de interface semelhantes ao que está na [Interface]seção, sem perceber que isso limitaria os endereços de origem dos pacotes.

No entanto, isso sequestra todo o tráfego e tenta encaminhá-lo através do link wireguard enquanto wg-quickolha AllowedIPse pensa que deveria adicionar uma rota e redirecionar todo o tráfego através da VPN. Obviamente, isso não é desejado, mas felizmente há uma solução: adicionar Table = offà [Interface]seção evitará isso.

Responder1

Consulte sua tabela de regras para entender como os pacotes de saída são roteados no servidor doméstico. wg-quick adicionará algumas regras.

ip rule show

Para mim, tive que remover algumas regras geradas pelo wg-quick (que faz com que ele encaminhe todos os pacotes para o wg) e depois adicionar regras que encaminhem as portas necessárias. Você pode ver a tabela wg# do comando acima.

ip -4 rule add sport 80 table XXXXX
ip -4 rule add sport 443 table XXXXX

O acima funcionou por um tempo. Mas o systemd-networkd removerá as regras personalizadas quando a concessão do DHCP expirar ou o cabo LAN for desconectado e reconectado. Então removi completamente o wg-quick e usei o systemd-networkd para configurar a interface wg e as regras de roteamento.

informação relacionada