Configurar roteamento e iptables para nova conexão VPN para redirecionar ** apenas ** portas 80 e 443


8

Eu tenho uma nova conexão VPN (usando o openvpn) para me permitir contornar algumas restrições do provedor. Enquanto está funcionando bem, está absorvendo todo o tráfego pela VPN. Isso está me causando problemas para fazer o download (minha conexão à Internet é muito mais rápida do que a vpn permite) e para o acesso remoto. Eu executo um servidor ssh e tenho um daemon em execução que me permite realizar downloads através do meu telefone.

Eu tenho minha conexão Ethernet existente no eth0 e a nova conexão VPN no tun0.

Acredito que preciso configurar a rota padrão para usar minha conexão eth0 existente na rede 192.168.0.0/24 e definir o gateway padrão como 192.168.0.1 (meu conhecimento é instável, pois não faço isso há vários anos ) Se isso estiver correto, não sei exatamente como fazê-lo! Minha tabela de roteamento atual é:

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface    MSS   Window irtt
0.0.0.0         10.51.0.169     0.0.0.0         UG    0      0        0 tun0     0     0      0
10.51.0.1       10.51.0.169     255.255.255.255 UGH   0      0        0 tun0     0     0      0
10.51.0.169     0.0.0.0         255.255.255.255 UH    0      0        0 tun0     0     0      0
85.25.147.49    192.168.0.1     255.255.255.255 UGH   0      0        0 eth0     0     0      0
169.254.0.0     0.0.0.0         255.255.0.0     U     1000   0        0 eth0     0     0      0
192.168.0.0     0.0.0.0         255.255.255.0   U     1      0        0 eth0     0     0      0

Depois de corrigir o roteamento, acredito que preciso usar o iptables para configurar o pré-roteamento ou o disfarce para forçar tudo na porta de destino 80 ou 443 em tun0. Novamente, não sei exatamente como fazer isso!

Tudo o que encontrei na internet está tentando fazer algo muito mais complicado, e tentar separar a madeira das árvores está se mostrando difícil.

Qualquer ajuda seria muito apreciada.

ATUALIZAR

Até agora, das várias fontes, juntei o seguinte:

#!/bin/sh

DEV1=eth0
IP1=`ifconfig|perl -nE'/dr:(\S+)/&&say$1'|grep 192.`
GW1=192.168.0.1
TABLE1=internet
TABLE2=vpn
DEV2=tun0
IP2=`ifconfig|perl -nE'/dr:(\S+)/&&say$1'|grep 10.`
GW2=`route -n | grep 'UG[ \t]' | awk '{print $2}'`

ip route flush table $TABLE1
ip route flush table $TABLE2
ip route show table main | grep -Ev ^default | while read ROUTE ; do
    ip route add table $TABLE1 $ROUTE
    ip route add table $TABLE2 $ROUTE
done
ip route add table $TABLE1 $GW1 dev $DEV1 src $IP1
ip route add table $TABLE2 $GW2 dev $DEV2 src $IP2
ip route add table $TABLE1 default via $GW1
ip route add table $TABLE2 default via $GW2

echo "1" > /proc/sys/net/ipv4/ip_forward
echo "1" > /proc/sys/net/ipv4/ip_dynaddr

ip rule add from $IP1 lookup $TABLE1
ip rule add from $IP2 lookup $TABLE2
ip rule add fwmark 1 lookup $TABLE1
ip rule add fwmark 2 lookup $TABLE2

iptables -t nat -A POSTROUTING -o $DEV1 -j SNAT --to-source $IP1
iptables -t nat -A POSTROUTING -o $DEV2 -j SNAT --to-source $IP2

