Iptables interdire les pays sauf la france

Salut,

J’avais inclus dans .htaccess quelques pays de l’est particulièrement virulents mais j’ai été oblige de faire marche arrière suite au temps d’attente pour arriver à se connecter.
Quitte à faire une list mieux vaudrait prendre le problème à l’envers et autoriser les CIDR français que ce soit pour iptables ou htaccess.

+1 pour la discrimination positive. Il est plus facile d’interdire toute ip sauf les ip françaises. La liste à consulter est plus courte.

Comme le souligne syam, ipset est effectivement l’outil le plus approprié. A ma connaissance le noyau stable n’est pas compilé avec le support pour ipset. Il faudra passer par module-assistant et les sources d’ipset pour en faire un module. Pas très compliqué, c’est l’affaire de 3 minutes. Il faudra sans doute installer les entêtes de ton noyau pour la compilation du module.

aptitude install module-assistant linux-headers-$(uname -r) ipset ipset-source module-assistant auto-install ipset-source
Pour la règle ipset, choisir le set type nethash et insérer les adresses ip françaises sous la forme CIDR. Un bête script dash/bash/awk de quelques lignes fera l’affaire.

PascalHambourg évidemment!

indesirables-firewall-t37580-25.html#p378693

Je ne suis pas allé plus loin que l’installation faute d’un réel besoin…
Mais ça mériterait un vrai retour et une page dans le Wiki!

Salut,

Mais la solution de Pascal ne m’est pas permise sur ce foutu Synology : Je ne peux pas installer IPSET :mrgreen:

Console-toi, je viens de faire quelques tests grossiers et, à condition que mon protocole de test soit correct, ipset ne semble pas plus rapide qu’iptables.

Protocole: iptables vs ipset sur une grosse liste noire d’adresses CIDR (2800 adresses) avec un REJECT comme target pour pouvoir mesurer le temps de réaction du firewall à renvoyer un icmp-port-unreachable. Sur le poste de test (exclu par la liste noire), un simple$ time ssh <ip_firewall>

Aucune différence notable. Sur le firewall par contre le temps de chargement des “règles” est 3 fois plus rapide avec ipset. En mémoire, ipset semble plus léger (2 Mo de différence) - pour autant que la commande free donne une idée correcte de l’utilisation de la mémoire (rien n’est plus difficile sous Linux de se faire un idée exacte de l’utilisation réelle de la mémoire).

J’ai mis la règle d’exclusion du poste test à la fin ou au début, aucune différence. J’ai un peu l’impression qu’iptables optimise la recherche d’ip, après chargement des règles dans le noyau.

Je sais que mes conclusions vont à l’encontre de ce qu’on dit sur le net mais les résultats sont là. Peut-être que les dernières versions de netfilter/iptables optimisent la recherche d’ip. Si vous avez des idées pour améliorer le test…

Je ne crois pas que ton test soit fiable :

  • 2800 adresses c’est rien du tout
  • tu mesures avec une granularité de l’ordre de la milliseconde alors que le temps de traitement est très certainement inférieur
  • le temps de traitement est complètement noyé dans le temps que mettent les paquets réseau à faire l’aller-retour
  • augmenter sérieusement la taille de la liste noire, mettre le poste de test à la fin
  • envoyer autant de connexions simultanées que tu peux
  • mesurer l’occupation CPU sur le firewall
    Je pense que ça serait déjà un peu plus fiable. Je vais voir si je peux faire un test dans ce genre, je reviens… :wink:

Résultats du test…

J’ai pris l’ensemble des adresses proposées par countryipblocks.net/country_selection.php soit plus de 128000. J’ai déplacé 192.168.0.0/16 (mon réseau) tout à la fin.

iptables : 2.9 secondes de chargement (iptables-restore), règles au format -A INPUT -s -j REJECT
ipset : 7.6 secondes de chargement (ipset restore), une seule règle iptables -A INPUT -m set --match-set TEST src -j REJECT

Depuis un autre poste j’ai floodé avec des pings pour une bande passante totale de 7.9 Mo/s :

Sur le “firewall” (Atom N450 1.66GHz) :

  • iptables se maintient à environ 5 % d’utilisation CPU
  • ipset se maintient à environ 1 % d’utilisation CPU
    Les deux mesures ont été prises avec top, et incluent KDE et SSH qui continuaient de tourner en arrière plan (environ 0.5 % CPU à retrancher des valeurs mesurées).

Bref, mon test semble confirmer qu’ipset est largement plus optimisé (même si le chargement initial est plus long). :wink:
Je n’ai pas cherché à voir l’utilisation mémoire.

