Release first dockerfile, first documentation etc.. Update will follow

This commit is contained in:
2025-02-02 19:35:13 +01:00
parent 4aa0a1914e
commit 4c8f235b5b
25 changed files with 496 additions and 79 deletions

1
.gitignore vendored
View File

@@ -26,3 +26,4 @@ go.work.sum
# Project specific
fail2ban-ui-settings.json
_dev

58
Dockerfile Normal file
View File

@@ -0,0 +1,58 @@
# =========================================
# STAGE 1: Build Fail2Ban UI Binary
# =========================================
FROM golang:1.22.9 AS builder
WORKDIR /app
# Copy module files and download dependencies first
COPY go.mod go.sum ./
RUN go mod download
# Copy the application source code
COPY . .
# Build Go application (as static binary)
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o fail2ban-ui ./cmd/server/main.go
# ===================================
# STAGE 2: Standalone UI Version
# ===================================
FROM alpine:latest AS standalone-ui
# Install required container dependencies
RUN apk --update --no-cache add \
bash curl wget whois tzdata jq ca-certificates htop fail2ban geoip \
&& adduser -D -u 1000 -G root fail2ban
RUN mkdir -p /app /config \
/etc/fail2ban/jail.d \
/etc/fail2ban/filter.d \
/etc/fail2ban/action.d \
/var/run/fail2ban \
/usr/share/GeoIP \
&& touch /etc/fail2ban/jail.local \
&& chown -R fail2ban:0 /app /config /etc/fail2ban /var/run/fail2ban
# Set working directory
WORKDIR /config
# Copy Fail2Ban UI binary and templates from the build stage
COPY --from=builder /app/fail2ban-ui /app/fail2ban-ui
RUN chown fail2ban:0 /app/fail2ban-ui && chmod +x /app/fail2ban-ui
COPY --from=builder /app/pkg/web/templates /app/templates
# Set environment variables
ENV CONTAINER=true
# Persist config data
VOLUME ["/config"]
# Expose UI port
EXPOSE 8080
# Run the application as non-root (currently not possible because of fail2ban running as privileged)
#USER fail2ban
# Start Fail2Ban UI
CMD ["/app/fail2ban-ui"]

184
README.md
View File

