IPtables/IPset : accès ports/services selon IP, protections diverses et blocage IP chinoises (NORACISM)

Chine 15 mars 2016

J’en ai un peu marre de me prendre des scans d’IP chinoises. Ça affole certaines de mes machines et je me retrouve souvent bombardé d’emails d’alerte pour le coup inutiles. Reports que je ne veux pas annuler vu que “on ne sait jamais”.

Donc je viens de mettre en place un truc radical pour peu que ça ne concerne pas une machine devant être accessible aux IP chinoises : le filtrage et DROP pur et simple des IP en question.

Ça se fait en 3 étapes :

  1. Récupération d’une liste à jour sur http://www.ipdeny.com/,
  2. Mise à jour dans la foulée des règles IPtables (IPv4 en l’occurrence),
  3. Mise en cron du script de MàJ IPset + règles IPtables.

Au passage j’ai ajouté un filtrage par IP (source) pour des services/ports et quelques règles de protection diverses. Le script est à télécharger ici et il sera expliquer juste après.

Je ne filtre rien en sortie, toutes les connexions Serveur -> Internet sont actives et libres. Ceci est pour un serveur dédié, sur VPS il faut ajouter des règles pour l’interface virtuelle et il se peut qu’IPtables ne soit pas à jour (et ne puisse pas l’être). Dans ce cas il convient de remplacer -m conntrack par -m state et --ctstate par --state.

 

ATTENTION : le filtrage du port SSH par IP est à vos risques et périls. Si l’IP en question ne vous est pas/plus accessible pour X raison alors vous ne pourrez plus vous connecter en SSH (donc mode rescue chez votre hébergeur et faire sauter les règles IPtables ou les modifier en conséquence). Si vous mettez une IP de VPN non personnel gardez-bien à l’esprit que tous ceux ayant accès à ce VPN pourront alors tenter de se connecter en SSH à votre machine. Idem si vous filtrez un port de serveur Web ou FTP/ZNC/rutorrent/sickrage/etc.

Dans ce tutoriel je prends l’exemple d’un serveur ProxMox (basé sur Debian) personnel auquel je suis le seul à avoir un accès (pour la machine hôte). Et vu ma configuration ProxMox ces règles IPtables ne s’appliquent bien qu’à la machine hôte et en aucun cas aux VM. Pour protéger vos VM sur ProxMox vous pouvez soit monter une VM firewall (PFsense/IPcop) qui va gérer les autres soit manipuler vous-mêmes IPtables sur chaque VM.

 

 

Création des règles IPtables

sudo nano /etc/iptables.firewall.rules

Et y copier/coller ces règles  (ou les prendre ici), en les mettant à jour selon votre config (IP, ports)

*filter

# Purge des regles IPtables
-F
-X


# Regles de base
# Autorisation de tout trafic sortant
 -P OUTPUT ACCEPT
# Autorisation forward
-P FORWARD ACCEPT
# Rejeter tout le trafic entrant sauf règles qui suivent
 -P INPUT DROP
# Autorisation des connexions entrantes deja etablies 
 -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Autorisation des connexions internes (loopback)
 -A INPUT -i lo -j ACCEPT


# Autorisations entrantes des services
# SSH / autorisation IP VPN 1
-I INPUT -p tcp -s xx.xx.xx.xx --dport yyy -j ACCEPT
# SSH / autorisation IP VPN 3
-I INPUT -p tcp -s xx.xx.xx.xx --dport yyy -j ACCEPT
# SSH / autorisation IP FAI 94 ligne 2
-I INPUT -p tcp -s xx.xx.xx.xx --dport yyy -j ACCEPT
# Interace Web de gestion ProxMox selon IP VPN personnel 1
-I INPUT -p tcp -s xx.xx.xx.xx --dport 8006 -j ACCEPT
# Backup via FTP - Ouvrir si besoin
# -I INPUT -p tcp --dport 21 -j ACCEPT
# Backup via Rsync
-I INPUT -p tcp -s xx.xx.xx.xx --dport 824 -j ACCEPT
# Serveurs Web
# -I INPUT -p tcp --dport 80 -j ACCEPT
-I INPUT -p tcp -s xx.xx.xx.xx --dport 443 -j ACCEPT


