[IPROUTE - IPTABLES] problème de filtres avec marquage

problème de filtres avec marquage [IPROUTE - IPTABLES] - réseaux et sécurité - Linux et OS Alternatifs

Marsh Posté le 25-02-2003 à 15:21:11    

J?ai un problème avec iproute.  
 
Principe :  
- je marque les paquets selon le port et l?interface avec iptables.
J?obtiens :

:PREROUTING ACCEPT [1618529:1275747491]
-A PREROUTING -i eth0 -p tcp -m tcp --dport 22 -j MARK --set-mark 0xb  
-A PREROUTING -i eth0 -p tcp -m tcp --dport 80 -j MARK --set-mark 0xc  
-A PREROUTING -i eth0 -p tcp -m tcp --dport 443 -j MARK --set-mark 0xc  
-A PREROUTING -i eth0 -p tcp -m tcp --dport 20 -j MARK --set-mark 0xd  
-A PREROUTING -i eth0 -p tcp -m tcp --dport 21 -j MARK --set-mark 0xd  
-A PREROUTING -i eth0 -j MARK --set-mark 0xd  
-A PREROUTING -i eth1 -p tcp -m tcp --dport 22 -j MARK --set-mark 0x15  
-A PREROUTING -i eth1 -p tcp -m tcp --dport 80 -j MARK --set-mark 0x16  
-A PREROUTING -i eth1 -p tcp -m tcp --dport 443 -j MARK --set-mark 0x16  
-A PREROUTING -i eth1 -p tcp -m tcp --dport 20 -j MARK --set-mark 0x17  
-A PREROUTING -i eth1 -p tcp -m tcp --dport 21 -j MARK --set-mark 0x17  
-A PREROUTING -i eth1 -j MARK --set-mark 0x17  
-A PREROUTING -i lo -p udp -m udp --dport 53 -j MARK --set-mark 0x1f  
-A PREROUTING -i lo -p tcp -m tcp --dport 22 -j MARK --set-mark 0x1f  
-A PREROUTING -i lo -p tcp -m tcp --dport 80 -j MARK --set-mark 0x20  
-A PREROUTING -i lo -p tcp -m tcp --dport 25 -j MARK --set-mark 0x21  
-A PREROUTING -i lo -p tcp -m tcp --dport 110 -j MARK --set-mark 0x21  
-A PREROUTING -i lo -p tcp -m tcp --dport 4661:4666 -j MARK --set-mark 0x22  
-A PREROUTING -i lo -j MARK --set-mark 0x22  
:PREROUTING ACCEPT [16298:834255]
-A PREROUTING -i eth0 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 3128  
-A PREROUTING -i eth2 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 3128  
-A PREROUTING -i eth3 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 3128

 
 
- je crée des classes qui va permettre de gérer tous les filters:
J?obtiens :

class htb 1:101 parent 1:10 leaf 101: prio 0 rate 16Kbit ceil 128Kbit burst 6Kb cburst 1753b  
class htb 1:202 parent 1:20 leaf 202: prio 5 rate 16Kbit ceil 128Kbit burst 6Kb cburst 1753b  
class htb 1:303 parent 1:30 leaf 303: prio 2 rate 16Kbit ceil 128Kbit burst 6Kb cburst 1753b  
class htb 1:1 root rate 128Kbit ceil 128Kbit burst 6Kb cburst 1753b  
class htb 1:10 parent 1:1 rate 64Kbit ceil 128Kbit burst 6Kb cburst 1753b  
class htb 1:203 parent 1:20 leaf 203: prio 6 rate 8Kbit ceil 128Kbit burst 6Kb cburst 1753b  
class htb 1:302 parent 1:30 leaf 302: prio 1 rate 32Kbit ceil 128Kbit burst 6Kb cburst 1753b  
class htb 1:103 parent 1:10 leaf 103: prio 2 rate 16Kbit ceil 128Kbit burst 6Kb cburst 1753b  
class htb 1:20 parent 1:1 rate 32Kbit ceil 128Kbit burst 6Kb cburst 1753b  
class htb 1:301 parent 1:30 leaf 301: prio 0 rate 8Kbit ceil 32Kbit burst 6Kb cburst 1638b  
class htb 1:102 parent 1:10 leaf 102: prio 1 rate 32Kbit ceil 128Kbit burst 6Kb cburst 1753b  
class htb 1:201 parent 1:20 leaf 201: prio 4 rate 8Kbit ceil 128Kbit burst 6Kb cburst 1753b  
class htb 1:30 parent 1:1 rate 64Kbit ceil 128Kbit burst 6Kb cburst 1753b  
class htb 1:304 parent 1:30 leaf 304: prio 3 rate 8Kbit ceil 64Kbit burst 6Kb cburst 1679b

 
 
