Limitation de bande passante avec IP Masquerade - Howto


Contents
  Introduction
  Programmes nécessaires
  Configurer la limitation de bande passante
  Marquer les packets pour la limitation
  Monitorer la bande passante
  Conclusion

Premiere version - 11 mai 2004.

Introduction

Cet article de Joe Roback est une traduction à partir de l'anglais disponible ici :
http://roback.cc/howto/bandwidth.html : Bandwidth Limiting with IP Masquerade.
Cette traduction a été réalisée par Sylvestre Ledru. Merci à Matthieu Walter (Gamo) pour la relecture.

Ce document est prévu pour les utilisateurs de IP Masquerade (NAT) qui veulent limiter la bande passante d'une machine.
L'exemple utilisé dans ce document est une connexion ADSL (640Kbits en download / 640Kbits en upload) où les machines du sous-réseau sont limitées en bandes passantes.
J'ai pris mes idées et des exemples de cbq-init mais j'ai aussi voulu une version simplifiée.

Les spécifités du routeur utilisé dans la documentation originale sont :

Distribution:
Gentoo Linux 1.4 gcc 3.2.3, Linux 2.6.1 (SMP), iptables 1.2.9 et tout mis à jour dans l'arbre de portage de Gentoo.
Matériel:
CPU: 1000Mhz Pentium III x 2
RAM: 1024MB
DISK: 13GB ATA66, 4x80GB ATA133, 2x120GB ATA133 = 528GB Volume utilisant EVMS de IBM.

Services:
DHCP Serveur
IP Masquerade (avec port fowarding)

Programmes nécessaires

Les specifications ici concernent uniquement les limitations de bandes passantes et non pas le masquerading ou le serveur DHCP.

Options du Kernel:

Tout le support de base d'Iptables est obligatoire pour l'IP Masquerade plus
  CONFIG_IP_NF_CONNTRACK
  CONFIG_IP_NF_TARGET_MARK --> Ceci est pour le marquage des packets qui vont être bridé.

QoS et fair queueing
  CONFIG_NET_SCH_CBQ
  CONFIG_NET_CLS_FW

Maintenant, je compile en général toutes les options de iptables et de QOS et/ou de fair queueing comme modules, bien que lsmod ne montre que les options au dessus comme modules utilisés.

Programmes :

iptables --> http://www.iptables.org
iproute2   --> ftp://ftp.inr.ac.ru/ip-routing  --> La plupart des distributions l'intégrent par defaut (sous debian, apt-get install iproute)
 
Configurer la bande passante

Je déclare ma bande passante dans un script shell dans le but de l'avoir déclaré automatiquement au démarrage et pour faciliter le démarrage et l'arrêt.
#!/bin/bash
#
#  Tous les débits sont en Kbits, donc pour récuperer des kilo-octets(Ko), divisez ce chiffre par 8
#  ex: 25Kbps == 3.125KB/s
#
TC=/sbin/tc
DNLD=150Kbit              # Limite de download
DWEIGHT=15Kbit         # coefficient de DOWNLOAD (Weight Factor) ~ 1/10 of DOWNLOAD Limit
UPLD=25KBit                # Limite d'upload Limit
UWEIGHT=2Kbit           # Coefficient d'UPLOAD (Weight Factor)
 
tc_start() {

    $TC qdisc add dev eth0 root handle 11: cbq bandwidth 100Mbit avpkt 1000 mpu 64
    $TC class add dev eth0 parent 11:0 classid 11:1 cbq rate $DNLD weight $DWEIGHT allot 1514 prio 1 avpkt 1000 bounded
    $TC filter add dev eth0 parent 11:0 protocol ip handle 4 fw flowid 11:1

    $TC qdisc add dev eth1 root handle 10: cbq bandwidth 10Mbit avpkt 1000 mpu 64
    $TC class add dev eth1 parent 10:0 classid 10:1 cbq rate $UPLD weight $UWEIGHT allot 1514 prio 1 avpkt 1000 bounded
    $TC filter add dev eth1 parent 10:0 protocol ip handle 3 fw flowid 10:1

}

tc_stop() {

    $TC qdisc del dev eth0 root
    $TC qdisc del dev eth1 root

}

tc_restart() {

    tc_stop
    sleep 1
    tc_start

}

tc_show() {

    echo ""
    echo "eth0:"
    $TC qdisc show dev eth0
    $TC class show dev eth0
    $TC filter show dev eth0
    echo ""

    echo "eth1:"
    $TC qdisc show dev eth1
    $TC class show dev eth1
    $TC filter show dev eth1
    echo ""

}

case "$1" in

  start)

    echo -n "Starting bandwidth shaping: "
    tc_start
    echo "done"
    ;;

  stop)

    echo -n "Stopping bandwidth shaping: "
    tc_stop
    echo "done"
    ;;

  restart)

    echo -n "Restarting bandwidth shaping: "
    tc_restart
    echo "done"
    ;;

  show)
   
    tc_show
    ;;

  *)

    echo "Usage: /etc/init.d/tc.sh {start|stop|restart|show}"
    ;;

esac

exit 0

