IPTABLES - Taux limite d'une adresse IP entrante spécifique

103

Je ne souhaite pas limiter le taux d'un service spécifique. Mon objectif est de limiter le débit uniquement en fonction de 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 évaluer la limite en utilisant IPTables en fonction des adresses IP entrantes?

James
la source

Réponses:

165

IPTables n'est pas conçu pour ce type de travail, où de nombreux paquets doivent être analysés pour prendre ces décisions. IPTables est en partie la solution!

La vraie réponse à cette question est les installations de contrôle du trafic impressionnantes et sous-utilisées de Linux. Notez que vous débrouiller avec cela sans savoir ce qui se passe peut vous amener à perdre la connectivité réseau vers la machine! Tu étais prévenu!

En supposant que eth0 soit le périphérique sortant, vous aurez besoin de créer une file d'attente de contrôle du trafic basée sur les classes qui, par défaut, générera le plus de trafic par le biais de la file d'attente "rapide" et placera une liste spécifique de personnes dans la file d'attente "lente".

L'avantage de cela est que vous pouvez créer une situation dans laquelle vous autorisez une grande quantité de trafic sortant pour l'utilisateur lent, sauf si une classe substituante souhaite la bande passante, mais cet exemple ne le fait pas (fournira toujours 10 kbps aux utilisateurs lents). Le système de 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 l'exécuter en tant que script entier

#!/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

La "valeur par défaut 11" est importante car elle indique au noyau quoi faire avec le trafic non classé.

Une fois cette opération effectuée, vous pouvez configurer une règle iptables pour classer les paquets correspondant à certains critères. Si vous envisagez de mettre beaucoup de gens dans cette règle lente, une règle ipset est plus appropriée (elle devrait être disponible sur rhel6 je crois).

Alors, créez une base de données ipset pour faire la correspondance avec ...

ipset create slowips hash:ip,port

Créez ensuite 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

Ceci indique au noyau que si vous faites correspondre l’adresse IP de destination avec le port source de l’ensemble, classifiez-la dans la file d'attente lente configurée avec le contrôle du trafic.

Maintenant, enfin, chaque fois que vous voulez ralentir une IP, vous pouvez utiliser la commande ipset pour ajouter l'ip à l'ensemble tel que:

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

Vous pouvez tester le fonctionnement à l'aide de la commande "tc -s class show dev eth0" et vous y verrez des statistiques indiquant que les paquets sont redirigés vers la file d'attente lente.

Notez que le seul inconvénient de cette opération est qu’il survit au redémarrage. Je ne pense pas que des scripts d'initialisation soient disponibles pour créer les jeux d'ips à partir de sauvegardes au redémarrage (ils doivent également être créés avant les règles iptables) et je suis certain qu'il n'y a pas de scripts d'initialisation pour réinitialiser les règles de contrôle du trafic lors du redémarrage. Si vous n'êtes pas dérangé, vous pouvez simplement recréer le tout en invoquant un script dans rc.local.

Matthew Ife
la source
3
Eh bien, je ne peux pas vous remercier assez. C'est très descriptif et très informatif. Je me suis rendu compte plus tard que la connaissance de TC serait nécessaire et j'ai depuis commencé à étudier cela. Merci encore!
James
Oh et quant à perdre la connexion. Je m'assure d'avoir la configuration en place 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 le problème. Mais avertissement entendu!
James
2
Je ne peux pas vous dire combien de fois j'ai lu des tutoriels similaires, c'est le premier qui ait un sens
RC1140
5
En résumé, il est généralement plus approprié de limiter les ressources de la sorte dans les groupes de contrôle (là aussi, possible, mais aussi sous-utilisé et génial), car vous pouvez définir des limites par application sur le processeur, la mémoire, les E / S et le réseau dans un magasin de règles centralisé. '. Mais n’avons pas encore vu une telle question posée pour offrir une réponse.
Matthew Ife
2
Si vous n'aimez pas la tcsyntaxe, vous pouvez essayer tcng qui ajoute un langage un peu plus convivial qui génère des tccommandes. Je l' ai utilisé pour ce genre dans les scripts shell: echo '... multi line tcng configuration ...' | tcng | sh.
Mattias Wadman
5

C'est aussi simple que de prendre une règle de limitation de débit et d'ajouter le -scommutateur. Le -scommutateur correspond aux adresses IP entrantes. Par exemple iptables -A INPUT -s 1.1.1.1, puis terminez avec votre méthode préférée de limitation de débit pour cette règle.

Wesley
la source
Merci pour votre réponse rapide. Malheureusement, mon problème principal est la seconde moitié. J'ai examiné - limite et je n'ai rien vu qui me permette de limiter en KB / s - aucune direction que vous puissiez me diriger?
James
1
@James, je vous aurais répondu mais je devais sortir chez un ami. Je viens de rentrer et je constate que MIfe a fait un travail considérable. =)
Wesley le