les filtres seront appliqués aux classes 1:X0Y (101, 203?)
 
- les filtres sont créés en utilisant le marquage iptables et redistribuent les paquets dans les classes 1 :X0Y
J?obtiens :

filter parent 1: protocol ip pref 49151 fw  
filter parent 1: protocol ip pref 49151 fw handle 0x22 classid 1:304  
filter parent 1: protocol ip pref 49151 fw  
filter parent 1: protocol ip pref 49151 fw handle 0x21 classid 1:303  
filter parent 1: protocol ip pref 49151 fw  
filter parent 1: protocol ip pref 49151 fw handle 0x20 classid 1:302  
filter parent 1: protocol ip pref 49151 fw  
filter parent 1: protocol ip pref 49151 fw handle 0x1f classid 1:301  
filter parent 1: protocol ip pref 49151 fw  
filter parent 1: protocol ip pref 49151 fw handle 0x17 classid 1:203  
filter parent 1: protocol ip pref 49151 fw  
filter parent 1: protocol ip pref 49151 fw handle 0x16 classid 1:202  
filter parent 1: protocol ip pref 49151 fw  
filter parent 1: protocol ip pref 49151 fw handle 0x15 classid 1:201  
filter parent 1: protocol ip pref 49151 fw  
filter parent 1: protocol ip pref 49151 fw handle 0xd classid 1:103  
filter parent 1: protocol ip pref 49151 fw  
filter parent 1: protocol ip pref 49151 fw handle 0xc classid 1:102  
filter parent 1: protocol ip pref 49152 fw  
filter parent 1: protocol ip pref 49152 fw handle 0xb classid 1:101

 
 
- sous ces classes sont associées des qdisc SFQ (et parent 1: )
j'obtiens:

qdisc sfq 304: quantum 1200b perturb 10sec  
qdisc sfq 303: quantum 1200b perturb 10sec  
qdisc sfq 302: quantum 1200b perturb 10sec  
qdisc sfq 301: quantum 1200b perturb 10sec  
qdisc sfq 203: quantum 1200b perturb 10sec  
qdisc sfq 202: quantum 1200b perturb 10sec  
qdisc sfq 201: quantum 1200b perturb 10sec  
qdisc sfq 103: quantum 1200b perturb 10sec  
qdisc sfq 102: quantum 1200b perturb 10sec  
qdisc sfq 101: quantum 1200b perturb 10sec  
qdisc htb 1: r2q 10 default 40 direct_packets_stat 2653


 
- Mais au final rien n?est dispatché quand je regarde le résultat:
 

