iblock: block scanner TCP connections under OpenBSD

Article published the ; modified the
4 minutes to read

This article has 824 words.
RAW source of the article:
Commit version: 36e3c52


iblock is a software whose purpose is to detect TCP connections, on specific ports, in order to block the corresponding IP adresses, through Packet Filter.

The inetd service is responsible for active listening.


Let’s start with the copy of Git depository:

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

Compile the binary — OpenBSD contains natively the appropriate tools:

$ 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*

If the compilation phase does not run correctly, contact Solène!

Solène did not create the “install” target, so let’s copy it into the target directory:

$ 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*

Let’s move to the configuration:



In first, create a dedicated user, named _iblock:

$ doas useradd -s /sbin/nologin _iblock


  • Configuration file: /etc/doas.conf

Now, add the below rule into the doas configuration file to allow the dedicated user to use pfctl:

permit nopass _iblock cmd /sbin/pfctl


  • Configuration file: /etc/inetd.conf

Configure the inetd service:

666 stream tcp nowait _iblock /usr/local/bin/iblock iblock blocked_tcp
666 stream tcp6 nowait _iblock /usr/local/bin/iblock iblock blocked_tcp
  • 666: used port — of course, you can change…
  • the _iblock user manage the binary iblock
  • the last argument: the name of the added parameter to the IP addresses stored in the PF table.

And, now, let’s active and start the service:

$ doas rcctl enable inetd && doas rcctl start inetd


Create a “backup” file to make the future table persistent in PF, on server shutdown and restart:

# touch /etc/pf-blocked_tcp.txt

And, create|modify the /etc/rc.shutdown file:

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


Here is an instance of rules to add to Packet Filter:

  1. one variable, named block_tcp_ports: a set of ports to monitor
  2. one persistent table, named blocked_tcp.
  3. the blocking rule, labeled iblock.
  4. the two ultime rules analyze the TCP flow, on IPv(4|6) protocols, by active listening on the stored ports into the block_tcp_ports variable, and then redirect on the local interface, to the 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 port 666
pass in quick on egress inet6 proto tcp to port $block_tcp_ports rdr-to ::1       port 666

Remember: reload the rule set: $ doas pfctl -f /etc/pf.conf


But, who is the monitor?

⇒ The activity is recorded in the two logs ‘daemon’ and ‘messages’.

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

⇒ Also, pfctl can show us the different IP addresses registered into the PF table:

$ doas pfctl -t blocked_tcp -T show

or event to use it to find the related statistics to — see documentation for column meaning:

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

⇒ It’s possible to monitoring the user _iblockbut, in this case, not very useful:

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


If you want to get statistics with munin , Solène provided me a script, to be executed with the rights of the user _munin:


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

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

This need to modify the configuration of doas to allow the user _munin to use pfctl:

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

Below, here a view of statistics of blocked IP addresses, gived by Solène,

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

Statistics of IP addresses blocked with iblock
Statistics of IP addresses blocked with iblock


Into the both logs ‘daemon’ and ‘messages’, see the message:

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

Make sure you have compiled and copied the iblock binary to the target directory!