• # Script avancé avec gestion des traffics entrant et sortant

    Posté par . En réponse à la dépêche Introduction à la qualité de service sous Linux. Évalué à 10.

    hello!
    Si vous avez lu comme moi ( avec plaisir :)
    ces documents qui arrivent peu à peu, vous
    êtes peut être maintenant à la recherche d'un script puissant.
    m'y étant penché depuis quelques mois pendant
    lesquels les solutions disponibles ont bien avancées, j'ai mis au point ce script dont je vous fait profiter:)
    le voilà, brut: ( nom du fichier : qos )
    [ j'utilise cette version depuis 3 jours ]

    dites bye bye au surf lent et aux pings désastreux ;)

    #!/bin/bash

    # curio QoS script 0.3
    # par François Simond
    # script pour htb et imq iproute2 et bien sur iptables
    # iptables : www.netfilter.org
    # htb : luxik.cdi.cz/~devik/qos/htb/
    # imq : luxik.cdi.cz/~patrick/imq/
    # iproute2 : defiant.coinet.com/iproute2/
    # pour d'autres détails consultrez le howto: lartc.org
    # ce script vous donnera de très hautes performances
    # réseau à la maison ou au travail. il est prévu pour
    # utiliser la connection internet dans tous les sens
    # sans que les applications importantes ne soient ralenties
    # 09.04.2002: pre release pour tests
    # 01.05.2002: tests et ajustements..
    # 03.05.2002: fonctionne efficacement, à voir dans la durée
    # dimanche 5 mai: posté chez linuxfr.org
    # sous licence GPL

    # usage ./qos
    # usage ./qos stop
    # usage ./qos clear

    # ici, le script est finement ajusté pour 512kbit de download
    # et 128kbit d'upload en ADSL pppoe
    # merci d'avance pour le retour sur curio@free.fr
    # les versions futures de ce script seront dispos a:
    # http://www.hq-studio.net/linux/qos/current-qos(...)
    # .. quand je suis pas en train de tester des trucs
    # dangereux sur le serveur :)

    # vous pouvez surveiller ce qui se passe en tapant:
    # # tc -s class show dev interface_qui_vous_interesse
    # # tc -s qdisc show dev interface_qui_vous_interesse

    IPTABLES="/usr/local/sbin/iptables"
    TC="/sbin/tc"
    LOGGER="/usr/bin/logger"
    IP="/sbin/ip"
    MODPROBE="/sbin/modprobe"

    # définition des UID des users sous lesquels tournent edonkey
    # audiogalaxy (ne jamais les lancer en root !)
    UIDDONKEY=525
    UIDAG=523

    # si vous n'avez pas installé imq ( parcque beta ),
    # mettez cette variable à 1
    NOINGRESS="0"

    IFINPUT="ppp0"
    IFINGRESS="imq0"
    IFOUTPUT="ppp0"

    SUBNET="192.168.0.0/24"
    SUBNET2="192.168.0.0/16"

    case "1ドル" in
    'stop')
    echo Stopping QoS on $IFINGRESS and $IFOUTPUT...
    $TC qdisc del dev $IFINGRESS root
    $IP link set $IFINGRESS down
    $TC qdisc del dev $IFOUTPUT root
    $LOGGER "QoS disabled"
    ;;

    'clear')
    echo Stopping QoS on $IFINPUT and $IFOUTPUT...
    $TC qdisc del dev $IFOUTPUT root
    $IPTABLES -F
    $IP link set $IFINGRESS down
    $IPTABLES -t mangle -F
    $TC qdisc del dev $IFINGRESS root
    echo Done !
    $LOGGER "QoS disabled & iptable rules cleared"
    ;;
    *)

    # iptables clean
    $IPTABLES -t nat -F
    $IPTABLES -F
    $IPTABLES -t mangle -F

    if [ "$NOINGRESS" == "0" ]; then

    # mise en place de l'interface imq
    $MODPROBE imq numdevs=1
    $IPTABLES -t mangle -A PREROUTING -i $IFINPUT -j IMQ
    fi

    # masquerading
    echo 1 > /proc/sys/net/ipv4/ip_forward

    $IPTABLES -t nat -A POSTROUTING -s $SUBNET ! -d $SUBNET2 -o $IFOUTPUT -j MASQUERADE
    $IPTABLES -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

    # mettez vos rêgles de firewall ici ( l'exemple est assez gentil mais efficace )

    # anti spoof
    $IPTABLES -A INPUT -i $IFINPUT -p udp -s $SUBNET -j DROP
    $IPTABLES -A INPUT -i $IFINPUT -p tcp -s $SUBNET -j DROP
    $IPTABLES -A INPUT -i $IFINPUT -p tcp -s 127.0.0.1 -j DROP

    # tcp restrictions
    $IPTABLES -A INPUT -i $IFINPUT -p tcp --dport 23 -j DROP # telnet drop
    $IPTABLES -A INPUT -i $IFINPUT -p tcp --dport 79 -j DROP # finger drop
    $IPTABLES -A INPUT -i $IFINPUT -p tcp --dport 135 -j DROP # smb
    $IPTABLES -A INPUT -i $IFINPUT -p tcp --dport 139 -j DROP # smb
    $IPTABLES -A INPUT -i $IFINPUT -p tcp --dport 445 -j DROP # smb
    $IPTABLES -A INPUT -i $IFINPUT -p tcp --dport 512:514 -j DROP # insecure login
    $IPTABLES -A INPUT -i $IFINPUT -p tcp --dport 3306 -j DROP # mysql
    $IPTABLES -A INPUT -i $IFINPUT -p tcp --dport 6000:6009 -j DROP # X11
    $IPTABLES -A INPUT -i $IFINPUT -p tcp --dport 7100 -j DROP # xfs

    # udp restrictions
    $IPTABLES -A INPUT -i $IFINPUT -p udp --dport 53 -j ACCEPT # dns
    $IPTABLES -A INPUT -i $IFINPUT -p udp --dport 500 -j ACCEPT # ipsec auth
    $IPTABLES -A INPUT -i $IFINPUT -p udp --dport 0:1024 -j DROP

    # icmp restrictions
    $IPTABLES -A INPUT -i $IFINPUT -p icmp --icmp-type echo-request -m limit --limit 2/s -j ACCEPT
    $IPTABLES -A INPUT -i $IFINPUT -p icmp --icmp-type echo-request -j DROP
    $IPTABLES -A INPUT -i $IFINPUT -p icmp -j ACCEPT

    # début de la configuration des marques du firewall

    # marques pour le traffic icmp ( pour benchmark uniquement )
    #$IPTABLES -t mangle -A INPUT -i $IFINPUT -p icmp -j MARK --set-mark 11

    if [ "$NOINGRESS" == "0" ]; then
    ########################### INPUT RULES (INGRESS) ############################

    # par défaut on met tout dans la classe par défaut
    $IPTABLES -t mangle -A PREROUTING -i $IFINPUT -m length --length 0:1500 -j MARK --set-mark 13

    # marques du traffic interactif (telnet & ssh)
    $IPTABLES -t mangle -A PREROUTING -i $IFINPUT -p tcp --sport 22:23 -j MARK --set-mark 11
    $IPTABLES -t mangle -A PREROUTING -i $IFINPUT -p tcp --dport 22:23 -j MARK --set-mark 11

    # marques du traffic edonkey
    $IPTABLES -t mangle -A PREROUTING -i $IFINPUT -p tcp --sport 4662 -j MARK --set-mark 15
    $IPTABLES -t mangle -A PREROUTING -i $IFINPUT -p tcp --dport 4662 -j MARK --set-mark 15

    # marques du traffic audiogalaxy
    $IPTABLES -t mangle -A PREROUTING -i $IFINPUT -p tcp --sport 1024:5000 --dport 41000:41999 -j MARK --set-mark 16

    # marques du traffic web , http et https
    $IPTABLES -t mangle -A PREROUTING -i $IFINPUT -p tcp --sport 80 -j MARK --set-mark 17
    $IPTABLES -t mangle -A PREROUTING -i $IFINPUT -p tcp --sport 443 -j MARK --set-mark 17

    # classement des longs downloads http au même niveau que le traffic ftp - en test -
    # utilise le match recent, qui est dans le patch-o-matic d'iptables
    $IPTABLES -t mangle -A PREROUTING -i $IFINPUT -p tcp --sport 80 -m recent --name web ! --rcheck -j MARK --set-mark 200 2> /dev/null
    $IPTABLES -t mangle -A PREROUTING -i $IFINPUT -p tcp --sport 80 -m mark --mark 200 -m recent --name web --set 2> /dev/null
    $IPTABLES -t mangle -A PREROUTING -i $IFINPUT -p tcp --sport 80 -j MARK --set-mark 17 2> /dev/null
    $IPTABLES -t mangle -A PREROUTING -i $IFINPUT -p tcp --sport 80 -m recent --name web ! --rcheck --seconds 45 -j MARK --set-mark 18 2> /dev/null

    # marques du traffic ftp
    $IPTABLES -t mangle -A PREROUTING -i $IFINPUT -p tcp --sport 20 -j MARK --set-mark 18
    $IPTABLES -t mangle -A PREROUTING -i $IFINPUT -p tcp --sport 1024: --dport 1024: -m state --state ESTABLISHED,RELATED -j MARK --set-mark 18

    # maques du traffic des radios shoutcast
    $IPTABLES -t mangle -A PREROUTING -i $IFINPUT -p tcp --sport 8000:8600 -j MARK --set-mark 19

    fi

    ######################### OUTPUT RULES (EGRESS) #############################

    # marquage et classement par taille de paquets sortants ( methode d'Emmanuel Roger - www.prout.be )
    # remarque: cette méthode réordonne les paquets d'une même connection tcp et peut la ralentir
    # dans des cas particuliers ( ici j'ai pas remarqué :), donc si ce script vous ralenti,
    # modifiez cette partie ou bien faites une classe pour le traffic qui vous intéresse
    $IPTABLES -t mangle -A PREROUTING ! -i $IFINPUT -m length --length 0:75 -j MARK --set-mark 22
    $IPTABLES -t mangle -A PREROUTING ! -i $IFINPUT -m length --length 76:444 -j MARK --set-mark 23
    $IPTABLES -t mangle -A PREROUTING ! -i $IFINPUT -m length --length 445:1500 -j MARK --set-mark 24
    $IPTABLES -t mangle -A OUTPUT -o $IFOUTPUT -m length --length 0:75 -j MARK --set-mark 22
    $IPTABLES -t mangle -A OUTPUT -o $IFOUTPUT -m length --length 76:520 -j MARK --set-mark 23
    $IPTABLES -t mangle -A OUTPUT -o $IFOUTPUT -m length --length 521:1500 -j MARK --set-mark 24

    # marquage du traffic interactif sortant
    $IPTABLES -t mangle -A PREROUTING ! -i $IFINPUT -p tcp --sport 22:23 -j MARK --set-mark 21
    $IPTABLES -t mangle -A PREROUTING ! -i $IFINPUT -p tcp --dport 22:23 -j MARK --set-mark 21
    $IPTABLES -t mangle -A OUTPUT -o $IFOUTPUT -p tcp --sport 22:23 -j MARK --set-mark 21
    $IPTABLES -t mangle -A OUTPUT -o $IFOUTPUT -p tcp --dport 22:23 -j MARK --set-mark 21

    # marquage du traffic edonkey sortant
    $IPTABLES -t mangle -A PREROUTING ! -i $IFINPUT -p tcp ! --syn --sport 4662 -j MARK --set-mark 25
    $IPTABLES -t mangle -A PREROUTING ! -i $IFINPUT -p tcp ! --syn --dport 4662 -j MARK --set-mark 25
    $IPTABLES -t mangle -A OUTPUT -o $IFOUTPUT -p tcp --sport 4662 -j MARK --set-mark 25
    $IPTABLES -t mangle -A OUTPUT -o $IFOUTPUT -p tcp --dport 4662 -j MARK --set-mark 25
    $IPTABLES -t mangle -A OUTPUT -o $IFOUTPUT -m owner --uid-owner "$UIDDONKEY" -j MARK --set-mark 25
    # pour garder un ping très bas, on peut forcer une taille plus petite des paquets au traffic edonkey (facultatif)
    $IPTABLES -t mangle -A PREROUTING ! -i $IFINPUT -p tcp --sport 4662 --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1000
    $IPTABLES -t mangle -A PREROUTING ! -i $IFINPUT -p tcp --dport 4662 --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1000
    $IPTABLES -A OUTPUT -m owner --uid-owner $UIDDONKEY -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1000

    # marquage du traffic audiogalaxy sortant
    $IPTABLES -t mangle -A PREROUTING ! -i $IFINPUT -p tcp --dport 41000:42000 -j MARK --set-mark 26
    $IPTABLES -t mangle -A OUTPUT -o $IFOUTPUT -p tcp --dport 41000:42000 -j MARK --set-mark 26
    $IPTABLES -t mangle -A OUTPUT -o $IFOUTPUT -m owner --uid-owner $UIDAG -j MARK --set-mark 26
    # diminution de la taille des paquets pour audiogalaxy
    $IPTABLES -A OUTPUT -m owner --uid-owner $UIDAG -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 768

    # marquage du traffic du serveur web local
    $IPTABLES -t mangle -A OUTPUT -o $IFOUTPUT -p tcp --sport 80 -j MARK --set-mark 27
    $IPTABLES -t mangle -A OUTPUT -o $IFOUTPUT -p tcp --sport 443 -j MARK --set-mark 27

    # declaration des fonctions utilisées pour ajouter des qdisc ou des filtres
    function addqdisc {
    $TC qdisc add dev 1ドル parent 2ドル handle 3ドル 4ドル 5ドル 6ドル 7ドル 8ドル
    }
    function addfilter {
    $TC filter add dev 1ドル parent 2ドル protocol ip handle 3ドル fw flowid 4ドル
    }


    # cleaning
    $TC qdisc del dev $IFINGRESS root 2> /dev/null > /dev/null

    if [ "$NOINGRESS" == "0" ]; then

    # règles tc / htb pour le traffic entrant ( ingress )

    $TC qdisc add dev $IFINGRESS handle 1:0 root htb default 1
    $TC class add dev $IFINGRESS parent 1:0 classid 1:1 htb rate 512kbit ceil 512kbit burst 77k

    $TC qdisc add dev $IFINGRESS parent 1:1 handle 10: htb default 203
    $TC class add dev $IFINGRESS parent 10: classid 10:1 htb rate 512kbit ceil 512kbit burst 77k
    $TC class add dev $IFINGRESS parent 10:1 classid 10:201 htb rate 128kbit ceil 512kbit burst 10k prio 0 # best interactivity for terminal
    $TC class add dev $IFINGRESS parent 10:1 classid 10:2 htb rate 384kbit ceil 500kbit burst 67k
    $TC class add dev $IFINGRESS parent 10:2 classid 10:203 htb rate 48kbit ceil 500kbit burst 2k prio 1 # medium size packets or generic
    $TC class add dev $IFINGRESS parent 10:2 classid 10:205 htb rate 5kbit ceil 480kbit burst 1k prio 3 # edonkey speed limitation
    $TC class add dev $IFINGRESS parent 10:2 classid 10:206 htb rate 1kbit ceil 450kbit burst 2k prio 3 # audiogalaxy speed limitation
    $TC class add dev $IFINGRESS parent 10:2 classid 10:207 htb rate 64kbit ceil 480kbit burst 10k prio 2 # www client
    $TC class add dev $IFINGRESS parent 10:2 classid 10:208 htb rate 6kbit ceil 480kbit burst 2k prio 2 # ftp data, less important than web surf
    $TC class add dev $IFINGRESS parent 10:2 classid 10:209 htb rate 260kbit ceil 480kbit burst 50k prio 0 # guaranted bandwidth, sound must be never cut:)

    addqdisc $IFINGRESS 10:201 61:0 pfifo limit 20
    addqdisc $IFINGRESS 10:203 63:0 sfq quantum 1492 perturb 120
    addqdisc $IFINGRESS 10:205 65:0 sfq quantum 1492 perturb 120
    addqdisc $IFINGRESS 10:206 66:0 sfq quantum 1492 perturb 120
    addqdisc $IFINGRESS 10:207 67:0 sfq quantum 1492 perturb 120
    addqdisc $IFINGRESS 10:208 68:0 sfq quantum 1492 perturb 120
    addqdisc $IFINGRESS 10:209 69:0 sfq quantum 1492 perturb 120

    addfilter $IFINGRESS 10: 11 10:201
    addfilter $IFINGRESS 10: 12 10:202
    addfilter $IFINGRESS 10: 13 10:203
    addfilter $IFINGRESS 10: 15 10:205
    addfilter $IFINGRESS 10: 16 10:206
    addfilter $IFINGRESS 10: 17 10:207
    addfilter $IFINGRESS 10: 18 10:208
    addfilter $IFINGRESS 10: 19 10:209

    $IP link set $IFINGRESS up

    $LOGGER QoS on $IFINPUT for 512k download
    echo QoS on $IFINPUT for 512k download

    fi

    # cleaning
    $TC qdisc del dev $IFOUTPUT root 2> /dev/null > /dev/null

    # règles tc / htb pour le traffic sortant ( egress )

    $TC qdisc add dev $IFOUTPUT root handle 1: htb
    $TC class add dev $IFOUTPUT parent 1: classid 1:1 htb rate 128kbit ceil 128kbit burst 7k
    $TC class add dev $IFOUTPUT parent 1:1 classid 1:100 htb rate 34kbit ceil 128kbit prio 0 burst 1k # ssh
    $TC class add dev $IFOUTPUT parent 1:1 classid 1:101 htb rate 26kbit ceil 128kbit prio 1 burst 1k # petits paquets
    $TC class add dev $IFOUTPUT parent 1:1 classid 1:102 htb rate 16kbit ceil 128kbit prio 1 burst 1k # paquets moyens
    $TC class add dev $IFOUTPUT parent 1:1 classid 1:103 htb rate 13kbit ceil 128kbit prio 2 burst 128 # gros paquets
    $TC class add dev $IFOUTPUT parent 1:1 classid 1:2 htb rate 3kbit ceil 122kbit prio 3 burst 128 ## classe basse priorité
    $TC class add dev $IFOUTPUT parent 1:2 classid 1:104 htb rate 2kbit ceil 112kbit prio 3 burst 128 # edonkey
    $TC class add dev $IFOUTPUT parent 1:2 classid 1:105 htb rate 1kbit ceil 64kbit prio 3 burst 128 # audiogalaxy
    $TC class add dev $IFOUTPUT parent 1:1 classid 1:106 htb rate 33kbit ceil 120kbit prio 2 burst 3k # webserver

    addqdisc $IFOUTPUT 1:100 20:0 pfifo limit 3
    addqdisc $IFOUTPUT 1:101 21:0 sfq perturb 3
    addqdisc $IFOUTPUT 1:102 22:0 pfifo limit 2
    addqdisc $IFOUTPUT 1:103 23:0 sfq perturb 180
    addqdisc $IFOUTPUT 1:104 24:0 sfq perturb 30
    addqdisc $IFOUTPUT 1:105 25:0 sfq perturb 180
    addqdisc $IFOUTPUT 1:106 26:0 sfq perturb 10

    # en premier, on met les ack au haute priorité (ceci peut aussi se faire avec iptables)
    $TC filter add dev $IFOUTPUT parent 1: protocol ip prio 1 u32 \
    match ip protocol 6 0xff \
    match u8 0x05 0x0f at 0 \
    match u16 0x0000 0xffc0 at 2 \
    match u8 0x10 0xff at 33 \
    flowid 1:101
    addfilter $IFOUTPUT 1: 21 1:100
    addfilter $IFOUTPUT 1: 22 1:101
    addfilter $IFOUTPUT 1: 23 1:102
    addfilter $IFOUTPUT 1: 24 1:103
    addfilter $IFOUTPUT 1: 25 1:104
    addfilter $IFOUTPUT 1: 26 1:105
    addfilter $IFOUTPUT 1: 27 1:106

    $LOGGER QoS on $IFOUTPUT for 128k upload
    echo QoS on $IFOUTPUT for 128k upload

    ;;
    esac
    exit