Ces intégrations utilisent ipset comme conteneur de réseaux, puis une règle de pare-feu unique référence le set.

Pour les systèmes modernes disposant de nftables natif, le guide nftables est généralement plus simple. ipset reste utile lorsque l'environnement existant repose sur iptables, UFW ou Shorewall.

1. Créer les sets

ipset -exist create blocklist4 hash:net family inet  maxelem 131072
ipset -exist create blocklist6 hash:net family inet6 maxelem 131072

Le type hash:net accepte des réseaux de tailles différentes et peut être référencé par les règles iptables.

Limite importante : /0

hash:net ne peut pas stocker un préfixe /0. Le synchroniseur fourni refuse donc une publication contenant 0.0.0.0/0 ou ::/0 au lieu de l'appliquer partiellement.

Si un profil peut légitimement publier un /0, utilisez le backend nftables.

2. Mise à jour atomique d'un set

Le synchroniseur ne fait pas :

ipset flush blocklist4
# puis des milliers de ipset add...

car cela créerait une fenêtre où la liste est vide.

Il prépare un set temporaire :

ipset create blocklist4_new hash:net family inet maxelem 131072
ipset add blocklist4_new 192.0.2.0/24
ipset add blocklist4_new 198.51.100.42/32
ipset swap blocklist4 blocklist4_new
ipset destroy blocklist4_new

ipset swap échange le contenu des deux sets compatibles sans devoir modifier la règle iptables qui référence blocklist4.

IPv4 et IPv6 sont basculés séparément : il peut donc exister un très court intervalle où les deux familles ne sont pas encore sur la même version. Si vous exigez une transaction multi-familles unique, préférez nftables.


iptables + ipset

3. Ajouter les règles

IPv4 :

iptables -C INPUT -m set --match-set blocklist4 src -j DROP 2>/dev/null || \
iptables -I INPUT 1 -m set --match-set blocklist4 src -j DROP

IPv6 :

ip6tables -C INPUT -m set --match-set blocklist6 src -j DROP 2>/dev/null || \
ip6tables -I INPUT 1 -m set --match-set blocklist6 src -j DROP

Pour un routeur, ajouter de la même manière des règles dans FORWARD si cela correspond à la politique voulue.

4. Configurer le synchroniseur

{
  "base_url": "https://blocklist.example.net",
  "slug": "all",
  "backend": "ipset",
  "state_dir": "/var/lib/blocklist-sync",
  "ipset_v4": "blocklist4",
  "ipset_v6": "blocklist6"
}

Tester :

/usr/local/sbin/blocklist-sync.py --config /etc/blocklist-sync/config.json --verbose
ipset list blocklist4
ipset list blocklist6

5. Persistance

Deux éléments doivent survivre au boot :

  1. les sets vides doivent exister avant que les règles qui les référencent soient chargées ;
  2. le timer de synchronisation les remplit ensuite depuis Phase 19.

Le fichier systemd/blocklist-ipset-prepare.service crée les sets vides. Adaptez le chemin de ipset avec :

command -v ipset

Puis :

install -m 0644 systemd/blocklist-ipset-prepare.service \
  /etc/systemd/system/blocklist-ipset-prepare.service
systemctl daemon-reload
systemctl enable --now blocklist-ipset-prepare.service

La persistance des règles iptables dépend de votre distribution (iptables-persistent, scripts réseau, etc.).


UFW + ipset

UFW permet de personnaliser ses règles « before ». Ces règles sont évaluées avant les règles ajoutées par la CLI UFW et utilisent la syntaxe iptables-restore.

6. Prérequis

Créer les sets avant un reload UFW :

ipset -exist create blocklist4 hash:net family inet  maxelem 131072
ipset -exist create blocklist6 hash:net family inet6 maxelem 131072

Activer le service de préparation ipset décrit plus haut pour le boot.

7. IPv4 — /etc/ufw/before.rules

Dans la section *filter, avant le COMMIT correspondant, ajouter :

-A ufw-before-input -m set --match-set blocklist4 src -j DROP

Exemple contextuel :

*filter
:ufw-before-input - [0:0]
# ... règles existantes ...
-A ufw-before-input -m set --match-set blocklist4 src -j DROP
COMMIT

Ne dupliquez pas les déclarations de chaînes existantes ; l'extrait montre seulement l'emplacement logique.

8. IPv6 — /etc/ufw/before6.rules

Dans la section *filter :

-A ufw6-before-input -m set --match-set blocklist6 src -j DROP

Le nom exact de la chaîne avant IPv6 doit être vérifié dans le fichier existant de votre distribution avant modification.

9. Recharger UFW

ufw reload
ufw status verbose

Les règles placées directement dans before.rules/before6.rules ne sont pas forcément détaillées par ufw status. Vérifiez aussi :

iptables-save | grep blocklist4
ip6tables-save | grep blocklist6

Sur un système UFW utilisant un backend nft et ne prenant pas correctement en charge le module set, utilisez plutôt l'intégration nftables native.


Shorewall + ipset

La documentation Shorewall permet d'utiliser un ipset à la place d'une adresse réseau en préfixant son nom par +.

10. IPv4 — /etc/shorewall/blrules

Exemple :

#ACTION     SOURCE              DEST
DROP        net:+blocklist4     -

L'ancien fichier /etc/shorewall/blacklist est déprécié dans les versions modernes ; utilisez blrules pour une nouvelle intégration.

11. IPv6 — /etc/shorewall6/blrules

Exemple :

#ACTION     SOURCE              DEST
DROP        net:+blocklist6     -

Adaptez les zones (net, etc.) à votre topologie Shorewall réelle.

12. Vérifier avant restart

shorewall check
shorewall6 check

Puis seulement :

shorewall reload
shorewall6 reload

Assurez-vous que les ipsets existent avant la compilation/application des règles.

13. Alternative : blacklist dynamique Shorewall

Shorewall 5.x possède aussi une blacklist dynamique basée sur ipset. Elle est utile pour ajouter/supprimer des hôtes individuellement, notamment avec Fail2ban.

Pour une publication Phase 19 complète, le modèle de ce guide — un set géré par le synchroniseur puis référencé depuis blrules — sépare mieux :

  • la source de vérité (publication Phase 19) ;
  • la mise à jour atomique du contenu ;
  • la politique Shorewall.

14. Références externes

Fichiers prêts à adapter