Question

nginx - how to force-redirect some urls to https?

Hi, I just set up an opencart nginx site that redirect non-www to www and https non-www to https www. But I also need to redirect specific urls to https in www. For instance:

http://website.com/admin to https://www.website.com/admin http://www.website.com/index.php?route=account/register to https://www.website.com/index.php?route=account/register

and all the following child-urls of those urls like so:

http://website.com/admin=codehere&codethere-etc-etc to https://www.website.com/admin=codehere&codethere-etc-etc

http://www.website.com/register/subdirectory1/subdirectory2 to https://www.website.com/register/subdirectory1/subdirectory2

It’s for security reason, obviously.

I don’t know how to do this. I successfully redirect all non-www to www urls and all https non-www urls to https www urls. BUT I don’t know how to redirect specific urls.

This is my current nginx set up:

server {
    listen      80;
    server_name website.com;

    add_header Strict-Transport-Security max-age=2592000;
    return 301 http://www.website.com$request_uri;
}

server {
    listen      80;
    server_name www.website.com;

    root /home/username/website.com;

    index index.html index.htm index.php;

    charset utf-8;

    access_log  /var/log/nginx/website.com.access.log;
    error_log   /var/log/nginx/website.com.error.log;

    rewrite /admin$ $scheme://$host$uri/ permanent;

    location / {
         try_files $uri @opencart;
    }

    location @opencart {
        rewrite ^/(.+)$ /index.php?_route_=$1 last;
    }

    location /admin {
        index index.php;
    }

    rewrite ^/sitemap.xml$ /index.php?route=feed/google_sitemap last;
    rewrite ^/googlebase.xml$ /index.php?route=feed/google_base last;
    rewrite ^/download/(.*) /index.php?route=error/not_found last;

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

    sendfile off;

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php5-fpm-username.sock;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_intercept_errors off;
        fastcgi_buffer_size 16k;
        fastcgi_buffers 4 16k;
    }

    location ~ /\.ht {
        deny all;
    }
}


server {
    listen 443 ssl spdy;
    server_name website.com;

    ssl on;
    ssl_certificate     /etc/nginx/ssl/opencart.crt;
    ssl_certificate_key /etc/nginx/ssl/opencart.key;

    return 301 https://www.website.com$request_uri;
}

server {
    listen      443 ssl spdy;
    server_name www.website.com;

    ssl on;
    ssl_certificate     /etc/nginx/ssl/opencart.crt;
    ssl_certificate_key /etc/nginx/ssl/opencart.key;
    ssl_session_timeout 5m;

    ssl_ciphers               'INSERT_CIPHERS_CODES_HERE';
    ssl_protocols              TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;

    root /home/username/website.com;

    index index.html index.htm index.php;

    charset utf-8;

    access_log  /var/log/nginx/website.com.ssl.access.log;
    error_log   /var/log/nginx/website.com.ssl.error.log;

    rewrite /admin$ $scheme://$host$uri/ permanent;

    location / {
         try_files $uri @opencart;
    }

    location @opencart {
        rewrite ^/(.+)$ /index.php?_route_=$1 last;
    }


    location /admin {
        index index.php;
    }

    rewrite ^/sitemap.xml$ /index.php?route=feed/google_sitemap last;
    rewrite ^/googlebase.xml$ /index.php?route=feed/google_base last;
    rewrite ^/download/(.*) /index.php?route=error/not_found last;

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

    sendfile off;

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php5-fpm-username.sock;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_intercept_errors off;
        fastcgi_buffer_size 16k;
        fastcgi_buffers 4 16k;
    }

    location ~ /\.ht {
        deny all;
    }
}

Any help is appreciated. Thanks!!

Subscribe
Share

Submit an answer
You can type!ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

These answers are provided by our Community. If you find them useful, show some love by clicking the heart. If you run into issues leave a comment, or add your own answer to help others.

Have you tried something like:

# Redirects (production)

server {
  listen 80;
  listen 443 ssl;
  server_name example.com example.com.au example.net.au www.example.com www.example.net.au;
  ssl_certificate /etc/letsencrypt/live/www.example.com.au/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/www.example.com.au/privkey.pem;
  return 301 https://www.example.com.au$request_uri;
}

# Production server

server {
  listen 443 ssl spdy;
  listen [::]:443 ssl spdy;

  server_name www.example.com.au;
  root /var/www/example.com.au/dist;
  index index.html index.htm;

  client_max_body_size 10G;

  ssl on;
  ssl_certificate /etc/letsencrypt/live/www.example.com.au/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/www.example.com.au/privkey.pem;
  ssl_session_timeout 5m;
  ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
  ssl_prefer_server_ciphers on;

  error_page 404 /404.html;
  error_page 500 502 503 504 /50x.html;
}

Works for me.

Also rewrites are frowned upon from performance point of view, so I read.

You should be able to get what you want using rewrite. This will redirect every request to the https website with the complete URL rewrite ^/(.*) https://www.example.com/$1 permanent;

Have a nice day!