Iptables

Le FORWARD n’est utile que si ton serveur sert de passerelle (vers des machines physiques, ou éventuellement virtuelles). Sinon, tu peux tout bloquer.

Ce n’est pas si simple qu’il y paraît. Si tu veux te simplifier la tâche, utilise plutôt un gestionnaire de pare-feu tout fait comme ufw, qui crée les règles iptables à partir des règles de haut niveau que tu lui donnes. Le jeu de règles iptables résultant sera une usine à gaz mais ce n’est pas ton problème.

iptables -A INPUT -p tcp --dport 22 -j ACCEPT iptables -P INPUT DROP
Ça, c’est trop simpliste. D’un point de vue strict, cela correspond bien à ta spécification de départ, mais cette dernière est mal formulée, probablement par manque de connaissance du fonctionnement de TCP/IP. Ce que tu veux en réalité, c’est bloquer toutes les connexions entrantes autres que SSH (port TCP 22).

Ce qu’il faut bien comprendre, c’est qu’iptables ne bloque pas des connexions ni des ports mais des paquets IP. Un paquet reçu n’est pas la même chose qu’une connexion entrante. Quand on fait une connexion sortante vers une machine distante, on s’attend à recevoir des paquets de réponse de celle-ci. Avec ta règle simpliste, tu bloques toutes les réponses aux paquets que tu envoies, y compris entre processus locaux sur l’interface de loopback.

Comme il est pratique de raisonner en terme de connexion mais qu’iptables lui-même ne peut pas déterminer seul en examinant un paquet s’il est un paquet de réponse attendu, on lui a adjoint une fonctionnalité appelée “suivi de connexion” (connection tracking ou conntrack) qui examine tous les paquets émis et reçus et les classe dans différents “états” par rapport à une éventuelle connexion : NEW, ESTABLISHED, RELATED, INVALID.

Le jeu de règles minimal qui ferait ce que tu demandes correctemant a les spécifications suivantes :

  • accepter tous les paquets entrants sur l’interface de loopback
  • accepter tous les paquets entrants appartenant ou liés à une connexion existante
  • accepter tous les paquets TCP entrants à destination du port 22
  • bloquer tous les autres paquets entrants.

Voici les commandes iptables correspondantes :

iptables -A INPUT -i lo -j ACCEPT iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A INPUT -p tcp --dport 22 -j ACCEPT iptables -P INPUT DROP
Notes :

  • Contrairement à ce qui a été écrit, la définition de la politique par défaut (-P) n’est pas une règle et sa position par rapport aux règles (-A) n’a aucune importante autre que transitoire lors de la création des règles. La politique par défaut d’une chaîne n’est examinée qu’après avoir traversé toutes les règles de la chaîne.

  • La plupart des sockets montrées par netstat sont des connexions UDP avec des serveurs de temps NTP pour la synchronisation de l’horloge.

  • iptables-restore n’attend pas un script shell mais un fichier de règles ayant un format particulier, dont tu peux avoir un aperçu avec la sortie de sa commande soeur iptables-save lorsqu’un jeu de règles a été créé.

  • [mono]#!/bin/sh[/mono] ne signale pas un script bash mais un script qui doit être interprété par le shell par défaut /bin/sh. Dans les versions anciennes de Debian, /bin/sh pointait vers bash mais depuis deux ou trois versions il pointe par défaut vers dash, qui est un shell plus léger et plus sécurisé qui convient mieux à l’exécution non interactive de scripts systèmes. Cette transition a d’ailleurs été l’occasion d’une chasse aux “bashismes” (ajouts de Bash par rapport à la spécification POSIX) dans les scripts systèmes des paquets Debian. Bash a des fonctions qui le rendent pratiques comme shell interactif (pour saisir de commandes dans un terminal) mais qui sont inutiles pour l’exécution de scripts.

je te remercie pour ces informations importantes.

Donc toutes les requêtes en loopback devraient d’office être autorisé que ce soit en INPUT OUTPUT ou FORWARD?
en acceptant toutes les connexions déjà existantes on ne peut pas risquer de conserver une connexion malicieuse?

tu aurais des liens, anglais ou français pour apprendre à utiliser iptables?

Note : par construction il ne peut y avoir de trafic dans la chaîne FORWARD sur l’interface de loopback.

Oui, à moins que tu ne fasses pas confiance aux processus locaux. Mais je trouve que ce serait un peu paradoxal de faire tourner un service accessible de l’extérieur et pas en local. Si un service ne doit être accessible ni de l’extérieur ni en local, il vaut mieux ne pas le faire tourner plutôt que de bloquer ses ports.

Note : en français on dit plutôt “malveillant” (traduction du faux ami “malicious”).

Oui, forcément. Mais cette connexion malveillante, il a d’abord fallu qu’elle soit acceptée quand elle était nouvelle et pas encore établie. Et donc qu’elle se fasse sur un port autorisé. Si c’est le contenu qui s’avère malveillant, alors iptables n’est pas très armé contre cela. Il peut faire du filtrage sur le contenu des paquets (correspondances string, u32), mais les possibilités sont limitées. Cela ne vaut pas un IDS (système de détection d’intrusion).

je te remercie énormément, ca m’aide vraiment beaucoup.

De mon côté j’ai changé de serveur pour un serveur livré avec KVM sur IP. Du coup j’ai pu me permettre de mettre des DROP sur tous les comportements par défaut (c’était fun) je rajoute les règles une à une.

pour un serveur web + sftp basique le fichier suivant serait adapté?

#!/bin/sh
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport http -j ACCEPT
iptables -A INPUT -p tcp --dport https -j ACCEPT
iptables -P INPUT DROP