qdisc sfq 304: quantum 1200b limit 128p flows 128/1024 perturb 10sec  
 Sent 0 bytes 0 pkts (dropped 0, overlimits 0)  
 
 qdisc sfq 303: quantum 1200b limit 128p flows 128/1024 perturb 10sec  
 Sent 0 bytes 0 pkts (dropped 0, overlimits 0)  
 
 qdisc sfq 302: quantum 1200b limit 128p flows 128/1024 perturb 10sec  
 Sent 0 bytes 0 pkts (dropped 0, overlimits 0)  
 
 qdisc sfq 301: quantum 1200b limit 128p flows 128/1024 perturb 10sec  
 Sent 0 bytes 0 pkts (dropped 0, overlimits 0)  
 
 qdisc sfq 203: quantum 1200b limit 128p flows 128/1024 perturb 10sec  
 Sent 0 bytes 0 pkts (dropped 0, overlimits 0)  
 
 qdisc sfq 202: quantum 1200b limit 128p flows 128/1024 perturb 10sec  
 Sent 0 bytes 0 pkts (dropped 0, overlimits 0)  
 
 qdisc sfq 201: quantum 1200b limit 128p flows 128/1024 perturb 10sec  
 Sent 0 bytes 0 pkts (dropped 0, overlimits 0)  
 
 qdisc sfq 103: quantum 1200b limit 128p flows 128/1024 perturb 10sec  
 Sent 0 bytes 0 pkts (dropped 0, overlimits 0)  
 
 qdisc sfq 102: quantum 1200b limit 128p flows 128/1024 perturb 10sec  
 Sent 0 bytes 0 pkts (dropped 0, overlimits 0)  
 
 qdisc sfq 101: quantum 1200b limit 128p flows 128/1024 perturb 10sec  
 Sent 0 bytes 0 pkts (dropped 0, overlimits 0)  
 
 qdisc htb 1: r2q 10 default 40 direct_packets_stat 2291 ver 3.6
 Sent 168929 bytes 2291 pkts (dropped 0, overlimits 0)


 
 
Alors qq?un a-t-il une idée?


Message édité par bobor le 25-02-2003 à 17:26:31

---------------
Gitan des temps modernes
Reply

Marsh Posté le 25-02-2003 à 15:21:11   

Reply

Marsh Posté le 25-02-2003 à 17:14:47    

ça m'est arrivé également.
quand je tapais tc qdisc show dev <dev>
                tc class show dev <dev>
             et tc filter show dev <dev>
tout paraissait bon mais rien n'était dispatché.
Je me suis aperçu en fait que je n'avais pas précisé le bon parent pour mes filtres.
vérifie donc tes lignes: filter parent 1: protocol ip pref 49151 fw  et surout le "1:" en fonction de ce que tu veux faire.
autrement poste ton script si ce n'est pas ça, ce sera plus facile pour t'aider.;)


Message édité par nikosaka le 25-02-2003 à 17:15:11
Reply

Marsh Posté le 25-02-2003 à 17:16:31    

c'est quoi le pref 49151?
je post le script de suite mais ce n'est pas très "lisible"  :D


---------------
Gitan des temps modernes
Reply

Marsh Posté le 25-02-2003 à 17:18:36    

le script:

#!/bin/bash
if [ "$1" != "" ] ; then
 CONF_FILE=$1  
else exit 1  
fi
#récupère des éléments dans le fichier de conf
INET_ITF=`sed -n -e '/^INET_ITF/p' ${CONF_FILE} | sed -e 's/\(.*\)\=\(.*\)/\2/'`
INET_IFACE=`sed -n -e '/^INET_IFACE/p' ${CONF_FILE} | sed -e 's/\(.*\)\=\(.*\)/\2/'`
UPLINK=`sed -n -e '/^UPLINK/p' ${CONF_FILE} | sed -e 's/\(.*\)\=\(.*\)/\2/'`
TC=`sed -n -e '/^TC_PROG/p' ${CONF_FILE} | sed -e 's/\(.*\)\=\(.*\)/\2/'`
IPTABLES=`sed -n -e '/^IPTABLES/p' ${CONF_FILE} | sed -e 's/\(.*\)\=\(.*\)/\2/'`
 
#crée le qdisc root et la classe root 1:1
${TC} qdisc del dev ${INET_IFACE} root 2> /dev/null > /dev/null  
 
${TC} qdisc add dev ${INET_IFACE} root handle 1: htb default 1
 
${TC} class add dev ${INET_IFACE} parent 1: classid 1:1 htb rate ${UPLINK}kbit ceil ${UPLINK}kbit burst 6k
 
