Webmin's login page on port 10000 is hit by automated password-guessing bots all day, and one compromised account gives an attacker root-level control of your server. Fail2Ban stops this by reading your logs and banning any IP address that fails to log in too many times. This guide shows how to set it up for Webmin in 2026.
Fail2Ban is the standard tool for blocking brute-force attacks. It watches authentication logs and bans IP addresses after a configurable number of failed login attempts. The guide covers the filter and jail for Webmin, Webmin's native Fail2Ban module (which most guides ignore), jails for other services, and how to manage banned IPs. It also explains how to confirm the filter matches your Webmin version's log format, because that is where most setups fail.
Why Webmin Is a Prime Brute Force Target
Several characteristics make Webmin particularly attractive to attackers:
- Predictable port β Port 10000 is Webmin's default across all installations. Automated scanners target it globally.
- Root access on success β Unlike SSH which might connect as a limited user, Webmin typically grants full root-equivalent control through its web interface.
- No rate limiting by default β A fresh Webmin installation has no built-in brute-force protection. An attacker can attempt thousands of passwords per minute without restriction.
- Exposed to the internet β Many server administrators don't restrict Webmin to a VPN or specific IP range, leaving the admin panel accessible from anywhere.
Fail2Ban addresses the rate-limiting gap by monitoring Webmin's authentication log and banning IPs after repeated failures. This only works if the filter is configured for the log format your Webmin version actually writes, so the later steps include a way to test it.
Step 1: Install Fail2Ban on Your Server
If Fail2Ban isn't already installed, add it via your distribution's package manager:
CentOS/RHEL/AlmaLinux/Rocky:
dnf install epel-release -y
dnf install fail2ban fail2ban-systemd -y
Ubuntu/Debian:
apt update
apt install fail2ban -y
Enable and start Fail2Ban:
systemctl enable fail2ban
systemctl start fail2ban
Verify Fail2Ban is running:
systemctl status fail2ban
fail2ban-client status
Package repositories ship different Fail2Ban versions, so check yours with fail2ban-client --version. Newer releases of some distributions read logs from the systemd journal instead of plain log files. If a log file you expect is missing, that is usually the reason.
π‘ None of these worked? Skip the guesswork.
Get Expert Help βStep 2: Configure the Webmin Fail2Ban Jail
Fail2Ban works through "jails". Each jail monitors a specific log file using a filter (regex pattern) and applies a ban action when the filter matches too many times. You need to configure a jail specifically for Webmin's authentication log.
ls -la /var/webmin/miniserv.log
# or:
ls -la /var/log/webmin/miniserv.log
Webmin logs authentication attempts to miniserv.log. Failed logins appear as entries like:
Failed login from 192.168.1.100 for root : Invalid password
The exact wording of these entries can differ between Webmin versions and logging settings. Some setups record failed logins in a separate error log or in syslog instead. Open the log, trigger one deliberate failed login from a test IP, and compare what you see with the example above before you write the filter.
Create the filter file at /etc/fail2ban/filter.d/webmin-auth.conf:
[Definition]
failregex = Failed login from <HOST>
ignoreregex =
The <HOST> placeholder is Fail2Ban's built-in pattern that matches IPv4 and IPv6 addresses. If your log lines are worded differently, change the text before <HOST> to match them. You will confirm the match with fail2ban-regex in Step 5.
Create or edit /etc/fail2ban/jail.local (never edit jail.conf directly β it gets overwritten on updates). Add the Webmin jail:
[webmin-auth]
enabled = true
filter = webmin-auth
logpath = /var/webmin/miniserv.log
maxretry = 5
findtime = 600
bantime = 3600
port = 10000
Key settings explained:
- maxretry = 5 β Ban after 5 failed attempts
- findtime = 600 β Count failures within a 10-minute window
- bantime = 3600 β Ban for 1 hour (3600 seconds). Use
-1for a permanent ban - port = 10000 β The port Webmin listens on (adjust if you've changed Webmin's port)
fail2ban-client reload
fail2ban-client status webmin-auth
The status output should show the jail is active with 0 currently banned IPs (until an attack occurs). If Fail2Ban reports that the jail failed to start, check that the log path exists and that the filter file name matches the filter line exactly.
Log into Webmin, go to Networking > Fail2Ban Intrusion Detector. If the module doesn't appear, it may not be installed β go to Webmin > Webmin Modules and install "Fail2Ban Intrusion Detector." The menu layout can vary slightly between Webmin versions, so use the search box in Webmin if you can't find it.
The module's main page lists all configured jails with their status (enabled/disabled), ban count, and current banned IP list. You can see at a glance how many IPs are currently blocked for each service.
Click any jail to edit its settings through the web interface. The module lets you adjust maxretry, findtime, bantime, and the log path without manually editing configuration files.
When a legitimate user gets accidentally banned (common with sysadmins working from dynamic IP addresses), click the jail name, find the banned IP in the list, and click "Unban." This is significantly faster than the CLI equivalent and doesn't require SSH access to the server.
Step 4: Extend Fail2Ban to Protect SSH and Other Services
While configuring Fail2Ban for Webmin, set up protection for SSH and other exposed services at the same time. Add these jails to /etc/fail2ban/jail.local:
[sshd]
enabled = true
filter = sshd
logpath = /var/log/secure # CentOS/RHEL
# logpath = /var/log/auth.log # Ubuntu/Debian
maxretry = 5
findtime = 600
bantime = 7200
port = 22
[sshd-ddos]
enabled = true
filter = sshd-ddos
logpath = /var/log/secure
maxretry = 10
findtime = 120
bantime = 600
Recent Fail2Ban releases have folded the separate sshd-ddos filter into the main sshd filter, which has its own modes. If Fail2Ban reports that the sshd-ddos filter can't be found after a reload, remove that jail and rely on the sshd jail. If your system logs SSH to the journal rather than a file, set backend = systemd in the jail instead of using logpath.
For servers running Apache or Nginx:
[apache-auth]
enabled = true
filter = apache-auth
logpath = /var/log/httpd/*error_log
maxretry = 6
bantime = 3600
[nginx-http-auth]
enabled = true
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 6
bantime = 3600
On Ubuntu and Debian, Apache's error log is normally under /var/log/apache2/ rather than /var/log/httpd/, so adjust the logpath to match your system.
Reload Fail2Ban after adding new jails:
fail2ban-client reload
fail2ban-client status # shows all active jails
Step 5: Monitor Fail2Ban and Manage Banned IPs
View currently banned IPs for a specific jail:
fail2ban-client status webmin-auth
Unban a specific IP address (CLI method):
fail2ban-client set webmin-auth unbanip 192.168.1.100
Check Fail2Ban logs for diagnostic information:
tail -f /var/log/fail2ban.log
Look for entries like Ban 1.2.3.4 and Unban 1.2.3.4 to confirm bans are being applied and lifted correctly.
Test that your Webmin filter is working correctly:
fail2ban-regex /var/webmin/miniserv.log /etc/fail2ban/filter.d/webmin-auth.conf
This command tests the filter against your actual log file and reports how many lines matched. If the match count is 0 when you know failed logins exist in the log, the regex needs adjustment for your Webmin version's log format. Copy a real failed-login line from the log, compare it with your failregex, and rerun the test until the count is above zero. Run this test after every Webmin upgrade, since a change in log wording would silently stop the jail from catching attacks.
Additional Security: Change Webmin's Default Port
Fail2Ban reacts to attacks, while changing Webmin's port stops automated scanners from finding the login page in the first place. Scanners that only probe port 10000 will miss Webmin if it's moved to an obscure high port. This reduces noise but is not a substitute for strong passwords, two-factor authentication and Fail2Ban.
In Webmin, go to Webmin > Webmin Configuration > Ports and Addresses. Change the "Listen on port" value to an unused high port (e.g., 47392). After saving, update your firewall rules to allow the new port and block port 10000, then update the port setting in your Fail2Ban jail config accordingly.
For comprehensive server hardening beyond Fail2Ban β including SSH key authentication, firewall configuration, and intrusion detection β CloudHouse's server hardening service provides a full security audit and implementation for Linux servers managed through Webmin or any other control panel.
FAQs
How do I know if Fail2Ban is actually blocking attacks on Webmin?
Check the Fail2Ban log: grep "Ban\|webmin" /var/log/fail2ban.log | tail -50. Each successful ban shows as "Ban [IP]" with the jail name. You can also check the Webmin module's GUI (Networking > Fail2Ban Intrusion Detector) which shows a real-time list of banned IPs per jail. If you see no bans but know attacks are occurring, verify the filter matches your log format with: fail2ban-regex /var/webmin/miniserv.log /etc/fail2ban/filter.d/webmin-auth.conf.
What's a good bantime setting for Webmin Fail2Ban?
For most servers, bantime = 3600 (1 hour) is a balanced starting point β long enough to stop attack scripts, short enough to automatically release accidentally banned legitimate users. For servers under heavy attack, use bantime = 86400 (24 hours) or -1 for permanent bans. Combine permanent bans with a whitelist (ignoreip = YOUR.IP.ADDRESS in jail.local) to protect your own access.
I accidentally banned my own IP. How do I unban myself without SSH access?
This is a critical scenario. If you have another IP address or can access the server via its console/VNC/KVM interface, run: fail2ban-client set webmin-auth unbanip YOUR.IP. If you have no alternative access, contact your hosting provider to either whitelist your IP at the firewall level or restart Fail2Ban (which clears all bans). Prevention: always add your static IP or IP range to the Fail2Ban whitelist: add ignoreip = 127.0.0.1/8 YOUR.STATIC.IP to /etc/fail2ban/jail.local.
Does Fail2Ban work with Webmin's built-in password timeout feature?
Yes, they complement each other. Webmin's built-in password timeout (configured under Webmin > Webmin Configuration > Authentication) adds a delay between login attempts, slowing brute-force attacks. Fail2Ban adds IP banning for persistent attackers. Use both: set Webmin's authentication timeout to 30-60 seconds AND configure Fail2Ban jails. The two-layer approach is more effective than either tool alone.
Should I use Fail2Ban or ConfigServer Firewall (CSF) for Webmin protection?
Both can protect Webmin, and they're compatible β you can run both simultaneously. CSF/LFD (Login Failure Daemon) is CSF's built-in brute-force protection that works similarly to Fail2Ban. If you already have CSF installed, LFD provides Webmin protection out of the box without additional configuration. If you only have Fail2Ban, the setup in this guide is sufficient. If you're managing multiple services and want centralized control, CSF's GUI integration with Webmin (via the CSF plugin) provides a cleaner management experience.



