lundi 23 septembre 2013

Mes débuts dans la sécurité, IPTABLES


Cet article fait suite à "Mes débuts en matière de défences de mon serveur", mais devrait être lu avant celui-ci.

Configuration d'iptables

Introduction

On peut difficilement parler de sécurité informatique et passer sous silence la question du firewall. Jusqu'à maintenant je n'avais pas activé iptables sur mon serveur, ça visibilité étant surtout locale, je n'avais pas vraiment peur d'un piratage.
Mais comme la sécurité commence par là, "So be it !" comme dirait les 'ricains et les rosbifs.

L'état exacte d'iptables sous Archlinux avant qu'on fasse quoi que ce soit, je ne le connais pas. Enfin bref, après un # touch /etc/iptables/iptables.rules et un redémarrage ça marche.

Plan d'attaque

Pour une question de sécurité, on va configurer iptables pour qu'il refuse tout sauf ce que l'on a autorisé.
Certaines configurations utilisent les redirections de lighttpd (cf. article précédent). Ainsi pas d'ouverture de port bizarre comme le 9091 de transmission, mais un passage par le port 443 avec un redirection de lighttpd vers le port 9091.
Si vous êtes en SSH - c'est mon cas - ne taper pas de règles bizarres, ça peut vous conduire à brancher un clavier sur le serveur pour le redémarrer (par exemple # iptables -P INPUT DROP qui consiste à refuser toute les connexions entrantes ... I did it).

On refuse tout ... sauf sur le port 22

Pour entrer les premières règles on va éditer le fichier de configuration (cf "Plan d'attaque"). On va interdire, DROP, tout (entrées, sorties, redirections, ...), sauf les connexions sur le port 22 et pour la machine locale.
J'ai pas tout pigé sur conntrack, c'est une gestion "intelligente" des connections, qui permet de repérer des connexions reliées mais, par exemple, sur des ports différents et donc de traiter le deuxième non pas comme NEW mais comme RELATED. Pour plus d'info chercher sur internet.

# Gestion des filtres
*filter

# On bloque tout
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]

# Pour simplifier l'écriture des règles de nouvelles connexions sur tcp et udp
:TCP [0:0]
:UDP [0:0]

# Règles de fonctionnement

## les connexion existantes
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
## l'interface locale
-A INPUT -i lo -j ACCEPT
## Puis on refuse les connexions invalide
-A INPUT -m conntrack --ctstate INVALID -j DROP

## On autorise les requêtes ICMP (genre "ping")
-A INPUT -p icmp -m icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT

## conntrack va gérer les nouvelles connexions UDP
-A INPUT -p udp -m conntrack --ctstate NEW -j UDP
## idem pour TCP
-A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j TCP

## On rejette le reste pour tcp et udp
-A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
-A INPUT -p tcp -j REJECT --reject-with tcp-reset

## Et finalement on rejette tout le reste
-A INPUT -j REJECT --reject-with icmp-proto-unreachable

# Règles personnelles

## SSH ... ben sinon on peut plus se connecter
## même si normalement la connexion actuelle devrait persister 
-A TCP -p tcp -m tcp --dport 22 -j ACCEPT

# systemctl (re)start iptables.service
# iptables-save
# Generated by iptables-save v1.4.19.1 on Mon Sep 23 12:39:17 2013
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
:TCP - [0:0]
:UDP - [0:0]
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate INVALID -j DROP
-A INPUT -p icmp -m icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -p udp -m conntrack --ctstate NEW -j UDP
-A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j TCP
-A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
-A INPUT -p tcp -j REJECT --reject-with tcp-reset
-A INPUT -j REJECT --reject-with icmp-proto-unreachable
-A TCP -p tcp -m tcp --dport 22 -j ACCEPT
COMMIT
# Completed on Mon Sep 23 12:39:17 2013

Pour sauvegarder ces règles de manière "plus formelle" remplacer par la sortie de iptables-save le contenu du fichier /etc/iptables/iptables.rules.

les [0:0] sont juste des valeurs de conteurs. Après avoir tout configuré et lancé le service iptables, amuser vous à vous connecter requérir des pages web, etc et faite un # iptables-save > /etc/iptables/iptables.rules vous verrez les valeurs des conteurs qui auront changés ... normal des données ont transitées.

Si vous avez un service qui tourne tester d'y accéder ... ben ça devrait pas marcher (comme votre serveur web).

Comment permettre les communications sur un port ?