k=1
nbprio="1 2 3 4"
 
for ifconf in ${INET_ITF} ; do
echo "$ifconf" | {
 IFS=':' read locif RATEIF CEILIF PRIOIF
 RATEIF=$(($UPLINK * $RATEIF))
 CEILIF=$(($UPLINK * $CEILIF))
 Mlocif=$(echo ${locif}|tr a-z A-Z) #mise en majuscule
 parid=$(($k*10))
#crée les classes associées à chaque interface réseau sous la classe 1:1
 ${TC} class add dev ${INET_IFACE} parent 1:1 classid 1:${parid} htb rate ${RATEIF}kbit ceil ${CEILIF}kbit burst 6k
 
 for i in ${nbprio} ; do
#récupère les données INET_ETHX_i et PORTS_ETHX_i dans le fichier de conf
 para=`sed -n -e "/^INET_""$Mlocif""_""$i""/p" ${CONF_FILE} | sed -e 's/\(.*\)\=\(.*\)/\2/'`
 ports=`sed -n -e "/^PORTS_""$Mlocif""_""$i""/p" ${CONF_FILE} | sed -e 's/\(.*\)\=\(.*\)/\2/'`
 
 if [ "$para" != "" ] && [ "$ports" != "" ] ; then
 echo "$para" | {
   IFS=':' read RATE CEIL
 
  RATE=$(($RATEIF * $RATE))
  CEIL=$(($CEILIF * $CEIL))
  id=$(($k*100+$i)) #handle minor de classe
  mark=$((10*$k+$i)) #marquage
  prio=$(($PRIOIF*4+$i-1)) #si interface de prio 0 alors sous-classes de prio 0 à 3, si interface de prio 1, alors prio de 4 à 7
 
#crée la sous-classe i à la classe de l'interface k  
  ${TC} class add dev ${INET_IFACE} parent 1:${parid} classid 1:$(($id)) htb rate ${RATE}kbit ceil ${CEIL}kbit prio ${prio} burst 6k
 
#crée un qdisc SFQ à chaque sous-classe 1:id
  ${TC} qdisc add dev ${INET_IFACE} parent 1:$(($id)) handle $(($id)): sfq perturb 10
 
#crée le filtre de parent le qdisc root 1:0 et renvoie à la sous-classe 1:id selon le marquage mark
  ${TC} filter add dev ${INET_IFACE} parent 1:0 protocol ip handle ${mark} fw flowid 1:$(($id))
 
 
  for p in ${ports} ; do
   if [ "$p" == "default" ] ; then
 
#tout ce qui n'est pas déjà marqué est marqué pour aller vers la sous-classes de prio la plus faible de l'interface
    ${IPTABLES} -t mangle -A PREROUTING -i ${locif} -j MARK --set-mark ${mark}
   else
    echo "$p" | {
     IFS='|' read port proto
     if [ "$proto" == "" ] ; then
      proto="tcp"
     fi
 
#crée la règle de marquage
     ${IPTABLES} -t mangle -A PREROUTING -i ${locif} -p ${proto} --dport ${port} -j MARK --set-mark ${mark}
    }
   fi
  done
 
  }
 fi
done
}
k=$(($k + 1))
done


 
je t'avais prévenu  [:xfalken]  
 
en gros il va chercher les paramètres de rate, ceil, ports dans CONF_FILE puis applique les règles.


Message édité par bobor le 25-02-2003 à 17:55:59

---------------
Gitan des temps modernes
Reply

Marsh Posté le 25-02-2003 à 17:31:47    

aaah le ouf  :pt1cable:  
bon je l'ai lu en gros (j'essayerai de regarder ça de plus près ce soir) je ne connais pas trop la syntaxe de htb, mais à ta place j'essayerai 2 3 trucs:
je remplacerai : ${TC} qdisc add dev ${INET_IFACE} root handle 1: htb default 1
par : ${TC} qdisc add dev ${INET_IFACE} root handle 1:0 htb
 
