opnsense fail2ban action script

Using fail2ban with the goal of blocking the suspicious IPs on a opnsense ... I wrote a script that can be used as a generic fail2ban action script:


You can define the action in /etc/fail2ban/action.d/opnsense-fail2ban.conf:

actionstart = /usr/local/sbin/opnsense-fail2ban.py -a flush
actionstop = /usr/local/sbin/opnsense-fail2ban.py -a flush
actioncheck = /bin/true
actionban = /usr/local/sbin/opnsense-fail2ban.py -k -a ban -i <ip>
actionunban = /usr/local/sbin/opnsense-fail2ban.py -a unban -i <ip>

name = opnsense-fail2ban
timeout = 120


For the ban action, I use the -k aka. --kill arg, in order to kill all states for the IP in question. This is required in order to block already established connections from the IP.

Depending on the load of your opnsense box, the kill state action may consume some time, so it might be necessary to increase the default timeout for the action (timeout setting in the action definition).

install the script via ansible

checkout the repo as submodule:

git submodule add https://github.com/zerwes/opnsense-fail2ban.git templates/opnsense-fail2ban

define the VARs:


  - fail2ban
  - python3-requests
  - python3-simplejson

opnsense_api_key: !vault ...
opnsense_api_secret: !vault ...
opnsense_api_host: ...
opnsense_default_alias: ...

and the tasks:

- name: role packages
    name: "{{ f2ban_rolepackages }}"
    update_cache: true
    cache_valid_time: 3600

- name: opnsense-fail2ban script
    src: opnsense-fail2ban/opnsense-fail2ban.py
    dest: /usr/local/sbin/opnsense-fail2ban.py
    mode: 0700

update In case you like to ensure the opnsense alias(es) you use have no elements that are not listed in the corresponding fail2ban jail, here is a script snippet for this task: https://gist.github.com/zerwes/f9f659a0751ee3acb6ba8910a9185f3d