iptables -t nat -A PREROUTING           -m state --state ESTABLISHED,RELATED          -j CONNMARK --restore-mark
iptables        -A OUTPUT               -m state --state ESTABLISHED,RELATED          -j CONNMARK --restore-mark
iptables -t nat -A PREROUTING -i $DEV1  -m state --state NEW                          -j CONNMARK --set-mark 1
iptables -t nat -A PREROUTING -i $DEV2  -m state --state NEW                          -j CONNMARK --set-mark 2
iptables -t nat -A PREROUTING           -m connmark --mark 1                          -j MARK --set-mark 1
iptables -t nat -A PREROUTING           -m connmark --mark 2                          -j MARK --set-mark 2
iptables -t nat -A PREROUTING           -m state --state NEW -m connmark ! --mark 0   -j CONNMARK --save-mark

iptables -t mangle -A PREROUTING -i $DEV2 -m state --state NEW -p tcp --dport  80 -j CONNMARK --set-mark 2
iptables -t mangle -A PREROUTING -i $DEV2 -m state --state NEW -p tcp --dport 443 -j CONNMARK --set-mark 2

route del default
route add default gw 192.168.0.1 eth0

Agora isso parece estar funcionando. Exceto que não é!

As conexões com os sites bloqueados estão passando, as conexões que não estão nas portas 80 e 443 estão usando a conexão não VPN.

No entanto, as conexões das portas 80 e 443 que não são para os sites bloqueados também estão usando a conexão não VPN!

Como o objetivo geral foi alcançado, estou relativamente feliz, mas seria bom saber por que não está funcionando exatamente da maneira certa.

Alguma ideia?

Para referência, agora tenho 3 tabelas de roteamento, main, internet e vpn. A lista deles é a seguinte ...

A Principal:

default via 192.168.0.1 dev eth0 
10.38.0.1 via 10.38.0.205 dev tun0 
10.38.0.205 dev tun0  proto kernel  scope link  src 10.38.0.206 
85.removed via 192.168.0.1 dev eth0 
169.254.0.0/16 dev eth0  scope link  metric 1000 
192.168.0.0/24 dev eth0  proto kernel  scope link  src 192.168.0.73  metric 1 

Internet:

default via 192.168.0.1 dev eth0 
10.38.0.1 via 10.38.0.205 dev tun0 
10.38.0.205 dev tun0  proto kernel  scope link  src 10.38.0.206 
85.removed via 192.168.0.1 dev eth0 
169.254.0.0/16 dev eth0  scope link  metric 1000 
192.168.0.0/24 dev eth0  proto kernel  scope link  src 192.168.0.73  metric 1 
192.168.0.1 dev eth0  scope link  src 192.168.0.73

VPN:

default via 10.38.0.205 dev tun0 
10.38.0.1 via 10.38.0.205 dev tun0 
10.38.0.205 dev tun0  proto kernel  scope link  src 10.38.0.206 
85.removed via 192.168.0.1 dev eth0 
169.254.0.0/16 dev eth0  scope link  metric 1000 
192.168.0.0/24 dev eth0  proto kernel  scope link  src 192.168.0.73  metric 1

O script acima funciona como esperado. Eu só esperava ver o tráfego originário do endereço 10. no netstat. No entanto, todo o tráfego se origina de 192., mas as portas 80 e 443 são direcionadas por VPN. Vou colocar toda a solução em uma resposta, mas adoro o @anttir por sugerir o iproute2 e o fwmark. Eu não tinha encontrado aqueles, e sem eles eu ainda estaria batendo minha cabeça contra uma parede de tijolos!
91111 Steve Steve

Respostas:


4

Portanto, a maior parte disso está acima, mas toda a solução foi a seguinte:

Edite / etc / iproute2 / rt_tables e adicione 2 linhas na parte inferior:

101 internet
102 vpn

Você pode dar a essas tabelas outros nomes que façam mais sentido, apenas seja consistente.

Então você precisa criar um script (eu o chamei de rt_setup) em /etc/init.d

#!/bin/sh

