Conexões OpenVPN redundantes com roteamento avançado do Linux em uma rede não confiável

9

Atualmente, moro em um país que bloqueia muitos sites e possui conexões de rede não confiáveis ​​com o mundo exterior. Eu tenho dois pontos de extremidade OpenVPN (digamos: vpn1 e vpn2) nos servidores Linux que eu uso para contornar o firewall. Eu tenho acesso total a esses servidores. Isso funciona muito bem, exceto pela grande perda de pacotes nas minhas conexões VPN. Essa perda de pacotes varia entre 1% e 30%, dependendo do tempo e parece ter uma baixa correlação, na maioria das vezes parece aleatória.

Estou pensando em configurar um roteador doméstico (também no Linux) que mantenha conexões OpenVPN para os dois pontos finais e envie todos os pacotes duas vezes, para os dois pontos finais. O vpn2 enviaria todos os pacotes de casa para o vpn1. O tráfego de retorno seria enviado diretamente do vpn1 para casa e também pelo vpn2.

       +------------+
       |    home    |
       +------------+
        |          |
        | OpenVPN  |
        |  links   |
        |          |
     ~~~~~~~~~~~~~~~~~~ unreliable connection
        |          |
+----------+   +----------+
|   vpn1   |---|   vpn2   |
+----------+   +----------+
        |
       +------------+
       | HTTP proxy |
       +------------+
             |
         (internet)

Para maior clareza: todos os pacotes entre o servidor doméstico e o proxy HTTP serão duplicados e enviados por caminhos diferentes, para aumentar as chances de um deles chegar. Se os dois chegarem, o primeiro segundo poderá ser descartado silenciosamente.

O uso da largura de banda não é um problema, tanto no lado inicial quanto no terminal. vpn1 e vpn2 estão próximos um do outro (ping de 3ms) e possuem uma conexão confiável.

Alguma dica de como isso pode ser alcançado usando as políticas de roteamento avançadas disponíveis no Linux?

Konrad
fonte

Respostas:

8

Use a infraestrutura de ligação no lado 'home' e 'vpn1' e, especificamente, com a configuração mode = 3 que transmite tráfego em todas as interfaces que pertencem a uma ligação.

Para obter mais informações sobre como configurar a ligação, consulte o excelente manual em http://git.kernel.org/?p=linux/kernel/git/stable/linux-2.6.37.y.git;a=blob;f = Documentação / rede / bonding.txt; h = 5dc638791d975116bf1a1e590fdfc44a6ae5c33c; hb = HEAD

jap
fonte
Eu testei essa configuração e funciona fantástico. A perda de pacotes é reduzida de cerca de 5% para 0,0-0,1% com uma conexão redundante a apenas um servidor!
precisa
7

Eu usei a resposta fornecida pelo @ user48116 e funciona como um encanto. A configuração é realmente muito fácil!

NOTA : Eu implementei isso com duas conexões para apenas um servidor, pois isso já resolveu o problema para mim. Se você quiser tentar uma configuração com dois servidores, a maneira mais fácil é provavelmente usar o encaminhamento de porta para encaminhar a porta UDP do segundo servidor para o primeiro e usar a mesma receita descrita aqui. Eu ainda não testei isso.

Primeiro, verifique se você possui um kernel 2.6 com suporte para ligação (padrão em todas as distribuições modernas) e se o ifenslave está instalado.

Em seguida, coloque isso no seu /etc/rc.local ou em qualquer outro lugar que você preferir, mas certifique-se de que seja executado antes do openvpn ser iniciado (porque ele tentará vincular ao bond0):

Cliente:

modprobe bonding mode=broadcast
ifconfig bond0 10.10.0.2 netmask 255.255.255.0 up

Você pode adicionar algum roteamento, se necessário, aqui; certifique-se de fazer todo o roteamento adequado do outro lado também.

route add -net 10.7.0.0/24 gw 10.10.0.1

Servidor:

modprobe bonding mode=broadcast
ifconfig bond0 10.10.0.1 netmask 255.255.255.0 up

Crie um script /etc/openvpn/tap-up.sh (e não se esqueça de marcá-lo como executável com chmod a + x tap-up.sh):

#!/bin/sh
# called as: cmd tap_dev tap_mtu link_mtu ifconfig_local_ip ifconfig_netmask [ init | restart ]
ifenslave bond0 "$1"

Em seguida, adicione bridge0a.conf e bridge0b.conf em / etc / openvpn / junto com uma chave compartilhada. Os arquivos são os mesmos para aeb, exceto para uma porta diferente (por exemplo, use 3002 para b). Substitua 11.22.33.44 pelo IP público do seu servidor.

Cliente:

remote 11.22.33.44
dev tap
port 3001
rport 3001
secret bridge.key
comp-lzo
verb 4
nobind
persist-tun
persist-key
script-security 2
up /etc/openvpn/tap-up.sh

Servidor:

local 11.22.33.44
dev tap
port 3001
lport 3001
secret bridge.key
comp-lzo
verb 4
script-security 2
up /etc/openvpn/tap-up.sh

Não se esqueça de editar / etc / defaults / openvpn para garantir que suas novas configurações de VPN sejam iniciadas. Reinicialize suas máquinas ou carregue o rc.local e reinicie o openvpn manualmente.

Agora você está pronto para testar sua configuração:

# ping 10.10.0.1
PING 10.10.0.1 (10.10.0.1) 56(84) bytes of data.
64 bytes from 10.10.0.1: icmp_req=1 ttl=64 time=50.4 ms
64 bytes from 10.10.0.1: icmp_req=1 ttl=64 time=51.1 ms (DUP!)
64 bytes from 10.10.0.1: icmp_req=1 ttl=64 time=51.1 ms (DUP!)
64 bytes from 10.10.0.1: icmp_req=1 ttl=64 time=51.1 ms (DUP!)
64 bytes from 10.10.0.1: icmp_req=2 ttl=64 time=52.0 ms
64 bytes from 10.10.0.1: icmp_req=2 ttl=64 time=52.2 ms (DUP!)
64 bytes from 10.10.0.1: icmp_req=2 ttl=64 time=53.0 ms (DUP!)
64 bytes from 10.10.0.1: icmp_req=2 ttl=64 time=53.1 ms (DUP!)
--- 10.10.0.1 ping statistics ---
2 packets transmitted, 2 received, +6 duplicates, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 50.428/51.786/53.160/0.955 ms

Se tudo correr bem e a linha for boa, você verá quatro respostas para cada pacote ICMP: seus pacotes são duplicados no lado local e as respostas a esses dois pacotes são duplicadas novamente no lado remoto. Isso não será um problema para conexões TCP, porque o TCP simplesmente ignorará todas as duplicatas.

Esse é um problema para os pacotes UDP, já que cabe ao software lidar com duplicatas. Por exemplo, uma consulta DNS produzirá quatro respostas em vez das duas esperadas (e usará quatro vezes a largura de banda normal para a resposta em vez de duas vezes):

# tcpdump -i bond0 -n port 53
listening on bond0, link-type EN10MB (Ethernet), capture size 65535 bytes
13:30:39.870740 IP 10.10.0.2.59330 > 10.7.0.1.53: 59577+ A? serverfault.com. (33)
13:30:40.174281 IP 10.7.0.1.53 > 10.10.0.2.59330: 59577 1/0/0 A 64.34.119.12 (49)
13:30:40.174471 IP 10.7.0.1.53 > 10.10.0.2.59330: 59577 1/0/0 A 64.34.119.12 (49)
13:30:40.186664 IP 10.7.0.1.53 > 10.10.0.2.59330: 59577 1/0/0 A 64.34.119.12 (49)
13:30:40.187030 IP 10.7.0.1.53 > 10.10.0.2.59330: 59577 1/0/0 A 64.34.119.12 (49)

Boa sorte!

Konrad
fonte