Add new comment

Debian 9 Stretch: sécuriser votre serveur avec le firewall iptables

Introduction

iptables est une interface qui permet de configurer le firewall interne de votre Debian.

La commande iptables -L vous permet d'afficher la configuration IP V4 de votre serveur

sudo iptables -L

Cette configuration par défaut ne filtre aucun traffic. Tout est authorisé : en entrée, en sortie et en transfert.

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

La commande ip6tables s'utilise de la même manière que iptables mais affiche les infos relatives à IP V6.

 

Garder votre config après un reboot

iptables fonctionne très bien mais son problème principal, c'est qu'après un reboot, toutes les règles sont perdues, il repart à 0.

Pour pouvoir définir des règles persistantes après un reboot, j'utilise le paquet iptables-persistent.
On commence donc par l'installer.

sudo apt-get install iptables-persistent

Pendant, l'installation du paquet, on vous est demande si vous souhaitez que les règles actuellement en cours d'utilisation soient enregistrées dans le fichier .

Répondez Oui, pour IP V4 comme pour IP V6.

 

Configuration des règles de votre firewall

Comme vous l'avez compris pendant l'installation, il a y 2 fichiers de config :

  • pour IP V4 c'est /etc/iptables/rules.v4
  • pour IP V6 c'est /etc/iptables/rules.v6

On va commencer par IP V6 pour lequel nous allons bloquer tout le trafic. On ouvre donc /etc/iptables/rules.v6

sudo nano /etc/iptables/rules.v6

La configuration par défaut est la suivante :

# Generated by iptables-save v1.6.0 on Sun Jul  9 15:04:15 2017
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT
# Completed on Sun Jul  9 15:04:15 2017

Et on va la remplacer par celle ci-dessous. J'ai juste remplacé ACCEPT par DROP sur les 3 traffcs réseau.

# Generated by ip6tables-save v1.6.0 on Sun Jul  9 15:04:15 2017
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
COMMIT
# Completed on Sun Jul  9 15:04:15 2017

 

Passons maintenant à IP V4

sudo nano /etc/iptables/rules.v4

Il a la même config par défaut que IP V6.

Dans la configuration que je vous propose :

  • je bloque tout le traffic transfert (FORWARD)
  • je laisse le traffic sortant non filtré
  • Je bloque le traffic entrant et j'applique des règles dessus

Et on édite notre configuration.
Vous pouvez bien sur l'adapter à vos besoins. J'ai commenté chaque ligne pour vous aider à comprendre

# Generated by iptables-save v1.6.0 on Sat Jul  8 16:56:03 2017
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [687:218631]

# Allow internal traffic on the loopback device
-A INPUT -i lo -j ACCEPT

# Continue connections that are already established or related to an established connection
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

# Drop non-conforming packets, such as malformed headers, etc.
-A INPUT -m conntrack --ctstate INVALID -j DROP

# SSH
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT

# DHCP used by OVH
-A INPUT -p udp --dport 67:68 --sport 67:68 -j ACCEPT

# DNS (bind)
-A OUTPUT -p tcp --dport 53 -j ACCEPT
-A OUTPUT -p udp --dport 53 -j ACCEPT

# HTTP + HTTPS
-A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT

# Email (postfix + devecot)
# 25 = smtp, 587 = submission and 993 = IMAPS
-A INPUT -p tcp -m multiport --dports 25,587,993 -j ACCEPT

# NTP
-A INPUT -p udp --dport 123 -j ACCEPT

# Chain for preventing ping flooding - up to 6 pings per second from a single
# source, again with log limiting. Also prevents us from ICMP REPLY flooding
# some victim when replying to ICMP ECHO from a spoofed source.
-N ICMPFLOOD
-A ICMPFLOOD -m recent --name ICMP --set --rsource
-A ICMPFLOOD -m recent --name ICMP --update --seconds 1 --hitcount 6 --rsource --rttl -m limit --limit 1/sec --limit-burst 1 -j LOG --log-prefix "iptables[ICMP-flood]: "
-A ICMPFLOOD -m recent --name ICMP --update --seconds 1 --hitcount 6 --rsource --rttl -j DROP
-A ICMPFLOOD -j ACCEPT

# Permit useful IMCP packet types.
# Note: RFC 792 states that all hosts MUST respond to ICMP ECHO requests.
# Blocking these can make diagnosing of even simple faults much more tricky.
# Real security lies in locking down and hardening all services, not by hiding.
-A INPUT -p icmp --icmp-type 0  -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -p icmp --icmp-type 3  -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -p icmp --icmp-type 8  -m conntrack --ctstate NEW -j ICMPFLOOD
-A INPUT -p icmp --icmp-type 11 -m conntrack --ctstate NEW -j ACCEPT

# Drop all incoming malformed NULL packets
-A INPUT -p tcp --tcp-flags ALL NONE -j DROP

# Drop syn-flood attack packets
-A INPUT -p tcp ! --syn -m conntrack --ctstate NEW -j DROP

# Drop incoming malformed XMAS packets
-A INPUT -p tcp --tcp-flags ALL ALL -j DROP

COMMIT
# Completed on Sat Jul  8 16:56:03 2017

Enfin, on redémarre le service pour recharger et appliquer nos règles.
Le service s'appele netfilter-persistent, pas iptables...

sudo service netfilter-persistent restart

Et on vérifie qu'elles ont bien été chargées.

sudo iptables -L

Ca donne

Chain INPUT (policy DROP)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
DROP       all  --  anywhere             anywhere             ctstate INVALID
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:ssh
ACCEPT     udp  --  anywhere             anywhere             udp spts:bootps:bootpc dpts:bootps:bootpc
ACCEPT     tcp  --  anywhere             anywhere             multiport dports http,https
ACCEPT     tcp  --  anywhere             anywhere             multiport dports smtp,submission,imaps
ACCEPT     udp  --  anywhere             anywhere             udp dpt:ntp
ACCEPT     icmp --  anywhere             anywhere             icmp echo-reply ctstate NEW
ACCEPT     icmp --  anywhere             anywhere             icmp destination-unreachable ctstate NEW
ICMPFLOOD  icmp --  anywhere             anywhere             icmp echo-request ctstate NEW
ACCEPT     icmp --  anywhere             anywhere             icmp time-exceeded ctstate NEW
DROP       tcp  --  anywhere             anywhere             tcp flags:FIN,SYN,RST,PSH,ACK,URG/NONE
DROP       tcp  --  anywhere             anywhere             tcp flags:!FIN,SYN,RST,ACK/SYN ctstate NEW
DROP       tcp  --  anywhere             anywhere             tcp flags:FIN,SYN,RST,PSH,ACK,URG/FIN,SYN,RST,PSH,ACK,URG

Chain FORWARD (policy DROP)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:domain
ACCEPT     udp  --  anywhere             anywhere             udp dpt:domain

Chain ICMPFLOOD (1 references)
target     prot opt source               destination
           all  --  anywhere             anywhere             recent: SET name: ICMP side: source mask: 255.255.255.255
LOG        all  --  anywhere             anywhere             recent: UPDATE seconds: 1 hit_count: 6 TTL-Match name: ICMP side: source mask: 255.255.255.255 limit: avg 1/sec burst 1 LOG level warning prefix "iptables[ICMP-flood]: "
DROP       all  --  anywhere             anywhere             recent: UPDATE seconds: 1 hit_count: 6 TTL-Match name: ICMP side: source mask: 255.255.255.255
ACCEPT     all  --  anywhere             anywhere

 

Sources

You must have Javascript enabled to use this form.