D’abord, une petite mise au point : ce n’est pas ma solution, mais juste une piste possible que j’avais mentionnée. Je n’ai moi-même jamais utilisé ipset.

Concernant les résultats de tests de performances, cela s’explique par l’algorithme de recherche utilisé par ipset, plus coûteux à la mise en place mais plus efficace à l’utilisation que le simple parcours séquentiel d’iptables.

Enfin, et peut-être le plus important, il faut garder à l’esprit que ces liste de blocs d’adresses ne sont pas la vérité absolue : elles produiront forcément des faux positifs et des faux négatifs : filiales de boîtes étrangères implantées en France qui ont des adresses “étrangères” et vice versa, blocs alloués à un FAI français mais pas (encore) répertoriées… Même une boîte que je connais n’est pas capable de répertorier complètement toutes les plages d’adresses qu’elle possède, c’est dire…

[quote=“syam”]Résultats du test…
Bref, mon test semble confirmer qu’ipset est largement plus optimisé (même si le chargement initial est plus long). :wink:
Je n’ai pas cherché à voir l’utilisation mémoire.[/quote]
Ce test est intéressant mais incomplet. Il ne mesure pas l’essentiel: en combien de temps netfilter trouve-t-il l’ip bannie et y répond-t-il. C’est ça qu’il faut mesurer. Ta boucle met chaque ping en arrière-plan sans attendre la réponse icmp. Il est donc impossible, avec ton test, de déterminer, côté attaquant, en combien de temps le firewall réagit à ton flood. Tu vas me dire qu’en cas de reject ou de drop ce n’est pas important mais ça l’est dans le cas d’un target accept. Essaye:

time (LOOPS=50; while ((LOOPS--)); do nc <ipCIble> 22; done) Tu peux remplacer netcat par ping, ssh ou ce que tu veux.

Quand je fais ce test, les premiers retours du icmp-port-unreachable sont immédiats, les suivants sont temporisés pour une raison que je ne m’explique pas. Le firewall ne contient que les règles du test. Rien d’autre. En conséquence, les deux méthodes (iptables et ipset) donnent les mêmes résultats sur un fichier d’ip CIDR de 31000 lignes. Il faudrait que je fasse un tcpdump sur les sorties icmp du serveur et en mesure la durée.

Ou alors il faudrait trouver une autre méthodologie pour calculer le temps mis par le firewall pour trouver l’ip filtrée dans ses tables et y répondre. Il faut surveiller l’activité du cpu, d’accord, mais pas en charge uniquement mais plutôt en charge pondérée par la durée.

Je n’aurai plus beaucoup de temps les semaines qui viennent pour poursuivre ces tests mais je passerai pour lire la suite de tes cogitations.

La raison pour laquelle j’ai procédé comme ça, c’est qu’il est impossible de mesurer directement le temps de traitement d’un seul paquet.

Avec un flood à quasiment 8 Mo/s (soit environ 130000 pings par seconde à raison de 64 octets par ping*), la charge CPU n’est qu’à 5 % dans le pire des cas. Si le réseau arrivait à suivre (bande passante infinie), en saturant le CPU il pourrait traiter grosso modo 20 fois plus de paquets (2600000 par seconde) c’est à dire 0.000385 millisecondes (385 nanosecondes) pour traiter un paquet.

(*) j’ai comme un doute quand même, je me demande si les trames Ethernet ne sont pas de taille fixe (1500 octets) quel que soit le contenu.
Qu’à cela ne tienne, le calcul est identique : 8 Mo/s ça nous fait 5590 pings par seconde, soit une capacité de traitement CPU (x 20) de 111800 paquets par seconde, c’est à dire 0.009 millisecondes (9 microsecondes) par paquet. Étant donné que les 385 nanosecondes me paraissent quand même vachement faibles, je pense que c’est plutôt les 9 microsecondes qui sont correctes. Mais bon, même comme ça on est quand même à des valeurs 100 fois plus petites que la milliseconde !

Ça, c’est sur un “petit” CPU à 1.66 GHz, avec plus de 128000 règles, dans le cas le plus lent (iptables, machine de test tout à la fin de la liste noire).
Dans ces conditions, comment veux-tu mesurer de manière fiable le temps de traitement d’un seul paquet alors que ta précision de mesure est au mieux d’une milliseconde, et que le simple fait de lancer un programme comme netcat implique déjà des variations de plusieurs millisecondes ? :wink:
Et c’est pas mes quelques arrondis qui vont changer l’ordre de grandeur de manière significative…

