Cette procédure installe la consommation des blocklists sur un hôte Debian 13 à protéger. L’application centrale reste sur son serveur actuel. Aucun profil all n’est utilisé côté client.
| Profil | Ports filtrés | Ensembles IPv4 / IPv6 |
|---|---|---|
| SSH | TCP 22 | bl_ssh4 / bl_ssh6 |
| Web | TCP 80, 443 | bl_web4 / bl_web6 |
| Messagerie | TCP 25, 465, 587, 110, 995, 143, 993 | bl_mail4 / bl_mail6 |
Une IP présente uniquement dans le profil SSH est bloquée sur SSH, tout en conservant l’accès aux autres services selon les règles habituelles du pare-feu.
Toutes les commandes sont à exécuter en root sur l’hôte à protéger. Les règles concernent INPUT : les services locaux de l’hôte. Le trafic transféré vers des conteneurs Docker ou à travers un routeur nécessite une adaptation distincte. Ce guide suppose une gestion directe d’iptables ; ne pas le superposer sans adaptation à UFW, Shorewall ou un gestionnaire qui remplace les règles.
1. Préparer les publications centrales
Activer et publier les profils ssh, web et mail. Pour chacun, les deux représentations doivent être disponibles, même si elles sont vides :
https://blocklist.example.net/blocklists/ssh/ipv4.txt
https://blocklist.example.net/blocklists/ssh/ipv6.txt
https://blocklist.example.net/blocklists/web/ipv4.txt
https://blocklist.example.net/blocklists/web/ipv6.txt
https://blocklist.example.net/blocklists/mail/ipv4.txt
https://blocklist.example.net/blocklists/mail/ipv6.txt
Placer les adresses d’administration dans Never Block, puis régénérer les publications avant d’activer le filtrage.
Les reporters doivent préciser leurs services : un rapport sans service crée actuellement un blocage global, inclus dans les profils spécialisés. Vérifier les associations applications/services des profils, notamment les ports personnalisés. Le profil choisit les adresses ; les règles locales ci-dessous choisissent les ports effectivement bloqués.
Conserver la génération périodique sur le serveur central. Les clients téléchargent des instantanés publiés, pas directement les rapports.
2. Installer les dépendances
apt update
apt install -y python3 ca-certificates iptables ipset
iptables --version
ipset --version
Conserver le backend iptables existant ; cette procédure n’impose pas de passage à legacy.
3. Installer le synchroniseur
Depuis une copie du dépôt GitLab, adapter le chemin :
cd /chemin/ip-blocklist-manager/docs/blocklist-integration-readmes
install -d -m 0700 /etc/blocklist-sync /var/lib/blocklist-sync
install -m 0755 sync/blocklist-sync.py /usr/local/sbin/blocklist-sync.py
Le synchroniseur fourni est également téléchargeable dans les guides publics. Aucune clé API n’est nécessaire pour récupérer les publications.
4. Créer une configuration par profil
Remplacer le domaine dans la première ligne :
BLOCKLIST_URL="https://blocklist.example.net"
for profil in ssh web mail; do
cat > "/etc/blocklist-sync/${profil}.json" <<EOF
{
"base_url": "${BLOCKLIST_URL}",
"slug": "${profil}",
"backend": "ipset",
"state_dir": "/var/lib/blocklist-sync",
"timeout_seconds": 20,
"ipset_v4": "bl_${profil}4",
"ipset_v6": "bl_${profil}6"
}
EOF
chmod 0600 "/etc/blocklist-sync/${profil}.json"
done
Les caches peuvent partager le même dossier : leurs noms comportent le profil.
5. Préparer les ensembles au démarrage
cat > /usr/local/sbin/blocklist-multi-prepare <<'EOF'
#!/bin/sh
set -eu
PATH=/usr/sbin:/usr/bin:/sbin:/bin
export PATH
for profil in ssh web mail; do
ipset -exist create "bl_${profil}4" hash:net family inet maxelem 131072
ipset -exist create "bl_${profil}6" hash:net family inet6 maxelem 131072
# Forcer le téléchargement après démarrage : les ensembles sont volatils.
rm -f "/var/lib/blocklist-sync/${profil}-http.json"
done
EOF
chmod 0755 /usr/local/sbin/blocklist-multi-prepare
La suppression ciblée des métadonnées ETag contourne une limite du script actuel : si les deux réponses sont 304, il n’applique pas les listes. Après un redémarrage, des ensembles vides doivent donc être remplis par un nouveau téléchargement.
6. Installer les règles par port
Adapter le port SSH et les ports de messagerie aux services réellement utilisés. Les règles sont ajoutées seulement si elles n’existent pas déjà.
cat > /usr/local/sbin/blocklist-multi-rules <<'EOF'
#!/bin/sh
set -eu
PATH=/usr/sbin:/usr/bin:/sbin:/bin
export PATH
ensure_rule() {
tool="$1"
shift
"$tool" -w -C INPUT "$@" 2>/dev/null ||
"$tool" -w -I INPUT 1 "$@"
}
# SSH.
ensure_rule iptables -p tcp --dport 22 \
-m set --match-set bl_ssh4 src -j DROP
ensure_rule ip6tables -p tcp --dport 22 \
-m set --match-set bl_ssh6 src -j DROP
# Web.
ensure_rule iptables -p tcp -m multiport --dports 80,443 \
-m set --match-set bl_web4 src -j DROP
ensure_rule ip6tables -p tcp -m multiport --dports 80,443 \
-m set --match-set bl_web6 src -j DROP
# Messagerie.
ensure_rule iptables -p tcp -m multiport --dports 25,465,587,110,995,143,993 \
-m set --match-set bl_mail4 src -j DROP
ensure_rule ip6tables -p tcp -m multiport --dports 25,465,587,110,995,143,993 \
-m set --match-set bl_mail6 src -j DROP
# Décommenter si HTTP/3 est utilisé :
# ensure_rule iptables -p udp --dport 443 \
# -m set --match-set bl_web4 src -j DROP
# ensure_rule ip6tables -p udp --dport 443 \
# -m set --match-set bl_web6 src -j DROP
EOF
chmod 0755 /usr/local/sbin/blocklist-multi-rules
Ces règles ajoutent du blocage ; elles n’ouvrent aucun port. Les règles habituelles d’autorisation restent nécessaires. Placées en tête de INPUT, elles s’appliquent également aux connexions déjà établies provenant d’une adresse listée.
7. Installer le service de préparation
cat > /etc/systemd/system/blocklist-multi-prepare.service <<'EOF'
[Unit]
Description=Prepare multi-service blocklists and iptables rules
After=netfilter-persistent.service
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/blocklist-multi-prepare
ExecStart=/usr/local/sbin/blocklist-multi-rules
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
EOF
Ce service recrée les ensembles et les règles à chaque démarrage. Ne pas enregistrer ces nouvelles règles dans iptables-persistent avec cette procédure : leur création est assurée par ce service, après création des ensembles.
Si un autre outil recharge ensuite le pare-feu et supprime ces règles, les réappliquer avec /usr/local/sbin/blocklist-multi-rules.
8. Installer le service et le timer par profil
cat > /etc/systemd/system/blocklist-sync@.service <<'EOF'
[Unit]
Description=Synchronize blocklist profile %i
Wants=network-online.target
Requires=blocklist-multi-prepare.service
After=network-online.target blocklist-multi-prepare.service
[Service]
Type=oneshot
User=root
Group=root
Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ExecStart=/usr/local/sbin/blocklist-sync.py --config /etc/blocklist-sync/%i.json
TimeoutStartSec=5min
NoNewPrivileges=true
PrivateTmp=true
ProtectHome=true
ProtectSystem=strict
ReadWritePaths=/var/lib/blocklist-sync /run
EOF
cat > /etc/systemd/system/blocklist-sync@.timer <<'EOF'
[Unit]
Description=Periodically synchronize blocklist profile %i
[Timer]
OnBootSec=30s
OnUnitActiveSec=5min
RandomizedDelaySec=30s
Unit=blocklist-sync@%i.service
[Install]
WantedBy=timers.target
EOF
Les trois instances possèdent chacune leur configuration, leurs ensembles et leur cache. Utiliser systemd pour les lancements manuels également, afin d’éviter deux synchronisations concurrentes du même profil.
9. Activer et tester
systemctl daemon-reload
systemctl enable --now blocklist-multi-prepare.service
systemctl start blocklist-sync@ssh.service
systemctl start blocklist-sync@web.service
systemctl start blocklist-sync@mail.service
journalctl \
-u blocklist-sync@ssh.service \
-u blocklist-sync@web.service \
-u blocklist-sync@mail.service \
-n 60 --no-pager
Après vérification des premières synchronisations :
systemctl enable --now \
blocklist-sync@ssh.timer \
blocklist-sync@web.timer \
blocklist-sync@mail.timer
La revalidation a lieu environ toutes les cinq minutes, avec un délai aléatoire supplémentaire pouvant atteindre trente secondes.
10. Retirer l’ancienne intégration all, si elle était installée
Exécuter cette section uniquement si les services et règles proviennent de la précédente procédure avec blocklist4 et blocklist6. Valider d’abord les trois nouvelles synchronisations.
systemctl disable --now blocklist-sync.timer
systemctl stop blocklist-sync.service
systemctl disable --now blocklist-iptables.service
systemctl disable --now blocklist-ipset-prepare.service
while iptables -w -C INPUT -m set --match-set blocklist4 src -j DROP 2>/dev/null; do
iptables -w -D INPUT -m set --match-set blocklist4 src -j DROP
done
while ip6tables -w -C INPUT -m set --match-set blocklist6 src -j DROP 2>/dev/null; do
ip6tables -w -D INPUT -m set --match-set blocklist6 src -j DROP
done
Si ces anciennes règles étaient aussi enregistrées dans /etc/iptables/rules.v4 et rules.v6, retirer leurs lignes dans ces fichiers. Sinon, elles reviendront au redémarrage et continueront à bloquer tous les ports.
11. Vérifications courantes
for profil in ssh web mail; do
ipset list "bl_${profil}4" -terse
ipset list "bl_${profil}6" -terse
done
iptables -L INPUT -n -v --line-numbers
ip6tables -L INPUT -n -v --line-numbers
systemctl list-timers 'blocklist-sync@*.timer'
Actualiser les trois profils immédiatement :
systemctl start \
blocklist-sync@ssh.service \
blocklist-sync@web.service \
blocklist-sync@mail.service
Tester l’appartenance d’une adresse (remplacer l’exemple par une adresse connue de la publication) :
ipset test bl_ssh4 203.0.113.42
Après un redémarrage planifié, vérifier de nouveau les ensembles, les règles, les timers et les journaux.
12. Limites et diagnostic
- Le script fourni accepte au maximum 100 000 entrées par famille et par profil, et 8 Mio par fichier. Au-delà, adapter les limites du synchroniseur et la capacité des ensembles actifs et temporaires ; changer seulement
maxelemdans le script de préparation ne suffit pas. - Les préfixes
/0sont refusés par le backend ipsethash:net. - Chaque ensemble est remplacé par
ipset swap. IPv4 et IPv6 sont appliqués séparément : une erreur lors de la seconde bascule peut laisser les familles sur des versions différentes. - Un échec de téléchargement ou de validation conserve les ensembles actifs. Après redémarrage, ils sont cependant vides jusqu’à la première synchronisation réussie : cette procédure ne restaure pas de liste hors ligne.
- Une liste vide publiée avec HTTP 200 est valide et vide l’ensemble correspondant lors de son application.
- Une erreur 404 indique généralement un profil non publié ; vérifier la génération sur le serveur central.
- Le filtre local ne retire pas de lui-même une adresse à l’expiration des 12 heures : le serveur central doit republier la liste, puis le client la synchroniser.
- Aucun test d’installation complet n’a été exécuté sur un hôte Debian 13 pour ce document.