Houve dois problemas com minha configuração de roteamento original:
-
Como indicado na resposta de Gabe, MARK in OUTPUT não pode influenciar a decisão de roteamento, apenas a decisão de redirecionamento após o NAT.
Isso resultou em ter o endereço de origem errado nos pacotes de saída, porque o endereço de origem é atribuído pela decisão de roteamento e é deixado sozinho pelo reencaminhamento. Eu finalmente decidi que a melhor solução é lidar com isso com uma ação MASQUERADE baseada na marca:
iptables -A POSTROUTING -t nat -m mark --mark 64 -j MASQUERADE
-
O Linux tem um filtro de pacotes reverso.
Veja, por exemplo, um comentário no link para ver o efeito do filtro em cenários de roteamento relacionados à VPN.
Se um pacote do endereço de origem
A
for recebido na interfaceI
, ele será descartado, a menos que um pacote para o endereço de destinoA
tenha sido roteado para a interfaceI
. Naturalmente, respostas de, e.8.8.8.8
entrada paratun0
será descartada, pois o roteamento normal rotearia os pacotes para8.8.8.8
aeth0
na ausência da marca.Pode-se desativar o filtro de pacotes com
echo 2 > /proc/sys/net/ipv4/conf/tun0/rp_filter
mas isto é considerado prejudicial, uma vez que agora os pacotes forjados pretendem vir de, e.
127.0.0.1
poderia atingir a máquina através detun0
. Podemos configurar regras de firewall apropriadas para evitar essa violação de segurança. Note que a exploração da vulnerabilidade acima mencionada exigiria comprometimento do próprio servidor VPN (apenas desabilitamos o filtro rp paratun0
), então, na minha opinião, não é um risco muito grande de qualquer maneira.
Um ótimo efeito colateral dessa configuração é que tun0
nunca é explicitamente mencionado nas regras do iptables. Agora posso adicionar qualquer tipo de informação de roteamento à tabela de roteamento vpn e criar IPs "falsos" que a obedeçam (embora seja preciso lembrar do filtro rp). Por exemplo, a configuração é igualmente útil para VPNs baseadas em PPTP, modificando uma única entrada da tabela de roteamento.