et donc la classe qui suit par :
${TC} class add dev ${INET_IFACE} parent 1:0 classid 1:1 htb rate ${UPLINK}kbit ceil ${UPLINK}kbit burst 6k  
 
je m'explique: j'ai bien peur que dans ta qdisc htb comme tu ne précise pas de nombre mineur "1:" (qui est l'équivalent de 1:0) et qu'ensuite tu met "default 1", le handle est donc de 1:1 (à la place de 1:0 cf la classe qui suit)
mais je me trompe peut-être sur l'option default.
enfin essaye toujours ça coute rien
 

Reply

Marsh Posté le 25-02-2003 à 17:32:16    

petit détail: le fait que les ligne soient doublées lors d'un tc filter show provient d'un bug de tc (signalé dans la doc de htb). Il faut seulement prendre en compte les lignes complètes. Il parait que ça fait la même chose avec cbq.


---------------
Gitan des temps modernes
Reply

Marsh Posté le 25-02-2003 à 17:38:27    

je dois raconter des conneries grosses comme moi, si ton erreur était sur le handle tu aurais des messages d'erreurs à gogo...
hum ... :pt1cable:  
fo ke j'arrte de bosszer moi vivement dans 1/2 heure  :sweat:

Reply

Marsh Posté le 25-02-2003 à 17:41:02    

c'est toujours pareil  :(  
 
pour info:
- le "default X" correspond à un minor-id: htb renvoie les paquets non classés vers la classe 1:X
- 1: et 1:0 sont strictement identiques
 
Je te remercie de bien vouloir jeter un oeil dessus. Je vais essayer de poster le fichier de configuration pour que ce soit plus lisible.


---------------
Gitan des temps modernes
Reply

Marsh Posté le 25-02-2003 à 17:47:00    

voici le fichier de configuration pour aider à la compréhhensio du script (j'y ai rajouté l'aide et il n'est complet car je n'ai pas mis la partie concernant le firewall):
 

#Routing
UPLINK=128
DOWNLINK=512
 
#inet_if: interface:rate:ceil:prio de l'interface
INET_ITF=eth0:1/2:1:0 eth1:1/4:1:1 lo:1/2:1:0
 
#inet_interface: rate:ceil (chaque interface est découpée en 4 sous-classes de la plus haute vers la plus faible priorité)
INET_LO_1=1/8:1/4
INET_LO_2=1/2:1
INET_LO_3=1/4:1
INET_LO_4=1/8:1/2
 
#ports_interface: les ports à associer pour chaque sous-classes de l'interface. protocole tcp par défaut.
PORTS_LO_1=53|udp 22
PORTS_LO_2=80
PORTS_LO_3=25 110
PORTS_LO_4=4661:4666 default
 
INET_ETH0_1=1/4:1
INET_ETH0_2=1/2:1
INET_ETH0_3=1/4:1
INET_ETH0_4=
PORTS_ETH0_1=22
PORTS_ETH0_2=80 443
PORTS_ETH0_3=20 21 default
PORTS_ETH0_4=
 
INET_ETH1_1=1/4:1
INET_ETH1_2=1/2:1
INET_ETH1_3=1/4:1
INET_ETH1_4=
PORTS_ETH1_1=22
PORTS_ETH1_2=80 443
PORTS_ETH1_3=20 21 default
PORTS_ETH1_4=


---------------
Gitan des temps modernes
Reply

Marsh Posté le 25-02-2003 à 17:56:49    

je viens de mettre l'aide en ligne dans le script. Maintenant ce sera un plaisir à lire!  
 :lol:  
Bon courage!  [:spykem@n]


---------------
Gitan des temps modernes
Reply

Marsh Posté le 25-02-2003 à 17:56:49   

Reply

Marsh Posté le 25-02-2003 à 20:25:53    

résultats après d'autres tests:
- sur eth0 ça marche (je n'ai pas essayé sur eth1 mais ça doit être bon). En fait j'ai retiré une règle de PREROUTING: celle qui gère le "default" dans le script. Sinon tout partait dans la classe root.
- pour le loopback, rien à faire, ça passe pas. Est-ce que cela vient des chaines de PREROUTING? de HTB? je ne sais pas et je cherche.
 
Donc l'algorithme du script en soi est bon. Reste le loopback et le default à gérer.


---------------
Gitan des temps modernes
Reply

Marsh Posté le 25-02-2003 à 20:48:48    

ça marche!
 
j'ai mis la règle loopback en OUTPUT au lieu de PREROUTING et ça roxe!
 
Plus qu'à gérer la partie download. Qq'un connait les règles iptables utilisant le match "recent"? Vois pas trop comment ça marche  :(  
 
Et à gérer la partie default aussi...


---------------
Gitan des temps modernes
Reply

Marsh Posté le 25-02-2003 à 23:43:53    

Code :
  1. -A PREROUTING -i eth0 -p tcp -m tcp --dport 22 -j MARK --set-mark 0xb 
  2. -A PREROUTING -i eth0 -p tcp -m tcp --dport 80 -j MARK --set-mark 0xc 
  3. -A PREROUTING -i eth0 -p tcp -m tcp --dport 443 -j MARK --set-mark 0xc 
  4. -A PREROUTING -i eth0 -p tcp -m tcp --dport 20 -j MARK --set-mark 0xd 
  5. -A PREROUTING -i eth0 -p tcp -m tcp --dport 21 -j MARK --set-mark 0xd 
  6. -A PREROUTING -i eth0 -j MARK --set-mark 0xd


 
A remplacer par
 

Code :
  1. -A PREROUTING -i eth0 -j MARK --set-mark 0xd 
  2. -A PREROUTING -i eth0 -p tcp -m tcp --dport 22 -j MARK --set-mark 0xb 
  3. -A PREROUTING -i eth0 -p tcp -m tcp --dport 80 -j MARK --set-mark 0xc 
  4. -A PREROUTING -i eth0 -p tcp -m tcp --dport 443 -j MARK --set-mark 0xc 
  5. -A PREROUTING -i eth0 -p tcp -m tcp --dport 20 -j MARK --set-mark 0xd 
  6. -A PREROUTING -i eth0 -p tcp -m tcp --dport 21 -j MARK --set-mark 0xd


 
Meme principe pour les autres. La regle MARK ne fait pas quitter la chaine au packet. Donc, ca le marque et ca le laisse passer a traver les autres. Donc avec tes anciennes rules, ca les mark et pui apres la efface en remettant la rules par default.
 
Si tu veut que les connection ftp soit pas trop ralentie, tu peut aussi utiliser le filtre -m conntrack --ctstatus EXPECTED pour matcher les connection de donnée d'un FTP ( a mettre dans une priorité entre le interactive et le bulk ).
Tu peut aussi dir par ex que les petit packet qui on le bit ACK mais pas le SYN doivent etre un peu plus prioritaire. Enfin bref, y a moyen de s'amuser ...
 
Je bosse justement sur des truc de ce genre en ce moment aussi ( 2 connection Net, 13 users, beaucoup de P2P et faut que ce soit rapide et interactif ... )

Reply

Marsh Posté le 26-02-2003 à 00:10:10    

ok je vais voir ça comment je vais pouvoir le mettre dans l'algorithme (un bien grand mot  [:lex] ). Et si je fais un -j RETURN sur le PREROUTING? Cela quitte complètement les règles ou seulement la partie PREROUTING?
 
pour les ACK... effectivement j'ai lu pas mal de chose. Pour l'instant je mets en fonction le bazar et après je vais paufiner. Notamment le fichier de conf n'aura pas la même gueule et ce sera plus simple à modifier.
 
J'ai un autre problème. Je n'arrive pas à trouver le patch IMQ pour mon kernel. J'ai trouvé le patch 2.4.18 mais pas pour le 2.4.19 ou 2.4.20. Qq'un a-t-il un lien? car google.... :pfff:


---------------
Gitan des temps modernes
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed