/home/posts/setup-nginx-subdomain-redirect

Using Nginx to Redirect Unused Subdomains to Root Domain

Published on

#Introduction

I self-host several applications on my server, each available on different subdomains, e.g. cloud.example.com and music.example.com. If a given subdomain is not being used, e.g. test.example.com, I want nginx to automatically redirect users to the root domain, example.com.

#Defining Nginx Configuration

First, we must declare a server block in the nginx configuration that will deal with any traffic to any subdomain. Create a new server configuration at /etc/nginx/sites-available/redirect-subdomains and place the following, replacing example.com with your domain:

server {
        listen 80;
        listen [::]:80 default_server;
        server_name *.example.com;
        return 301 https://example.com;
}

This server block listens at *.example.com on port 80, and automatically redirects any subdomain to the root domain.

#Redirecting with HTTPS

You’ll notice that the above solution only works for http, not https. In order to redirect both, you must set up a wildcard https certificate that works for any given subdomain. Luckily, you don’t need to get a certificate for every possible combination of letters, you can instead just get a wildcard certificate.

Using certbot, you can get a wildcard certificate like so:

sudo certbot certonly --manual --preferred-challenges=dns --email admin@example.com --server https://acme-v02.api.letsencrypt.org/directory --agree-tos -d example.com -d *.example.com

Notice that this wildcard certificate covers both the root domain (example.com) and all subdomains (*.example.com), so it’s the only certificate you should need.

If you were already using subdomain certificates, certbot will realize this and ask you if you want to “expand and replace” those with the new certificate. In addition, you will be asked to acknowledge that your IP address is being logged. Finally, you are asked to place a DNS TXT record on your domain, which proves to certbot that you actually own the domain and are able to change its records.

Once all this is done, your certificate will be live at /etc/letsencrypt/live/example.com.

#Utilizing the HTTPS Certificates

#Redirect HTTPS Subdomains to Root Domain

If you used the methods above to get your wildcard (and root domain) certificate, then certbot will not automatically install it to all your nginx server blocks. First, we need to define a wildcard server block that will catch all subdomains, so go back and edit /etc/nginx/sites-available/redirect-subdomains add a second server block for HTTPS:

server {
	listen 80;
	listen [::]:80 default_server;
	server_name *.example.com;
	return 301 https://example.com;
}
server {
	listen 443 ssl;
	server_name *.example.com;

	ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
	include /etc/letsencrypt/options-ssl-nginx.conf;
	ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

	return 301 https://example.com;
}

Now, any non-existent subdomains will redirect to your root domain, regardless of whether the subdomain is accessed via HTTP or HTTPS.

#Fix Existing Subdomain Nginx Server Blocks

Finally, if you’re running any services available at a certain subdomain, like cloud.example.com, you need to edit the configuration to use this new wildcard certificate and delete the old certificate.

For example, if we are running a cloud.example.com service at /etc/nginx/sites-available/cloud, ensure that the SSL certificate is pointed to /etc/letsencrypt/live/example.com like so:

server {
	server_name cloud.example.com;

	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
}

If you were using a certificate for specific subdomains, like cloud.example.com, and you’ve just replaced them, you can now delete the old subdomain-specific certificate by running certbot delete and interactively choosing the old certificate for deletion. The certificate you just got will be named after your root domain (e.g. example.com), so don’t delete that one!

#Conclusion

In this tutorial, we used certbot to get a wildcard and root certificate, then used it to ensure existing subdomains still work, and non-existent subdomains are redirected to the root domain regardless of whether they are accessed via HTTP or HTTPS.

Meet the Author

John Allbritten

Nashville, TN

I love learning new technologies, and I have a passion for open source. As I learn things, my notes turn into articles to share.

Related Posts