Mail-in-a-Box: access Munin from a different subdomain

Munin monitoring can be placed into an entirely different domain or subdomain. This will guide you through the steps on how to do it.


Munin is a network and infrastructure monitoring software that comes standard in a Mail-in-a-Box installation. Depending on your wants or needs, you can access Munin from a subdomain, or domain, other than the default box.example.com/admin/munin directory.

For instance, our Mail-in-a-Box install is located at mail.obstance.com. Because we added several servers to monitor through the box, it made less sense accessing Munin from mail.obstance.com/admin/munin.

Why you should use Munin on a different subdomain

My preference is to use a more relevant subdomain such as metrics.obstance.com/munin since we’ll be monitoring various servers; MiaB’s Munin being the master, with the other servers being Munin nodes. This keeps the URL agnostic and semantic, as in this case it’s not a monitoring system used exclusively for mail.

Relevant read: Adding more servers to monitor with Munin in Mail-in-a-Box

Does this preference actually matter? Absolutely not. But changing the URL does help if your brain prefers one way over the other. It can also be helpful if your partners or employees don’t know or understand the technology you’re utilizing to set up your infrastructure, making your assets look and feel a little more streamlined (and possibly more professional).

Using a subdomain like metrics is also a good route if you have multiple monitoring systems aside from Munin. Place them into different subdirectories, and then use the root URL to redirect to an index file or subdirectory that:

  • displays a static info page
  • displays data from those monitoring systems
  • or does something else creative

Moving Munin to a different subdomain

Now that we’ve covered why you should move Munin, we can begin telling you how to do it.

Note: this process can be done without touching any of the files maintained by Mail-in-a-Box. That means you’ll be able to upgrade your box without losing your changes, so you won’t have to redo anything.

Nginx Configuration

  1. SSH into your box. SFTP is also a nice option. Navigate to /etc/nginx/conf.d
  2. Create a conf file and name it anything. We’ll call it munin-subdomain.conf. Paste the contents below into that file, but change metrics.example.com with whatever subdomain you want to use. That will be in three places, the server_name, root and alias directives.
# Serve Munin through a different subdomain
server {
	listen 80;
	listen [::]:80;

	server_name metrics.example.com;

	root /home/user-data/www/metrics.example.com;
	index index.html index.htm;

	# Hide Nginx version
	server_tokens off;

	# Change /admin/ to root (/) of domain so that Munin
	# can be accessed at /munin instead of /admin/munin
	location / {
		proxy_pass http://127.0.0.1:10222/;
		proxy_set_header   Host $host;
		add_header X-Frame-Options "SAMEORIGIN"; # allow frames from same domain; helpful for displaying data on index.html
		add_header X-Content-Type-Options nosniff;
		add_header Content-Security-Policy "frame-ancestors 'none';";
	}

	# Allows assets to load in Python-based admin section
	# Not used for our purposes, but doesn't hurt
	# anything in case of change of heart
	location /admin/assets {
		alias /usr/local/lib/mailinabox/vendor/assets;
	}

	# Redirect root of domain to index.html file
	# 302 redirect; no need for 301 for a noindex'd site
	rewrite ^/$ /index/ redirect;
	location /index/ {
		alias /home/user-data/www/metrics.example.com/;
	}

	# Necessary for Let's Encrypt Domain Name ownership validation
	location ~ /.well-known {
		location ~ /.well-known/acme-challenge/(.*) {
			add_header Content-Type application/jose+json;
		}
	}
}

Note: the above Nginx config is only for HTTP; we’ll get certificates generated using Certbot to set up HTTPS later in the guide. If you’re sticking with insecure HTTP, you’re good to go on that end. But don’t do that. Use HTTPS.

Now test your Nginx configuration and reload it (only if there are no errors).

user@box:~$ sudo nginx -t && sudo systemctl reload nginx

Add DNS for your subdomain and point it to your mail server box

An obvious step: create your subdomain and point it to your mail server, either with an A record or CNAME record.

I prefer using CNAMEs for subdomains most of the time, because it’s less maintenance if your server’s IP address changes. Plus, you create less records since you don’t need a record for both IPv4 and IPv6, yet the CNAME will still utilize those (as long as the domain you’re pointing to has both A and AAAA records).

metrics.example.com.	43200	IN	CNAME	box.example.com.

After adding the Nginx conf and the subdomain, check out your new subdomain to make sure it’s accessible at metrics.example.com/munin/.

Place an index.html file in your public folder

Whatever directory you put into the root directive of your Nginx configuration, place an index.html file into it. We’ll use this as the landing page for the metrics subdomain. You can use it as an actual page with content or simply redirect it to /munin/.

/home/user-data/www/metrics.example.com/index.html:

