Soit 2 Freebox ADSL plafonnant joyeusement autour de 4Mb/s, et partageant le même réseau local.
Comment agréger les box pour obtenir 8Mb/s ? Avec “OpenVPN Bonding” bien sur… et quelques autres trucs.
~~READMORE~~
Le réseau local:
2 Freebox:
Je peux choisir la Freebox avec laquelle je surfe par un simple:
# route add default gw 192.168.0.253 # route del default gw 192.168.0.254
En clair:
Aprés un petit lag, les communications reprennent par l'une ou l'autre des Freebox, selon la route sélectionnée.
Maintenant, je voudrais utiliser alternativement et automatiquement, l'une ou l'autre route afin de mutualisé les débits (et accessoirement, aussi, la redondance ).
“Alternativement” mais trés rapidement: suffisament rapidement pour approcher le débit théorique maximum d'une agrégation réussie.
Pour cela il faut un serveur sur Internet, pas trop loin, par exemple une Dedibox
. (la distance “IP” entre une “Freebox” et une “Dedibox” correspond a 2 ou 3 sauts).
Cette Dedibox
sera la nouvelle sortie sur le Net, et donc, ma nouvelle IP publique aussi. (Accessoirement: Bye bye Hadopi)
Donc:
+--> OpenVPN --> Freebox A --> Internet --> OpenVPN --+ | | Mon PC --> bonding --+ +--> bonding --> Ma Dedibox | | +--> OpenVPN --> Freebox B --> Internet --> OpenVPN --+
Il faudra jouer avec les “route” et le “nat” aussi.
On va d'abord mettre en place 2 connexions VPN entre un PC (le mien) et une Dedibox (la mienne).
Donc 2 “openvpn” sur mon PC, et 2 “openvpn” sur ma Dedibox
.
Au final, chaque connexion “vpn” passera par une Freebox dédié.
Le but est simplement d’agréger des connexions ADSL, en conséquence, on ne va pas mettre en œuvre la notion de clefs d'authentification et de chiffrement “client/serveur” cher a OpenVPN:
On peut mettre un systeme plus lourd avec easy-rsa TLS/RSA et tout le coin-coin.Ce n'est pas le but de ce baratin. |
Donc, il y aura 2 “serveurs” OpenVPN fonctionnant de concert .
( J'ai aussi fait le test avec un seul serveur OpenVPN, et ça fonctionnait. Mais quelques warnings dans les logs m'y ont fait renoncer: “… MULTI: Learn: 192.168.0….. ” )
Pour le transport via le VPN, un petit réseau imaginaire va être mis en place:
10.4.4.64/26
Avec:
10.4.4.65 | ma Dedibox |
10.4.4.66 | mon PC |
D'abord créer le secret partagé, soit un mot de passe aléatoire de 256 caractères…
# cd /etc/openvpn # openvpn --genkey --secret bonding-secret.key
Ce qui créé un fichier ressemblant à ça:
# ls -la | grep secret -rw------- 1 root root 636 11 oct. 19:15 bonding-secret.key
Donc, lisible et modifiable uniquement par root
. Parfait.
J'ai pour habitude (surement la bonne) , de mettre les conf dans : /etc/openvpn/conf
Puis de faire un lien symbolique vers /etc/openvpn/
pour activer les confs.
Sur ma Dedibox
donc…
(Si pas déjà fait)
# aptitude update && aptitude install openvpn
Pour le support du bonding:
# aptitude update && aptitude install ifenslave
Modifier le fichier /etc/network/interfaces
afin d'avoir:
auto bond0 iface bond0 inet static address 10.4.4.65 netmask 255.255.255.192 bond-slaves none bond-mode 0 bond-miimon 300 bond-use-carrier 0 allow-hotplug tap0 iface tap0 inet manual bond-master bond0 allow-hotplug tap1 iface tap1 inet manual bond-master bond0
Monter l'interface “bond0” :
# ifup bond0
L'interface monte, mais elle ne fait rien pour l'instant puisqu'aucune interface “tap” n'y est associée.
bond-miimon 300 | 300 ms parce que j'ai un ping autour de 150 ms lorsque je suis a fond |
bond-use-carrier 0 | : je ne sais plus. |
Voila la configuration du 1er serveur OpenVPN , dans /etc/openvpn/conf/server-bonding-A.conf
:
# ---------------------------- #local <IP_QUI_ECOUTE> port 1195 proto udp dev tap0 dev-type tap mode p2p #auth none secret bonding-secret.key cipher none # The keepalive directive causes ping-like keepalive 10 120 txqueuelen 1000 nice 10 # Downgrade privileges after initialization (non-Windows only) user nobody group nogroup # Because we downgrade privileges: persist-tun persist-key comp-lzo status /etc/openvpn/server-bonding-A-status.log #verb 5 verb 3 mute 20 cd /etc/openvpn # --------- # EOF
Et l'autre fichier /etc/openvpn/conf/server-bonding-B.conf
qui contient les differences suivantes:
port 1196 ... dev tap1 ... status /etc/openvpn/server-bonding-B-status.log
Finir d'installer par:
# ln -s /etc/openvpn/conf/server-bonding-A.conf /etc/openvpn/. # ln -s /etc/openvpn/conf/server-bonding-B.conf /etc/openvpn/.
Et demarrer les VPNs.
# /etc/init.d/openvpn start server-bonding-A # /etc/init.d/openvpn start server-bonding-B
On peut aussi simplement tester en tapant:
# openvpn --config /etc/openvpn/server-bonding-A.conf
En coup d'oeil par là :
$ cat /proc/net/bonding/bond0 Ethernet Channel Bonding Driver: v3.5.0 (November 4, 2008) Bonding Mode: load balancing (round-robin) MII Status: up MII Polling Interval (ms): 300 Up Delay (ms): 0 Down Delay (ms): 0 Slave Interface: tap0 MII Status: up Link Failure Count: 0 Permanent HW addr: a6:8e:b7:34:cc:39 Slave Interface: tap1 MII Status: up Link Failure Count: 0 Permanent HW addr: 62:d9:79:b0:af:a4
( conf sur mon PC )
On copie la clé “bonding-secret.key
” de la Dedibox
sur le PC
, dans /etc/openvpn/
et en conservant les mêmes droits d'accès !
(Si pas déjà fait)
# aptitude update && aptitude install openvpn
Comme pour la “Dedibox”, mettre en place les outils nécessaire au “bonding”:
# aptitude update && aptitude install ifenslave
Modifier le fichier /etc/network/interfaces
afin d'avoir:
auto bond0 iface bond0 inet static address 10.4.4.66 netmask 255.255.255.192 bond-slaves none bond-mode 0 bond-miimon 300 bond-use-carrier 0 allow-hotplug tap0 iface tap0 inet manual bond-master bond0 allow-hotplug tap1 iface tap1 inet manual bond-master bond0
Monter l'interface “bond0” :
# ifup bond0
Voila le 1er fichier de conf dans /etc/openvpn/conf/client-bonding-A.conf
:
# ---------------------------- remote <IP_DE_LA_DEDIBOX> 1195 proto udp dev tap0 dev-type tap mode p2p #auth none secret bonding-secret.key cipher none # The keepalive directive causes ping-like keepalive 10 120 txqueuelen 1000 nice 10 nobind # Downgrade privileges after initialization (non-Windows only) user nobody group nogroup # Because we downgrade privileges: persist-tun persist-key comp-lzo status /etc/openvpn/client-bonding-A-status.log #verb 5 verb 3 mute 20 cd /etc/openvpn # --------- # EOF
Pour le 2ieme fichier de conf, /etc/openvpn/conf/client-bonding-B.conf
, les différences par rapport au premier sont:
remote <IP_DE_LA_DEDIBOX> 1196 ... dev tap1 ... status /etc/openvpn/client-bonding-B-status.log
Quoi? La même IP ? Oui: On effectuera un routage différent basé sur l'IP et le numéro de port de destination. |
Finir d'installer par:
# ln -s /etc/openvpn/conf/client-bonding-A.conf /etc/openvpn/. # ln -s /etc/openvpn/conf/client-bonding-B.conf /etc/openvpn/.
Et demarrer les VPNs.
# /etc/init.d/openvpn start client-bonding-A # /etc/init.d/openvpn start client-bonding-B
On doit pouvoir pinguer chaque bout du reseau.
Sur le client/PC:
# ping 10.4.4.65
Sur le serveur/Dedibox
# ping 10.4.4.66
Tous les ping doivent passer. Si ce n'est pas le cas, un “vpn” n'est pas connecté.
Sinon: vérifier le “firewall” possiblement en place.
Jeter un coup d'oeil dans /proc/net/bonding/bond0
Hummm…. Pour l'instant, on n'a pas vraiment agréger les Freebox puisque tout passe par la Freebox A (enfin, la gateway par défaut choisit).
La règle qui va être mise en place dira:
0x0fff0001
”
Dans le fichier /etc/iproute2/rt_tables
ajouter un nouveau nom de table, par exemple:
200 gw-freeboxB
Dans /etc/network/if-up.d
, créer un script nommé freebox-B-route
, et contenant:
#!/bin/bash #set -x WFACE="eth0" # --pour debug-- [ -n "$IFACE" ] || IFACE=$WFACE [ -n "$MODE" ] || MODE="$1" [ "$IFACE" = $WFACE ] || exit 0 IPROUTE=/sbin/ip [ -x $IPROUTE ] || exit 0 if [ -f /etc/ferm/mark-conf ]; then . /etc/ferm/mark-conf fi TABLENAME="gw-freeboxB" MARK="0x0fff0001" GATEWAY=192.168.0.254 case "$MODE" in start) $IPROUTE rule add fwmark $MARK table $TABLENAME $IPROUTE route add default via $GATEWAY dev $IFACE table $TABLENAME $IPROUTE route flush cache ;; stop) $IPROUTE route del default via $GATEWAY dev $IFACE table $TABLENAME $IPROUTE rule del fwmark $MARK table $TABLENAME $IPROUTE route flush cache ;; *) echo "$0 {start|stop}" exit 1 ;; esac exit 0
Rendre executable:
# chmod a+x freebox-B-route
Ne pas oublier aussi:
# ln -s /etc/networks/ifup-d/freebox-B-route /etc/networks/if-down.d/.
… en effet: le même script sera utilisé lorsque l'interface monte (up/start) ou descend (down/stop).
Puisque l'interface eth0
est déjà en service, le scripte doit être appelé manuellement pour cette fois:
# ./freebox-B-route start
Voila: la règle est chargé et prête a être utilisée.
J'utilise “ferm” pour rediger les règles iptables
, ce qui donne:
table mangle chain OUTPUT of eth0 daddr <IP_DE_LA_DEDIBOX> proto udp dport 1196 mod mark mark 0x00000000 MARK set-mark 0x0fff0001;
Ou avec la commande IpTables
:
# iptables -t mangle -A OUTPUT --out-interface eth0 --destination <IP_DE_LA_DEDIBOX> --protocol udp --dport 1196 --match mark --mark 0x00000000 --jump MARK --set-mark 0x0fff0001
Ce qui signifie dans les 2 cas:
Pour les paquets sortant de l'interface “eth0” , a destination de l'IP <IP_DE_LA_DEDIBOX> avec le protocole udp
a destination du port 1196
, et dont le marquage est actuellement “0” , alors marquer le paquet avec la valeur “0x0fff0001” .
Voila:
Pour l'instant, on a une configuration simple où mon PC a l'IP 10.4.4.66
et peut communiquer avec l'IP 10.4.4.65
.
Un test de débit:
$ scp 10.4.4.65:~/debian.iso . debian.iso 2% 14MB 864.2KB/s 12:31 ETA
YES! : 8 Mb/s , entre mon PC et ma Dedibox
De temps en temps, le débit retombe dans les limbes de 400 Mb/s !!! Mais je crois avoir compris que les paquets arrivent plus fréquemment dans le désordre ce qui perturbe la pile TCP/IP. |
Le but est simplement de créer 1 utilisateur
qui sera routé par defaut via l'interface “bond0”.
Donc, d'abord créé un simple utilisateur:
# adduser zorro
Et accésoirement:
# adduser zorro audio # adduser zorro video
Retour en tant qu'utilisateur simple , en l'occurence “thierry”.
Dans mon KDE, je créé un petit script là: ~/.kde/Autostart/xhost4zorro
, et contenant:
#!/bin/sh xhost +local:zorro exit 0
Rendre executable:
$ chmod a+x ~/.kde/Autostart/xhost4zorro
A moins de redemarrer “KDE”, executer le script maintenant:
$ ~/.kde/Autostart/xhost4zorro
Voila: l'utilisateur “zorro” pourra jouir de mon environnement fenêtrés sous KDE.
Créer une nouvelle règle “netfilter/iptables” de “routage” pour changer la gateway par défaut pour cette utilisateur.
En “ferm” :
table mangle chain OUTPUT mod owner uid-owner zorro { daddr ( 192.168.0.0/16 10.20.0.0/16 172.16.0.0/12 ) RETURN; daddr ( 212.27.40.240 212.27.40.241 ) RETURN; mod mark mark $MARK_UNDEF MARK set-mark 0x0fff0001; RETURN; }
En “iptables” :
# iptables -t mangle -A OUTPUT --match owner --uid-owner zorro --destination 192.168.0.0/16 --jump RETURN # iptables -t mangle -A OUTPUT --match owner --uid-owner zorro --destination 10.20.0.0/16 --jump RETURN # iptables -t mangle -A OUTPUT --match owner --uid-owner zorro --destination 172.16.0.0/12 --jump RETURN # iptables -t mangle -A OUTPUT --match owner --uid-owner zorro --destination 212.27.40.240 --jump RETURN # iptables -t mangle -A OUTPUT --match owner --uid-owner zorro --destination 212.27.40.241 --jump RETURN # iptables -t mangle -A OUTPUT --match owner --uid-owner zorro --match mark --mark 0x00000000 --jump MARK --set-mark 0x0fff0002 # iptables -t mangle -A OUTPUT --match owner --uid-owner zorro --jump RETURN
ces règles peuvent être largement optimisées |
En clair:
( le serveur )
D'abord, s'assurer que:
Il faut activer le “forward” entre interface, parce qu'on va avoir les interfaces “eth0” et “bond0” qui vont devoir s’échanger des paquets IP.
Si ce n'est pas déjà le cas, pour activer le “forward” , on peut créer un fichier dans /etc/sysctl.d/
, nommé local.conf
, et contenant:
# Les requetes ARP ne traversent pas net.ipv4.conf.all.arp_ignore=1 # Activer forward net.ipv4.ip_forward=1 # ---------------
Et puis appliquer immédiatement le forward:
# sysctl -p /etc/sysctl.d/local.conf
Ensuite, il faut sans doute activer des règles au niveau du firewall, par exemple avec ferm
:
chain FORWARD if bond0 of eth0 saddr 10.4.4.66 ACCEPT; chain FORWARD if eth0 of bond0 daddr 10.4.4.66 ACCEPT;
En pratique, il faudra être plus rigoureux en interdisant les subnet privés (genre 172.16.0.0/24 ) et en appliquant un tracking des connexions |
En sortie vers le WAN/Internet, il faudra “simplement” jouer avec “SNAT” ou “MASQUERADE” pour l'IP de mon PC: 10.4.4.66.
Exemple en ferm:
table nat chain POSTROUTING of eth0 saddr 10.4.4.66 SNAT to <IP_DE_LA_DEDIBOX> ;
ou
table nat chain POSTROUTING of eth0 saddr 10.4.4.66 MASQUERADE ;
# su - zorro $ firefox &
le ping ne semble pas routé , mais je crois que c'est intrinsèque au fonctionnement de “ping” … (à vérifier) |
Un petit de test de transfert entre mon PC et le reste du Monde… enfin, les serveurs ftp de proxad
$ curl -o /dev/null ftp://ftp.proxad.net/pub/Distributions_Linux/debian-cd/current/armel/iso-cd/debian-6.0.6-armel-CD-1.iso % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 3 639M 3 25.2M 0 0 1077k 0 0:10:07 0:00:23 0:09:44 1122k ...
Là, je suis clairement au dela des 8 Mb/s !
Le bonding c'est fantastique:
Mais, il subsiste quelques problèmes:
Youtube
est toujours aussi lent A faire:
J'imagine qu'on pourrait intégrer les interfaces “bond” dans les DSLAM.
Dans ces conditions, on n'a pas besoin d'OpenVPN dans la Freebox ou dans les DSLAMs !
Client <---->[Freebox principale] ------- ADSL ------- DSLAM-A <----> Reseau Free <---> Reste du Monde | | [Freebox secondaire 1] ----- ADSL ------- DSLAM-B | | [Freebox secondaire 2] ----- ADSL ------- DSLAM-B | | [ etc... ]------------------ ADSL ------- DSLAM-A
Cela suppose que:
Sinon, les DSLAM restent passif en font juste le transport jusqu'a un cloud de Dedibox ou de serveur Free.
Client <---->[Freebox principale] ------- Internet -------+---> Cloud VPN <---> Reste du Monde | | [Freebox secondaire 1] ----- Internet -------+ | | [Freebox secondaire 2] ----- Internet -------+ | | [ etc... ]------------------ Internet -------+
Cela suppose d'ajouter OpenVPN dans les Freebox: sans chiffrement , ça reste (peut être) possible.
Liens:
A l'origine, je souhaitais juste voir le live de Devin Townsend
dans de meilleures conditions ! Objectif atteint, grâce au “bonding”, a mon plus grand plaisir :