How To Install Webmin And Secure With Nginx On Ubuntu 18.04 LTS

By bhagwatchouhan
How To Install Webmin And Secure With Nginx On Ubuntu 18.04 LTS

Webmin is one of the popular web-based interfaces for system administration for Unix. We can manage the system services using the appropriate Webmin modules. The popular and official modules available for Webmin includes cron, bind8, apache, mysql, dovecot, postfix, postgrey, fail2ban, and syslog. We can install these modules based on the actual needs and manage the associated services from the Webmin itself without using the shell. Webmin makes it easy to administer the system using the graphical interface. The most recent version of Webmin while writing this tutorial is 1.930. We will install the same as part of this tutorial.

 

This tutorial provides the steps required to install Webmin on the popular Linux distribution Ubuntu and access it via Nginx by configuring it as a reverse proxy. In this way, we will install Webmin and access it via Nginx over the standard HTTP/HTTPS ports. It provides all the steps required to install and use Webmin on Ubuntu 18.04 LTS. The steps should be similar for other Linux systems and Ubuntu versions.

 

You may also follow the relevant tutorials including How To Install And Configure Nginx on Ubuntu 18.04 LTS, Configure Virtual Host Or Server Block On Nginx and How To Install Let's Encrypt For Nginx On Ubuntu.

 

Updates: The newer version of this tutorial is available at How To Install Webmin And Secure With Nginx On Ubuntu 20.04 LTS.

 

Prerequisites

 

You must meet the below-listed prerequisites on the server to continue with this tutorial.

 

Ubuntu Server - This tutorial is written for Ubuntu 18.04 LTS, though it can be any other Linux system. The steps should be the same on other systems. You can also follow Complete Guide To Install Ubuntu 18.04 LTS (Bionic Beaver) to install the desktop version of Ubuntu.

 

Nginx Web Server - It assumes that the Nginx is already installed on the system and it's configured properly to access it using the domain. You can also follow How To Install And Configure Nginx on Ubuntu 18.04 LTS to install the Nginx Web Server.

 

Domain - A valid domain properly configured at your domain registrar pointing to your server. I have used example.com in this tutorial for reference. Make sure to replace it with your own domain.

 

Firewall - Ports 80 and 443 are open to accept connections.

 

Add Virtual Host (Server Block)

 

In this section, we will add the virtual host and enable it to access the application using the domain. You may skip this step in case you already have an active website or application accessible from the browser using the domain name.

 

Add and update the Virtual Host to Nginx Web Server as shown below. I have used the nano editor for demonstration purposes. You can use any editor of your choice. Also, replace example.com with the actual domain. Create the directory /var/www/example.com/html to store the website or application files.

 

# Create the directories if does not exist
sudo mkdir /etc/nginx/sites-available
sudo mkdir /etc/nginx/sites-enabled

# Copy the default config
sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/example.com
# OR
sudo cp /etc/nginx/conf.d/default.conf /etc/nginx/sites-available/example.com

 

Now update the configuration to configure your domain and the system path having site files. The configuration should look like the one as shown below.

 

# Update configuration
/etc/nginx/sites-available/example.com

