103 votes

IPTABLES - Limiter le débit d'une IP entrante spécifique

Je ne souhaite pas limiter le tarif d'un service spécifique. Mon objectif est de limiter le débit en se basant uniquement sur l'adresse IP entrante. Par exemple en utilisant une pseudo-règle :

john.domain.local (192.168.1.100) can only download from our httpd/ftp servers at "10KB/s" (instead of 1MB/s)

Comment puis-je limiter le débit en utilisant IPTables en fonction des adresses IP entrantes ?

168voto

Matthew Ife Points 22370

IPTables n'est pas fait pour ce genre de travail, où il faut analyser des tas et des tas de paquets pour prendre ces décisions. Mais IPTables est en partie la solution !

La vraie réponse à cette question est l'impressionnante et sous-utilisée facilité de contrôle du trafic dans Linux. Notez que si vous vous y prenez mal sans savoir ce qui se passe, vous risquez de perdre la connectivité réseau de la machine ! Vous êtes prévenus !

En supposant que eth0 est le périphérique de sortie, vous devrez créer une file d'attente de contrôle du trafic basée sur la classe qui, par défaut, fera passer la plupart du trafic par la file d'attente 'rapide' et mettra une liste spécifique de personnes dans la file d'attente 'lente'.

L'avantage de ce système est que vous pouvez créer une situation dans laquelle vous autorisez beaucoup de trafic sortant pour l'utilisateur lent, à moins qu'une classe prioritaire ne demande la bande passante, mais cet exemple ne le fait pas (il fournira toujours 10kbps aux utilisateurs lents). Le système de mise en file d'attente ressemblera à quelque chose comme ceci :

                         Inbound traffic
                              +
                              |
                              |
                              v
                     +------------------+
                     |   Class 1:1      |
                     |------------------|
                     |  Root (all flows)|
                     |       100mbit    |
                     +-----+-----+------+
                           |     |
                           |     |
                           |     |
                           |     |
                           |     |
          +----------+     |     |     +----------+
          |    1:11  +-----+     +-----+    1:12  |
          |----------|                 |----------|
          | Default  |                 | Slow     |
          |100mb-80kb|                 |   80kb   |
          +----------+                 +----------+

Pour ce faire, vous devez d'abord configurer la discipline de mise en file d'attente dans le noyau. Ce qui suit le fera pour vous vous devez exécuter ceci comme un seul script.

#!/bin/bash
tc qdisc add dev eth0 parent root handle 1: hfsc default 11
tc class add dev eth0 parent 1: classid 1:1 hfsc sc rate 100mbit ul rate 100mbit
tc class add dev eth0 parent 1:1 classid 1:11 hfsc sc rate 99920kbit ul rate 100000kbit
tc class add dev eth0 parent 1:1 classid 1:12 hfsc sc rate 80kbit ul rate 80kbit

tc qdisc add dev eth0 parent 1:11 handle 11:1 pfifo
tc qdisc add dev eth0 parent 1:12 handle 12:1 pfifo

Le "default 11" est important car il indique au noyau ce qu'il doit faire avec le trafic non classé.

Une fois que c'est fait, vous pouvez alors configurer une règle iptables pour classer les paquets qui correspondent à un certain critère. Si vous prévoyez de mettre beaucoup de personnes dans cette règle lente, une règle ipset est plus appropriée (qui devrait être disponible sur rhel6 je crois).

Donc, créer une base de données ipset pour faire la correspondance avec...

ipset create slowips hash:ip,port

Ensuite, créez la règle iptables pour faire la correspondance

iptables -t mangle -I OUTPUT -m set --match-set slowips dst,src -j CLASSIFY --set-class 1:12

Cela indique au noyau que si l'IP de destination correspond au port source de l'ensemble, il doit le classer dans la file d'attente lente que vous avez configurée avec le contrôle du trafic.

Enfin, chaque fois que vous voulez ralentir une IP, vous pouvez utiliser la commande ipset pour ajouter l'IP à l'ensemble, comme ceci :

ipset add slowips 192.168.1.1,80
ipset add slowips 192.168.1.1,21
...

Vous pouvez vérifier que cela fonctionne en utilisant la commande "tc -s class show dev eth0" et vous verrez des statistiques indiquant que les paquets sont redirigés vers la file lente.

Notez que le seul véritable inconvénient à cela est de le faire survivre aux redémarrages. Je ne pense pas qu'il y ait de scripts scripts disponibles pour créer les ipsets à partir des dumps au redémarrage (et ils doivent aussi être créés antes de iptables) et je suis certain qu'il n'y a pas d'init scripts pour réinitialiser les règles de contrôle du trafic au redémarrage. Si cela ne vous dérange pas, vous pouvez simplement recréer le tout en invoquant un scripts dans rc.local.

3 votes

Eh bien, je ne peux pas vous remercier assez. C'est très descriptif et très instructif. J'ai réalisé par la suite que des connaissances en matière de CT seraient nécessaires et j'ai depuis commencé à me renseigner à ce sujet. Merci encore !

0 votes

Oh et quant à la perte de connexion. Je m'assure de bien connaître la configuration avant de passer de mon VPS à la machine hôte. De plus, j'ai un accès VPN au réseau privé sur ETH0. Je ne travaillerai que sur ETH1, donc en théorie je n'aurai pas ce problème. Mais attention !

2 votes

Je ne peux pas vous dire combien de fois j'ai lu des tutoriels similaires, c'est le premier qui a eu du sens.

5voto

Wesley Points 32020

C'est aussi simple que de prendre une règle de limitation de taux et d'ajouter le facteur -s l'interrupteur. Le site -s Le commutateur correspond aux IPs entrants. Par exemple iptables -A INPUT -s 1.1.1.1 puis terminez par votre méthode préférée de limitation du taux pour cette règle.

0 votes

Merci pour votre réponse rapide. Malheureusement, mon principal problème est la seconde moitié. J'ai cherché dans --limit et je n'ai rien vu qui me permette de limiter en fonction du KB/s - pouvez-vous m'indiquer une direction ?

1 votes

@James J'aurais pu vous répondre mais j'ai dû sortir pour aller chez un ami. Je viens de rentrer et je vois que MIfe a fait un sacré boulot. =)

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X