Why Webmin Servers Are Targeted — and What Attackers Do
Webmin runs on port 10000 by default and is reachable from the public internet on most VPS installations. Its web-based interface, combined with the fact that it runs as root, makes it a high-value target: compromising Webmin means compromising the entire server. In 2023, a critical remote code execution vulnerability (CVE-2023-10904) affected Webmin 1.x before 2.021 — and unpatched servers were being exploited within 48 hours of disclosure.
This guide walks through a layered security hardening approach: Fail2Ban to block brute force attacks on Webmin and SSH, firewall IP restriction, disabling unused modules, enabling 2FA, and system-wide security scanning — all configured via Webmin's own interface or Webmin's shell access.
Step 1: Update Webmin to the Latest Version
Before hardening, ensure you are running a patched version. Webmin 2.x has significantly improved the security architecture compared to 1.x.
# Check current Webmin version
webmin --version
cat /usr/share/webmin/version
# Update on Debian/Ubuntu
apt-get update and apt-get upgrade webmin
# Update on CentOS/RHEL
yum update webmin
# Verify CVE-2023-10904 is patched (requires webmin >= 2.021)
webmin --version | grep -E "^[2-9]\." and echo "Patched" or echo "VULNERABLE — update immediately"
Step 2: Change the Default Webmin Port
Port 10000 is the default and is actively scanned by automated bots. Moving Webmin to a non-standard port eliminates the vast majority of automated attack traffic.
# Edit miniserv.conf
nano /etc/webmin/miniserv.conf
# Change: port=10000
# To: port=37241
# Restart Webmin
service webmin restart
# Update your firewall to allow the new port
iptables -A INPUT -p tcp --dport 37241 -j ACCEPT
iptables -D INPUT -p tcp --dport 10000 -j ACCEPT
Step 3: Restrict Webmin Access by IP Address
Allow Webmin access only from your known administrative IP addresses. This is the single most effective control — even if an attacker knows your password, they cannot log in from an unknown IP.
# Edit miniserv.conf directly
nano /etc/webmin/miniserv.conf
# Add this line:
allow=203.0.113.10 10.0.0.0/24
# Restart Webmin to apply
service webmin restart
Use an SSH Tunnel Instead
Even better than IP allowlisting: put Webmin on localhost only and access it through an SSH tunnel. This removes Webmin from the public internet entirely:
# Set Webmin to listen on localhost only
nano /etc/webmin/miniserv.conf
# Change: bind=0.0.0.0
# To: bind=127.0.0.1
service webmin restart
# SSH tunnel from your laptop to the server:
ssh -L 10000:localhost:10000 root@yourserver.com
# Then open: https://localhost:10000 in your browser
Step 4: Install and Configure Fail2Ban for Webmin and SSH
Fail2Ban monitors authentication logs and bans IP addresses after a configurable number of failed login attempts. It is essential for any server with SSH or Webmin exposed to the internet.
Install Fail2Ban
# Debian/Ubuntu
apt-get install fail2ban -y
# CentOS/RHEL
yum install epel-release -y and yum install fail2ban -y
# Start and enable
systemctl enable --now fail2ban
Configure SSH and Webmin Protection
Create /etc/fail2ban/jail.local (never edit jail.conf — it gets overwritten on updates):
[DEFAULT]
bantime = 3600
findtime = 900
maxretry = 5
backend = systemd
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
maxretry = 3
bantime = 86400
[webmin-auth]
enabled = true
port = 10000,37241
filter = webmin-auth
logpath = /var/log/auth.log
maxretry = 5
bantime = 3600
findtime = 600
Create the filter file /etc/fail2ban/filter.d/webmin-auth.conf:
[Definition]
failregex = webmin.*Invalid login as .+ from <HOST>
webmin.*Failed password for .+ from <HOST>
ignoreregex =
# Restart Fail2Ban to apply
service fail2ban restart
# Verify jails are active
fail2ban-client status
fail2ban-client status sshd
fail2ban-client status webmin-auth
Test Fail2Ban Is Working
# Check banned IPs in SSH jail
fail2ban-client status sshd | grep "Banned IP"
# Check the ban log
tail -50 /var/log/fail2ban.log | grep -i "banned"
# Manually ban an IP for testing
fail2ban-client set sshd banip 192.0.2.99
# Unban an IP
fail2ban-client set sshd unbanip 192.0.2.99
Step 5: Harden SSH Configuration
SSH is the most attacked service on any Linux server. These settings close the most common attack vectors:
nano /etc/ssh/sshd_config
# Disable password authentication (use SSH keys instead)
PasswordAuthentication no
ChallengeResponseAuthentication no
# Disable root login
PermitRootLogin no
# Only allow specific users
AllowUsers youradminuser
# Change the default port
Port 2222
# Disable empty passwords
PermitEmptyPasswords no
# Use modern algorithms only
KexAlgorithms curve25519-sha256,diffie-hellman-group16-sha512
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
# Disconnect idle sessions after 15 minutes
ClientAliveInterval 300
ClientAliveCountMax 3
# Test config before restarting (avoid lockout!)
sshd -t
# If no errors:
service sshd restart
Step 6: Enable Two-Factor Authentication in Webmin
Even with Fail2Ban and IP allowlisting, enabling 2FA adds a critical second layer. Webmin supports Google Authenticator (TOTP) natively.
# Install the Perl TOTP module
apt-get install libauthen-oath-perl -y # Debian/Ubuntu
yum install perl-Authen-OATH -y # CentOS/RHEL
- In Webmin, go to Webmin > Webmin Configuration > Two-Factor Authentication
- Select Google Authenticator from the dropdown
- Click Save
- Go to Webmin > Webmin Users > [your username]
- Click Enroll For Two-Factor Authentication
- Scan the QR code with Google Authenticator or Authy
- Enter a TOTP code to confirm enrollment
Step 7: Run a Rootkit Scan with rkhunter
Run a baseline integrity check to confirm the server has not been compromised before applying hardening.
# Install rkhunter
apt-get install rkhunter -y # Debian/Ubuntu
yum install rkhunter -y # CentOS/RHEL
# Update the database
rkhunter --update
# Run a full scan
rkhunter --check --sk
# Show warnings only
rkhunter --check --sk 2>&1 | grep -E "Warning|Found|Infected"
Step 8: Disable Unused Webmin Modules
Every enabled Webmin module is a potential attack surface. Disable modules you do not use:
# Via Webmin GUI
# Webmin > Webmin Configuration > Webmin Modules
# Select unused modules and click "Delete from Webmin"
# Commonly safe to disable if unused:
# - Bandwidth Monitoring
# - PPP Dialup Client
# - PPTP Client
# - NFS Exports (if not using NFS)
# Verify modules via file system
ls /usr/share/webmin/ | head -20
Post-Hardening Verification Checklist
- Webmin runs on non-default port:
ss -tlnp | grep webmin - Webmin IP restriction active: check
/etc/webmin/miniserv.conffor allow= line - Fail2Ban SSH jail active:
fail2ban-client status sshd - Fail2Ban Webmin jail active:
fail2ban-client status webmin-auth - SSH password auth disabled:
grep PasswordAuthentication /etc/ssh/sshd_config - 2FA enrolled for all Webmin admin accounts
- rkhunter scan clean: no "Warning: Possible rootkit" results
- Webmin updated to latest 2.x version
Conclusion
Securing a Webmin server is not a single configuration change — it is a layered defence: update the software, restrict access by IP, enable Fail2Ban for both SSH and Webmin, configure 2FA, harden SSH, and scan for existing compromises. Each layer makes the next attack harder. If you want this hardening applied correctly with ongoing monitoring — so you know immediately if something changes — the team at CloudHouse server management handles Webmin security configuration as part of our fully managed server plans.
