Iptables
Apparence
Règles recommandées
# par défaut, droper les paquets qui ne sont pas à destination de l'hôte
iptables -P FORWARD DROP
# par défaut, autoriser les paquets sortants
iptables -P OUTPUT ACCEPT
# par défaut, droper les paquets entrants
iptables -P INPUT DROP
# autorise les paquets des connexions déjà établies ou les paquets de nouvelles connexions liées à celles déjà établies
iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
# autorise les packet de l'interface lo (loopback)
iptables -A INPUT -i lo -j ACCEPT
# dropper le trafic dont l'état est INVALID
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
# autorise les requêtes echo ICMP (ping)
iptables -A INPUT -p icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT
|
![]() |
Les règles sont appliquées dans l'ordre dans lesquelles elles sont écrites. La première correspondance est appliquée. |
TCP et UDP
# créer les chain TCP et UDP
iptables -N TCP
iptables -N UDP
# jumper les nouvelles connexions udp vers la chain UDP
iptables -A INPUT -p udp -m conntrack --ctstate NEW -j UDP
# jumper les nouvelles (mais pas SYN) connexions tcp vers la chain TCP
iptables -A INPUT -p tcp --syn -m conntrack --ctstate NEW -j TCP
# logger le reste (ce qui va être rejeté)
iptables -I INPUT 7 -m limit --limit 2/min -j LOG --log-prefix "iptables:INPUT:REJECT: " --log-level 4
# rejeter ce qui n'a pas été jumpé vers TCP et UDP
iptables -A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset
# rejeter les autres protocoles
iptables -A INPUT -j REJECT --reject-with icmp-proto-unreachable
# ouvrir les ports utilisés
# serveur HTTP et HTTPS
iptables -A TCP -p tcp --dport 80 -j ACCEPT
iptables -A TCP -p tcp --dport 443 -j ACCEPT
# serveur SSH
iptables -A TCP -p tcp --dport 22 -j ACCEPT -s 192.168.0.0/24
# serveur Postfix
iptables -A TCP -p tcp --dport 25 -j ACCEPT
# serveur DNS
iptables -A UDP -p udp -s 192.168.0.0/24 --dport 53 -j ACCEPT
# serveur DHCP
iptables -I UDP -i eth0 -p udp -s 192.168.0.0/24 --dport 67:68 --sport 67:68 -j ACCEPT
|
ipv6
# par défaut, droper tous les paquets
ip6tables -P FORWARD DROP
ip6tables -P INPUT DROP
# ip6tables -P OUTPUT DROP
# message d'erreur avec dig: net.c:592: sendmsg() failed: Operation not permitted
# sauvegarder la configuration
ip6tables-save > /etc/iptables/ip6tables.rules
# démarrer le service au démarrage
systemctl enable ip6tables
|
![]() |
Commenter les lignes référençant les ipv6 dans /etc/hosts |
VPN server
# port UDP
iptables -A UDP -i eth0 -p udp --dport 1194 -j ACCEPT -m comment --comment "VPN"
# FORWARD
iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -m comment --comment "VPN"
iptables -A FORWARD -i tun0 -o eth0 -s 10.8.0.0/24 -d 192.168.0.0/24 -m conntrack --ctstate NEW -j ACCEPT -m comment --comment "VPN"
# retirer -d 192.168.0.0/24 pour permettre aux clients l'accès à internet
# NAT
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE -m comment --comment "VPN"
# iptables -t nat -nvL --line-numbers
# DNS
iptables -A UDP -p udp -s 10.8.0.0/24 --dport 53 -j ACCEPT -m comment --comment "DNS pour VPN"
|
Log
# tous les éléments entrant ne provenant pas de 192.168.0.x
iptables -I INPUT 1 -j LOG ! -s 192.168.0.x
# créer une nouvelle chain
iptables -N LOGGING
# inscrire dans le log (journalctl) tous les packet passant par LOGGING
iptables -A LOGGING -j LOG --log-prefix "IPTables-LOGGING: " --log-level 5
# log-level: 0 - Emergency, 1 - Alerts, 2 - Critical, 3 - Errors, 4 - Warnings, 5 - Notification, 6 - Information, 7 - Debug
# rediriger tous les packets entrants et sortants vers LOGGING
iptables -A INPUT -j LOGGING
iptables -A OUTPUT -j LOGGING
|
Loguer seulement les paquets droppés
iptables -N LOGDROP
# tous les packet passant par LOGDROP sont logués dans la limite de 10 puis de 5 par minute
iptables -A LOGDROP -m limit --limit 5/m --limit-burst 10 -j LOG
# tous les packet passant par LOGDROP sont droppés
iptables -A LOGDROP -j DROP
# jumper les paquets vers LOGDROP les log puis les drop
iptables -A INPUT -s x.x.x.x -j LOGDROP
|
Commandes
Lister les règles existantes
# lister toutes les chaînes et toutes les règles
iptables -nvL --line-numbers
# -n afficher les adresses ip plutôt que les noms d'hôte
# -v plus de détails (pkts, bytes, in, out)
# --line-numbers les numéros des règles
# lister les règles d'une chaîne donnée
iptables -nvL [chain] --line-numbers
|
Chaînes
# ajouter une chaîne
iptables -N [new-chain]
# supprimer une chaîne vide créée par un utilisateur
iptables -X [chain]
# définir la politique par défaut d'une chaîne
iptables -P [chain] [ACCEPT ou DROP]
# iptables -P INPUT DROP
|
Règles
# ajouter une règle à la fin (Append)
iptables -A [chain] [rule]
# iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# insérer une règle au numéro spécifié, 1 par défaut
iptables -I [chain] [rule_number] [rule]
# iptables -I INPUT 1 -p tcp --dport 80 -j ACCEPT
# supprimer une règle par son numéro
iptables -D [chain] [rule_number]
# iptables -D INPUT 1
# supprimer une règle par correspondance
iptables -D [chain] [rule]
# supprimer toutes les règles de la chaîne spécifiée
iptables -F [chain]
# supprimer toutes les règles (Flush)
iptables -F
# modifier une règle
iptables -R [chain] [rule_number] [règle complète modifiée]
# remettre à 0 les compteurs
iptables -LZ [chain [rule_number]]
# tester si une règle existe déjà
iptables -C [chain] [rule]
# if [[ $? -ne 0 ]]; then [la règle n'existe pas];fi
|
Écriture des règles
# protocol (tcp, udp, icmp)
iptables -A INPUT -p tcp ...
# port de destination (pour tcp et udp)
iptables -A INPUT -p tcp --dport xxxx
# adresse ip de l'expéditeur
iptables -A INPUT -s x.x.x.x ...
iptables -A INPUT -m iprange --src-range x.x.x.0-x.x.x.255 ...
# adresse ip du destinataire
iptables -A INPUT -d x.x.x.x ...
# interface réseau d'entrée
iptables -A INPUT -i [interface] ...
# interface réseau de sortie
iptables -A OUTPUT -o [interface] ...
# état de la connexion
iptables -A INPUT -m conntrack --ctstate [state]
iptables -A INPUT -m state --state [state] # (remplacé par conntrack)
# INVALID le paquet n'est associé à aucune connexion
# NEW le paquet démarre une nouvelle connexion
# ESTABLISHED le paquet appartient à une connexion déjà existante
# RELATED le paquet démarre une nouvelle connexion et appartient à une connexion déjà existante
# commentaires
iptables -A INPUT ... -m comment --comment "mon commentaire"
|
jump
# autorise les paquets correspondant à la règle
iptables -A INPUT [rule] -j ACCEPT
# bloque les paquets correspondant à la règle
iptables -A INPUT [rule] -j DROP
# bloque les paquets correspondant à la règle et envoie un message d'erreur à l'expéditeur
iptables -A INPUT [rule] -j REJECT
# « --reject-with tcp-reset » permet de demander à l'expéditeur de fermer la connexion tcp
# « --reject-with icmp-port-unreachable »
# « --reject-with icmp-proto-unreachable »
|
![]() |
DROP devrait être utilisé pour les expéditeurs qui ne devraient pas connaître l’existence du serveur et à l'inverse REJECT devrait être utilisé pour les expéditeurs qui connaissent l’existence du serveur. |
Fichier de configuration
# après avoir utiliser la ligne de commandes pour modifier la configuration d'iptables
# il faut enregistrer ces modifications pour quelles puissent être chargée au démarrage du service
iptables-save > /etc/iptables/iptables.rules
# restaurer la configuration du fichier iptables.rules
iptables-restore < /etc/iptables/iptables.rules
# recharger les règles du fichier de configuration au cas ou le fichier aurait été modifié
systemctl reload iptables
|
Mangle table
Mark packets.
iptables -t mangle -A OUTPUT -j CONNMARK --restore-mark
# mark packet sent by [user]
iptables -t mangle -A OUTPUT ! --dest [local-ip] -m owner --uid-owner [user] -j MARK --set-mark 1
iptables -t mangle -A OUTPUT -j CONNMARK --save-mark
# flush the mangle table
iptables -F -t mangle
|
Service
# lit le fichier de configuration et charge les règles
systemctl start iptables
# lit le fichier de configuration et charge les règles au démarrage
systemctl enable iptables
|
Ban IPs with ipsum
# install ipset and ipset-persistent
ai ipset ipset-persistent
# create a set of IPs
sudo ipset create ipsum hash:ip
# add an iptables rule to drop all communications from the IPs in the ipsum set
iptables -I INPUT -m set --match-set ipsum src -j DROP
# list the ipsets
sudo ipset -n list
# list the ipsets with their content
sudo ipset list
# list the content of a specific ipset
sudo ipset list [SETNAME]
|
![]() |
Make it work with UFW |
/root/scripts/ban-ipsum.sh |
# create a cron script to load the list of IPs to ban
# flush all entries of the ipsum set
ipset -q flush ipsum
# add the IPs to the ipsum set
for ip in $(curl --compressed https://raw.githubusercontent.com/stamparm/ipsum/master/ipsum.txt 2>/dev/null \
| grep -v "#" | grep -v -E "\s[1-2]$" | cut -f 1); do ipset add ipsum $ip; done
# save the banned ips to /etc/iptables/ipsets so they will be ban again on startup thanks to ipset.service
netfilter-persistent save
|
![]() |
ipset-persistent package installs:
|
Bad IP
badips.sh |