Permanent Redirect 301/302 with HTTPS multiple domains - NGINX

How to setup HTTPS 301 redirect for your domain using Ubuntu running NGINX server with multiple domains

Description of Problem at Hand

Suppose that, I have a website up and running at https://www.domain-old.com. This site is getting regular traffic from search engines such as Google. For some reasons, I decided to change my domain name to https://www.domain-new.com. The page structure of the new domain will remain the same as old one. In this scenario, I want all the traffic from old website to be redirected to new site with 301 PERMANENT REDIRECT status code and path forwarding enabled. The setup should work for both http and https protocols. The setup should word as follows.

Traffic At Redirects To
http://domain-old.com https://domain-old.com
https://domain-old.com https://domain-new.com
http://www.domain-old.com https://www.domain-old.com
https://www.domain-old.com https://www.domain-new.com
http://domain-old.com/somepath https://domain-old.com/somepath
https://domain-old.com/somepath https://domain-new.com/somepath
http://www.domain-old.com/somepath https://www.domain-old.com/somepath
https://www.domain-old.com/somepath https://www.domain-new.com/somepath

Description of Resources at Hand

I have one Linux VPS instance running Ubuntu 20.04 which has NGINX as web server and currently used for hosting an API service at https://api.otherdomain.com. I will use this same machine for running domain redirections service at domain-old.com and www.domain-old.com

Changing Profile Pic on Facebook
Steps for Setting up Redirection on NGINX VPS

Adding DNS record in registrar portal

First of all, I have to add the static I.P. of my VPS in the A RECORD entry of the domain. This step varies depending on the registrar you are using i.e. GoDaddy, Bigrock, etc. After this, any request made to domain-old.com or www.domain-old.com will be received by the server.

NGINX Config File for redirection server

Following are the steps for creating a blank config file and creating a system link in the 'enabled-sites' directory.

cd /etc/nginx/sites-available/
sudo touch domain-old
sudo ln -s /etc/nginx/sites-available/domain-old /etc/nginx/sites-enabled/

Now, use any text editor, such as nano, to write following configuration in the created file.

sudo nano /etc/nginx/sites-available/domain-old
server {
    listen 80;
    server_name domain-old.com;
}

server {
    listen 80;
    server_name www.domain-old.com;
}

Save the file and exit. Now, you will need certbot for SSL/HTTPS activation for the site. You can use following lines of code installing the certbot or you can refer to official site for detailed instructions.

sudo snap install core; sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

Activating SSL / HTTPS using CERTBOT

You have to use following command for SSL activation on your old domain. After running the command, tool will prompt you to select the server for activation. You have to run this command twice, once for HTTPS activation of naked domain and once again for www subdomain.

sudo certbot --nginx

If your config file looks something like this after running the certbot, it means all went well.

server {
    server_name domain-old.com;

    listen 443 ssl; # managed by Certbot

    ssl_certificate /etc/letsencrypt/live/domain-old.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/domain-old.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
}

server {
    server_name www.domain-old.com;

    listen 443 ssl; # managed by Certbot

    ssl_certificate /etc/letsencrypt/live/www.domain-old.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/www.domain-old.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
}

server {
    if ($host = domain-old.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot
    
    listen 80;
    server_name domain-old.com;
    return 404; # managed by Certbot
}

server {
    if ($host = www.domain-old.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot
    
    listen 80;
    server_name www.domain-old.com;
    return 404; # managed by Certbot
}

Configure 443 HTTPS server to return 301 with redirection

You have to enable conditional redirection alongwith path forwarding using the following snippet of code in your NGINX config file.

if ($host = domain-old.com) {
        return 301 https://domain-new.com$request_uri;
    }
if ($host = www.domain-old.com) {
        return 301 https://www.domain-new.com$request_uri;
    }

Your final config file will look as follows.

server {
    server_name domain-old.com;

    listen 443 ssl; # managed by Certbot

    if ($host = domain-old.com) {
        return 301 https://domain-new.com$request_uri;
    }

    ssl_certificate /etc/letsencrypt/live/domain-old.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/domain-old.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
}

server {
    server_name www.domain-old.com;

    listen 443 ssl; # managed by Certbot

    if ($host = www.domain-old.com) {
        return 301 https://www.domain-new.com$request_uri;
    }

    ssl_certificate /etc/letsencrypt/live/www.domain-old.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/www.domain-old.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
}

server {
    if ($host = domain-old.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot
    
    listen 80;
    server_name domain-old.com;
    return 404; # managed by Certbot
}

server {
    if ($host = www.domain-old.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot
    
    listen 80;
    server_name www.domain-old.com;
    return 404; # managed by Certbot
}
\0

Post a Comment

© MadCap-ed. All rights reserved.