Debian 9 Stretch: sécuriser votre serveur avec le firewall iptables
dim, 07/09/2017 - 11:34 — geek17Introduction
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
- https://gist.github.com/jirutka/3742890
- https://debian-facile.org/doc:reseau:iptables-pare-feu-pour-un-client
- https://help.ubuntu.com/community/IptablesHowTo
- https://www.cyberciti.biz/tips/linux-iptables-10-how-to-block-common-attack.html
- https://www.digitalocean.com/community/tutorials/how-to-set-up-a-basic-iptables-firewall-on-centos-6