Connexions OpenVPN redondantes avec routage Linux avancé sur un réseau peu fiable

9

Je vis actuellement dans un pays qui bloque de nombreux sites Web et a des connexions réseau non fiables avec le monde extérieur. J'ai deux points de terminaison OpenVPN (disons: vpn1 et vpn2) sur des serveurs Linux que j'utilise pour contourner le pare-feu. J'ai un accès complet à ces serveurs. Cela fonctionne assez bien, à l'exception de la forte perte de packages sur mes connexions VPN. Cette perte de paquets varie entre 1% et 30% selon le temps et semble avoir une faible corrélation, la plupart du temps elle semble aléatoire.

Je pense à mettre en place un routeur domestique (également sous Linux) qui maintient les connexions OpenVPN aux deux points de terminaison et envoie tous les paquets deux fois, aux deux points de terminaison. vpn2 enverrait tous les paquets de la maison à vpn1. Le trafic de retour serait envoyé à la fois directement de vpn1 à la maison et également via vpn2.

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

Pour plus de clarté: tous les paquets entre la maison et le proxy HTTP seront dupliqués et envoyés sur des chemins différents, pour augmenter les chances que l'un d'eux arrive. Si les deux arrivent, la première seconde peut être éliminée en silence.

L'utilisation de la bande passante n'est pas un problème, tant du côté de la maison que du côté du point de terminaison. vpn1 et vpn2 sont proches l'un de l'autre (ping de 3 ms) et ont une connexion fiable.

Avez-vous des indications sur la façon dont cela pourrait être réalisé en utilisant les politiques de routage avancées disponibles sous Linux?

Konrad
la source

Réponses:

8

Utilisez l'infrastructure de liaison côté «home» et «vpn1», et en particulier avec le paramètre mode = 3 qui diffuse le trafic sur toutes les interfaces qui appartiennent à une liaison.

Pour plus d'informations sur la configuration de la liaison, consultez l'excellent manuel sur http://git.kernel.org/?p=linux/kernel/git/stable/linux-2.6.37.y.git;a=blob;f = Documentation / networking / bonding.txt; h = 5dc638791d975116bf1a1e590fdfc44a6ae5c33c; hb = HEAD

jap
la source
J'ai testé cette configuration et cela fonctionne à merveille. La perte de paquet est réduite d'environ 5% à 0,0-0,1% avec une connexion redondante à un seul serveur!
konrad
7

J'ai utilisé la réponse fournie par @ user48116 et cela fonctionne comme un charme. La configuration est en fait assez simple!

REMARQUE : J'ai implémenté cela avec deux connexions à un seul serveur, car cela a déjà résolu le problème pour moi. Si vous voulez essayer une configuration avec deux serveurs, le moyen le plus simple est probablement d'utiliser la redirection de port pour transférer le port UDP du deuxième serveur vers le premier, et d'utiliser la même recette que celle décrite ici. Je n'ai cependant pas testé cela moi-même.

Tout d'abord, assurez-vous que vous avez un noyau 2.6 avec prise en charge de la liaison (par défaut dans toutes les distributions modernes) et que vous avez installé ifenslave.

Ensuite, mettez-le dans votre /etc/rc.local ou dans tout autre endroit que vous préférez, mais assurez-vous qu'il est exécuté avant le démarrage de openvpn (car il essaiera de se lier à bond0):

Client:

modprobe bonding mode=broadcast
ifconfig bond0 10.10.0.2 netmask 255.255.255.0 up

Vous pouvez ajouter un routage si nécessaire ici, assurez-vous que vous effectuez également tout le routage approprié de l'autre côté.

route add -net 10.7.0.0/24 gw 10.10.0.1

Serveur:

modprobe bonding mode=broadcast
ifconfig bond0 10.10.0.1 netmask 255.255.255.0 up

Créez un script /etc/openvpn/tap-up.sh (et n'oubliez pas de le marquer comme exécutable avec 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"

Ensuite, ajoutez un bridge0a.conf et bridge0b.conf à / etc / openvpn / avec une clé partagée. Les fichiers sont les mêmes pour a et b, sauf pour un port différent (par exemple, utilisez 3002 pour b). Remplacez 11.22.33.44 par l'IP publique de votre serveur.

Client:

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

Serveur:

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'oubliez pas de modifier / etc / defaults / openvpn pour vous assurer que vos nouvelles configurations VPN sont démarrées. Redémarrez vos machines ou chargez rc.local et redémarrez openvpn manuellement.

Vous êtes maintenant prêt à tester votre configuration:

# 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

Si tout se passe bien et que la ligne est bonne, vous verrez quatre réponses pour chaque package ICMP: vos packages sont dupliqués du côté local, et les réponses à ces deux packages sont à nouveau dupliquées du côté distant. Ce ne sera pas un problème pour les connexions TCP, car TCP ignorera simplement tous les doublons.

C'est un problème pour les paquets UDP, car c'est au logiciel de gérer les doublons. Par exemple, une requête DNS donnera quatre réponses au lieu des deux attendues (et utilisera quatre fois la bande passante normale pour la réponse au lieu de deux fois):

# 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)

Bonne chance!

Konrad
la source