Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 3 additions & 9 deletions deployment/systemd/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,11 @@ For **containerized** Fail2Ban UI (Podman/Docker) talking to the host Fail2Ban s
In this case we will run **Fail2Ban-UI from `/opt/fail2ban-ui/`** using systemd.

### Prerequisites
Install **Go 1.24+** and required dependencies:
Install **Go 1.25+** and required dependencies:
```bash
sudo dnf install -y golang git
sudo dnf install -y golang git jq
```
> **Note:** Whois lookups are now performed by Fail2Ban UI directly (no Linux `whois` binary required).

> **Note:** GeoIP lookups can use either:
> - **Built-in (ip-api.com)**: Default option, requires no installation
> - **MaxMind (Local Database)**: Optional, requires MaxMind GeoIP database at `/usr/share/GeoIP/GeoLite2-Country.mmdb`

> **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.
> **Note:** A local Fail2ban installation is optional. Fail2Ban-UI can manage remote Fail2ban servers via SSH or API agents without requiring a local Fail2ban installation.

Clone the repository to `/opt/fail2ban-ui`:
```bash
Expand Down
6 changes: 5 additions & 1 deletion docs/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ firewall-cmd --reload

Check:

* The "jq" package is installed
* Fail2Ban is running and socket exists
* Container has the socket mounted
* Permissions allow access to the socket
Expand All @@ -35,6 +36,9 @@ Check:
Examples:

```bash
# check on RHEL / Rocky / Amlalinux
rpm -qa | grep jq

systemctl status fail2ban
ls -la /var/run/fail2ban/fail2ban.sock
fail2ban-client status
Expand Down Expand Up @@ -451,4 +455,4 @@ If the UI loads but real-time updates fail:

Reference configurations:

- [`docs/reverse-proxy.md`](https://github.com/swissmakers/fail2ban-ui/blob/main/docs/reverse-proxy.md)
- [`docs/reverse-proxy.md`](https://github.com/swissmakers/fail2ban-ui/blob/main/docs/reverse-proxy.md)
24 changes: 23 additions & 1 deletion internal/fail2ban/connector_global.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,28 @@ package fail2ban

import (
"context"
"os"
"sort"
"strconv"
"sync"
)

// summaryMaxBannedIPs caps the number of banned IPs returned per jail in
// the /api/summary response. The accurate TotalBanned count is always
// preserved; only the BannedIPs slice is truncated. Set the
// FAIL2BAN_UI_SUMMARY_MAX_IPS env var to 0 to disable the cap.
var summaryMaxBannedIPs = func() int {
v := os.Getenv("FAIL2BAN_UI_SUMMARY_MAX_IPS")
if v == "" {
return 100
}
n, err := strconv.Atoi(v)
if err != nil || n < 0 {
return 100
}
return n
}()

// =========================================================================
// Types
// =========================================================================
Expand Down Expand Up @@ -93,10 +111,14 @@ func collectJailInfos(ctx context.Context, jails []string, getBannedIPs bannedIP
results <- jailResult{err: err}
return
}
totalBanned := len(ips)
if summaryMaxBannedIPs > 0 && totalBanned > summaryMaxBannedIPs {
ips = ips[:summaryMaxBannedIPs]
}
results <- jailResult{
jail: JailInfo{
JailName: j,
TotalBanned: len(ips),
TotalBanned: totalBanned,
BannedIPs: ips,
Enabled: true,
},
Expand Down
Loading