iblock : bloqueur de connexions TCP indésirables, sous OpenBSD

Article publié, le et modifié le
5 minutes de lecture

Cet article contient 908 mots.
Source brute de l'article :

Description

iblock est un logiciel dont le but est de détecter des connexions TCP, sur des ports précis, afin de bloquer les adresses IP correspondantes par le biais du parefeu Packet Filter, sous OpenBSD.

Le service inetd est chargé de l’écoute active.

Installation

Commençons par la copie du dépôt Git :

$ git clone https://tildegit.org/solene/iblock.git
$ cd iblock

Compilons le binaire - OpenBSD renferme nativement les outils adéquats - :

$ doas make 
cc -o iblock main.c
; vérifions la présence du binaire
$ ls -al iblock
-rwxr-xr-x  1 root  moi  8496 Apr 10 12:23 iblock*

Si la phase de compilation s’exécute mal, contactez Solène !

Solène n’a pas créé la cible “install”, donc copions le binaire dans le répertoire cible :

$ doas cp iblock /usr/local/bin/
$ ls -al /usr/local/bin/iblock                                                                                       
-rwxr-xr-x  1 root  wheel  8496 Apr 10 12:26 /usr/local/bin/iblock*

Passons maintenant à la phase de configuration !

Configuration

Utilisateur dédié _iblock

Créons en tout premier un utilisateur dédié, nommé _iblock :

$ doas useradd -s /sbin/nologin _iblock

doas

  • Fichier de configuration : /etc/doas.conf

Ajoutons la règle suivante dans le fichier de configuration de doas pour autoriser l’utilisateur dédié à utiliser l’outil pfctl :

permit nopass _iblock cmd /sbin/pfctl

inetd

  • Fichier de configuraton : /etc/inetd.conf

Configurons maintenant le service inetd :

666 stream tcp nowait _iblock /usr/local/bin/iblock iblock blocked_tcp
666 stream tcp6 nowait _iblock /usr/local/bin/iblock iblock blocked_tcp
  • le port 666 est utilisé - bien sûr, vous pouvez le changer.
  • géré par l’utilisateur _iblock, appelant le binaire iblock.
  • le dernier argument est le nom du paramètre qui est ajouté aux adresses IP qui sont enregistrées dans la table gérée par PF.

Et activons et démarrons le service :

$ doas rcctl enable inetd && doas rcctl start inetd

shutdown

En premier, créons un fichier de “secours” pour rendre la future table dans PF persistante à l’extinction et au redémarrage du serveur :

# touch /etc/pf-blocked_tcp.txt

Puis créons/modifions le fichier /etc/rc.shutdown pour y ajouter :

pfctl -t blocked_tcp -T show > /etc/pf-blocked_tcp.txt

PF

Voici un exemple de règles à ajouter à PF :

  1. déclaration d’une variable, ici nommée block_tcp_ports, soit un ensemble de ports à surveiller
  2. création d’une table persistante, ici nommée blocked_tcp
  3. règle bloquante, portant le label iblock
  4. les deux dernières règles analysent le flux TCP, sur les protocoles IPv4 et IPv6, en “écoutant” les ports enregistrés dans la variable block_tcp_ports, puis redirigent sur l’interface locale, à destination du port 666.
block_tcp_ports = "{ 21 23 111 135 137:139 445 1433 3306 3389 5432 6000:6010 7890 9999 25565 27019 }"

table <blocked_tcp> persist file "/etc/pf-blocked_tcp.txt"

### iblock: block all in table 
block in quick from <blocked_tcp> label iblock

### iblock: redirect to inetd service on localhost
pass in quick on egress inet  proto tcp to port $block_tcp_ports rdr-to 127.0.0.1 port 666
pass in quick on egress inet6 proto tcp to port $block_tcp_ports rdr-to ::1       port 666
Info
Attention

Pensez à faire recharger le jeu de règles par PF :
$ doas pfctl -f /etc/pf.conf

Surveillance

Mais qui surveille ?

⇒ L’activité est enregistrée dans les deux logs ‘daemon’ et ‘messages’.

$ grep iblock /var/log/messages
Apr 10 12:26:38 sh1 iblock: blocking 46.23.148.71
Apr 10 12:30:28 sh1 iblock: blocking 180.225.98.236
Apr 10 12:31:48 sh1 iblock: blocking 46.23.157.246
Apr 10 12:32:43 sh1 iblock: blocking 95.57.218.103
Apr 10 12:36:00 sh1 iblock: blocking 103.89.91.158
Apr 10 12:38:41 sh1 iblock: blocking 23.128.248.41

⇒ De même, l’outil pfctl peut nous montrer les différentes adresses IP enregistrées dans la table, gérée par PF :

$ doas pfctl -t blocked_tcp -T show 
   23.128.248.41
   46.23.148.71
   46.23.157.246
   95.57.218.103
   103.89.91.158
   180.225.98.236

voire de l’utiliser pour connaître les statistiques liées - pour comprendre ces informations, merci de lire le manpage de l’outil pour connaître la signification du colonnage :

$ doas pfctl -sl | grep iblock
iblock 44666 1188 58504 1188 58504 0 0 0

⇒ Il est possible de surveiller l’activité de l’utilisateur _iblock avec - mais dans ce cas, franchement peu utile :

  • top -U _iblock
  • fstat -u _iblock -n
  • ps aux -U _iblock

munin

Si vous souhaitez obtenir des statistiques avec munin , Solène m’a fournit un script, à exécuter avec les droits de l’utilisateur _munin, tel que :

#!/bin/sh

if [ "$1" = "config" ]; then
        echo "graph_title Banned IP absolute number"
        echo "graph_vlabel gauge"
        echo "a1.label value"
        exit 0
fi

printf "a1.value "
doas /sbin/pfctl -t blocked_tcp -T show | sort -n -u | awk 'END { print NR }'

Ce qui nécessite de modifier la configuration de doas pour autoriser l’utilisateur _munin à utiliser l’outil pfctl, tel que :

# iblock: auth _munin-plugin to use pfctl
permit nopass _munin-plugin cmd /sbin/pfctl args -t blocked_tcp -T show

Ci-dessous, voici une image de statistiques d’adresses IP bloquées, restituée par Solène, en date du 10/04/2022 :

Statistiques d'adresses IP bloquées grâce à iblock
Statistiques d'adresses IP bloquées grâce à iblock

Dépannage

Dans les logs ‘daemon’ et ‘messages’, vous retrouvez le message suivant :

inetd[69849]: execv /usr/local/bin/iblock: No such file or directory

Assurez-vous d’avoir compiler puis copier le binaire iblock dans le répertoire en question !


Voilà !