Webmin System Administration 2.670
Overview
Webmin is the long-standing web-based system administration panel for Linux. From one browser session, you can manage users and groups, packages and updates, systemd services, cron jobs, the firewall, disks and filesystems, web and DNS servers and much more. Webmin runs its own web server (miniserv) as root and serves the console over HTTPS on port 10000.
This guide covers the Webmin System Administration 2.670 on Ubuntu 24.04 AMI from SecureAnyCloud on Amazon EC2. It is one version of the SecureAnyCloud Infrastructure as Code and Config Management listing on AWS Marketplace. You pick it as the software version when you subscribe and launch.
Webmin can do anything root can do on this server. Treat its admin password as a root password, and allow port 10000 only from the addresses you manage the server from.
What you get:
- A password unique to your instance, and no other way in. The only Webmin user is
admin. Its password is generated on your instance's first boot, hashed straight into Webmin's user file, and written to/root/webmin-credentials.txt, readable byrootonly. The password never appears on a command line or in a log. Logins by Unix users, by root and by sudo-capable users are switched off, and no module is reachable without signing in. - HTTPS only, with a certificate made on your instance. Port 10000 accepts TLS 1.2 and 1.3 only, plain HTTP on port 10000 is redirected to HTTPS, and HSTS is on. The certificate and its private key are generated on first boot, so no two instances share a key. Port 80 is served by nginx and only redirects to Webmin, plus a
/healthzcheck. It never proxies Webmin. - Brute-force protection. An address is blocked for 5 minutes after 5 failed logins, and a user name is blocked after 5 failures. Each failure adds a growing delay before the next attempt for that user.
- Requests from other web sites are refused. Webmin's referer check is on, and a request that arrives with no referer is refused too.
- The host name comes from configuration, never from a request. Webmin answers only to the name it is configured for (your instance's public IP address by default) and refuses any other
Hostheader. A request therefore cannot steer its redirects or its referer check. The helperwebmin-set-hostchanges the name. - URL downloads cannot reach private addresses. Webmin 2.670 includes the fix for GHSA-x8qr-rx2g-f23g, and the image switches it on for
admin. The Upload and Download, File Manager and Mailboxes modules refuse to download from a URL that resolves to a private, loopback, link-local or other non-public address. Webmin checks the address after it connects, so the request itself can still reach such a host. The block below covers the instance metadata service separately. - Instance metadata is blocked for Webmin and nginx, and the instance requires IMDSv2.
- Exactly three ports: 22 (SSH), 80 (redirect) and 10000 (Webmin). Webmin's UDP discovery listener is off, and Usermin is not installed.
What is on the image: Webmin 2.670 (installed from the official .deb, checksum verified), nginx, Ubuntu 24.04 LTS, cloud-init and the AWS Systems Manager agent. Webmin's working data (sessions, logs, the block list) lives on its own EBS volume at /var/webmin.
Default user: ubuntu. Architecture: x86_64. Recommended instance type: m5.large.
Prerequisites
You need an AWS account subscribed to the listing, an EC2 key pair, and a VPC subnet with a route to the internet (or a private route you use for management).
Configure a security group that allows TCP 10000 (Webmin) and TCP 22 (SSH) from your own IP address or management network only. Optionally allow TCP 80, which only redirects to Webmin. Do not open port 10000 to 0.0.0.0/0.
Launch the instance
In the AWS Marketplace listing, choose Continue to Subscribe, then Continue to Configuration. Pick Webmin System Administration 2.670 on Ubuntu 24.04 as the software version, select your Region, and choose Launch through EC2.
Choose m5.large, your key pair and a security group as described above. Webmin itself is light, so a smaller type works for a single server. Keep the second EBS volume, because it holds Webmin's working data.
To launch with the AWS CLI instead, replace the values in angle brackets:
aws ec2 run-instances --region <region> --image-id <ami-id-from-the-listing> \
--instance-type m5.large --key-name <your-key-pair> \
--security-group-ids <your-security-group> --subnet-id <your-subnet> \
--metadata-options HttpTokens=required,HttpEndpoint=enabled \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=webmin}]'Connect to your instance
Connect over SSH as the user ubuntu, the SSH user for Webmin System Administration 2.670 on Ubuntu 24.04:
ssh -i <your-key.pem> ubuntu@<public-ip>Check the services and the ports
First boot takes a few seconds. After that, Webmin, nginx and the two SecureAnyCloud first-boot units are active:
systemctl is-active webmin nginx webmin-firstboot webmin-set-hostactive active active activeWebmin (miniserv.pl) listens on port 10000, nginx on port 80 and SSH on port 22. Nothing else listens on a public address:
sudo ss -tlnp | awk 'NR==1 || /nginx|sshd|miniserv/' | awk '{print $1, $4, $6}' | sed -E 's/,pid=[0-9]+,fd=[0-9]+//g'State Local Peer LISTEN 0.0.0.0:22 users:(("sshd"),("systemd")) LISTEN 0.0.0.0:80 users:(("nginx"),("nginx"),("nginx")) LISTEN 0.0.0.0:10000 users:(("miniserv.pl")) LISTEN [::]:22 users:(("sshd"),("systemd")) LISTEN [::]:80 users:(("nginx"),("nginx"),("nginx")) LISTEN [::]:10000 users:(("miniserv.pl"))Webmin's working data is on the separate volume:
findmnt -no SOURCE,TARGET,FSTYPE /var/webmin df -h --output=size,avail,target /var/webmin/dev/nvme1n1 /var/webmin ext4 Size Avail Mounted on 20G 19G /var/webminGet your URL and admin password
Read the credentials file with sudo:
sudo cat /root/webmin-credentials.txt# Webmin - generated on this instance's first boot. Unique to this instance. # Webmin runs as root and can manage the whole server: treat these as root credentials. WEBMIN_URL=https://<public-ip>:10000/ WEBMIN_USERNAME=admin WEBMIN_PASSWORD=<24 letters and digits> # The certificate is self-signed (per instance). Allow TCP 10000 only from your own IP in the security # group. To serve Webmin under a DNS name:
sudo webmin-set-host <name> Guide: https://secureanycloud.com/stacks/webmin-system-administration-2-670/Sign in
Open the WEBMIN_URL from the credentials file in your browser, for example https://<public-ip>:10000/. The certificate is self-signed, so your browser shows a warning the first time. Check that the address is your instance's, then continue. You can also install your own certificate (Step 9).
Sign in as admin with the password from the credentials file.
The dashboard shows the server at a glance: host name, operating system, Webmin version, CPU, memory, disk and whether packages are up to date. The menu on the left opens every module.
Open System > Users and Groups to manage the server's Unix accounts. Open System > Software Package Updates to list and install pending Ubuntu updates.
Webmin answers only to its configured name. If you browse to it by another name or address, for example the private IP address over a VPN, it replies Invalid HTTP hostname. Set the name you use with webmin-set-host (Step 8).
Check the sign-in from the command line
The command below signs in over HTTPS on the instance itself and prints the HTTP status. It reads the password from the credentials file on standard input, so the password never appears on a command line.
A status of 302 means you are signed in. A wrong password returns 200 with "Login failed":
HOST=$(sudo awk -F= '$1=="musthost"{print $2}' /etc/webmin/miniserv.conf)
JAR=$(mktemp)
curl -sk -o /dev/null -c "$JAR" -H "Host: $HOST:10000" https://127.0.0.1:10000/session_login.cgi
sudo grep '^WEBMIN_PASSWORD=' /root/webmin-credentials.txt | cut -d= -f2- | tr -d '\n' | \
curl -sk -o /dev/null -b "$JAR" -c "$JAR" -w 'sign in: %{http_code}\n' -H "Host: $HOST:10000" \
--data-urlencode user=admin --data-urlencode pass@- --data page=/ https://127.0.0.1:10000/session_login.cgi rm -f "$JAR"sign in: 302Security checks
Check the Webmin server configuration. It enforces HTTPS only, redirects plain HTTP, and turns TLS 1.0 and 1.1 off. Sudo and Unix logins are off, root is denied, the UDP listener is off, brute-force blocking is on and the host is pinned:
sudo grep -E '^(port|ssl|ssl_enforce|ssl_hsts|no_tls1|no_tls1_1|sudo|denyusers|listen|blockhost_failures|blockhost_time|blockuser_failures|blockuser_time)=' /etc/webmin/miniserv.confport=10000 ssl=1 ssl_enforce=2 ssl_hsts=1 no_tls1=1 no_tls1_1=1 blockhost_failures=5 blockhost_time=300 blockuser_failures=5 blockuser_time=300 sudo=0 denyusers=root listen=Referer checking refuses requests with no referer. admin is the only Webmin user, and its URL downloads are limited to public addresses:
sudo grep -E '^referers_none=' /etc/webmin/config
sudo cut -d: -f1 /etc/webmin/miniserv.users
sudo cat /etc/webmin/admin.aclreferers_none=1 admin download_address_mode=publicOnly TLS 1.2 and 1.3 are accepted:
for v in tls1 tls1_1 tls1_2 tls1_3; do if echo | timeout 5 openssl s_client -connect 127.0.0.1:10000 -$v >/dev/null 2>&1; then echo "$v accepted"; else echo "$v refused"; fi donetls1 refused tls1_1 refused tls1_2 accepted tls1_3 acceptedWebmin refuses a request for any other host name with 400. nginx gives no answer, which curl shows as 000:
curl -sk -o /dev/null -w 'webmin: %{http_code}\n' -H 'Host: other.invalid:10000' https://127.0.0.1:10000/
curl -s -o /dev/null -w 'nginx: %{http_code}\n' -H 'Host: other.invalid' http://127.0.0.1/ || truewebmin: 400 nginx: 000Webmin and nginx cannot reach the instance metadata service:
systemctl show -p IPAddressDeny webmin nginxIPAddressDeny=168.63.129.16/32 169.254.169.254/32 fd00:ec2::254/128 IPAddressDeny=168.63.129.16/32 169.254.169.254/32 fd00:ec2::254/128What the metadata block means for you. Everything Webmin runs runs inside the webmin service. This includes commands from its Command Shell, downloads in Upload and Download and anything else started from the Webmin console. None of it can read instance metadata or use the instance's IAM role. This stops a request smuggled through Webmin from reading your instance's role credentials. Run AWS CLI commands that need the instance role from an SSH session instead.
Separately, Webmin's own URL downloads reach only public addresses. To download from a server on your private network, open Webmin > Webmin Users and choose Global ACL for admin (Permissions for all modules). Set URL download destinations to Public IP addresses and these exceptions. List only the addresses or networks you trust (never 169.254.169.254) rather than choosing All IP addresses.
If you need Webmin itself to reach the metadata service, remove /etc/systemd/system/webmin.service.d/50-sac-imds-deny.conf and run sudo systemctl daemon-reload && sudo systemctl restart webmin. Anyone who can sign in to Webmin can then read the role's credentials.
Your own DNS name
Point a DNS name at the instance. An Elastic IP keeps the address stable.
Then tell Webmin to use the name. The command below creates a new certificate for the name, updates Webmin's allowed host, the port 80 redirect and the URL in the credentials file, and restarts Webmin:
sudo webmin-set-host <your-domain>Without a configured name, the instance uses its public IP address, or its private IP address when it has no public one. It picks up a new address automatically after a stop and start.
Your own certificate
To use a certificate from your certificate authority, open Webmin > Webmin Configuration > SSL Encryption and upload the private key and certificate.
Alternatively, replace /etc/ssl/private/sac-webmin.key and /etc/ssl/certs/sac-webmin.crt, keeping the key 0600 root, and run sudo systemctl restart webmin. Running webmin-set-host again replaces them with a new self-signed certificate.
Change the admin password
Sign in, open Webmin > Webmin Users, choose admin and set a new password. The credentials file is not updated. Once you have stored the new password somewhere safe, delete the file with sudo shred -u /root/webmin-credentials.txt.
Avoid changepass.pl with the password as an argument, because other users on the server can see a command line while it runs.
Updates
Ubuntu security updates install automatically through unattended-upgrades.
Webmin reports newer Webmin releases on its dashboard. Upgrade with Upgrade Webmin Now or from Webmin > Webmin Configuration > Upgrade Webmin.
The hardening described above lives in /etc/webmin and is kept across upgrades. sudo=0 stays set, so an upgrade does not turn sudo logins back on. Recheck the hardening after an upgrade with the commands in Step 7.
Server components
- Webmin 2.670: /usr/share/webmin, configuration in /etc/webmin, service webmin (port 10000, HTTPS)
- nginx: port 80, serving /healthz and a redirect to Webmin only
- Data volume: /var/webmin (sessions, action and access logs, block list)
- First boot: webmin-firstboot.service (once) and webmin-set-host.service (every boot)
- Credentials: /root/webmin-credentials.txt (root only)
- Certificate and key: /etc/ssl/certs/sac-webmin.crt and /etc/ssl/private/sac-webmin.key
- Logs: /var/webmin/miniserv.log (requests), /var/webmin/webmin.log (actions), and failed logins in the journal (journalctl -t webmin)
Security recommendations
- Allow TCP 10000 and 22 only from your own addresses. Use a VPN or AWS Systems Manager Session Manager where you can.
- Use a DNS name with a certificate from your certificate authority for anything beyond your own use.
- Change the admin password after your first sign-in and delete the credentials file.
- Consider enabling Webmin > Webmin Configuration > Two-Factor Authentication.
- Keep Webmin and Ubuntu up to date.
Support and licensing
Webmin is open source software under the BSD 3-Clause License. A copy is at /usr/share/doc/sac/webmin/LICENSE. Webmin is a trademark of its respective owner, and SecureAnyCloud is not affiliated with or endorsed by the Webmin project.
SecureAnyCloud provides 24/7 support for this image by email at sales@secureanycloud.com.
Deploy on AWS
Launch Webmin System Administration 2.670 on Ubuntu 24.04 on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com