# Content
server {
listen 80;
server_name example.com www.example.com;

#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;

location / {
root /var/www/example.com/html;
index index.html index.htm;
}

#error_page 404 /404.html;

# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}

# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}

# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}

# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}

# Save and exit the editor

# Create the site directory and update permissions
sudo mkdir /var/www/example.com/html
sudo chmod -R 755 /var/www/example.com

 

Use the below-mentioned commands to enable or disable the site configuration.

 

# Enable Site - Create the symlink
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com

# Disable Site
sudo rm /etc/nginx/sites-enabled/example.com
# OR
sudo unlink /etc/nginx/sites-enabled/example.com

 

Apply the configuration using the below-mentioned commands.

 

# Check configurations
sudo nginx -t

# Reload configuration
sudo nginx -s reload
# OR
sudo systemctl reload nginx

 

Now add the index.html file having content as shown below.

 

# Add index.html
sudo nano /var/www/example.com/html/index.html

# Content
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Domain</title>
</head>
<body>
<h1>Welcome to My Domain.</h1>
</body>
</html>

# Save and exit the editor

 

If your domain is correctly pointing to your system, you must be able to access it from the browser by navigating to http://www.example.com. It should show the output of our simple HTML file - Welcome to My Domain.

 

Install Certbot

 

In this section, we will install the most recent version of Certbot using the official repository. You may uninstall the previous installation of Certbot using the commands as shown below.

 

# Uninstall Certbot
sudo apt remove python-certbot-nginx
sudo apt remove certbot
sudo apt purge certbot
sudo apt-get autoclean

# Make sure to use purge
sudo apt-get autoremove
# OR
sudo apt-get --purge autoremove

 

Now we will add the official repository to the system repositories. It can be done using the commands as shown below.

 

# Add Certbot repository
sudo add-apt-repository ppa:certbot/certbot

# Press Enter to confirm
This is the PPA for packages prepared by Debian Let's Encrypt Team and backported for Ubuntu(s).
More info: https://launchpad.net/~certbot/+archive/ubuntu/certbot
Press [ENTER] to continue or Ctrl-c to cancel adding it.
...
...

 

Now refresh the packages index using the command as shown below.

 

# Refresh packages index
sudo apt-get update

 

We can install the Certbot using the same command as we did in the previous section.

 

# Install Let's Encrypt
sudo apt-get install python-certbot-nginx

# Installation results
...
...
Setting up python3-certbot (0.31.0-1+ubuntu18.04.1+certbot+1) ...
Setting up certbot (0.31.0-1+ubuntu18.04.1+certbot+1) ...
Created symlink /etc/systemd/system/timers.target.wants/certbot.timer → /lib/systemd/system/certbot.timer.
certbot.service is a disabled or a static unit, not starting it.
Setting up python3-certbot-nginx (0.31.0-1+ubuntu18.04.1+certbot+1) ...
Setting up python-certbot-nginx (0.31.0-1+ubuntu18.04.1+certbot+1) ...
Processing triggers for man-db (2.8.3-2ubuntu0.1) ...

 

We can confirm the installation by checking the Certbot version as shown below.

 

# Check Certbot version
certbot --version

# Output
certbot 0.31.0

 

This is how we can clean the existing installation of Certbot and install the most recent version of it on the system.

 

Install SSL Certificate and Secure Virtual Host

 

We will install the SSL certificate and secure virtual host in this step. It can be done using the command as shown below.

 

# Install Certificate - Syntax - Single Domain
sudo letsencrypt --nginx -d <domain 1> --email <email address>

# Install Certificate - Syntax - Multiple Domains
sudo letsencrypt --nginx -d <domain 1>,<domain 2>,<domain 3> --email <email address>

# Example
sudo letsencrypt --nginx -d example.com,www.example.com --email admin@example.com

# Agree - Press A and Enter - First time only
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel: A

# Share Email for communication - Press Y and Enter
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y

# Choose redirect options - redirect
Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2

# Certificate installed successfully
Congratulations! You have successfully enabled https://example.com

You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=example.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/example.com/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/example.com/privkey.pem
Your cert will expire on 2020-01-04. To obtain a new or tweaked
version of this certificate in the future, simply run certbot again
with the "certonly" option. To non-interactively renew *all* of
your certificates, run "certbot renew"
- Your account credentials have been saved in your Certbot
configuration directory at /etc/letsencrypt. You should make a
secure backup of this folder now. This configuration directory will
also contain certificates and private keys obtained by Certbot so
making regular backups of this folder is ideal.
- If you like Certbot, please consider supporting our work by:

Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le

 

Now if you try to open the URL - http://www.example.com, it must redirect you to https://www.example.com. Make sure that your firewall allows communication on port 443.

 

This is how we can secure an entire website or application using the SSL certificate for secure communication over the Nginx web server and the clients(Browser etc).

 

Now if you again open the virtual host file, you must see that Certbot has removed the listen directive for port 80 and added the SSL certificate lines at the bottom of the Server Block.

 

# Check Virtual Host
sudo nano /etc/nginx/sites-available/example.com


server {
listen 80;
server_name example.com www.example.com;
....
....
# deny all; #} listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot }

 

The Certbot client also updates the virtual host and redirect all the HTTP requests to HTTPS as part of the SSL installation process. You can check it's content as shown below.

 

# Check SSL Virtual Host
sudo nano /etc/nginx/sites-available/example.com


# Scroll to bottom
...
...
server {
if ($host = example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot


listen 80;
server_name example.com;
return 404; # managed by Certbot


}

 

Auto-Renewal

 

The SSL certificates issued by Let's Encrypt expires after 90 days from the date of installation. The good point is that the Certbot installed by us from the official repository checks for renewal twice a day using the system timer. The auto-renewal feature on non systemd timer is provided by a cron script placed in /etc/cron.d. It renews the certificates that are about to expire in the next 30 days.

 

You can also test the renewal process by simulating the renewal command as shown below.

 

# Simulate renewal command
sudo certbot renew --dry-run

 

The above command will show the logs having messages to get an idea about how it will be run for actual renewal. We can also run the command manually to renew the certificates that are about to expire in the next 30 days.

 

# Renew certificates
sudo certbot renew

# Renewal messages

Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/example.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert not yet due for renewal

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

The following certs are not due for renewal yet:
/etc/letsencrypt/live/example.com/fullchain.pem expires on 2020-01-01 (skipped)
No renewals were attempted.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

 

The Nginx service must be reloaded after certificate renewal. We can do it by appending --renew-hook "systemctl reload nginx" to the /etc/cron.d/certbot file as shown below.

 

# Append renew hook
0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(43200))' && certbot -q renew --renew-hook "systemctl reload nginx"

 

Now again do a dry run by simulating the renewal command as shown below.

 

# Simulate renewal command
sudo certbot renew --dry-run

 

It should run successfully to ensure that the certificates will be automatically renewed before the expiry.

 

Install Webmin

 

In this step, we will install Webmin using the official repository on both Debian and non-Debian based systems. We can install Webmin using the Webmin APT repository on Ubuntu as shown below. I have used the nano editor for demonstration purposes. You can use any editor of your choice.

 

# Add repository
sudo nano /etc/apt/sources.list

# Add these lines at last
deb http://download.webmin.com/download/repository sarge contrib
deb http://webmin.mirror.somersettechsolutions.co.uk/repository sarge contrib

# Save and exit the editor

 

Save the file using the Nano text editor by pressing CTRL + O, then press Enter to write the file. Press CTRL + X to close the editor.

 

Install the GPG key as shown below. We need the GPG key to trust the repository.

 

# Navigate to your preferred directory
cd ~

# Download the GPG Key
wget http://www.webmin.com/jcameron-key.asc

# Add the Key
sudo apt-key add jcameron-key.asc

# Output
OK

 

Now we can install the most recent version of Webmin as shown below.

 

# Refresh the packages index
sudo apt-get update

# Install Webmin
sudo apt-get install webmin -y

# Installation logs
Setting up webmin (1.930) ...
Webmin install complete. You can now login to https://ip-xx-xx-xx-xx:10000/
as root with your root password, or as any user who can use sudo
to run commands as root.
Processing triggers for man-db (2.8.3-2ubuntu0.1) ...
Processing triggers for mime-support (3.60ubuntu1) ...
Processing triggers for ureadahead (0.100.0-21) ...
Processing triggers for systemd (237-3ubuntu10.29) ...

 

Test Webmin

 

You can test the Webmin in case port 10000 is open, else simply skip this section and continue with the next section.

 

We can directly access the Webmin using the URL - https://xx.xx.xx.xx:10000 in case port 10000 is opened. Make sure to replace the xx.xx.xx.xx with your actual IP. It will show the security risk warning as shown in Fig 1.

 

Webmin Security Warning

Fig 1

 

Accept the risk and continue to access Webmin. It will show the login screen as shown in Fig 2.

 

Webmin Login

Fig 2

 

Now login to Webmin using your root or sudo user credentials. You can also change the root credentials for Webmin using the command as shown below.

 

# Change Webmin password
sudo /usr/share/webmin/changepass.pl /etc/webmin <username> <password>

# Example
sudo /usr/share/webmin/changepass.pl /etc/webmin root pass123

 

The above command will change the root user password for Webmin. Now login to your Webmin. It will show the dashboard as shown in Fig 3.

 

Webmin Dashboard

Fig 3

 

Reverse Proxy For Webmin - Primary Domain

 

We will access the Webmin by configuring reverse proxy on port 80/443 as a regular web app by configuring the webserver. This will avoid opening an additional port for Webmin i.e. 10000 and maintaining SSL certificate for Webmin. It can be done for the Nginx Web Server as shown below.

 

# Update Virtual Host
sudo nano /etc/nginx/sites-available/example.com


# Content
server {
server_name example.com;

....
....

location / { #root /var/www/example.com/html; #index index.html index.htm; # proxy_buffering off; proxy_pass http://127.0.0.1:10000/; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $http_x_forwarded_for; proxy_redirect http://$host:10000/ http://$host/; }

....
....
}

# Save and exit the editor

# Check configurations
sudo nginx -t

# Output
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

# Reload Nginx
sudo systemctl reload nginx

 

We also need to configure Webmin to accept connections from Nginx as shown below. Also, make sure to use the FQDN or the domain name used to access the website. We can configure Webmin for the primary domain as shown below.

 

# Update config
sudo nano /etc/webmin/config

# Add at last
.....
.....
referers=example.com

# Save and exit the editor

Update miniserv
sudo nano /etc/webmin/miniserv.conf

# Configure SSL
...
ssl=0
...
...
ssl_redirect=0

# Save and exit the editor

# Restart Webmin
sudo systemctl restart webmin

 

Now we can access Webmin using the primary domain by redirecting to https://www.example.com. It will show the login screen as shown below.

 

Webmin Login

Fig 4

 

Reverse Proxy For Webmin - Subdomain

 

We must update the SSL certificate in order to support the subdomain. It can be done using the command as shown below. Let's Encrypt allows up to 100 domains for a single SSL certificate.

 

# Install Certificate - Syntax - Single Domain
sudo letsencrypt --nginx -d example.com,www.example.com,sub1.example.com --email admin@example.com

 

We can configure the Nginx server to access the Webmin over a subdomain similar to how we did for the primary domain by adding appropriate server blocks for the subdomain. In this way, we can access the website over the main domain and access the Webmin over a subdomain.

 

We also need to configure Webmin to accept connections from Nginx as shown below. We can configure Webmin for the subdomain as shown below.

 

# Update config
sudo nano /etc/webmin/config

# Add at last
.....
.....
referers=sub1.example.com

# Save and exit the editor

Update miniserv
sudo nano /etc/webmin/miniserv.conf

# Configure SSL
...
ssl=0
...
...
ssl_redirect=0

# Save and exit the editor

# Restart Webmin
sudo systemctl restart webmin

 

Now we can access Webmin using the subdomain by redirecting to https://sub1.example.com.

 

Reverse Proxy For Webmin - Subdirectory

 

We can configure the Nginx server to access the Webmin over the subdirectory. In this way, we can access the website over the main domain and access the Webmin over the sub URL. It can be done for the Nginx Web Server as shown below.

 

# Update Virtual Host
sudo nano /etc/nginx/sites-available/example.com


# Content
server {
server_name example.com;

....
....

location / {
root /var/www/example.com/html;
index index.html index.htm;

...
... }

location /webmin/ {
# proxy_buffering off;
proxy_pass http://127.0.0.1:10000/;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $http_x_forwarded_for;
proxy_redirect http://$host:10000/ http://$host/webmin/;
}

....
....
}

# Save and exit the editor

# Check configurations
sudo nginx -t

# Output
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

# Reload Nginx
sudo systemctl reload nginx

 

We also need to configure Webmin to accept connections from Nginx as shown below. We can configure Webmin for the subdirectory as shown below.

 

# Update config
sudo nano /etc/webmin/config

# Add at last
.....
.....
relative_redir=0
referers=example.com
webprefix=/webmin
webprefixnoredir=1

# Save and exit the editor

Update miniserv
sudo nano /etc/webmin/miniserv.conf

# Configure SSL
...
ssl=0
...
...
ssl_redirect=0

# Save and exit the editor

# Restart Webmin
sudo systemctl restart webmin

 

Now we can access Webmin using the subdirectory by redirecting to https://www.example.com/webmin/.

 

Summary

 

This is how we can install Webmin and access it over the primary domain, subdomain, and subdirectory by configuring the Nginx Web Server as a reverse proxy.

Share this blog:

Profile picture for user bhagwatchouhan
bhagwatchouhan