Maintenant commençons l'explication.
Au debut, il y a quelques variables qui rendent le script plus facile à changer.
CE SCRIPT N'EST FAIT QUE POUR UNE SEULE REGLE.
Cependant, vous pouvez ajouter autant de règles que vous voulez. (Je n'administre pas un fournisseur d'acces internet, j'ai seulement besoin de limiter quelques machines).

Ce script suppose deux choses :
eth0 ==> est la carte connectée sur le reseau local. exemple: 192.168.0.0/24
eth1 ==> est la carte connectée à Internet. Exemple : Notre FAI(ISP)

Stop, Restart, et Show parlent d'eux même. Je ne les expliquerais donc pas.

Start:
$TC qdisc add dev eth0 root handle 11: cbq bandwidth 100Mbit avpkt 1000 mpu 64
$TC class add dev eth0 parent 11:0 classid 11:1 cbq rate $DNLD weight $DWEIGHT allot 1514 prio 1 avpkt 1000 bounded
$TC filter add dev eth0 parent 11:0 protocol ip handle 4 fw flowid 11:1

$TC qdisc add dev eth1 root handle 10: cbq bandwidth 10Mbit avpkt 1000 mpu 64
$TC class add dev eth1 parent 10:0 classid 10:1 cbq rate $UPLD weight $UWEIGHT allot 1514 prio 1 avpkt 1000 bounded
$TC filter add dev eth1 parent 10:0 protocol ip handle 3 fw flowid 10:1

Les trois premières lignes sont pour la limitation de la bande passante allouée au téléchargement.

La première ligne crée et "PARENT"(?) qdisc:
  --> $TC qdisc add dev eth0 root handle 11: cbq bandwidth 100Mbit avpkt 1000 mpu 64
man tc pour plus d'informations mais, fondamentalement, c'est la déclaration du péripherique. Par exemple, une carte 100Mbit Netgear.
Ensuite, la ligne suivante crée le fils qdisc avec la limitation de download réel.
  --> $TC class add dev eth0 parent 11:0 classid 11:1 cbq rate $DNLD weight $DWEIGHT allot 1514 prio 1 avpkt 1000 bounded
man tc et ses amis encore si vous avez besoin de plus d'explications que cela (ce qui sera sans doute le cas si vous voulez pousser plus loin). Personnellement, je ne sais pas ce que signifient toutes les options.
J'ai surtout utilisé les defauts des man pages.
La dernière ligne et TRES importante ligne qui déclare le handle sur le fils qdisc.
Ceci declare le handle a 4.  Ensuite, nous utiliserons iptables pour MARK marquer les packets de telechargement, ainsi, le fils qdics saura quels packets limiter.

Les trois lignes finales sont pour la gestion de l'upload.
C'est sensiblement la même chose que pour le download en dehors de l'interface qui a changé (eth0 pour eth1) ainsi que la variable pour le début et le handle.

Marquer les paquets pour la limitation

Maintenant, vous êtes pret pour marquer les packets comme ils viennent dans le but de les limiter.
J'ai seulement ajouter les deux lignes suivantes dans mon fichier de firewall.

# Marque les packets
# Marquage des packets en upload
$IPTABLES -t mangle -A FORWARD -s 192.168.0.128/29 -j MARK --set-mark 3
$IPTABLES -t mangle -A FORWARD -s 192.168.0.6 -j MARK --set-mark 3

# Marquage des packets en download
$IPTABLES -t mangle -A FORWARD -s ! 192.168.0.0/24 -d 192.168.0.128/29 -j MARK --set-mark 4
$IPTABLES -t mangle -A FORWARD -s ! 192.168.0.0/24 -d 192.168.0.6 -j MARK --set-mark 4

** Une correction a été faite par Glen Hinkle sur le marquage du telechargement. J'utilisais la chaine POSTROUTING mais il m'a prévenu qu'il fallait vraiment utiliser la meme chaine que pour l'upload (FORWARD). Thanks Glen!

Ainsi, je marque les hosts suivants :
192.168.0.6
192.168.0.128/29 =>
        192.168.0.128
        192.168.0.129
        192.168.0.130
        192.168.0.131
        192.168.0.132
        192.168.0.133
        192.168.0.134
        192.168.0.135

J'espère que personne n'a besoin d'aide avec les masques de sous-reseau. :)
Les téléchargements sont marqués 4 et les uploads marqués 3.

Monitoring de la bande passante

Les outils suivants sont recommandés pour suivre la bande passante :
bwm (http://bwm-tools.lbsd.net/ ==> très simple, basé sur ncrurses, pour un suivi rapide et facile du reseau.
iptraf (http://cebu.mozcom.com/riker/iptraf/) ==> très robuste, basé lui aussi ncurses, mon preféré, sans de patch kernel, ce programme permet de suivre un host spécifique (à partir de son ip ou de l'adresse MAC)
connmon (http://www.student.lu.se/~nbi98oli/connmon.html) ==> interfaces ncurses et gtk. Avec un patch du kernel, il est possible de suivre la bande passante d'une ip.
iftop (http://www.ex-parrot.com/~pdw/iftop/) interface ncurses. permet de suivre le trafic en temps réel sur un reseau.
Conclusion

Ca m'a pris pas mal de temps pour tout comprendre.
J'ai énormement appris du script cbq-init de freshmeat. Merci
Envoyez-moi un email si vous avez des questions, corrections, plaintes ...




Ecris par joe@roback.cc
Traduction par Sylvestre Ledru