Journal Spécifier une interface réseau à un processus (2)

Posté par  (site web personnel) . Licence CC By‑SA.
17
5
août
2014

Il y a 2 ans et (bientôt) 6 mois j'ai posté une question sur le forum
Désolé pour les personnes m'ayant répondues mais je ne suis pas arrivé à quelque chose de concluant avec leurs solutions (je n'ai sûrement pas bien compris les explications)
Du coup je suis arrivé à une solution (que beaucoup qualifierons d'overkill) mais qui a le mérite de fonctionner et de ne pas être trop compliquée (pour moi en tout cas), je vais donc la décrire ici.

Rappel :

Le but avoué était de faire passer le trafic réseau de certains processus vers une interface particulière, dans un but inavouable de faire tourner transmission sur un tunnel VPN et de garder la navigation internet sur un canal non sécurisé pour avoir un meilleur débit.

L'idée générale :

Pour ce faire j'ai utilisé la virtualisation (j'espère ne pas trop me faire assassiner par les net-admins chevronnés).
Dans la VM (Machine Virtuelle) on crée la connexion VPN.
A l'extérieur de la VM on route le trafic.
Du coup tous les services réseau tournant dans la VM passeront par le VPN

Les détails :

- L'Hôte

Sur la machine hôte (une Debian Testing) il y a un bridge br0 défini dans le fichier /etc/network/interfaces tel que :

auto br0
 iface br0 inet static
 bridge_ports dummy0
 address 10.0.0.1
 netmask 255.255.255.0

On note la présence d'un port dummy qui ne sert qu'à une chose, que le pont ait au moins une interface. ce module s'active avec :
modprobe dummy numdummies=10 pour avoir 10 interface dummy.
Vous pouvez vérifier la présence des dummy avec la commande ifconfig -a ou mieux ip a
Pour que ces interfaces soient permanentes il faut créer un fichier nommé
/etc/modprobe.d/dummy.conf
et qui contiendra
options dummy numdummies=10

Ensuite on active le routage.
echo 1 > /proc/sys/net/ipv4/ip_forward
Pour que cette modification soit permanente.
if faut dé-commenter la ligne net.ipv4.ip_forward=1 du fichier /etc/sysctl.conf

Pour des raisons de facilité j'ai installé dnsmasq, en effet je trouve cela plus simple pour l'installation de la VM d'avoir un relais DNS, par contre je ne l'utilise pas pour le DHCP.
installation de dnsmasq
apt-get install dnsmasq
Le paramétrage se fait dans le fichier /etc/dnsmasq.conf il faut simplement mettre
interface=br0
no-dhcp-interface=br0
et relancer dnsmasq
/etc/init.d/dnsmasq restart ou systemctl restart dnsmasq.service si vous utilisez essayer d'adopter systemd.
Normalement une fois cela fait vous avez un fichier /var/run/dnsmasq/resolv.conf qui contient les dns extérieurs et un dig vous renvois un SERVER: 127.0.0.1#53(127.0.0.1)

Et enfin le routage (NAT) du trafic vers l'interface de sortie eth0.
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

- La Machine virtuelle

En ce qui concerne la distribution à virtualiser j'ai pris une Debian Stable installée sans interface graphique et avec un serveur SSH et serveur web.
Pour simplifier j'utilise virt-manager comme GUI et KVM comme solution, pensez à mettre le pont br0 en virtio sur l'interface réseau de la VM.
A l'installation on met l'IP 10.0.0.10 par exemple et 10.0.0.1 en DNS ainsi que 10.0.0.1/24 en passerelle.

Une fois l'installation finie, on installe OpenVPN (c'est ce qu'utilise mon fournisseur de VPN).
apt-get install openvpn
Et on le paramètre comme expliqué sur le site de votre fournisseur de VPN (souvent il faut télécharger des certificats et des fichiers de conf).

Optionnel : On fait un partage nfs de votre disque dur sur l'hôte vers la vm