DEV1=eth0
IP1=`ifconfig|perl -nE'/dr:(\S+)/&&say$1'|grep 192.`
GW1=192.168.0.1
TABLE1=internet
TABLE2=vpn
DEV2=tun0
IP2=`ifconfig|perl -nE'/dr:(\S+)/&&say$1'|grep 10.`
GW2=`route -n | grep 'UG[ \t]' | awk '{print $2}'`

ip route flush table $TABLE1
ip route flush table $TABLE2
ip route show table main | grep -Ev ^default | while read ROUTE ; do
    ip route add table $TABLE1 $ROUTE
    ip route add table $TABLE2 $ROUTE
done
ip route add table $TABLE1 $GW1 dev $DEV1 src $IP1
ip route add table $TABLE2 $GW2 dev $DEV2 src $IP2
ip route add table $TABLE1 default via $GW1
ip route add table $TABLE2 default via $GW2

echo "1" > /proc/sys/net/ipv4/ip_forward
echo "1" > /proc/sys/net/ipv4/ip_dynaddr

ip rule add from $IP1 lookup $TABLE1
ip rule add from $IP2 lookup $TABLE2
ip rule add fwmark 1 lookup $TABLE1
ip rule add fwmark 2 lookup $TABLE2

iptables -t nat -A POSTROUTING -o $DEV1 -j SNAT --to-source $IP1
iptables -t nat -A POSTROUTING -o $DEV2 -j SNAT --to-source $IP2

iptables -t nat -A PREROUTING           -m state --state ESTABLISHED,RELATED          -j CONNMARK --restore-mark
iptables        -A OUTPUT               -m state --state ESTABLISHED,RELATED          -j CONNMARK --restore-mark
iptables -t nat -A PREROUTING -i $DEV1  -m state --state NEW                          -j CONNMARK --set-mark 1
iptables -t nat -A PREROUTING -i $DEV2  -m state --state NEW                          -j CONNMARK --set-mark 2
iptables -t nat -A PREROUTING           -m connmark --mark 1                          -j MARK --set-mark 1
iptables -t nat -A PREROUTING           -m connmark --mark 2                          -j MARK --set-mark 2
iptables -t nat -A PREROUTING           -m state --state NEW -m connmark ! --mark 0   -j CONNMARK --save-mark

iptables -t mangle -A PREROUTING -i $DEV2 -m state --state NEW -p tcp --dport  80 -j CONNMARK --set-mark 2
iptables -t mangle -A PREROUTING -i $DEV2 -m state --state NEW -p tcp --dport 443 -j CONNMARK --set-mark 2

route del default
route add default gw 192.168.0.1 eth0

Então, obviamente, vincule-o em /etc/rc2.d (eu uso o ubuntu, o nível de execução pode ser diferente para você). Certifique-se de atribuir um número S acima do link openvpn!

O script faz várias coisas. A parte superior configura as variáveis, com algumas instruções perl e awk usadas para selecionar os IPs dinâmicos e os endereços de gateway. A segunda seção limpa as tabelas configuradas no ipruote2 e copia a tabela de roteamento atual para elas. Em seguida, ele cria duas novas rotas e dois gateways padrão para eles, com a VPN passando pela VPN e a Internet passando pela minha rede local.

Não estou convencido de que as próximas 2 linhas sejam necessárias, mas elas permitem o encaminhamento de ip para uso em iptables.

Em seguida, o script cria algumas regras sobre onde procurar tráfego originado no endereço IP relevante e onde procurar se o tráfego está especificamente marcado.

O POSTROUTING e o PREROUTING garantem que o tráfego originado de um endereço receba a resposta!

O iptables final PREROUTING é a parte que marca o tráfego e garante que qualquer coisa que vá para as portas 80 ou 443 seja marcada para usar a Tabela 2 (VPN)

As duas linhas finais removem o gateway VPN da tabela de roteamento padrão e adicionam de volta meu gateway de rede local.