Je ne comprends pas ton histoire de pondération par la durée. La charge réseau était stable, la charge CPU était stable, la stabilité de la mesure a été vérifiée à chaque fois sur une grosse minute, je ne vois pas ce qu’il y a à pondérer. Tu peux détailler ?

Salut,

Pour information mon Synology le possède que 128 Mo de mémoire vive et donc quelque soit l’algorithme il swappe la table des IP. Ce qui provoque un fort ralentissement même si le temps de traitement est optimisé.
Mon temps de réponse passe de 1 à 10, je n’ai nul besoin d’un chrono :slightly_smiling:

Salut,

Dans la série test, cette article devrait vous intéresser.

Mass-blocking IP addresses with ipset

Ipset, sujet qui revit, c’est cool … :083

Indirectement, si. Le noyau fait deux choses avec chaque paquet de requête : rechercher si l’adresse source est dans la liste, et le cas échéant répondre. Répondre prend à peu près toujours le même temps quelle que soit la méthode de recherche, par iptables ou ipset. Donc pour un même volume de trafic, si l’occupation du CPU est plus élevée avec iptables, c’est que la recherche lui prend plus de temps qu’avec ipset.

Non, mais elles ont une taille minimale de l’ordre de 64 octets.

Je serais très surpris que la mémoire du noyau contenant les règles d’iptables ou les listes d’ipset puisse être swappée.

Re,

lmt> free total used free shared buffers Mem: 118816 103036 15780 0 3768 Swap: 2097080 98724 1998356 Total: 2215896 201760 2014136

Et là il attend seulement le courrier :slightly_smiling:

Non, mais elles ont une taille minimale de l’ordre de 64 octets.[/quote]
Ok donc mon premier calcul qui donne 385 ns était le moins incorrect des deux (je sais bien que ce sont des calculs très approximatifs :mrgreen:).
L’informatique ne cessera jamais de m’étonner…

Merci de l’info. :wink:

Je ne comprends pas ton histoire de pondération par la durée. La charge réseau était stable, la charge CPU était stable, la stabilité de la mesure a été vérifiée à chaque fois sur une grosse minute, je ne vois pas ce qu’il y a à pondérer. Tu peux détailler ?[/quote]

J’imaginais qu’une charge CPU de 10% pendant 5 secondes n’est pas la même chose que 5% pendant 30 secondes. Maintenant, si iptables et ipset utilisent le cpu de la même manière la pondération n’est effectivement pas nécessaire comme souligné plus haut.

Entre-temps, j’ai changé ma méthodologie de test en n’utilisant plus le target reject qui, pour des raisons toujours inexpliquées, ralentit le rythme des réponses après les 5 premiers paquets icmp. J’ai simplement mis un target log, la charge et la latence d’écriture dans syslog devant être équivalentes pour les deux méthodes. J’ai mis le format rsyslog à RSYSLOG_ForwardFormat (a new high-precision forwarding format) pour avoir un horodatage précis et j’ai refait les tests. Et cette fois, ils sont conformes à la réputation d’ipset et aux résultats de syam.

Boucle de 1000 requêtes et fichier d’ip CIDR de 31000 lignes.
Temps de traitement: iptables: 24 sec., ipset: 11 sec.

Les règles ipset semblent aussi se charger beaucoup plus rapidement qu’iptables:
iptables-restore: 2 sec.
ipset -R: 0,3 sec.

Sur ce dernier test je ne rejoins donc pas les résultats de syam, le volume des règles n’est pas le même non plus. Mais c’est de moindre importance.

[quote=“loreleil”]Salut,
Dans la série test, cette article devrait vous intéresser.
Mass-blocking IP addresses with ipset
Ipset, sujet qui revit, c’est cool … :083[/quote]

Intéressant ce lien. Tout y est dit.

Salut,

Bon, je vais tiré un peu la couette … :033

J’avais laissé ipset en stand bye, c’est reparti.

Un os!

Le premier de la liste. UNITED STATES me retourne les erreurs suivantes.

:~/.ipset_block.list# while read ln; do ipset -A UNITED_STATES $ln; done < UNITED_STATES.list ipset v2.5.0: IP/port/element is outside of the set or set is full ipset v2.5.0: IP/port/element is outside of the set or set is full ipset v2.5.0: IP/port/element is outside of the set or set is full ipset v2.5.0: IP/port/element is outside of the set or set is full ...
J’ai laissé cette action se terminer, il en ressortis 32776 lignes créer. (32776 blocks d’ip enregistrer)