# Regles de protection + logs
# DROP paquets autres que SYN
-A INPUT -p tcp ! --syn -m conntrack --ctstate NEW -j DROP
# DROP paquets invalides
-A INPUT -m conntrack --ctstate INVALID -j DROP
# DROP paquets incomplets
-A INPUT -f -j DROP
# DROP NULL
-A INPUT -p tcp --tcp-flags ALL NONE -j DROP
# DROP XMAS
-A INPUT -p tcp --tcp-flags ALL ALL -j DROP
# DROP SYNFIN
-A INPUT -p tcp --tcp-flags ALL SYN,FIN -j DROP
# DROP FIN scan
-A INPUT -p tcp --tcp-flags ALL FIN -j DROP
# DROP SYN RST
-A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
# DROP NMAP XMAS
-A INPUT -p tcp --tcp-flags ALL URG,PSH,FIN -j DROP
# DROP NMAP 
-A INPUT -p tcp --tcp-flags ALL URG,PSH,SYN,FIN -j DROP
# DROP SYN FLOOD
-N SYN-FLOOD
-A SYN-FLOOD -m limit --limit 1/sec --limit-burst 4 -j RETURN
-A SYN-FLOOD -j DROP
# DROP port scans
-N PORT-SCAN
-A INPUT -p tcp --tcp-flags SYN,ACK,FIN,RST RST -j PORT-SCAN
-A PORT-SCAN -m limit --limit 1/s --limit-burst 4 -j RETURN
-A PORT-SCAN -j DROP
# Blocage IP attaque 24h
-A INPUT -m recent --name DUMBASS --rcheck --seconds 86400 -j DROP
-A FORWARD -m recent --name DUMBASS --rcheck --seconds 86400 -j DROP
# Levee du blocage
-A INPUT -m recent --name DUMBASS --remove
-A FORWARD -m recent --name DUMBASS --remove
# Blocage de toute IP chinoise (#NORACISM)
-A INPUT -p tcp -m set --match-set chine src -j DROP


# Logging des paquets entrants droppes
-N LOGGING
-A INPUT -j LOGGING
-A LOGGING -m limit --limit 3/min -j LOG --log-prefix "IPtables_DROP: " --log-level 7
-A LOGGING -j DROP


COMMIT

Puis on les sauvegarde (vous aurez une erreur du fait qu’on n’a pas encore paramétré les IP à bloquer “chine”)

sudo iptables-restore < /etc/iptables.firewall.rules

 

 

Modifier les règles IPtables

Pour autoriser une connexion entrante sur le port 1234 en TCP

-I INPUT -p tcp --dport 1234 -j ACCEPT

Pour autoriser une connexion entrante sur le port 1234 en UDP

-I INPUT -p udp --dport 1234 -j ACCEPT

Pour autoriser une connexion entrante sur le port 1234 en TCP avec filtre d’IP (connexion depuis XX.XX.XX.XX seulement)

-I INPUT -p tcp -s XX.XX.XX.XX --dport 1234 -j ACCEPT

 

 

Blocage des IP chinoises (ou autres)

Pour ça on utilise IPset qui permet de bloquer des IP dans IPtables et les listes du site ipdeny.com. S’il n’est pas installé

sudo apt-get install ipset

Ensuite nous créons un script qui permettra télécharger puis transmettre à IPset la liste d’IP à bloquer

sudo nano /etc/deny-china.sh

Détails :

  • Création de la liste “chine”
  • Suppression de l’ancienne liste (dans le cadre de la MàJ auto journalière)
  • Récupération de la liste
  • Transcription du fichier pour IPset
  • Rechargement des règles IPtables avec cette nouvelle liste
# Creation de liste ipset du nom 'chine'
ipset -N chine hash:net

# Suppression de l'ancienne liste
rm /etc/cn.zone

# Recuperation de la liste pour la Chine
wget -P . http://www.ipdeny.com/ipblocks/data/countries/cn.zone

# Ajout de chaque IP de la liste telechargee dans la liste ipset 'chine'
for i in $(cat /etc/cn.zone ); do ipset -A chine $i; done

# Restauration iptables
/sbin/iptables-restore < /etc/iptables.firewall.rules

On rend ce script exécutable

chmod +x /etc/deny-china.sh

Et on le lance manuellement avant ensuite de le mettre en cron pour qu’il s’exécute tous les jours

/etc/deny-china.sh

Ajout en cron

sudo crontab -e

Et on ajoute à la fin (MàJ à 1h du matin chaque jour)

* 1 * * * /etc/deny-china.sh

 

 

Activer les règles IPtables et les rendre persistantes

sudo iptables-restore < /etc/iptables.firewall.rules

 

Puis les activer en cas de reboot de la machine. Pour ça il y a plusieurs solutions dont

 – On place un script qui lancera nos règles IPtables après chaque démarrage de l’interface réseau

sudo nano /etc/network/if-pre-up.d/firewall

 – On y place notre script de lancement des règles et on sauvegarde

#!/bin/sh
/sbin/iptables-restore < /etc/iptables.firewall.rules

 – Et enfin on le rend exécutable