Tal como está, o processo funciona de maneira brilhante. A VPN é iniciada quando a máquina é ativada e esse script é executado alguns segundos depois (posso adicionar uma declaração de suspensão apenas para garantir que a VPN seja totalmente inicializada antes de executar este script). Minha conexão de acesso remoto (ssh etc.) funciona muito bem. Minhas conexões que não vão para as portas 80 ou 443 estão usando minha conexão local, mas todo o tráfego da Web está passando pela VPN e ignorando os controles implementados pelo meu ISP!

Como eu disse no meu comentário na minha pergunta, eu nem começaria a olhar para essa rota sem a sugestão do @anttir. Na parte de trás dessa sugestão, os sites http://blog.khax.net/2009/11/28/multi-gateway-routing-with-iptables-and-iproute2/ e http://linux-ip.net/ html / adv-multi-internet.html foram muito úteis (mesmo que o código não esteja 100% completo!)


11
Uma adição final, adicionei um sleep 20ao topo do script, pois a conexão openvpn não estava sendo concluída a tempo. Também adicionei echo 2 > /proc/sys/net/ipv4/conf/tun0/rp_filterao script, pois é necessário desativar o filtro de pacotes reversos para tun0. Quando uma resposta volta do tun0 com o endereço de origem S, o filtro de pacote reverso verifica "se eu deveria encaminhar um pacote para o endereço S e ele não passaria pelo tun0, vou abandonar o pacote" - e porque ao fazer isso Se não houver um fwmark válido, ele determina que a rota seria a rota padrão usual e, portanto, descarta o pacote.
11111 Steve Steve

Eu tive que editar seu script para fazê-lo funcionar para mim. A última linha route add default gw 192.168.0.1 eth0parecia direcionar o tráfego da porta 80/443 através do gateway local, em vez do tun0, conforme planejado. Alterar a última linha para route add default tun0parece fazer o truque para mim.

1

o roteamento por protocolo é um pouco complicado. Geralmente, a tabela de roteamento é usada para verificar o gateway de acordo com o IP de destino e usar o gateway padrão openvpn ou 192.168.0.1.

Seria mais fácil configurar, por exemplo, o proxy http do Squid na outra extremidade da VPN e configurar o navegador para usar o proxy.

Você não usaria as tabelas de ip, pois isso mudaria o IP de destino da conexão HTTP e não funcionaria.

Você pode criar uma nova tabela de roteamento (/ etc / iproute2 / rt_tables) com a rota padrão definida como o ponto de extremidade da VPN, usar iptables fwmark (-j MARK) para marcar todos os pacotes HTTP e usar a regra ip para criar uma regra personalizada para o pacotes marcados para usar a nova tabela de roteamento.


Obrigado pela ajuda. Certamente vou dar uma olhada nelas. As coisas são um pouco complicadas, pois não tenho controle sobre o servidor, apenas o meu lado. Além disso, não posso usar o squid porque preciso rotear o tráfego https pela conexão, e o squid não funciona tão bem com isso.
911 Steve Steve

Que tal encaminhar apenas alguns IPs pela VPN e pelo resto do mundo fora da VPN?
Antti Rytsölä

Pensei em rotear apenas alguns IPs, mas a lista muda à medida que os sites se movimentam, e preciso facilitar o uso para outros usuários no PC. Comecei a examinar a criação de uma nova tabela de roteamento e a marcação dos pacotes. Os pacotes de marcação foram fáceis, são as tabelas de roteamento das quais não tenho tanta certeza. Posso configurar um para VPN que parece certo e outro para tudo o que parece certo, mas não sei o que fazer com main, pois ele ainda está definido como padrão (o que é VPN). Ainda está jogando ... #
1146 Steve Steve

linux-ip.net/html/adv-multi-internet.html regra de ip show e regra de ip add fwmark 4 table 4 priority 10000
Antti Rytsölä

Adicionada uma atualização ao original que detalha onde estou indo até agora! Ah! Acabei de perceber que editei sua resposta, não minha pergunta. Desculpa! Não usei muito e não percebi que eu poderia editar a resposta de outra pessoa!
8111 Steve Steve
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.