LinuxÉdu

Comment faire du routage par process ?

Sous un titre un peu sibyllin se cache une idée relativement simple. Vous avez une ou plusieurs interfaces réseaux (physiques ou virtuelles) et M2050-654 souhaitez que certaines applications utilisent l’une ou l’autre.

Par exemple, vous souhaitez surfer sur Internet via votre box mais relever votre courrier via la connexion de votre téléphone portable. Autre exemple, vous êtes dans un hotspot wifi (pas vraiment sécurisé) et souhaitez lire vos mails via la connexion (plus sécurisée) de votre téléphone mais continuer à surfer via la connexion du hotspot. Certains établissements scolaires ont parfois plusieurs accès à Internet, on pourra trouver là (ou pas) un intérêt à faire un routage à la source.

Dans l’exemple ici, le but est de surfer sur Internet via la connexion de la box et utiliser un autre logiciel via la connexion wifi fournie par tetaneutral.net

La configuration est la suivante : [Internet] — [Box] — [LAN] — [machine] — [VLAN]– [Internet]

Bref, c’est un objectif qui peut sembler inintéressant… mais ce qui l’est moins est que les maigres connaissances utilisées ici peuvent potentiellement Canon 24-105mm Lens Coffee Mug permettre de :

  • autoriser (ou non) un accès Internet à certains utilisateurs
  • faire de la limitation de débit
  • faire de la répartition de charge sur plusieurs accès réseau

Pour en revenir au problème initial, il  y aurait plusieurs solutions :

  1. routage basé sur le M2060-237 propriétaire du processus : on créée un nouvel utilisateur que ne pourra sortir sur Internet que via la deuxième interface.
  2. lier une application à une IP spécifique (bind)
  3. Ifrt
  4. Namespace réseau
  5. cgroup

Canon 100mm Lens Coffee Mug On créée une nouvelle interface réseau virtuelle à partir de eth0, on l’allume puis on y affecte une IP cohérente :

ip link add link eth0 name eth0.3196 type vlan id 3196
ip link set eth0.3196 up
ip addr add 91.224.149.172/24 dev eth0.3196

Marquage de paquet et routage par utilisateur

Le principe, en bref, est le suivant

  1. création du paquet par un processus local
  2. marquage du paquet ou non
  3. choix de la table de routage à utiliser : cela détermine quelle passerelle utiliser
  4. translation NAT
  5. émission du paquet

On crée un utilisateur toto :

adduser toto

L’idée est de « tatouer » les paquets émis par cet utilisateur afin qu’ils soient routés vers Internet comme on le souhaite. Pour cela on modifie la table MANGLE qui permet de transformer les paquets. On rajoute une chaîne OUTPUT pour transformer les paquets générés localement avant qu’ils ne sollicitent une décision de routage. On les marque donc en fonction de l’utilisateur qui les émet. Ici MARK permet d’associer une valeur de marquage particulière. Elle sera ensuite identifiée pour appliquer un routage différent en fonction de l’existence ou l’absence de telle ou telle marque. On peut ainsi réaliser de la restriction de bande passante, de la gestion de priorité ou… du routage par utilisateur.

iptables -t mangle -A OUTPUT -m owner --uid-owner toto -j MARK --set-mark 2

On active le routage en donnant le lien entre le marquage des paquets et la nouvelle table de routage (ici avec le même numéro pour simplifier)

ip rule add fwmark 2 table 2

Définition de la route par défaut pour les paquets relevant de la table 2 :

ip route add default via 91.224.149.254 dev eth0.3196 table 2

On indique que toutes les IP en 91.224.149.XXX sont sur eth0.3196 et que la passerelle sera accessible via cette interface (requête arp)

ip route add 91.224.149.0/24 dev eth0.3196 table 2

On souhaite que ces paquets marqués transitent par notre interface eth0.3196. Pour cela, on effectue du NAT de source. Il est spécifié en utilisant les options « -j SNAT », et « –to-source » qui précise une adresse IP source (pour les protocoles UDP et TCP seulement, voir plus bas pourquoi) :

iptables -t nat -A POSTROUTING -o eth0.3196 -j SNAT --to-source 91.224.149.172

Tout cela ne fonctionne pas. Pourquoi ? Il faut autoriser le routage pour des IP qui ne sont manifestement pas dans le réseau local (qui est en 192.168.XXX.YYY). On rajoute alors un 0 dans le fichier relatif au « reverse path filtering » qui permet à la station de fonctionner comme un routeur :

echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter

On peut enfin lancer l’application de son choix avec notre user :

sudo -u toto mon_appli_qui_sort_par_ailleurs

Diagnostics

Attention ping et mtr ne sont pas en UDP mais en ICMP, donc les modifications faites via iptables ne s’appliquent pas à eux et il va être difficile de s’en servir pour diagnostiquer quoi que ce soit… Dans le meilleur des cas, cela créée des faux positifs.

Afficher la table 2 :

ip route show table 2

Afficher les règles NAT :

iptables -t nat -L

qui devrait renvoyer quelque chose comme :

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
SNAT       all  —  anywhere             anywhere             to:91.224.149.172

Quelle est mon IP en ligne de commande ? (nécessite le paquet links, un navigateur en mode texte) :

links -dump http://www.monip.fr/ | grep "Your IP address is"

Quel est le nom de mon FAI utilisé pour sortir sur Internet :

links -dump http://www.monip.fr/ | grep "ISP of your IP »

pour nettoyer

iptables -t nat -F

Vérifier que c’est vide :

iptables -t nat -nvL

qui, si elle n’est pas vide, renvoie (voir le compteur iptables au passage) :

Chain POSTROUTING (policy ACCEPT 2093 packets, 134K bytes)
pkts bytes target     prot opt in     out     source               destination
100  5972 SNAT       all  —  *      eth0.3196  0.0.0.0/0            0.0.0.0/0            to:91.224.149.172

Sources

man iptables (si si)

Liste de diffusion technique de tetaneutral : http://lists.tetaneutral.net/listinfo/technique

Le canal IRC de tetaneutral : irc.freenode.net sur le canal #tetaneutral.net

http://blog.sebastien.raveau.name/2009/04/per-process-routing.html

http://lartc.org/howto/lartc.rpdb.multiple-links.html

http://www.inetdoc.net/guides/iptables-tutorial/traversingoftables.html

rp_filter : net.ipv4.conf.default.rp_filter = 0 : http://www.tolaris.com/2009/07/13/disabling-reverse-path-filtering-in-complex-networks/

Bind

Piste : force_bind allows you to force binding on a specific IP and/or port. It works with both IPv4 and IPv6. It is useful if you have a binary application without sources and without the ability to configure an address or port to bind to.

FORCE_BIND_ADDRESS_V4=IP_DU_VPN LD_PRELOAD=/usr/lib/force_bind.so weechat

http://daniel-lange.com/archives/53-Binding-applications-to-a-specific-IP.html

Namespace réseau

https://linuxfr.org/nodes/89429/comments/1320077

ifrt

Pour gérer plusieurs routes par défaut sur un GNU/Linux, et plus particulièrement sur
debian, on peut tester :
http://stor.balios.net/ifrt/

Comments are closed.