sudo chmod +x /etc/network/if-pre-up.d/firewall

 OU

sudo apt-get install iptables-persistent

 

 

Vérifier les règles chargées

iptables -L -v

Chain INPUT (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     tcp  --  any    any     XX.XX.XX.XX  anywhere             tcp dpt:https
    0     0 ACCEPT     tcp  --  any    any     XX.XX.XX.XX  anywhere             tcp dpt:8006
  201 13472 ACCEPT     tcp  --  any    any     XX.XX.XX.XX  anywhere             tcp dpt:XXX
   16  6234 ACCEPT     all  --  any    any     anywhere             anywhere             ctstate RELATED,ESTABLISHED
    6   426 ACCEPT     all  --  lo     any     anywhere             anywhere            
    0     0 DROP       tcp  --  any    any     anywhere             anywhere             tcp flags:!FIN,SYN,RST,ACK/SYN ctstate NEW
    0     0 DROP       all  --  any    any     anywhere             anywhere             ctstate INVALID
    0     0 DROP       all  -f  any    any     anywhere             anywhere            
    0     0 DROP       tcp  --  any    any     anywhere             anywhere             tcp flags:FIN,SYN,RST,PSH,ACK,URG/NONE
    0     0 DROP       tcp  --  any    any     anywhere             anywhere             tcp flags:FIN,SYN,RST,PSH,ACK,URG/FIN,SYN,RST,PSH,ACK,URG
    0     0 DROP       tcp  --  any    any     anywhere             anywhere             tcp flags:FIN,SYN,RST,PSH,ACK,URG/FIN,SYN
    0     0 DROP       tcp  --  any    any     anywhere             anywhere             tcp flags:FIN,SYN,RST,PSH,ACK,URG/FIN
    0     0 DROP       tcp  --  any    any     anywhere             anywhere             tcp flags:SYN,RST/SYN,RST
    0     0 DROP       tcp  --  any    any     anywhere             anywhere             tcp flags:FIN,SYN,RST,PSH,ACK,URG/FIN,PSH,URG
    0     0 DROP       tcp  --  any    any     anywhere             anywhere             tcp flags:FIN,SYN,RST,PSH,ACK,URG/FIN,SYN,PSH,URG
    0     0 PORT-SCAN  tcp  --  any    any     anywhere             anywhere             tcp flags:FIN,SYN,RST,ACK/RST
    0     0 DROP       all  --  any    any     anywhere             anywhere             recent: CHECK seconds: 86400 name: DUMBASS side: source mask: 255.255.255.255
    0     0            all  --  any    any     anywhere             anywhere             recent: REMOVE name: DUMBASS side: source mask: 255.255.255.255
   15   752 DROP       tcp  --  any    any     anywhere             anywhere             match-set chine src
 1947 75731 LOGGING    all  --  any    any     anywhere             anywhere            

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       all  --  any    any     anywhere             anywhere             recent: CHECK seconds: 86400 name: DUMBASS side: source mask: 255.255.255.255
    0     0            all  --  any    any     anywhere             anywhere             recent: REMOVE name: DUMBASS side: source mask: 255.255.255.255

Chain OUTPUT (policy ACCEPT 1051 packets, 205K bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain LOGGING (1 references)
 pkts bytes target     prot opt in     out     source               destination         
  356 12084 LOG        all  --  any    any     anywhere             anywhere             limit: avg 3/min burst 5 LOG level debug prefix "IPtables_DROP: "
 1947 75731 DROP       all  --  any    any     anywhere             anywhere            

Chain PORT-SCAN (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 RETURN     all  --  any    any     anywhere             anywhere             limit: avg 1/sec burst 4
    0     0 DROP       all  --  any    any     anywhere             anywhere            

Chain SYN-FLOOD (0 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 RETURN     all  --  any    any     anywhere             anywhere             limit: avg 1/sec burst 4
    0     0 DROP       all  --  any    any     anywhere             anywhere   

 

 

Et pour voir les logs vous faites

grep -n IPtables_DROP /var/log/kern.log

Dedans vous pourrez avoir beaucoup de lignes, dont des IP qui reviennent fréquemment. Ce peut être le cas par exemples des IP de services de votre hébergeurs. Dans le cas d’OVH/SYS, par exemple, 167.114.37.1 & 92.222.185.1 qui correspondent à du monitoring OVH.

Pour les autoriser à pinguer votre machine (ICMP) et ne plus les avoir dans vos logs, ajoutez-les à vos règles IPtables :

-I INPUT -p icmp -s 167.114.37.1 -j ACCEPT
-I INPUT -p icmp -s 92.222.185.1 -j ACCEP

 

Mots clés