La traduction très relative qu’en fait google, “élément est en dehors de l’ensemble ou d’un ensemble est pleine” ma laissé supposer que le fichier .list était trop imposant sur ma bête de course. (en local)

Un copier/coller de la liste créer par countryipblocks me sort un fichier (nommé: UNITED_STATES.list) de 42295 blocks d’IP. Autrement dit 42295 lignes.

J’ai limité le fichier à 32000 lignes. J’ai relancé, et cette fois aucune erreur.

Ça c’était pour la bête local.

Une recherche avec find sur les fichiers ipset, mais bon … :confused:

Je n’ai pas su mettre la main sur ce script, par contre j’ai trouvé ceci sur la toile.

svn.netfilter.org/netfilter/trunk/ipset/ipset.c

[quote]…
static void kernel_error(unsigned cmd, int err)
{
unsigned int i;
struct translate_error {
int err;
unsigned cmd;
const char message;
} table[] =
{ /
Generic error codes /
{ EPERM, 0, “Missing capability” },
{ EBADF, 0, “Invalid socket option” },
{ EINVAL, 0, “Size mismatch for expected socket data” },
{ ENOMEM, 0, “Not enough memory” },
{ EFAULT, 0, “Failed to copy data” },
{ EPROTO, 0, “ipset kernel/userspace version mismatch” },
{ EBADMSG, 0, “Unknown command” },
/
Per command error codes /
/
Reserved ones for add/del/test to handle internally:
* EEXIST
*/
{ ENOENT, CMD_CREATE, “Unknown set type” },
{ ENOENT, 0, “Unknown set” },
{ EAGAIN, 0, “Sets are busy, try again later” },
{ ERANGE, CMD_CREATE, “No free slot remained to add a new set” },
{ ERANGE, 0, “IP/port/element is outside of the set or set is full” },
{ ENOEXEC, CMD_CREATE, “Invalid parameters to create a set” },
{ ENOEXEC, CMD_SWAP, “Sets with different types cannot be swapped” },
{ EEXIST, CMD_CREATE, “Set already exists” },
{ EEXIST, CMD_RENAME, “Set with new name already exists” },
{ EEXIST, 0, “Set specified as element does not exist” },
{ EBUSY, 0, “Set is in use, operation not permitted” },
};
for (i = 0; i < sizeof(table)/sizeof(struct translate_error); i++) {
if ((table[i].cmd == cmd || table[i].cmd == 0)
&& table[i].err == err)
exit_error(err == EPROTO ? VERSION_PROBLEM
: OTHER_PROBLEM,
table[i].message);
}
exit_error(OTHER_PROBLEM, “Error from kernel: %s”, strerror(err));
}

[/quote]

J’ai lancé la même procédure sur mon dédié, kif-kif avec un fichier UNITED_STATES.list de 42295 blocks d’IP.

# while read ln; do ipset -A UNITED_STATES $ln; done < UNITED_STATES.list ipset v2.5.0: IP/port/element is outside of the set or set is full

Un Z’idée …

Salut,

Autre bizarrerie …

# while read ln; do ipset -A block3 $ln; done < AFGHANISTAN.list ipset v2.5.0: -A requires setname and IP Try `ipset -H' or 'ipset --help' for more information. :~/.ipset_block.list#

[quote]–add -A setname IP
Add an IP to a set
[/quote]

afficher 5710 regles avec iptable -L c’est long :confused:
je suis a 5710 regles

je drop tout et j’autorise que les CIDR français sur 22 et 80
y a pas moyen d’englober toutes les regles dans une liste blanche ? afin que ça soit plus leger et plus lisible

[quote=“loreleil”]Autre bizarrerie …
ipset v2.5.0: -A requires setname and IP
[/quote]
Tu dois sans doute avoir une ligne vide dans ton fichier d’ip. essaye avec ceci:

Cela dit, à chaque tour de boucle, tu invoques la commande ipset. Il vaudrait mieux stocker toutes les lignes dans un fichier au format ipset --save et de l’exécuter avec un ipset --restore. Même principe que pour iptables-save vs iptables.

[quote=“tonyx”]afficher 5710 regles avec iptable -L c’est long :confused:
je suis a 5710 regles
je drop tout et j’autorise que les CIDR français sur 22 et 80
y a pas moyen d’englober toutes les regles dans une liste blanche ? afin que ça soit plus leger et plus lisible[/quote]
Bien sûr. C’est le principe de la discrimination positive. Tu mets la policy par défaut de la chaîne INPUT à DROP et ensuite tu autorises les ip légitimes. N’oublie pas de commencer par ton ip (lan ou wan)!