<!doctype html>
<html lang="en">
	<head>
		<meta charset="utf-8">
		<meta name="robots" content="noindex">
		<title>Metrics</title>
		<style>
		  body {
			  text-align: center;
			  border-top: 10px solid #f1f1f1;
			  color: #414141;
			  font: 17px Helvetica, Arial, sans-serif;
			  margin: 0;
			  padding: 0;
			  line-height: 1.86;
		  }
		  h1 { font-size: 50px; font-weight: 400; line-height: 1.2; }
		  article { display: block; text-align: left; max-width: 650px; margin: 0 auto; margin-top: 80px; padding: 0 50px 50px; }
		  a { color: #0077bd; text-decoration: none; }
		  a:hover { color: #0282b1; text-decoration: none; }
		</style>
	</head>

<body>
	<article>
		<h1>Metrics</h1>
		<div>
			<p>This page is used for internal purposes.</p>
		</div>
	</article>
</body>
</html>
Example index page

Generate Let’s Encrypt TLS certificates for the Munin metrics subdomain

Almost finished! Now we need to generate some certificates to make the new subdomain secure. We’ll generate the certificates with Certbot and then replace the contents of the Nginx conf file.

user@box:~$ sudo -H certbot certonly --webroot-path=/home/user-data/www/metrics.example.com -d metrics.example.com

Add --dry-run to the command to test it first, if you’d like. Be sure to change metrics.example.com in both places with your actual subdomain.

After your certs are successfully generated, head back to your Nginx file and replace its contents.

/etc/nginx/conf.d/munin-subdomain.conf:

# Serve Munin through a different subdomain
server {
	listen 443 ssl http2;
	listen [::]:443 ssl http2;

	server_name metrics.example.com;

	root /home/user-data/www/metrics.example.com;
	index index.html index.htm;

	# Hide Nginx version
	server_tokens off;

	# Change /admin/ to root (/) of domain so that Munin
	# can be accessed at /munin instead of /admin/munin
	location / {
		proxy_pass http://127.0.0.1:10222/;
		proxy_set_header   Host $host;
		add_header X-Frame-Options "SAMEORIGIN"; # allow frames from same domain; helpful for displaying data on index.html
		add_header X-Content-Type-Options nosniff;
		add_header Content-Security-Policy "frame-ancestors 'none';";
	}

	# Allows assets to load in Python-based admin section
	# Not used for our purposes, but doesn't hurt
	# anything in case of change of heart
	location /admin/assets {
		alias /usr/local/lib/mailinabox/vendor/assets;
	}

	# Redirect root of domain to index.html file
	# 302 redirect; no need for 301 for a noindex'd site
	rewrite ^/$ /index/ redirect;
	location /index/ {
		alias /home/user-data/www/metrics.example.com/;
	}

	####
	### SSL and SSL Optimizations
	####

	# Necessary for Let's Encrypt Domain Name ownership validation
	location ~ /.well-known {
		location ~ /.well-known/acme-challenge/(.*) {
			add_header Content-Type application/jose+json;
		}
	}

	# In default /etc/letsencrypt location (not in /home/user-data/ssl)
	ssl_certificate /etc/letsencrypt/live/metrics.example.com/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/metrics.example.com/privkey.pem;

	### ssl_ciphers, ssl_dhparam, ssl_session_cache, ssl_session_timeout, stapling and resolvers are in /etc/nginx/conf.d/ssl.conf
	ssl_trusted_certificate /etc/letsencrypt/live/metrics.example.com/chain.pem;

	# ssl files sha1: 9dc67cb167738c5c712137dd8513b9457c437f14 / 4708e05e578813027dfbae359895d69c3c5d95e9
	add_header Strict-Transport-Security "max-age=15768000" always;

	####
	### Restrictions
	####

	location = /robots.txt {
		log_not_found off;
		access_log off;
	}

	location = ^/favicon.ico {
		log_not_found off;
		access_log off;
	}

	# Disable viewing dotfiles (.htaccess, .svn, .git, etc.)
	# This block is placed at the end. Nginx's precedence rules means this block
	# takes precedence over all non-regex matches and only regex matches that
	# come after it (i.e. none of those, since this is the last one.) That means
	# we're blocking dotfiles in the static hosted sites but not the FastCGI-
	# handled locations for Nextcloud (which serves user-uploaded files that might
	# have this pattern, see #414) or some of the other services.
	location ~ /\.(ht|svn|git|hg|bzr) {
		log_not_found off;
		access_log off;
		deny all;
	}
} # End 443 server block

# Redirect all HTTP requests to HTTPS
server {
	listen 80;
	listen [::]:80;
	server_name metrics.example.com;
	return 301 https://$host$request_uri;
}

There are 7 places where you should replace metrics.example.com.

Reload Nginx.

user@box:~$ sudo nginx -t && sudo systemctl reload nginx

Check that your new location works fine and you’re all good to go! Read the next optional section to learn how to redirect the old location to the new subdomain.

Optional: redirect old Munin subdirectory to your new subdomain

The process in this guide outlines how to access Munin from a different place, but it doesn’t stop access from the old one. That’s completely fine as-is, but you can optionally use a redirect so that you’re only using your new subdomain.

In /home/user-data/www you can create a custom.yaml file. This will allow you to add rewrites (redirects) in the Nginx local.conf file that Mail-in-a-Box maintains — without having to touch the file yourself, and with the added bonus of maintaining your changes across MiaB upgrades.

custom.yaml:

## Custom YAML ##
# Redirect box.example.com/admin/munin to metrics.example.com/munin
box.example.com:
  redirects:
    ^/admin/munin(/.*): https://metrics.example.com/munin$1

After saving that file, you’ll need to update the configuration so that it actually adds the rewrite rule into the local.conf file. You can do this using either of these two options:

  1. Go to box.example.com/admin#web and click on the “Change” button next to any of the sites, and then click the “Update” button.
  2. Run sudo ~/mailinabox/tools/web_update from the command line using the user you used to set the box up with.

Now when you try accessing the old Munin URL, like through the Python admin panel dropdown, you’ll automatically be taken to your new subdomain location. If you have any old Munin bookmarks leading to specific monitoring pages, they’ll also be redirected to the new location correctly — there’s no need to update your bookmarks because the regex will pass the value over.

No comments yet.

Post a comment

  • (will not be published)


This site uses Akismet to reduce spam. Learn how your comment data is processed.

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>