@metyun, merci pour cette réponse.
Je ne suis pas un expert d’iptables
, j’ai seulement quelques bases. (Je ne connais pas du tout le fonctionnement des modules)
Avec iptables
il est possible de faire des règles de traitement des paquets relativement fines.
Par exemple si je souhaite que les paquets en provenance de la plage d’adresse 1.0.0.0/24
, qui utilise le protocole tcp
et à destination du port 22
ne soient pas traité :
# Ajoute la régle
iptables -I INPUT -s 1.0.0.0/24 -p tcp --dport 22 -j DROP
Attention : Si on exécute deux fois cette commande, cela ajoute deux fois la même règle.
Détails :
-
-I : Insert dans la liste ici INPUT
-
-s : Source du paquet ip ou cidr ici cidr
-
-p : Protocole tcp, udp, etc ici tcp car ssh, port 22, utilise du tcp
-
–dport : Port de destination ici 22
-
-j : Traitement du paquet qui correspond aux règles de filtrage ici DROP juste on jette le paquet
# Supprime la régle
iptables -D INPUT -s 1.0.0.0/24 -p tcp --dport 22 -j DROP
Je me suis amusé à faire un script pour créer ou supprimer les règles de blocage par pays.
Attention : ce script ne devrait pas être utilisé si vous ne comprenez pas ce qu’il fait (comme tous les scripts que l’on trouve au hasard des forums) et surement pas sur une machine en production 
De plus, comme @ljf l’a déjà dit sur le post 21 :
Script
#!/bin/bash -e
# Bloque/unbloque les requêtes selon le pays et le port avec iptables
# 2022-04-30 creation
action=$1
pays=$2
port=$3
# Recup les ips du pays
function get_ips_pays {
pays=$1
url="http://www.ipdeny.com/ipblocks/data/aggregated/${pays,,}-aggregated.zone"
dest=/tmp/${pays,,}.zone
wget -q $url -O $dest
if [ $? == 0 ] ; then
pays=$dest
else
echo "ERR: get $url"
exit 1
fi
}
# Deux action possible (block/unblock)
function check_action {
action=$1
if [ ${action,,} == "block" ] ; then
action=" -I INPUT "
elif [ ${action,,} == "unblock" ] ; then
action=" -D INPUT "
else
echo "ERR: action is block or unblock"
exit 1
fi
}
# Verif le port
function check_port {
port=$1
if [ $port -ge 1 ] && [ $port -le 65535 ] ; then
port=" --dport $port "
else
echo "ERR: port in range 1-65535"
exit 1
fi
}
function help {
echo "geo_block.sh ACTION PAYS PORT"
echo
echo " ACTION block or unblock"
echo " PAYS code pays (cn, au, fr, ...)"
echo " PORT number port destination in 1-65535"
echo
echo "example: geo_block.sh block cn 22"
}
# main
if [ "$EUID" -ne 0 ] ; then
echo "Please run as root"
fi
if [ $# != 3 ] ; then
help
else
check_action "$action"
check_port "$port"
get_ips_pays "$pays"
for ip in $(cat $pays) ; do
iptables $action -s $ip -p tcp $port -j DROP
done
fi
exit 0
Exemple d’utilisation :
-
bash geo_block.sh block cn 22
→ bloque les ips de chine pour le port 22
-
bash geo_block.sh unblock cn 22
→ débloque les ips de chine pour le port 22
J’ai fait des tests sur une VM de test cela fonctionne, mais il y a encore des point à améliorer par exemple pouvoir spécifier plusieurs ports à bloquer.
Note : Sur ma machine de test le unblock
était relativement long…
Si vous avez de retour, avis ou suggestion à faire je suis preneur