Iptables
De Banane Atomic
Aller à la navigationAller à la recherche
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 |
set -u set -e set -o pipefail DATABASE=badips.db INTERFACE=eth0 CHAIN=BADIPS cd /tmp # Get the bad IPs wget -qO- http://www.badips.com/get/list/any/5 > ${DATABASE} || { echo "$0: Unable to download ip list."; exit 1; } # Ajout de la chain BADIPS si elle n'existe pas set +e $(iptables -S ${CHAIN} >/dev/null 2>&1) ok=$? set -e if [[ ${ok} -ne 0 ]]; then iptables -N ${CHAIN} fi # Flush the previous rules iptables -F ${CHAIN} # Append everything to $CHAIN for IP in $(cat ${DATABASE}) do $(iptables -A ${CHAIN} -s ${IP} -j DROP) done # ajoute le filtrage des ips si la règle n'existe pas set +e $(iptables -C INPUT -i ${INTERFACE} -j ${CHAIN} >/dev/null 2>&1) ok=$? set -e if [[ ${ok} -ne 0 ]]; then iptables -I INPUT 5 -i ${INTERFACE} -j ${CHAIN} fi # supprime le fichier rm -f ${DATABASE} exit 0 |