$linuxjunkies
>

How to Secure Webmin

Harden Webmin against attack: restrict access by IP, enforce HTTPS with valid certs, set up TOTP two-factor auth, integrate Fail2ban, and lock down modules.

IntermediateUbuntuDebianFedoraArch10 min readUpdated June 7, 2026

Before you start

  • Webmin 2.x installed and accessible on the target server
  • Root or sudo access to the server via SSH
  • A registered FQDN pointing to the server (required for Let's Encrypt)
  • A TOTP authenticator app installed on your mobile device

Webmin is a powerful web-based administration interface that exposes root-level control over your server. Out of the box it is functional but not hardened — default port, broad network access, and no multi-factor authentication. This guide walks through every practical layer of defense: network restriction, HTTPS enforcement, strong authentication, two-factor auth (TOTP), Fail2ban integration, and module-level lockdown.

Prerequisites and Assumptions

Webmin is already installed and reachable. These steps assume you are running Webmin 2.x and have root or sudo access to the underlying system. All firewall examples show both ufw (Debian/Ubuntu) and firewalld (Fedora/RHEL/Rocky) equivalents.

1. Restrict Access by IP at the Firewall

Webmin listens on TCP port 10000 by default. The first line of defense is making that port unreachable except from trusted addresses. Do this at the firewall before touching Webmin's own settings.

ufw (Debian/Ubuntu/Mint)

# Replace 203.0.113.10 with your admin IP or CIDR range
sudo ufw deny 10000
sudo ufw allow from 203.0.113.10 to any port 10000 proto tcp
sudo ufw reload

firewalld (Fedora/RHEL/Rocky)

# Create a rich rule; repeat for additional IPs
sudo firewall-cmd --permanent --add-rich-rule=\
  'rule family=ipv4 source address=203.0.113.10/32 port port=10000 protocol=tcp accept'
sudo firewall-cmd --permanent --remove-service=webmin 2>/dev/null || true
sudo firewall-cmd --reload

nftables (Arch / any distro using raw nftables)

# Add to your existing inet filter input chain
sudo nft add rule inet filter input \
  ip saddr 203.0.113.10 tcp dport 10000 accept
sudo nft add rule inet filter input \
  tcp dport 10000 drop

If you connect over a VPN, allow only the VPN subnet and block public access entirely — that alone eliminates the majority of attack surface.

2. Enforce HTTPS with a Valid Certificate

Webmin ships with a self-signed certificate. Replace it with a real one or at minimum verify TLS is active and using modern ciphers.

Confirm SSL is enabled

In the Webmin UI: Webmin → Webmin Configuration → SSL Encryption. Ensure Enable SSL is set to Yes. Alternatively, check the config directly:

grep -E '^ssl=' /etc/webmin/miniserv.conf
# Expected output: ssl=1

Install a Let's Encrypt certificate via Webmin's built-in tool

Go to Webmin → Webmin Configuration → SSL Encryption → Let's Encrypt. Enter your FQDN (e.g., admin.example.com) and click Request Certificate. Webmin handles renewal automatically via a systemd timer it installs itself.

Set minimum TLS version and strong ciphers

Edit /etc/webmin/miniserv.conf and ensure these lines are present (add or update them):

sudo sed -i '/^ssl_version=/d; /^ssl_cipher_list=/d' /etc/webmin/miniserv.conf
echo 'ssl_version=3' | sudo tee -a /etc/webmin/miniserv.conf
echo 'ssl_cipher_list=HIGH:!aNULL:!MD5:!RC4:!DH' | sudo tee -a /etc/webmin/miniserv.conf
sudo systemctl restart webmin

ssl_version=3 tells Webmin's miniserv to use TLSv1.2 as the minimum. Versions of Webmin 2.x compiled against OpenSSL 1.1+ will negotiate TLS 1.3 automatically.

3. Enforce Strong Authentication

Disable the root account login; use a dedicated admin user

Creating a Webmin-only admin avoids exposing the system root password. In the UI: Webmin → Webmin Users → Create a new Webmin user. Grant the new user only the modules it needs, then:

# Disable root login to Webmin (keep Unix root separate)
grep -q '^not_allow_root=' /etc/webmin/miniserv.conf && \
  sudo sed -i 's/^not_allow_root=.*/not_allow_root=1/' /etc/webmin/miniserv.conf || \
  echo 'not_allow_root=1' | sudo tee -a /etc/webmin/miniserv.conf
sudo systemctl restart webmin

Set a password policy

Under Webmin → Webmin Configuration → Authentication, set Minimum password length to at least 16 and enable Block logins after 5 failures. Also enable Session authentication to invalidate idle sessions after a timeout (15–30 minutes is reasonable).

4. Enable Two-Factor Authentication (TOTP)

Webmin has native TOTP support via the Two-Factor Authentication module — no external package needed on Webmin 2.x.

  1. Navigate to Webmin → Webmin Configuration → Two-Factor Authentication.
  2. Select Google Authenticator (TOTP) as the provider.
  3. Click Save, then click Enroll for Two-Factor Authentication for your admin user.
  4. Scan the QR code with your authenticator app (Aegis, Google Authenticator, etc.).
  5. Enter the 6-digit code to confirm enrollment.

After enrollment, every login requires the one-time code. Store your backup codes somewhere safe and offline. If the server is headless and you lose your TOTP device, recovery requires editing /etc/webmin/<username>.totp directly on the host.

5. Configure Fail2ban for Webmin

Fail2ban can ban IPs that repeatedly fail Webmin authentication by watching the Webmin auth log.

Install Fail2ban

# Debian/Ubuntu
sudo apt install fail2ban -y

# Fedora/RHEL/Rocky
sudo dnf install fail2ban -y

# Arch
sudo pacman -S fail2ban

Create the Webmin filter

sudo tee /etc/fail2ban/filter.d/webmin.conf <<'EOF'
[Definition]
failregex = ^%(__prefix_line)sInvalid password for user .+ from \s*$
             ^%(__prefix_line)sFailed login as .+ from \s*$
ignoreregex =
EOF

Create the jail

sudo tee /etc/fail2ban/jail.d/webmin.conf <<'EOF'
[webmin]
enabled  = true
filter   = webmin
logpath  = /var/log/webmin/miniserv.log
maxretry = 5
bantime  = 1h
findtime = 10m
EOF
sudo systemctl enable --now fail2ban
sudo systemctl restart fail2ban

Verify the jail is active

sudo fail2ban-client status webmin
# Output will show Status, currently failed count, and banned IPs

6. Lock Down Webmin Modules

By default a Webmin admin user can access every module. Restrict access to only what each operator actually needs.

Per-user module access

Go to Webmin → Webmin Users, click your admin user, then click Available Webmin modules. Deselect everything not required. For a typical application admin, that might mean granting only Apache, MySQL, and System Logs — not Disk and Network Filesystems, BIND DNS, or Software Packages.

IP-based access control per module

Under Webmin → Webmin Configuration → IP Access Control, you can restrict which IPs may access Webmin at all. This is a second layer on top of your firewall rule and useful when multiple people share an admin account (not recommended, but common).

Disable unused modules globally

# List all enabled modules
ls /etc/webmin/

Each subdirectory corresponds to a module. To disable one, add a nomodule=1 line to its config file or delete the module's directory entry from /etc/webmin/webmin.acl. The cleaner way is through the UI: Webmin → Webmin Configuration → Webmin Modules → Uninstall.

7. Change the Default Port

Security through obscurity is not a primary defense, but changing port 10000 reduces automated scan noise significantly.

sudo sed -i 's/^port=10000/port=10043/' /etc/webmin/miniserv.conf
sudo systemctl restart webmin

Update your firewall rules to allow the new port and deny 10000. If you use SELinux (Fedora/RHEL/Rocky), you must also label the new port:

sudo semanage port -a -t http_port_t -p tcp 10043

Verification Checklist

  • From an untrusted IP, curl -k https://<your-server>:10000 should time out or be refused.
  • From your trusted IP, the Webmin login page loads over HTTPS with a valid certificate (check with openssl s_client -connect <host>:<port>).
  • Logging in with a wrong password five times triggers a Fail2ban ban — confirm with sudo fail2ban-client status webmin.
  • TOTP prompt appears after correct username/password entry.
  • The limited admin user cannot see modules they were not granted.

Troubleshooting

Webmin won't start after SSL changes
Check sudo journalctl -u webmin -n 50. A bad ssl_cipher_list value causes miniserv to abort. Remove the line and restart to confirm, then correct the cipher string.
Fail2ban not banning — log path wrong
Webmin's log location varies: check /var/log/webmin/miniserv.log and /var/webmin/miniserv.log. Use whichever exists in the jail config.
Locked out after enabling TOTP
SSH into the server and delete or rename /etc/webmin/<username>.totp. Webmin will skip TOTP for that user on next login.
SELinux blocking Webmin on the new port
Run sudo ausearch -m avc -ts recent | audit2why to identify the denial, then use semanage port as shown above.
tested on:Ubuntu 24.04Debian 12Rocky 9Arch rolling

Frequently asked questions

Can I put Webmin behind an Nginx reverse proxy instead of exposing miniserv directly?
Yes, and it is a good approach. Proxy HTTPS through Nginx on port 443, set ssl=0 in miniserv.conf so miniserv handles plain HTTP on localhost only, and bind miniserv to 127.0.0.1 by adding 'bind=127.0.0.1' to miniserv.conf. Nginx handles TLS termination and you can add rate-limiting at the proxy layer.
Does enabling Fail2ban for Webmin interfere with the login lockout built into Webmin itself?
No, they operate independently. Webmin's built-in lockout works at the application layer per user, while Fail2ban bans at the IP level using the firewall backend. Running both gives you defence in depth.
Is it safe to use Webmin on a public-facing server at all?
With the hardening in this guide applied — IP restriction, HTTPS, TOTP, and Fail2ban — the risk is significantly reduced. The safest posture is still to allow access only from a VPN or bastion host so no login interface is reachable from the public internet.
How do I recover if Fail2ban bans my own IP?
SSH in on port 22 (which Fail2ban is not monitoring here) and run: sudo fail2ban-client set webmin unbanip YOUR_IP. To prevent self-bans, add your admin IP to the ignoreip line in /etc/fail2ban/jail.local.
Does Webmin's TOTP work with hardware keys like YubiKey?
Webmin's native two-factor module supports TOTP and Authy but not FIDO2/WebAuthn natively in version 2.x. For hardware key support you would need to front Webmin with an SSO proxy (e.g., Authelia) that supports WebAuthn, or use the PAM module path if Webmin is configured to authenticate via PAM.

Related guides