Eu tenho um servidor Linux que é um endpoint OpenVPN, mas também hospeda um servidor web. Quando meu cliente se conecta ao endereço do servidor da web, os pacotes viajam para fora da VPN. Com razão, já que a rota para o servidor definida pelo OpenVPN é mais específica do que a rota padrão para entrar na VPN. No entanto, vejo isso como um "vazamento".
Por isso, tentei configurar uma configuração semelhante à do Wireguard (o Wireguard é ótimo, mas preciso do OpenVPN porque precisa ser TCP).
Baseei minha configuração na página Wireguard, bem como em outras questões: Evitar loop de roteamento com FwMark no Wireguard (Tiremos o chapéu para a palestra realizada lá!) Roteando fwmark para gateway VPN usando nftables mark
Apesar da configuração, o Wireshark mostra que as solicitações http/https ainda passam pela interface física e não pela interface vpn tun0. Quando olho para as marcas de pacotes com rastreamento do monitor NFT, parece que a metamarca está definida corretamente e apenas os pacotes apropriados (de/para a porta 1194) aparecem.
Então eu suspeitei que isso fosse:
- a regra pbr que não funciona conforme o esperado.
- a marcação do pacote que não acontece com antecedência suficiente.
Tentei alterar a cadeia para marcar os pacotes de saída como:
- digite saída do gancho de rota
- tipo saída de gancho de filtro
- --> sem mais sorte
Esses comandos retornam o seguinte:
- ip rule:
0: from all lookup local
32764: from all lookup main suppress_prefixlength 0
32765: not from all fwmark 0x4 lookup vpn
32766: from all lookup main
32767: from all lookup default
- ip route show table vpn:
default dev tun0 scope link
- ip route:
default via 10.8.0.1 dev tun0 proto static metric 50
default via 192.168.1.1 dev wlp4s0 proto dhcp src 192.168.1.10 metric 600
10.8.0.0/24 dev tun0 proto kernel scope link src 10.8.0.2 metric 50
END.POINT.IP.ADDRESS via 192.168.1.1 dev wlp4s0 proto static metric 50
192.168.1.0/24 dev wlp4s0 proto kernel scope link src 192.168.1.10 metric 600
-nft list ruleset:
table inet vpn {
chain premangle {
type filter hook prerouting priority mangle; policy accept;
ip saddr END.POINT.IP.ADDRESS tcp sport 1194 meta nftrace set 1
meta mark set ct mark
}
chain postmangle {
type filter hook postrouting priority mangle; policy accept;
ip daddr END.POINT.IP.ADDRESS tcp dport 1194 meta nftrace set 1
ip daddr END.POINT.IP.ADDRESS tcp dport 1194 meta mark set 0x00000004
meta mark 0x00000004 ct mark set meta mark
}
}
- traceroute -n --fwmark=0x4 END.POINT.IP.ADDRESS
shows it goes via the physical interface out of the vpn (as expected)
- traceroute -n END.POINT.IP.ADDRESS
shows it goes via the physical interface out of the vpn (UNWANTED)
Muito obrigado antecipadamente !
Se não estiver usando Strict Reverse Path Forwarding ("SRPF"), nenhum nftables deverá ser usado.
Embora o tráfego roteado (encaminhado) geralmente funcione bem quando as marcas são tratadas em iptables ou nftables , o tráfego redirecionado iniciado localmente por causa de uma marca (em
type route hook output
cadeia) geralmente apresenta problemas: a verificação de redirecionamento que acontece natype route hook output
cadeia não alterará magicamente a origem local Endereço IP que já foi escolhido no soquete do cliente. Geralmente é o endereço IP errado. Portanto, geralmente requer um bandaid NAT (que seria necessário notype nat hook output
) e provavelmente tornará o manuseio do UDP ainda mais difícil do que já é em um ambiente multi-homed. O uso de nftables para isso deve ser evitado sempre que possível.Assim como o WireGuard, o OpenVPN pode definir adequadamente a própria marca do firewall no tráfego de saída do envelope, e isso acontecerá antes de qualquer pesquisa de rota acontecer para o tráfego de saída local:
Isso funciona da mesma forma que o WireGuard: os pacotes de envelope de saída, na interface real, recebem a marca, provavelmente fazendo com que o cliente use
SO_MARK
seu soquete antes de se conectar ao servidor:É claro que se não houver reencaminhamento nem utilização directa de políticas de encaminhamento, incluindo marcação directa (com
SO_MARK
ou um método equivalente), é provável que não funcione de todo.Portanto, exclua todas as regras do nftables :
e, em vez disso, adicione a configuração do cliente:
Mantenha as regras e a tabela de roteamento (elas provavelmente devem ser integradas nos ganchos VPN):
Nota: as partes no final desta resposta, apenas para o caso SRPF, devem ser adicionadas antes de adicionar a entrada da tabela de roteamento acima para evitar interrupções temporárias.
Não adicione uma rota padrão através da VPN nem uma rota explícita para o terminal remoto . Não faça com que o servidor envie esta configuração. Ou faça com que o cliente ignore com:
ou:
Para que essas rotas não apareçam:
mas apenas este é adicionado:
Em vez disso, as regras de roteamento da política tratarão a rota padrão selecionando a tabela de roteamento
vpn
somente quando for adequado.Conforme explicado em minha resposta à primeira pergunta/resposta vinculada, a maior parte do conjunto de regras nftables para WireGuard
Table = auto
+AllowedIPs = 0.0.0.0
é lidar com SRPF para tráfego de resposta. Existem alguns casos:rp_filter=0
em todos os lugaresincluindo
net.ipv4.conf.default.rp_filter
enet.ipv4.conf.all.rp_filter
. Nenhuma verificação RPF: nada a fazer. Não são necessários nftables .rp_filter=1
Agora o tráfego de resposta de envelope pode falhar no SRPF
Escolha Loose RPF na interface principal:
e acabar com isso. Não são necessários nftables ,
ou implementar toda a lógica para marcar o tráfego do envelope de retorno assim como é feito no WireGuard
Faça com que o fwmark também seja usado na pesquisa de caminho reverso
habilitando
src_valid_mark
a interface principal (poderia ter sido ativadaall
), permitindo assim que o SRPF passasse:Transpor (somente IPv4 aqui) a configuração do WireGuard
conforme visto nas perguntas e respostas vinculadas, com casos adicionais descritos no final também contabilizados, portanto, o tráfego de resposta recebe a marca fw
A corrente
preraw
é opcional e pode ser removida se necessário. Ele protege contra tentativas remotas (LAN) de acesso ao endereço local VPN interno.A marca é criada pelo OpenVPN em pacotes de envelope de saída, copiada para a marca de conexão no pós-roteamento do gancho e reinjetada nos pacotes de envelope de resposta no pré-roteamento do gancho. Nenhum endereço de endpoint ou porta aparece em nenhum lugar.
Nenhum reencaminhamento é feito (não
type route hook output
nemtype nat hook output
presente).Nota: o comando sysctl e o conjunto de regras nftables acima devem ser executados antes de adicionar a rota padrão na tabela de roteamento
vpn
ou a perda temporária de conectividade acontecerá até que o soquete TCP da VPN se recupere (ainda assim, apenas quando ambos forem adicionados).O sistema cliente agora pode alcançar o servidor de dentro do túnel.
Os testes de conectividade podem ser feitos assim:
Os OPs
tcpdump
devem chegar a END.POINT.IP.ADDRESS em um único salto: através da VPN.Pelo menos em uma arquitetura amd64 (x86-64), a VPN pode ser ignorada (como root) com:
onde
setsockopt-listen
significa: usarSO_MARK
antes de conectar (em vez de ouvir, neste caso). e 4 polL4
é o mesmo valor de marca usado pelo OpenVPN.Nota: o caso específico do cliente que consulta através do túnel um serviço UDP no servidor com o endereço IP público de um servidor pode atingir um problema comum não relacionado realmente à VPN, mas ao uso de UDP e ao fato de ser multi-homed. Isso requer que o serviço UDP seja compatível com multi-homed: geralmente usando vários soquetes UDP, vinculando uma vez para cada endereço local (geralmente pelo menos uma vez por interface) ou com um único soquete UDP não vinculado usando
IP_PKTINFO
código de manipulação adicional.Primeiramente muito obrigado pela pronta resposta.
Ah, ok. Entendo que, como a decisão inicial de roteamento logo após o processo de solicitação já ocorreu, sem NAT, o reencaminhamento enviará os pacotes com uma fonte errada e, portanto, falhará.
Então eu fiz o seguinte:
Em relação ao rp_filter, o padrão da minha distribuição é 2, não vou adicionar mais complexidade a isso. Então, deixando tudo isso fora do caminho, conforme recomendado. Eu configurei tudo isso como 0 por enquanto.
Eu mantive nftables apenas para rastrear pacotes e garantir que o openvpn marcasse os pacotes conforme abaixo).
No entanto, agora não consigo mais acessar o servidor web:
Eu fiz
ip route flush cache
apenas por precaução. Sem sucesso, enquanto tudo parece em ordem com:O Wirehshark não mostra nenhum pacote relacionado à solicitação, nem mesmo para endereço errado ou sem resposta.
Alguma pista de algo que possa atrapalhar, por favor?! Desculpe se entendi mal algum ponto, a configuração que você propôs faz sentido para mim, francamente. Obrigado !