iptables -A OUTPUT -i lo -j ACCEPT
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEP
iptables -A OUTPUT -p tcp --dport http -j ACCEPT
iptables -A OUTPUT -p tcp --dport https -j ACCEPT
iptables -A OUTPUT -p tcp --dport 22 -j ACCEPT
iptables -P OUTPUT DROP

iptables -P FORWARD DROP

ps: quand je tape

et que je fais ensuite un iptables -L

je lis [quote]ACCEPT all – anywhere anywhere[/quote]

En INPUT : ok.
En OUTPUT : les règles avec --dport autorisent les connexions sortantes depuis ton serveur vers d’autres serveurs en HTTP, HTTPS, SFTP/SSH. Elles ne sont pas nécessaires pour les connexions entrantes. A voir si elles sont nécessaires pour ta machine. HTTP peut servir pour la connexion aux miroirs Debian. Il faut aussi généralement autoriser les requêtes DNS sortantes, port 53 en UDP et TCP. Tu peux limiter les connexions sortantes aux adresses des serveurs avec lesquels tu sais qu’il doit communiquer (serveurs DNS, miroirs Debian). Attention : certains noms de domaines de serveurs ont plusieurs adresses.

La sortie d’[mono]iptables -L[/mono] est incomplète : elle n’affiche que la table filter, et pas certains éléments des règles comme les interfaces d’entrée ou de sortie. L’option -v affiche ces éléments mais je trouve que le format de sortie est volumineux et pas facile à mettre en correspondance avec les règles. A mon avis la sortie de la commande iptables-save est bien meilleure, complète et proche de la syntaxe des règles.

Concernant la demande de documentation dans ton message précédent, tu peux chercher “iptables tutorial” d’Oskar Andreasson, dont il existe une version française.

ok merci je vais essayer de lire tout ca.

Par contre je n’arrive pas à faire apt-get update maintenant
je vois que c’est du ftp, j’ai donc autorisé le ftp entrant et sortant mais je reste à 0%…

edit : c’est bon fallait autoriser le http ^^

Bonjour,

j’ai une nouvelle question sur [quote]-m state --state ESTABLISHED,RELATED -j ACCEPT[/quote]
Mettons qu’au moment où je rentre la règle une ip est en train de tenter un bruteforce ssh. Ca veut dire que le seul moyen de filtrer cette ip sera d’insérer une règle la banissant AVANT la ligne -m state --state ESTABLISHED, dans le script?

donc je garde les lignes en enlevant --dport?

bon j’ai essayé de corrigé quelques trucs, voilà mon script final (l’éventail des ip à été “anonymisé”

# !/bin/sh
# Supprimer les règles écrites
/etc/init.d/parefeu clean
#... nouvelles règles
#     INPUT
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

iptables -A INPUT -p tcp --dport 22 -m iprange --src-range 0.0.0.0-90.200.255.255 -j ACCEPT
iptables -A INPUT -p tcp --dport http -j ACCEPT
iptables -A INPUT -p tcp --dport https -j ACCEPT

iptables -P INPUT DROP
#     OUTPUT
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

iptables -A OUTPUT -p tcp --dport http -j ACCEPT
iptables -A OUTPUT -p tcp --dport https -j ACCEPT
iptables -A OUTPUT -p tcp --dport 22 -j ACCEPT

iptables -P OUTPUT DROP
#     FORWARD

iptables -P FORWARD DROP
# Lister les règles nouvellement écrites
iptables -L

apt-get impossible à faire…

Hello, quelques pistes : la première sur la résolution DNS :

probleme-apt-get-update-t15856.html

D’autres liens :

probleme-apt-get-update-t48792.html
probleme-apt-get-update-t48792.html
isalo.org/wiki.debian-fr/Sou … _les_bases
isalo.org/wiki.debian-fr/L%2 … references

tcho :smiley:

apt-get fonctionne très bien sans le firewall, le soucis c’est que je pensais que la ligne -m state --steate ESTABLISHED… devait autoriser l’apt get…

Ben de rien pour l’aide que je t’ai apporté, j’ai passé du temps quand même à rechercher pour toi ces pistes là au dessus.

mdr merci quand même, la piste DNS est probablement bonne mais quand j’ai ajouté le port 53 aux ports autorisé ca n’a rien changé :confused:

Tu peux surfer sur plein de sites (tes règles iptables en état de fonctionnement ET selon ton dernier script) stp ? Et de rien…

jviens d’installer le serveur donc avant ces règles là j’en avait pas tout simplement… ou alors sans policy à drop

si j’enlève simplement la policy DROP en output l’apt get fonctionne !!!

edit : désolé je suis très fatigué et je planche trop sur le même problème du coup je sature, j’avais pas ajouté le port 53 en output c’est pour ca que ca refusait l’apt-get, je viens de le faire ouf -_-’

Ah ben voilà, ça prouve qu’iptables fonctionne bien, ben si tu as d’autres soucis passe, à plus

je te remercie

Ça dépend si chaque tentative de force brute nécessite une nouvelle connexion ou si plusieurs tentatives peuvent passer par la même connexion établie. Dans le second cas, il faudra casser la connexion établie pour arrêter l’attaque.

donc je garde les lignes en enlevant --dport?[/quote]
Non. Plus on enlève de conditions, plus une règle est permissive. Ce sont les règles qui ne sont pas nécessaires, et non la condition --dport. Si ta machine ne doit pas faire de connexion sortante vers le port X, tu supprimes la règle correspondante.

Si tu avais autorisé le port 53 en INPUT, il ne faut pas le laisser si ton serveur n’héberge pas de service DNS accessible de l’extérieur.
De même qu’une règle --dport en OUTPUT ne sert à rien pour les connexions entrantes, une règle --dport en INPUT ne sert à rien pour les connexions sortantes.