A Go-based, management interface for Fail2Ban.
100K+
A guide for deploying Fail2Ban UI using Docker/Podman.
Pull the official image with podman from Docker Hub (default):
podman pull swissmakers/fail2ban-ui:latest
# or with Docker:
docker pull swissmakers/fail2ban-ui:latest
Alternative: Pull from Swissmakers registry (fallback):
podman pull registry.swissmakers.ch/infra/fail2ban-ui:latest
docker pull registry.swissmakers.ch/infra/fail2ban-ui:latest
podman run -d \
--name fail2ban-ui \
--network=host \
-v /opt/podman-fail2ban-ui:/config:Z \
-v /etc/fail2ban:/etc/fail2ban:Z \
-v /var/log:/var/log:ro \
-v /var/run/fail2ban:/var/run/fail2ban \
swissmakers/fail2ban-ui:latest
You can change the default port (8080) using the PORT environment variable:
podman run -d \
--name fail2ban-ui \
--network=host \
-e PORT=8436 \
-v /opt/podman-fail2ban-ui:/config:Z \
swissmakers/fail2ban-ui:latest
Access the web interface at http://localhost:8436.
Start the container:
podman start fail2ban-ui
Stop the container:
podman stop fail2ban-ui
View logs:
podman logs -f fail2ban-ui
Remove the container:
podman stop fail2ban-ui
podman rm fail2ban-ui
Execute commands inside the container:
podman exec -it fail2ban-ui /bin/bash
The Fail2Ban UI container requires several volume mounts to function properly. Below is a detailed explanation of each volume:
/config - Configuration and Database Storage/opt/podman-fail2ban-ui (or your preferred location)/configfail2ban-ui.db), application settings, and SSH keys for remote server connections:Z flag required on SELinux-enabled systemsfail2ban-ui.db - SQLite database with server configurations and ban events.ssh/ - Directory for SSH keys used for remote server connections/etc/fail2ban - Fail2Ban Configuration Directory (reqired for local fail2ban connector only)/etc/fail2ban/etc/fail2ban:Z flag required on SELinux-enabled systems/var/run/fail2ban - Fail2Ban Socket Directory (reqired for local fail2ban connector only)/var/run/fail2ban/var/run/fail2banfail2ban.sock)/var/log - Log Files (reqired for local fail2ban connector only)/var/log/var/log:ro)/path/to/your/GeoIPFolder/usr/share/GeoIP paht must match the settings in the UI.:ro)| Volume | Required | Read/Write | SELinux Context | Purpose |
|---|---|---|---|---|
/config | ✅ Yes | Read/Write | :Z | Database, settings, SSH keys |
/etc/fail2ban | ✅ Yes* | Read/Write | :Z | Fail2Ban configuration files |
/var/run/fail2ban | ✅ Yes* | Read/Write | - | Fail2Ban control socket |
/var/log | ✅ Yes* | Read-Only | :ro | System log files for automated logpath tests on jail management. |
/path/to/your/GeoIPFolder | ⚠️ Optional | Read-Only | :ro | MaxMind GeoIP databases (only needed if using MaxMind provider) |
*Required only if managing a local Fail2Ban instance. Not needed for remote-only deployments.
| Variable | Default | Description |
|---|---|---|
PORT | 8080 | Port number for the web interface |
BIND_ADDRESS | 0.0.0.0 | IP address to bind the web interface to. Useful when running with host networking to prevent exposing the web UI to unprotected networks. Set to a specific IP (e.g., 127.0.0.1 or a specific interface IP) to restrict access. |
CONTAINER | true | Automatically set by the container (do not override) |
After starting the container, access the web interface and configure your first Fail2Ban server:
Access the Web Interface
http://localhost:8080 (or your configured port)Add Your First Server
Configure Settings
http://127.0.0.1:8080 or your configured port)https://fail2ban.example.com)Note: The local Fail2Ban service is optional. Fail2Ban UI can manage remote Fail2Ban servers via SSH or API agents without requiring a local Fail2Ban installation in the container.
Important: The Fail2Ban Callback URL must be accessible from all Fail2Ban instances (local and remote) that need to send alerts. If you change the Fail2Ban UI port, ensure the callback URL is updated accordingly.
For easier management, you can use Docker Compose. Create a docker-compose.yml file:
services:
fail2ban-ui:
# Use pre-built image from Docker Hub (default)
image: swissmakers/fail2ban-ui:latest
# Alternative: Use Swissmakers registry (fallback)
# image: registry.swissmakers.ch/infra/fail2ban-ui:latest
# Or build from source (uncomment to use):
# build:
# context: .
# dockerfile: Dockerfile
container_name: fail2ban-ui
#privileged: true # needed if you want to use a container-local fail2ban instance (because fail2ban.sock is owned by root)
# a single all-in-one container is planned, currently you need to use the fail2ban container from linuxserver, see docker-compose-allinone.yml for an example
network_mode: host
environment:
# Change this to use a different port for the web interface (defaults is 8080)
- PORT=8080
volumes:
# Required for fail2ban-ui: Stores SQLite database, application settings, and SSH keys of the fail2ban-ui container
- /opt/podman-fail2ban-ui:/config:Z
# Required for fail2ban-ui: Used for testing, that logpath is working, before enabeling a jail. Without this read only access the fail2ban-ui will not be able to enable jails (logpath-test would fail)
- /var/log:/var/log:ro
# Required for local fail2ban instance: Fail2Ban configuration directory, needed for managing a local Fail2Ban instance (e.g. on host system) via fail2ban-ui
- /etc/fail2ban:/etc/fail2ban:Z
# Required for local fail2ban instance: Fail2Ban socket directory, needed for local Fail2Ban (e.g. on host system) for control via fail2ban-ui
- /var/run/fail2ban:/var/run/fail2ban
# Optional: Map MaxMind GeoIP databases (only needed if using MaxMind provider)
#- /usr/share/GeoIP:/usr/share/GeoIP:ro
restart: unless-stopped
Start with Docker Compose:
docker-compose up -d
View logs:
docker-compose logs -f
Stop:
docker-compose down
For a complete containerized setup with both Fail2Ban and Fail2Ban UI, use the all-in-one Docker Compose configuration:
services:
fail2ban:
image: lscr.io/linuxserver/fail2ban:latest
container_name: fail2ban
cap_add:
# Required for fail2ban container: Allows to manage network interfaces and iptables from the container
- NET_ADMIN
# Required for fail2ban container: Allows to create raw sockets (needed for fail2ban.sock)
- NET_RAW
# Required for fail2ban container: Allows to run as root (needed to manage network interfaces and raw sockets)
- SYS_ADMIN
#privileged: true
network_mode: host # needed to add iptables rules to the host network
environment:
- TZ=Europe/Zurich
- VERBOSITY=-vv
volumes:
# To make sure linuxserver-fail2ban configs are persistent across container restarts (also needed by fail2ban-ui to modify configs)
- ./fail2ban-config:/config:z
# Directory that contains fail2ban.sock for communication between fail2ban-ui and fail2ban container
- ./f2b-run:/var/run/fail2ban:z
# Log sources for fail2ban container
- /var/log:/var/log:ro
- /var/log/httpd:/remotelogs/apache2:ro
restart: unless-stopped
fail2ban-ui:
# Use pre-built image from Docker Hub (default)
image: swissmakers/fail2ban-ui:latest
# Alternative: Use Swissmakers registry (fallback)
# image: registry.swissmakers.ch/infra/fail2ban-ui:latest
# Or build from source (uncomment to use):
# image: localhost/fail2ban-ui:dev
container_name: fail2ban-ui
privileged: true # needed because the fail2ban-ui container needs to modify the fail2ban config owned by root inside the linuxserver-fail2ban container
network_mode: host
environment:
# Optional: Change this to use a different port for the web interface (defaults is 8080)
- PORT=3080
# Optional: Bind to a specific IP address (default: 0.0.0.0)
# This is useful when running with host networking to prevent exposing
# the web UI to unprotected networks. Set to a specific IP (e.g., 127.0.0.1
# or a specific interface IP) to restrict access.
# - BIND_ADDRESS=127.0.0.1
volumes:
# Required for fail2ban-ui: Stores SQLite database, application settings, and SSH keys of the fail2ban-ui container
- ./config:/config:Z
# Required for fail2ban-ui: Used for testing, that logpath is working, before enabeling a jail. Without this read only access the fail2ban-ui will not be able to enable jails (logpath-test would fail)
- /var/log:/var/log:ro
- /var/log/httpd:/remotelogs/apache2:ro # this mounts the apache2 logs of a RPM based system (e.g. Rocky Linux) to the default location set by linuxserver-fail2ban. (on debian based systems this is /var/log/apache2 and currently hardcoded in the linuxserver-fail2ban container)
# Required for compose-local fail2ban instance: We mount the same Fail2Ban config as the linuxserver-fail2ban container (under /config/fail2ban to fail2ban-ui can modify configs)
- ./fail2ban-config/fail2ban:/etc/fail2ban:z
# Required for compose-local fail2ban instance: Mount the same run directory that contains fail2ban.sock for communication between fail2ban-ui and the linuxserver-fail2ban container
- ./f2b-run:/var/run/fail2ban:z
restart: unless-stopped
# Edit docker-compose to customize:
# - PORT environment variable for Fail2Ban UI
# - Timezone (TZ environment variable)
# - Volume paths
# Start both services
docker-compose up -d
Features:
host network mode for proper iptables integrationVolume Structure:
./fail2ban-config/fail2ban → /config/fail2ban (fail2ban container)
./fail2ban-config/fail2ban → /etc/fail2ban (fail2ban-ui container)
./f2b-run → /var/run/fail2ban (both containers)
./config → /config (fail2ban-ui container)
Important Notes:
privileged: true to modify Fail2Ban configs owned by rootnetwork_mode: host for proper networking:z or :Z flags)If SELinux is enabled on your system, you must apply the required SELinux policies to allow the container to communicate with Fail2Ban.
The policies are located in ./SELinux/:
cd deployment/container/SELinux
semodule -i fail2ban-container-ui.pp
semodule -i fail2ban-container-client.pp
If you want to modify or compile the SELinux rules yourself:
cd deployment/container/SELinux
# Compile the module
checkmodule -M -m -o fail2ban-container-client.mod fail2ban-container-client.te
# Package the module
semodule_package -o fail2ban-container-client.pp -m fail2ban-container-client.mod
# Install the module
semodule -i fail2ban-container-client.pp
semodule -l | grep fail2ban
You should see:
fail2ban-container-uifail2ban-container-clientSymptoms: Cannot access web interface
Solutions:
Check if container is running:
podman ps | grep fail2ban-ui
Check container logs:
podman logs fail2ban-ui
Verify port is not blocked by firewall:
sudo firewall-cmd --list-ports
sudo firewall-cmd --add-port=8080/tcp --permanent
sudo firewall-cmd --reload
Check if Fail2Ban UI process is running inside container:
podman exec -it fail2ban-ui ps aux | grep fail2ban-ui
Verify port configuration:
PORT environment variable is set correctlySymptoms: Empty dashboard, no servers visible
Solutions:
Symptoms: Cannot connect to remote server
Solutions:
Verify SSH key authentication works from the host:
ssh -i /opt/podman-fail2ban-ui/.ssh/your_key user@remote-host
Ensure SSH user has proper permissions on remote server:
fail2ban-client and systemctl restart fail2ban (configured via sudoers)/etc/fail2ban for configuration file accessCheck SSH keys location:
/config/.ssh directory inside the containerEnable debug mode:
Verify network connectivity:
--network=host or configure proper port mappingsSymptoms: Permission errors when accessing Fail2Ban files
Solutions:
Check SELinux context on volumes:
ls -Z /opt/podman-fail2ban-ui
ls -Z /etc/fail2ban
Apply correct SELinux context:
chcon -Rt container_file_t /opt/podman-fail2ban-ui
Verify volume mount flags:
:Z flag for read/write volumes on SELinux systems:ro flag for read-only volumesSymptoms: Database-related errors in logs
Solutions:
Check database file permissions:
ls -la /opt/podman-fail2ban-ui/fail2ban-ui.db
Verify database integrity:
podman exec -it fail2ban-ui sqlite3 /config/fail2ban-ui.db "PRAGMA integrity_check;"
Backup and recreate if corrupted:
cp /opt/podman-fail2ban-ui/fail2ban-ui.db /opt/podman-fail2ban-ui/fail2ban-ui.db.backup
For issues, contributions, or feature requests, visit our GitHub repository:
🔗 GitHub Issues
For enterprise support, visit:
🔗 Swissmakers GmbH
Content type
Image
Digest
sha256:a9bcc7db6…
Size
71.8 MB
Last updated
17 days ago
docker pull swissmakers/fail2ban-ui