Eu tenho uma configuração um pouco mais complicada, que também inclui NAT e roteamento dinâmico (interno) na máquina.
Existem várias partes para isso. Vamos começar com as regras:
Maginot:~# ip rule ls
0: from all lookup local
1000: from all lookup main
1500: from 173.167.51.136/29 lookup comcast
1501: from 76.160.165.106/29 lookup cavtel
1502: from 151.200.251.90/31 lookup vzdsl
1502: from 151.200.251.92/31 lookup vzdsl
1502: from 151.200.251.94 lookup vzdsl
2000: from all fwmark 0x1 lookup comcast
2001: from all fwmark 0x2 lookup cavtel
2002: from all fwmark 0x3 lookup vzdsl
2500: from all lookup comcast
2501: from all lookup cavtel
2502: from all lookup vzdsl
32767: from all lookup default
(As tabelas recebem nomes em /etc/iproute2/rt_tables
)
Como você pode ver, temos três ISPs no momento e temos dois endereços IP estáticos em cada um deles. As regras 1500-1502 enviam o tráfego desses endereços IP de origem para a interface apropriada. As regras 2000-2002 enviam o tráfego com uma determinada marca de firewall (chegaremos a isso) na interface apropriada. Regras 2500-2502 dão a ordem de preferência de nossos ISPs, para o tráfego que não foi atribuído a um ISP já. Se um deles cair, você remove a regra para ele e o próximo da lista é usado.
Cada tabela de roteamento é bastante trivial:
Maginot:~# ip route ls table comcast
default via 173.167.51.142 dev comcast
(Local e main têm muito mais coisas, mas isso é diretamente conectado e rotas internas, respectivamente. O padrão da tabela é vazio).
Em seguida, é importante que uma vez que uma conexão seja atribuída a um ISP, ela permaneça ali (incluindo conexões de entrada). Tentar movê-lo é impossível, já que temos endereços IP diferentes em cada interface, e nossos provedores realmente têm filtragem de caminho inverso. Nós os mantemos no mesmo ISP com regras de firewall.
Lembre-se que o SNAT é feito após o roteamento, portanto, as políticas ip rule
não ajudarão. Você tem que usar outra coisa (talvez este seja o seu problema?)
iptables -t mangle -A PREROUTING -j CONNMARK --restore-mark
iptables -t mangle -A PREROUTING -m mark ! --mark 0 -j RETURN # if already set, we're done
iptables -t mangle -A PREROUTING -i wan -j MARK --set-mark $MARK_CAVTEL
iptables -t mangle -A PREROUTING -i comcast -j MARK --set-mark $MARK_COMCAST
iptables -t mangle -A PREROUTING -i vz-dsl -j MARK --set-mark $MARK_VZDSL
iptables -t mangle -A POSTROUTING -o wan -j MARK --set-mark $MARK_CAVTEL
iptables -t mangle -A POSTROUTING -o comcast -j MARK --set-mark $MARK_COMCAST
iptables -t mangle -A POSTROUTING -o vz-dsl -j MARK --set-mark $MARK_VZDSL
iptables -t mangle -A POSTROUTING -j CONNMARK --save-mark
Isto é do script de shell que o configura; as variáveis $MARK_…
correspondem às marcas que você vê nas regras acima. Bastante simples: restaure a marca de conexão (lembre-se, as marcas são por pacote); se houver uma marca agora (da marca de conexão), terminamos. Caso contrário, defina a marca para aquela baseada na interface envolvida.
Note que restaura a marcação antes do roteamento, e só salva depois. E a marca é definida para a interface de saída, independentemente (o que é discutível).
Finalmente, existem as regras reais do NAT. Temos vários prefixos locais, esse código é executado em um loop for com $local
definido para cada:
iptables -t nat -A POSTROUTING -s $local -o wan -j SNAT --to-source 76.160.165.106
iptables -t nat -A POSTROUTING -s $local -o comcast -j SNAT --to-source 173.167.51.137
iptables -t nat -A POSTROUTING -s $local -o vz-dsl -j SNAT --to-source 151.200.251.90
(Nota: Existem muito mais regras, incluindo alguns DNAT para servidores DMZ, etc ... Acho que copiei todos os relevantes.)