On installe Transmission en mode démon
apt-get install transmission-daemon
On paramètre le fichier json
Optionnel : dans la section "download-dir": du fichier json mettre votre point de montage sur le disque de l'hôte.
puis on se connecte sur 10.0.0.10:9091/transmission/web/ et on peut commencer à partager des torrent via VPN et surfer sur l'hôte sans passer par l'autre bout du monde.
Bien entendu tout autre service que vous voudriez voir passer par le tunnel sécurisé devra être installé sur la VM.

  • # Conteneurs

    Posté par  . Évalué à 10.

    En restant dans le même genre de solution, plutôt que de virtualiser tu ferais mieux d'utiliser des conteneurs, c'est immensément plus léger~: tu n'as qu'un seul système d'exploitation.

    • [^] # Re: Conteneurs

      Posté par  (site web personnel) . Évalué à 1. Dernière modification le 05 août 2014 à 18:49.

      J'y avais aussi pensé, une solution à base de LXC mais je ne vois pas exactement comment faire étant donné que les /dev/ sont montés en bind dans le conteneur.

      kentoc'h mervel eget bezan saotred

      • [^] # Re: Conteneurs

        Posté par  . Évalué à 6.

        Pour une problématique similaire avec deux connexions internet dans mon cas et j'utilise ip rule et ip route notamment avec des vservers (c'est kif kif avec LXC).

        Tu crées une table de routage par connexion avec ip route puis tu définis des règles sur l'hôte pour emprunter une table de routage ou l'autre.

        Avec iptables et MARK tu peux aussi le faire par service.

        #!/bin/bash
        
        ip route flush table free
        ip route flush table numericable
        
        #Création des tables de routage
        ip route add table free 192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.200
        #Accès au subnet 192.168.1.0 pour le serveur DNS local (en 1.0)
        ip route add table numericable 192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.200
        ip route add table numericable 192.168.40.0/24 dev eth1 proto kernel scope link src 192.168.40.200
        
        #Ajout des règles
        ip rule add from 192.168.1.1   table free prio 90
        ip rule add from 192.168.1.200 table free prio 90
        ip rule add from 192.168.1.201 table free prio 90
        ip rule add from 192.168.1.202 table numericable prio 90
        ip rule add from 192.168.1.203 table free prio 90
        ip rule add from 192.168.1.204 table free prio 90
        ip rule add from 192.168.1.205 table free prio 90
        ip rule add from 192.168.1.206 table free prio 90
        ip rule add from 192.168.1.207 table free prio 90
        ip rule add from 192.168.1.208 table free prio 90
        ip rule add from 192.168.1.209 table numericable prio 90
        ip rule add from 192.168.1.210 table numericable prio 90
        ip rule add from 192.168.1.0/24 table numericable prio 100
        
        #Règles pour iptables MARK
        ip rule del fwmark 1
        ip rule add fwmark 1 table free prio 80
        
        ip rule del fwmark 2
        ip rule add fwmark 2 table numericable prio 80

        Ne pas oublier de faire un ip route flush cache sur la machine cliente pour être sûr que la règle s'applique lors de modifications.

        Mes 2 roubles.

        • [^] # Re: Conteneurs

          Posté par  . Évalué à 2.

          Une connerie s'est glissée dans ce script il aura fallu que je le poste ici pour la remarquer ! :)

          La ligne "ip rule add from 192.168.1.200 table free prio 90"
          est inutile vu qu'il s'agit de l'hôte et qu'il passe par la table main.

          Mais sinon le reste fonctionne très bien :D !

        • [^] # Re: Conteneurs

          Posté par  (site web personnel) . Évalué à 1.

          Je ne comprend pas.
          Comment tu fais ensuite pour lancer un programme sur telle ou telle connexion ?

          kentoc'h mervel eget bezan saotred

          • [^] # Re: Conteneurs

            Posté par  . Évalué à 4.

            En le mettant dans un vServer et en ajoutant une règle pour cet hôte (ip rule add from <ip-du-vserver> table <foo>).

      • [^] # Re: Conteneurs

        Posté par  . Évalué à 3.

        Chaque conteneur LXC est isolé du point de vue du réseau (ce n'est pas compliqué à tester).

        « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

        • [^] # Re: Conteneurs

          Posté par  (site web personnel) . Évalué à -3. Dernière modification le 05 août 2014 à 22:31.

          ce n'est pas compliqué à tester

          Pour qui ?
          Pour Linus Torvalds d'Helsinki ou pour Germaine Michu du Cantal ?
          Ce que je veux dire c'est que tout le monde n'a pas forcément les même connaissances et par conséquent les même facilités à résoudre un problème :-)

          Chaque conteneur LXC est isolé du point de vue du réseau

          Merci pour cette précision, je ferais le test un de ces quatre, de toute façon il fallait que je me plonge sérieusement dans LXC ça fera une bonne occasion.

          kentoc'h mervel eget bezan saotred

          • [^] # Re: Conteneurs

            Posté par  . Évalué à 3. Dernière modification le 05 août 2014 à 22:41.

            Pour qui ?

            Pour celui qui lance un conteneur sans configurer de réseau, il n'aura rien. Si tu veux du réseau, il faut faire des manipulations spécifique et tu n'auras pas la même IP que l'hôte.

            « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

          • [^] # Re: Conteneurs

            Posté par  . Évalué à 9.

            Ce que je veux dire c'est que tout le monde n'a pas forcément les même connaissances et par conséquent les même facilités à résoudre un problème :-)

            Mon message n'était pas à prendre comme une critique mais comme une invitation à le faire.

            « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

            • [^] # Re: Conteneurs

              Posté par  (site web personnel) . Évalué à 4.

              Mon message n'était pas à prendre comme une critique mais comme une invitation à le faire.

              Alors ton message a marché. Je vais m'y coller ASAP.
              Merci pour ta réponse.

              kentoc'h mervel eget bezan saotred

          • [^] # Re: Conteneurs

            Posté par  (site web personnel) . Évalué à 4.

            Bonsoir,

            je me glisse ici juste pour un petit post qui j espère ravira beaucoup de monde par sa simplicité.
            sur une machine ayant LXC >1.0 on a accès a des conteneur user donc encore plus intéressant à utiliser, mais je ne parlerais que de l install en root

            installation de LXC (suivant votre distrib je vous laisse choisir)

            lxc-create -t download -n debian—-a amd64 -d debian -r jessie

            et ensuite reste à la démarrer

            lxc-start -d -n debian

            puis à regarder les paramètres

            lxc-ls -f -> ca donne les ip

            et a s y connecter avec

            lxc-console -n debian

            ou

            lxc-attach -n debian

      • [^] # Commentaire supprimé

        Posté par  . Évalué à 6. Dernière modification le 06 août 2014 à 22:44.

        Ce commentaire a été supprimé par l’équipe de modération.

    • [^] # Re: Conteneurs

      Posté par  (site web personnel) . Évalué à 2.

      par exemple

      https://github.com/jpetazzo/dockvpn

      ウィズコロナ

  • # Amusant

    Posté par  (site web personnel) . Évalué à 8.

    J'ai fait exactement la même chose que toi hier : mettre en place un vpn pour un seul utilisateur au lieu de l'installer pour le système complet.

    Je me suis inspiré d'un script disponible ici : http://www.niftiestsoftware.com/2011/08/28/making-all-network-traffic-for-a-linux-user-use-a-specific-network-interface/, mais que je vais quand même détailler (histoire de mettre une valeur ajoutée au commentaire) :

    tu as la possibilité de créer des tables de routages spécifiques, à travers iproute2. Donc il faut créer une table de routage qui utilisera le vpn, mais qui n'est pas cette par défaut. Ensuite il faut marquer les paquets en provenances d'un utilisateur pour les assigner à cette table de routage.

    Une option à ne pas oublier dans la configuration d'openvpn est « route-nopull » qui évite de charger les route au démarrage de la connexion. Par contre, il faut aller chercher à la main dans ce cas la passerelle à utiliser avec la connexion réseau nouvellement créée. J'ai pas encore eu le temps d'automatiser ça, mais tu peux regarder les paramètres « up » et « down » dans openvpn qui permettent d'exécuter un script à l'initialisation ou à l'arrêt de la connexion.

    Bon voilà en gros une autre manière de faire, je profite de ton journal pour rebondir dessus, mais j'avais l'intention de détailler tout ça davantage sur mon blog une fois tout bien rodé…

    • [^] # Re: Amusant

      Posté par  (site web personnel) . Évalué à 2.

      un vpn pour un seul utilisateur au lieu de l'installer pour le système complet.

      Si j'ai bien compris le principe il suffit de lancer le (ou les) processus avec l'utilisateur en question pour que le trafic passe (ou non) par le VPN, c'est ça ?

      kentoc'h mervel eget bezan saotred

      • [^] # Re: Amusant

        Posté par  (site web personnel) . Évalué à 6.

        Tout à fait.

        C'est fait avec iptables et les règles « -m owner --uid-owner » qui sont chargées de rediriger le trafic uniquement sur le vpn.

  • # marquage de paquets

    Posté par  (site web personnel) . Évalué à 10.

    Dommage, je ne traînais pas sur le forum il y a 2 ans, sinon je t'aurais donné ça plus tôt…

    Comme l'explique chimrod, ce que tu souhaites peut se faire avec une table de routage spécifique et du marquage de paquets.

    1/ lance OpenVPN sous un utilisateur en particulier ;
    2/ Avec iptables, table "mangle", chaîne "PREROUTING", module "owner", option "--uid-owner", cible "MARK", tu peux dire que tous les paquets provenant de cet utilisateur sont marqués avec un identifiant particulier (cf man iptables-extensions) ;
    3/ Avec "ip route", tu crées des règles de routage spécifique qui seront utilisées pour ces paquets (cf man ip-route) ;
    4/ avec "ip rule", sélecteur "fwmark", tu dis au noyau d'utiliser la table de routage créée ci-dessus (cf man ip-rule).

    • [^] # Re: marquage de paquets

      Posté par  (site web personnel) . Évalué à 1.

      Merci pour cette réponse, cette solution me plais je vais l'essayer.

      kentoc'h mervel eget bezan saotred

    • [^] # Re: marquage de paquets

      Posté par  (site web personnel) . Évalué à 1.

      J'avais mis en place le même système sur mon serveur il y a quelques temps. Depuis malheureusement je n'utilise plus de VPN et j'ai réinstallé mon serveur. En revanche, je suis quasiment sûr que transmission permet de se lier à une interface spécifique (tun0 par exemple). J'avais quand même utilisé iptables comme indiqué ci-dessus mais seulement pour m'assurer que l'utilisateur de transmission ne pouvait pas passer par une autre interface (DROP).
      J'ai pas accès à grand chose au bureau, je regarde ce soir si j'ai pas quelques sauvegardes de la configuration.

  • # Overkill

    Posté par  . Évalué à 7.

    Pourquoi mettre tout dans un conteneur (qui revient à utiliser tout les namespaces disponibles sous Linux) alors que tu n'a besoin que du namespace réseau ?
    http://www.evolware.org/?p=293

    Sinon beaucoup plus simple (et un peu plus crade) y allez à coup de LD_PRELOAD pour binder toutes les ouvertures de socket sur l'IP de l'interface que tu souhaite utiliser. Y'a beaucoup d’implémentations de cette astuce, genre http://www.ryde.net/code/bind.c.txt

    • [^] # Re: Overkill

      Posté par  (site web personnel) . Évalué à 4.

      Que de solution pour un seul problème décidément les voies de l'informatique sont en chmod 000
      :-D

      kentoc'h mervel eget bezan saotred

    • [^] # Re: Overkill

      Posté par  . Évalué à 2.

      C'est à ça que je pensais (utiliser le namespace réseau) et j'ai un peu halluciné en voyant tout le monde répondre des bulldozers genre LXC.

      En fait j'avais juste utilisé le mauvais terme, c'est namespace pas conteneur. Merci.

      • [^] # Commentaire supprimé

        Posté par  . Évalué à 4.

        Ce commentaire a été supprimé par l’équipe de modération.

        • [^] # Re: Overkill

          Posté par  (site web personnel) . Évalué à 1.

          Oui et je t'en remercie mais à l'époque je n'avais pas les compétences requises pour comprendre et encore moins mettre en œuvre ce que tu m'avais expliqué.

          kentoc'h mervel eget bezan saotred

  • # transmission

    Posté par  . Évalué à 8.

    Spécifiquement pour "transmission", il existe un patch pour choisir la carte réseau:

    https://trac.transmissionbt.com/ticket/2313

  • # Module Owner d'iptables

    Posté par  . Évalué à 2.

    Et pourquoi pas utiliser le module Owner pour définir des règles iptables en fonction du processus ?

    http://www.netfilter.org/documentation/HOWTO//packet-filtering-HOWTO-7.html (chercher owner)

    Par exemple, tu lances transmission depuis un compte spécifique, et tu désactives les ports utilisés en entrée sur l'interface normale.

    • [^] # Re: Module Owner d'iptables

      Posté par  . Évalué à 3.

      Voire même utiliser Shorewall qui est tout de même bien plus accessible et qui gère également les notions d'utilisateur et groupe (tout est dans la manpage).

      Article Quarante-Deux : Toute personne dépassant un kilomètre de haut doit quitter le Tribunal. -- Le Roi de Cœur

  • # Internet of Threads

    Posté par  . Évalué à 1.

    Ca me rappelle la présentation de l'Internet of Threads du FOSDEM 2012 https://archive.fosdem.org/2012/schedule/event/internet_of_threads.html
    C'est aussi overkill mais intéressant. Chaque process à sa propre pile TCP/IP.

    • [^] # Re: Internet of Threads

      Posté par  . Évalué à 2.

      Chaque processus aurait son micro noyau ? ce serait le retour de la vengeance de Tanenbaum face à Linus ?

      Disclaimer : j'ai pas lu le lien.

  • # TC ?

    Posté par  . Évalué à 2. Dernière modification le 06 août 2014 à 21:06.

    Et en faisant du T(raffic)C(ontrol) ?

    À une époque j’avais écrit un petit script d’init qui assignait un débit à mon réseau en fonction des ports utilisés. J’avais ainsi une priorité et un débit pour chaque “canal”, dans le but plus avouable de prioriser le SSH, la télé &co, et moins avouable de rendre le P2P non gênant pour la connectivité.

    Ça marchait… ça ne marche plus. Je corrige. Ça marche. Ça remarche plus. J’ai finis par abandonner.

    En compilant la dernière version du noyau, j’ai même vu qu’on peut maintenant filtrer en fonction des cgroups.

    Alors, une piste à suivre ? Ceci dit le LARTC m’avait bien aidé, et c’est un lien à avoir dans sa besace pour tout ce qui est réseau sous Linux.

    • [^] # Re: TC ?

      Posté par  . Évalué à 2.

      …et moins avouable de rendre le P2P non gênant pour la connectivité.

      J'aimerais bien pouvoir faire ça aussi. Je suis obligé d'arrêter transmission pour regarder une video YT.

      J'ai vu qu'on pouvait piloter transmission en ligne de commande. Mon idée est de mettre régler les quotas de transmission quand une page YT est ouverte dans Firefox.

      • [^] # Re: TC ?

        Posté par  . Évalué à 3. Dernière modification le 09 août 2014 à 20:06.

        Voilà, en guise d’exemple un script. À mon niveau c’est plus du bricolage qu’autre chose.

        Quelques petits trucs à savoir :
        — renseigner les 4 variables correctement (ça c’était le obvious) ;
        — le périphérique IFB est un périphérique spécial qui permet de contrôler le flux entrant¹, pour la plupart des noyaux (récents) il y a un module éponyme à activer, testez si chez vous c’est le cas avec modprobe ifb pour l’activer et vérifier ainsi qu’il est bien présent et rmmod ifb pour le désactiver à nouveau ;
        DOWNLINK et UPLINK sont les débits entrant et sortant (en kB/s).

        ATTENTION ! il faut impérativement sous-estimer les capacités réelles de la ligne, sinon ça marche pas (pour de sombres histoires de files d’attentes). On perd donc un chouïa en performance, mais on gagne en confort. Par exemple ma connexion doit tourner autour de 120/850 (au doigt mouillé, dans ses mauvais jours) mais je me limite à 105/750.

        Vous pouvez, à tout hasard essayer le script (en root bien sûr 0:) ), sous décharge de toute responsabilité… C’est qu’en règle générale il n’y a pas de solution clef en main. Il faut simplement mettre start, stop ou restart en argument.

        #!/bin/sh
        
        DEV=eth0
        IFB=ifb0
        DOWNLINK=750
        UPLINK=105
        
        start() {
        #echo "Upload"
            tc qdisc add dev $DEV root handle 1:0 htb default 1
            # limiter la bande-passante
            tc class add dev $DEV parent 1:0 classid 1:1 htb \
                rate ${UPLINK}kbps
            tc qdisc add dev $DEV parent 1:1 handle 2:0 prio \
                bands 4 priomap 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
        #echo "  Default (lowest) priority"
            tc qdisc add dev $DEV parent 2:4 handle 14:0 prio
            tc qdisc add dev $DEV parent 14:1 sfq perturb 10
            tc qdisc add dev $DEV parent 14:2 sfq perturb 10
            tc qdisc add dev $DEV parent 14:3 sfq perturb 10
        #echo "  Highest priority"
            # pour différencier session interactive ou non
            tc qdisc add dev $DEV parent 2:1 handle 10:0 prio
            # répartir équitablement
            tc qdisc add dev $DEV parent 10:1 handle 11:0 sfq \
                perturb 10
            tc qdisc add dev $DEV parent 10:2 handle 12:0 sfq \
                perturb 10
            tc qdisc add dev $DEV parent 10:3 handle 13:0 sfq \
                perturb 10
        #echo "    SSH (server)"
            tc filter add dev $DEV parent 2:0 protocol ip prio 1 \
                u32 match ip sport 22 0xffff flowid 2:1
            tc filter add dev $DEV parent 2:0 protocol ipv6 prio 2 \
                u32 match ip6 sport 22 0xffff flowid 2:1
        #echo "  High priority"
            tc qdisc add dev $DEV parent 2:2 handle 20:0 sfq \
                perturb 10
        #echo "    *box (192.168.0.254)"
            tc filter add dev $DEV parent 2:0 protocol ip prio 3 \
                u32 match ip dst 192.168.0.254 flowid 2:2
        #echo "  Normal priority"
            tc qdisc add dev $DEV parent 2:3 handle 30:0 sfq \
                perturb 10
        #     "    ICMP"
            tc filter add dev $DEV parent 2:0 protocol ip prio 5 \
                u32 match ip dport 1 0xffff flowid 2:3
            tc filter add dev $DEV parent 2:0 protocol ipv6 prio 6 \
                u32 match ip6 dport 1 0xffff flowid 2:3
        #echo "    HTTP (client)"
            tc filter add dev $DEV parent 2:0 protocol ip prio 5 \
                u32 match ip dport 80 0xffff flowid 2:3
            tc filter add dev $DEV parent 2:0 protocol ipv6 prio 6 \
                u32 match ip6 dport 80 0xffff flowid 2:3
        #echo "    DNS (client)"
            tc filter add dev $DEV parent 2:0 protocol ip prio 7 \
              u32 match ip protocol 17 0xff flowid 2:3
        #echo "    HTTPS (client)"
            tc filter add dev $DEV parent 2:0 protocol ip prio 8 \
                u32 match ip dport 443 0xffff flowid 2:3
            tc filter add dev $DEV parent 2:0 protocol ipv6 prio 9 \
                u32 match ip6 dport 443 0xffff flowid 2:3
            modprobe ifb
        #echo "Up the virtual device"
            ip link set dev $IFB up
            tc qdisc add dev $DEV handle ffff: ingress
        #echo "Download"
            tc filter add dev $DEV parent ffff: protocol ipv6 \
                u32 match u32 0 0 action mirred egress redirect dev $IFB
            tc filter add dev $DEV parent ffff: protocol ip \
                u32 match u32 0 0 action mirred egress redirect dev $IFB
            tc qdisc add dev $IFB root handle 1:0 htb default 1
            tc class add dev $IFB parent 1:0 classid 1:1 htb \
                rate ${DOWNLINK}kbps
            tc qdisc add dev $IFB parent 1:1 handle 2:0 prio \
                bands 4 priomap 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
        #echo "  Default (lowest) priority"
            tc qdisc add dev $IFB parent 2:4 handle 14:0 prio
            tc qdisc add dev $IFB parent 14:1 sfq perturb 10
            tc qdisc add dev $IFB parent 14:2 sfq perturb 10
            tc qdisc add dev $IFB parent 14:3 sfq perturb 10
        #echo "  Highest priority"
            # différencier session intéractive (automatique)
            tc qdisc add dev $IFB parent 2:1 handle 10:0 prio
            # répartir équitablement
            tc qdisc add dev $IFB parent 10:1 handle 11:0 sfq \
                perturb 10
            tc qdisc add dev $IFB parent 10:2 handle 12:0 sfq \
                perturb 10
            tc qdisc add dev $IFB parent 10:3 handle 13:0 sfq \
                perturb 10
        #echo "    SSH (server)"
            tc filter add dev $IFB parent 2:0 protocol ip prio 1 \
                u32 match ip dport 22 0xffff flowid 2:1
            tc filter add dev $IFB parent 2:0 protocol ipv6 prio 2 \
                u32 match ip6 dport 22 0xffff flowid 2:1
        #echo "  High priority"
            tc qdisc add dev $IFB parent 2:2 handle 20:0 sfq \
                perturb 10
        #echo "    *box (192.168.0.254)"
            tc filter add dev $IFB parent 2:0 protocol ip prio 3 \
                u32 match ip src 192.168.0.254 flowid 2:2
        #echo "  Normal priority"
            tc qdisc add dev $IFB parent 2:3 handle 30:0 sfq \
                perturb 10
        #echo "    ICMP"
            tc filter add dev $IFB parent 2:0 protocol ip prio 5 \
                u32 match ip sport 1 0xffff flowid 2:3
            tc filter add dev $IFB parent 2:0 protocol ipv6 prio 6 \
                u32 match ip6 sport 1 0xffff flowid 2:3
        #echo "    HTTP (client)"
            tc filter add dev $IFB parent 2:0 protocol ip prio 5 \
                u32 match ip sport 80 0xffff flowid 2:3
            tc filter add dev $IFB parent 2:0 protocol ipv6 prio 6 \
                u32 match ip6 sport 80 0xffff flowid 2:3
        #echo "    DNS (client)"
            tc filter add dev $IFB parent 2:0 protocol ip prio 7 \
              u32 match ip protocol 17 0xff flowid 2:3
        #echo "    HTTPS (client)"
            tc filter add dev $IFB parent 2:0 protocol ip prio 8 \
                u32 match ip sport 443 0xffff flowid 2:3
            tc filter add dev $IFB parent 2:0 protocol ipv6 prio 9 \
                u32 match ip6 sport 443 0xffff flowid 2:3
        }
        
        stop() {
          tc qdisc del dev $DEV root
          tc qdisc del dev $DEV ingress
          tc qdisc del dev $IFB root
          ip link set dev $IFB down
          rmmod ifb
        }
        
        restart() {
          stop
          start
        }
        
        [[ "$1" == "start" ]] && start
        [[ "$1" == "stop" ]] && stop
        [[ "$1" == "restart" ]] && restart

        Que fait le script ? Que ce soit le flux entrant ou sortant, la politique est la même. Je crée quatre files d’attente (bands 4 priomap), sachant qu’une file est vidée (et donc ses paquets envoyés sur le réseau) si et seulement si les files de priorités plus élevées sont déjà vides. Ensuite y’a quelques menus ajustements que je ne discuterai pas. Le plus important est la directive filter qui permet d’envoyer les paquets en fonction du port (source ou destination sport ou dport, etc.), sur la bonne file d’attente : flowid 2:n, avec n variant de 1 à 4 son numéro par priorité décroissante. Le serveur (local) SSH a la priorité maximale et monopolise la file 1. Ensuite vient la box (c’était pour la télé je crois), puis en priorité “normale” j’y ai foutu l’ICMP, le HTTP(S) et le DNS (lorsque le poste est client), en bref : la navigation. Il peut être utile d’y mettre tout service que vous considérez utiles (le POP/IMAP/SMTP aurait du s’y retrouver, ainsi que la messagerie instantannée, etc.). Tout le reste, donc le P2P, est envoyé par défaut sur la file d’attente de plus basse priorité (pour l’anecdote, j’ai mis un moment pour comprendre qu’il fallait promouvoir l’ICMP ).

        Voilà. Ça a l’air de fonctionner (je l’ai réactivé du coup chez moi, avec un noyau 3.14, mais je n’ai pas refait les tests poussé de l’époque) dans la grande majorité des cas, mais avec certains sites (bon à vrai dire un seul rencontré et j’ose pas aggraver mon cas alors je ne dirai pas lequel), ça torche pendant quelques secondes, puis ça me coupe la connexion, pour je ne sais quelle raison. Il me suffit de couper le script et relancer le téléchargement.

        Pour le lartc, j’ai oublié de préciser que ce sont les chapitres 9 et suivants qui sont utiles pour comprendre tout le bouzin. Y’a aussi dans le cookbook un exemple un peu similaire au mien, mais moins complet \o/.

        ¹ Ceux qui ont la chance de posséder un routeur peuvent s’en passer : il leur suffit de contrôler le débit sortant de chacune des deux interfaces.

        • [^] # Re: TC ?

          Posté par  . Évalué à -2.

          C'est sophistiqué.

          Ca mériterait d'être programmé dans un autre langage.

          Y as tu pensé ?

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.