Okidoki
By:
Okidoki

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

July 12, 2015 9.9k views
Nginx Security Ubuntu

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!!

2 Answers

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!

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.

Have another answer? Share your knowledge.