Bon c'est bien gentil tout ça, mais je fais comment pour voir mes pages web maintenant ?
# iptables -A TCP -p tcp --dport http -j ACCEPT
Noter le "numéro" http du port, iptables connaît certains port par défault (http pour 80, ssh pour 22, ...).
En remplaçant http par le numéro de port que vous souhaitez vous pouvez permettre (ou empêcher avec DROP au lieu de ACCEPT, mais c'est déjà le comportement pas défaut) les connexions pour le protocole TCP.
Si vous hébergez votre propre serveur DNS alors c'est le port 53 avec le protocole UDP qu'il faut ouvrir, pas de problème
# iptables -A UDP -p udp --dport 53 -j ACCEPT
Bon, convaincu ?

Mes services ne sont plus accessible ... et je ne connais pas leur port

Si vous utilisez nfs, samba, etc. Vous ne connaissez peut-être pas tout les ports de communication par défaut de ces services, et fouiller dans les fichiers de configuration est long.
J'ai la solution, nmap !
# systemctl stop iptables.service
# nmap 192.168.XXX.XXX

Starting Nmap 6.40 ( http://nmap.org ) at 2013-09-23 13:50 CEST
Nmap scan report for 192.168.XXX.XXX
Host is up (0.0049s latency).
Not shown: 994 closed ports
PORT     STATE SERVICE
22/tcp   open  ssh
80/tcp   open  http
111/tcp  open  rpcbind
2049/tcp open  nfs
8080/tcp open  http-proxy
MAC Address: XX:XX:XX:XX:XX:XX (SercoNet)

Nmap done: 1 IP address (1 host up) scanned in 0.45 seconds

# systemctl start iptables.service

Et maintenant vous autorisez les ports utilisés. Par contre faite attention au logiciels qui utilise un segment de port (comme les logiciels de pair-à-pair pour ne pas les nommer), il faut remplacer le numéro de port par les extrémités du segment --dport 500:520 (j'ai pas encore essayé).

Mes règles ont disparues !

Au démarrage du service iptables charge toutes (et exclusivement celles-là) ses règles à partir du fichier /etc/iptables/iptables.rules, donc si vous n'avez pas sauvé précédemment ce que vous avez fait ... c'est normal.
Quand vous avez ajouté une règle, que vous avez testé qu'elle était bonne, on sauvegarde :
# iptables-save > /etc/iptables/iptables.rules

iptables advanced

Désolé, là je passe la main. Mon mediacenter n'héberge pas de serveur DNS, de routeur ou autre machine bizarre.
Je vous conseille le site de netfilter (dégager vous du temps si vous comptez lire toute la doc). Le wiki de Archlinux propose une configuration pour routeur.

Conclusion

Créer des règles, comme je le fait, est assez simple et ne mange pas de pain. Donc pensez-y.
Je rappelle que je fais de la sécurité réseau comme passe temps (entre 2 run de VTT) et donc en tant que non expert je peux être limite sur certains sujet, se renseigner ailleurs (même ailleurs de ce ailleurs) est une bonne pratique.

Sources:

3 commentaires:

  1. Tout ça c'est utile si tu as placé ton serveur dans une DMZ ou alors que tu veux te protéger de tes attaques sur ton réseau local...
    Si tu n'utilises qu'un seul port (ou 2 ou 3) sur ton serveur, alors utilise le firewall de ton routeur qui sera aussi efficace (PAT) pour te protéger des attaques extérieures ! Si tu places ton serveur dans une DMZ, alors je te conseille de commencer par sécuriser ton serveur (iptables, très bon choix) avant de faire du développement dessus. Tu peux également faire des règles pour ne donner accès à tous les ports qu'à ton réseau local.
    Et on ne parle pas encore des accès VPN :-)...

    RépondreSupprimer
    Réponses
    1. Le routeur de ma box est pourri (dans le sens où je ne peux presque rien configurer) et d'un point de vu pédagogique je trouve plus intéressant de protéger mon serveur et donc d'utiliser iptables.
      Le but final étant d'utiliser fail2ban et autres pour lutter contre les attaques répétitives sur les urls.
      Le vpn plus tard, quand j'aurais réglé mes problèmes de clés pour certificats lighttpd, ssh, git, ...

      Supprimer
  2. Le routeur de ta box doit certainement faire du PAT, et c'est exactement ce que tu expliques ! Même si tu ne peux pas faire beaucoup de config, tu as cette possibilité et tu devrais commencer par l'utiliser car elle est très efficace. Rien ne t'empêche d'ajouter une autre sécurité sur ton serveur par la suite :-)

    RépondreSupprimer