Nginx Redirect HTTP To HTTPS with Rewrite 301 Rules

I have setup nginx as a secure reverse proxy server. How do I redirect all http://example.com/ requests (traffic) to https://example.com/ under nginx web server? How do I configure Nginx to redirect HTTP To HTTPS?

Tutorial details
Difficulty Intermediate (rss)
Root privileges Yes
Requirements Nginx
Unix/Linux
Time N/A
You can easily rewrite/redirect all http requests to https with Nginx web server. The syntax is as follows. You need to add the following in location or server directives. This quick guide explain how to redirect the HTTP traffic to HTTPS in Nginx.

ADVERTISEMENTS

Nginx Redirect HTTP To HTTPS

Now that you configured and installed an SSL certificate for Nginx, it is time to drop all HTTP traffic and send users to HTTPS version. Edit nginx.conf file:
sudo vi /etc/nginx/nginx.conf

if ($host ~* ^(example\.com|www\.example\.com)$ ){
  rewrite  ^/(.*)$  https://example.com/$1  permanent;
}

OR better use the following rewrite:

rewrite  ^ https://$server_name$request_uri? permanent;

Or use new syntax (recommended):

return         301 https://$server_name$request_uri;

Redirect all HTTP requests to HTTPS with Nginx server

Edit your nginx.conf file, enter:
# vi nginx.conf
You need to define both http and https server as follows:

################################
## our HTTP server at port 80 ##
################################
server {
      listen      80 default;
      ## set up domain name here ##
      server_name www.cyberciti.biz cyberciti.biz
      access_log off;
      error_log off;
      ##** nginx redirect ALL http requests to https ** ##
      return      301 https://$server_name$request_uri;
}
#########################################################################
## Our HTTPS server at port 443. You need to provide ssl config below ###
#########################################################################
server {
      access_log  logs/cyberciti.biz/ssl_access.log main;
      error_log   logs/cyberciti.biz/ssl_error.log;
      index       index.html;
      root        /usr/local/nginx/html;
      ## start ssl config ##
      listen      443 http2 ssl;
      server_name www.cyberciti.biz cyberciti.biz
 
     ## redirect www to nowww
      if ($host = 'www.cyberciti.biz' ) {
         rewrite  ^/(.*)$  https://cyberciti.biz/$1  permanent;
      }
 
    ### ssl config - customize as per your setup ###
     ssl_certificate      ssl/cyberciti.biz/cyberciti.biz_combined.crt;
     ssl_certificate_key  ssl/cyberciti.biz/cyberciti.biz.key_without_password;
     ssl_protocols        TLSv1 TLSv1.1 TLSv1.2;
     keepalive_timeout    70;
     ssl_session_cache    shared:SSL:10m;
     ssl_session_timeout  10m;
    ### Rest of my config. It is optional. Do it only if you have Apache on backend ## 
 
    ## PROXY backend 
      location / {
        add_header           Front-End-Https    on;
        add_header  Cache-Control "public, must-revalidate";
        add_header Strict-Transport-Security "max-age=2592000; includeSubdomains";
        proxy_pass  http://cybercitiproxy;
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
        proxy_set_header        Host            $host;
        proxy_set_header        X-Real-IP       $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
      }
}

Save and close the file. Reload or restart the nginx server:
# nginx -s reload
Test it:
$ curl -I http://cyberciti.biz
$ curl -I http://cyberciti.biz/foo/bar/file.html

Sample outputs:

Nginx Redirect HTTP To HTTPS

Fig.01 Rewrite 301 HTTP to HTTPS in Nginx server

Redirect All HTTP traffic

Edit or append as follows in your nginx.conf:

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;
    return 301 https://$host$request_uri;
}

The return directive stops processing and returns the specified code to a client. The non-standard code 444 closes a connection without sending a response header. In above example, we are returning HTTP code 301:
return code URL;
return 301 URL;
return 301 URL;

One can use the following code:

  • HTTP/301 – The HTTP response status code 301 Moved Permanently is used for permanent URL redirection
  • HTTP/302 – The HTTP response status code 302 Found is a common way of performing URL redirection with Moved Temporarily code.

In addition, a URL for temporary redirect with the code 302 can be specified as the sole parameter. Such a parameter should start with the http://, https://, or “$scheme” string. A URL can contain variables.

Conclusion

You learned how to redirect port 80 to port 443 using HTTP/301 redirect when using Nginx web server. See nginx docs for more info here.

🐧 Get the latest tutorials on SysAdmin, Linux/Unix, Open Source/DevOps topics:
CategoryList of Unix and Linux commands
File Managementcat
FirewallAlpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Network Utilitiesdig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg jobs killall kill pidof pstree pwdx time
Searchinggrep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNAlpine CentOS 8 Debian 10 Firewall Ubuntu 20.04

ADVERTISEMENTS
9 comments… add one
  • Jared Dec 2, 2012 @ 1:14

    An even better way to redirect would be with this:

    return 301 http://exampledomain.com$request_uri;

    • Ruben Decrop Nov 15, 2015 @ 11:59

      POST requests are converted to GET with a 301 redirect, which is not always what is desired

  • David Gómez (@emsLinux) Dec 2, 2012 @ 20:00

    Excelent tip!

    Please write more stuff about NGINX, I love it.

  • Sukoon Feb 12, 2013 @ 15:53

    This is the best redirect tutorial for nginx on the web. Great work!!

  • karnd01 Aug 19, 2014 @ 19:16

    need to change $server_name to $host as $server_name will default to the first and not the particular name the user typed in.

    may seem trivial but when getting into public vs internal dns entries and routing of traffic you may need to user the hostname that got you here.

  • Jon Sep 30, 2014 @ 23:02

    Doesn’t work on Ubuntu 14.04.

  • Komu Feb 4, 2015 @ 13:40

    To redirect on the same port:
    Lets assume your IP address is 89.89.89.89 and your app is running on port 3000 and you want nginx to listen on port 7000.

        server {
            listen 7000 ssl;
         
            ssl_certificate /path/to/ssl_certificate.cer;
            ssl_certificate_key /path/to/ssl_certificate_key.key;
            ssl_client_certificate /path/to/ssl_client_certificate.cer;
         
            # this line is important, for u to handle http and https on same port
            # see: http://bit.ly/1C0kgny
    
            error_page 497 301 =307 https://89.89.89.89:7000$request_uri;
    
            # in order to preserve the http VERB that the request came with,
            # we use error response redirection
            # see: http://bit.ly/1uX5jNO
         
         
            location / {
                proxy_pass http://89.89.89.89:3000/;
    
                proxy_pass_header Server;
                proxy_set_header Host $http_host;
                proxy_redirect off;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-Protocol $scheme;
            }
        }
    
  • Dawid Sep 8, 2015 @ 12:44

    Using if statements is strongly discouraged in nginx. See here: http://wiki.nginx.org/IfIsEvil and here: http://wiki.nginx.org/Pitfalls#Taxing_Rewrites

  • shairalibaig Dec 7, 2015 @ 6:00

    hii Thanks a lot for ur post..
    but am trieng to redirect https subadomain to another https subdomain
    but the post requests getting converted into get..
    how can redirect 301 for https to https using post to post
    any help would be greatly appreciated..

Leave a Reply

Your email address will not be published.

Use HTML <pre>...</pre>, <code>...</code> and <kbd>...</kbd> for code samples.