@@ -1,101 +1,133 @@
# Fail2ban UI
# **Fail2Ban UI**
A Swissmade, management interface for [Fail2ban](https://www.fail2ban.org/).
It provides a modern dashboard to currently:
🚀 **Fail2Ban-UI** is a Swiss-made **web-based management interface** for [Fail2Ban](https://www.fail2ban.org/).
It provides an intuitive dashboard to **monitor, configure, and manage Fail2Ban** in real time.
- View all Fail2ban jails and banned IPs
- Unban IP addresses directly
- Edit and save jail/filter configs
- Reload Fail2ban when needed
- See recent ban events
- More to come...
Developed by **[Swissmakers GmbH](https://swissmakers.ch)**.
Built by [Swissmakers GmbH](https://swissmakers.ch).
## **✨ Features**
**Real-time Dashboard**
- View **all active Fail2Ban jails** and **banned IPs** in a clean UI
- Displays **live ban events**
**Ban & Unban Management**
- **Unban IPs** directly via the UI
- **Search** for banned IPs accross all active jails
**Fail2Ban Configuration Management**
- **Edit & Save** active Fail2Ban jail/filter configs
- Get automatic **email alerts** for specific country-based bans
- Configure own SMTP settings for email alerts (STARTTLS only)
- Adjust default ban time, find time, and set ignore IPs
- Auto-detects changes and prompts for **reload** to apply
- Enable debug-mode for detailed module logs
**Mobile-Friendly & Responsive UI / Fast**
- Optimized for **mobile & desktop**
- Powered by **Bootstrap 5**
- **Go-based backend** ensures minimal resource usage
**Systemd & SELinux Support**
- **Run as a systemd service** (Standalone or Container)
- **Supports SELinux** for secure execution (also container version)
## **📸 Screenshots**
Some images from the UI in action:
| Dashboard | Search | Filter Configuration |
|-----------|-------------|--------------------|
| ![Dashboard](./screenshots/0_Dashboard.jpg) | ![Filter Debug](./screenshots/1_Dashboard_search.jpg) | ![Jail Config](./screenshots/3_Dashboard_edit_filter.jpg) |
📌 **More screenshots are found [here](./screenshots/)**
---
## Features
## **📥 Installation & Deployment**
1. **Basic Real-time Dashboard**
- Automatically loads all jails, banned IPs, and last 5 ban events on page load.
Fail2Ban-UI can be currently deployed in **two main ways**:
**1⃣ Running from local source**
**2⃣ Running as a container**
2. **Unban IPs**
- Unban any blocked IP without needing direct CLI access.
### **🔹 Method 1: Running from Local Source**
To install and run directly on the system:
📌 **[Follow the basic systemd setup guide](./deployment/systemd/README.md)**
3. **Edit Fail2ban Configs**
- Click on any jail name to open a modal with raw config contents (from `/etc/fail2ban/filter.d/*.conf` by default).
- Save changes, then reload Fail2ban.
4. **Responsive UI**
- Built with [Bootstrap 5](https://getbootstrap.com/).
5. **Loading Overlay & Reload Banner**
- Displays a loading spinner for all operations.
- Shows a reload banner when configuration changes occur.
```bash
git clone https://github.com/swissmakers/fail2ban-ui.git /opt/fail2ban-ui
cd /opt/fail2ban-ui
go build -o fail2ban-ui ./cmd/main.go
...
```
---
## Requirements
### **🔹 Method 2: Running as a Container**
For an easy containerized deployment:
📌 **[Follow the basic container deployment guide](./deployment/container/README.md)**
- **Go 1.22.9+** (module-compatible)
- **Fail2ban** installed and running
- **Linux** environment with permissions to run `fail2ban-client` and read/write config files (e.g., `/etc/fail2ban/filter.d/`)
- Sufficient privileges to reload Fail2ban (run as `sudo` or configure your system accordingly)
```bash
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 \
-v /usr/share/GeoIP:/usr/share/GeoIP:ro \
localhost/fail2ban-ui
```
---
> **📌 Note:** The container can also be managed as a **systemd service**.
## Installation & Usage
1. **Clone the repository**:
```bash
git clone https://github.com/swissmakers/fail2ban-ui.git
cd fail2ban-ui
```
## **🔒 Security Considerations**
- Fail2Ban-UI requires **root privileges** to interact with Fail2Ban.
- **Restrict access** using **firewall rules** or a **reverse proxy** with authentication.
- Ensure that Fail2Ban logs/configs **aren't exposed publicly**.
2. **Initialize or tidy Go modules** (optional if you already have them):
```bash
go mod tidy
```
For **SELinux users**, apply the **Fail2Ban-UI security policies**:
```bash
# Basic rule to allow fail2ban access the fail2ban-ui API
semodule -i fail2ban-curl-allow.pp
# Also needed for a secure container deployment
semodule -i fail2ban-container-ui.pp
semodule -i fail2ban-container-client.pp
```
3. **Run the server** (with `sudo` if necessary):
```bash
sudo go run ./cmd/server
```
By default, it listens on port `:8080`.
4. **Open the UI**:
- Visit [http://localhost:8080/](http://localhost:8080/) (or replace `localhost` with your server IP).
## **🛠️ Troubleshooting**
5. **Manage Fail2ban**:
- See jails and banned IPs on the main dashboard
- Unban IPs via the “Unban” button
- Edit jail configs by clicking the jail name
- Save your changes, then **reload** Fail2ban using the top banner prompt
### **UI not accessible?**
- Ensure **port 8080** is open:
```bash
sudo firewall-cmd --add-port=8080/tcp --permanent
sudo firewall-cmd --reload
```
- Check logs:
```bash
journalctl -u fail2ban-ui.service -f
```
---
## Security Considerations
- Running this UI typically requires **root** or sudo privileges to execute `fail2ban-client` and manipulate config files.
- Consider restricting network access or using authentication (e.g., reverse proxy with Basic Auth or a firewall rule) to ensure only authorized users can access the dashboard.
- Make sure your Fail2ban logs and configs arent exposed publicly.
---
## Contributing
We welcome pull requests and issues! Please open an [issue](./issues) if you find a bug or have a feature request.
## **🤝 Contributing**
We welcome **pull requests** and **feature suggestions**!
1. **Fork** this repository
2. **Create** a new branch: `git checkout -b feature/my-feature`
3. **Commit** your changes: `git commit -m 'Add some feature'`
4. **Push** to the branch: `git push origin feature/my-feature`
5. **Open** a pull request
2. **Create** a new branch:
```bash
git checkout -b feature/my-feature
```
3. **Commit** your changes:
```bash
git commit -m "Add new feature"
```
4. **Push** to the branch:
```bash
git push origin feature/my-feature
```
5. **Open** a Pull Request
---
## License
```text
GNU GENERAL PUBLIC LICENSE, Version 3
```
## **📜 License**
Fail2Ban-UI is licensed under **GNU GENERAL PUBLIC LICENSE, Version 3**.
See [`LICENSE`](./LICENSE) for details.

View File

@@ -3,6 +3,7 @@ package main
import (
"fmt"
"log"
"os"
"time"
"github.com/gin-gonic/gin"
@@ -21,8 +22,15 @@ func main() {
}
router := gin.Default()
router.LoadHTMLGlob("pkg/web/templates/*") // Load HTML templates from pkg/web/templates
web.RegisterRoutes(router) // Register routes (IndexHandler, /api/summary, jail/unban/:ip) etc..
// To detect if running inside a container or not
_, container := os.LookupEnv("CONTAINER")
if container {
router.LoadHTMLGlob("/app/templates/*") // Load HTML templates
} else {
router.LoadHTMLGlob("pkg/web/templates/*") // Load HTML templates
}
web.RegisterRoutes(router)
printWelcomeBanner()
log.Println("--- Fail2Ban-UI started in", gin.Mode(), "mode ---")

View File

@@ -0,0 +1,88 @@
# **Fail2Ban-UI Container**
A **containerized version of Fail2Ban-UI**, allowing easy deployment for managing Fail2Ban configurations, logs, and bans via a web-based UI.
## How to Build the Image
```bash
podman build -t fail2ban-ui --target=standalone-ui .
```
For **Docker**, just replace `podman` with `docker` for every command, e.g.:
```bash
docker build -t fail2ban-ui --target=standalone-ui .
```
## For SELinux enabled systems
If SELinux is enabled, you must apply the required SELinux policies to allow the container to communicate with Fail2Ban.
The policies are located here: "`./SELinux/`"
Apply the prebuilt SELinux Modules with:
```bash
semodule -i fail2ban-container-ui.pp
semodule -i fail2ban-container-client.pp
```
### Manually Compile and Install SELinux Rules
If you want to change or compile the SELinux rules by yourself run:
```bash
checkmodule -M -m -o fail2ban-container-client.mod fail2ban-container-client.te
semodule_package -o fail2ban-container-client.pp -m fail2ban-container-client.mod
semodule -i fail2ban-container-client.pp
```
## How to Run the Container
Create the needed folder to store the fail2ban-ui config first:
```bash
mkdir /opt/podman-fail2ban-ui
```
Then run the container with the following prompt in background (-d) as test. For a productive container setup please use a systemd service.
```bash
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 \
-v /usr/share/GeoIP:/usr/share/GeoIP:ro \
localhost/fail2ban-ui
```
### Stop and Remove Container
Stop the running container:
```bash
podman stop fail2ban-ui
```
Remove the container:
```bash
podman rm fail2ban-ui
```
## Troubleshooting
### UI Not Accessible
- Ensure port **8080 (or custom port)** is **not blocked** by the firewall. (e.g. firewalld)
- Check container logs:
```bash
podman logs fail2ban-ui
```
- Ensure **Fail2Ban UI is running** inside the container:
```bash
podman exec -it fail2ban-ui ps aux
```
## Contact & Support
For issues, contributions, or feature requests, visit our GitHub repository:
🔗 [GitHub Issues](https://github.com/swissmakers/fail2ban-ui/issues)
For enterprise support, visit:
🔗 [Swissmakers GmbH](https://swissmakers.ch)

View File

@@ -0,0 +1,29 @@
module fail2ban-container-client 1.0;
require {
type fail2ban_t;
type fail2ban_client_t;
type fail2ban_var_run_t;
type container_file_t;
type httpd_log_t;
type container_t;
type var_log_t;
class sock_file write;
class unix_stream_socket connectto;
class dir { read search open };
class file { read open getattr };
}
#============= container_t ==============
allow container_t fail2ban_t:unix_stream_socket connectto;
allow container_t fail2ban_var_run_t:sock_file write;
allow container_t httpd_log_t:dir { read search open };
allow container_t httpd_log_t:file { read open getattr };
allow container_t var_log_t:dir { read search open };
allow container_t var_log_t:file { read open getattr };
#============= fail2ban_client_t ==============
allow fail2ban_client_t container_file_t:dir { read search open };
allow fail2ban_client_t container_file_t:file { read open getattr };
allow fail2ban_client_t container_file_t:sock_file write;

Binary file not shown.

View File

@@ -0,0 +1,13 @@
module fail2ban-container-ui 1.0;
require {
type fail2ban_log_t;
type etc_t;
type container_t;
class file { open read write };
}
#============= container_t ==============
allow container_t etc_t:file write;
allow container_t fail2ban_log_t:file { open read };

View File

@@ -0,0 +1,188 @@
# Fail2Ban-UI Systemd Setup
This guide provides two methods to **run Fail2Ban-UI as a systemd service**.
1. Systemd service that starts the local compiled binary.
2. Systemd service that starts the fail2ban-ui container.
## For SELinux enabled systems (needed in bouth cases)
If SELinux is enabled, you must apply the required SELinux policies to allow Fail2Ban to communicate with the Fail2Ban-UI API via port 8080.
Apply the prebuilt SELinux Module with:
```bash
semodule -i fail2ban-curl-allow.pp
```
## Build and running Fail2Ban-UI from Local Source Code
In this case we will run **Fail2Ban-UI from `/opt/fail2ban-ui/`** using systemd.
### Prerequisites
Install **Go 1.22+** and required dependencies:
```bash
sudo dnf install -y golang git whois
```
Make sure you setup GeoIP and your country database is available under: `/usr/share/GeoIP/GeoLite2-Country.mmdb`
Clone the repository to `/opt/fail2ban-ui`:
```bash
sudo git clone https://github.com/swissmakers/fail2ban-ui.git /opt/fail2ban-ui
cd /opt/fail2ban-ui
sudo go build -o fail2ban-ui ./cmd/main.go
```
### Create the fail2ban-ui.service
Save this file as `/etc/systemd/system/fail2ban-ui.service`:
```ini
[Unit]
Description=Fail2Ban UI
After=network.target fail2ban.service
Requires=fail2ban.service
[Service]
WorkingDirectory=/opt/fail2ban-ui
ExecStart=/opt/fail2ban-ui/fail2ban-ui
Restart=always
User=root
Group=root
[Install]
WantedBy=multi-user.target
```
### Start & Enable the Service
1. Reload systemd to detect our new service:
```bash
sudo systemctl daemon-reload
```
2. Enable and start the service:
```bash
sudo systemctl enable fail2ban-ui.service --now
```
3. Check the status:
```bash
sudo systemctl status fail2ban-ui.service
```
### View Logs
To see the real-time logs of Fail2Ban-UI:
```bash
sudo journalctl -u fail2ban-ui.service -f
```
### Restart or Stop
Restart:
```bash
sudo systemctl restart fail2ban-ui.service
```
Stop:
```bash
sudo systemctl stop fail2ban-ui.service
```
## Running Fail2Ban-UI as a (Systemd controlled) Container
This method runs Fail2Ban-UI as a **containerized service** with **automatic startup** and handling through systemd.
### Prerequisites
- Ensure **Podman** or **Docker** is installed.
For **Podman**:
```bash
sudo dnf install -y podman
```
For **Docker** (if preferred):
```bash
sudo dnf install -y docker
sudo systemctl enable --now docker
```
Make sure you setup GeoIP and your country database is available under: `/usr/share/GeoIP/GeoLite2-Country.mmdb`
Create the needed folder to store the fail2ban-ui config:
```bash
sudo mkdir /opt/podman-fail2ban-ui
```
### Create the fail2ban-ui-container.service
Save this file as `/etc/systemd/system/fail2ban-ui-container.service`:
```ini
[Unit]
Description=Fail2Ban UI (Containerized)
After=network.target fail2ban.service
Requires=fail2ban.service
[Service]
ExecStart=/usr/bin/podman run --rm \
--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 \
-v /usr/share/GeoIP:/usr/share/GeoIP:ro \
localhost/fail2ban-ui
Restart=always
RestartSec=10s
[Install]
WantedBy=multi-user.target
```
### For SELinux enabled systems
If SELinux is enabled, you must apply the required SELinux policies to allow the container to communicate with Fail2Ban.
The policies are located here: "`../container/SELinux/`"
Apply the prebuilt SELinux Modules with:
```bash
semodule -i fail2ban-container-ui.pp
semodule -i fail2ban-container-client.pp
```
#### Manually Compile and Install SELinux Rules
If you want to change or compile the SELinux rules by yourself run:
```bash
checkmodule -M -m -o fail2ban-container-client.mod fail2ban-container-client.te
semodule_package -o fail2ban-container-client.pp -m fail2ban-container-client.mod
semodule -i fail2ban-container-client.pp
```
### Start & Enable the Container Service
1. Reload systemd to detect the new service:
```bash
sudo systemctl daemon-reload
```
2. Enable and start the containerized service:
```bash
sudo systemctl enable --now fail2ban-ui-container.service
```
3. Check the status:
```bash
sudo systemctl status fail2ban-ui-container.service
```
### View Logs
```bash
sudo journalctl -u fail2ban-ui-container.service -f
```
### Restart or Stop
Restart:
```bash
sudo systemctl restart fail2ban-ui-container.service
```
Stop:
```bash
sudo systemctl stop fail2ban-ui-container.service
```
## **Contact & Support**
For issues, visit our GitHub repository:
🔗 [GitHub Issues](https://github.com/swissmakers/fail2ban-ui/issues)
For enterprise support:
🔗 [Swissmakers GmbH](https://swissmakers.ch)

BIN
screenshots/0_Dashboard.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 872 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 811 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 970 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 813 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 873 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 899 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 848 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 400 KiB

BIN
screenshots/6_Settings.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 643 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 571 KiB

Binary file not shown.