I have a signup page on a subdomain like: https://signup.example.com
It should only be accessible via HTTPS but I'm worried people might somehow stumble upon it via HTTP and get a 404.
My html/server block in nginx looks like this:
html {
server {
listen 443;
server_name signup.example.com;
ssl on;
ssl_certificate /path/to/my/cert;
ssl_certificate_key /path/to/my/key;
ssl_session_timeout 30m;
location / {
root /path/to/my/rails/app/public;
index index.html;
passenger_enabled on;
}
}
}
What can I add so that people who go to http://signup.example.com
get redirected to https://signup.example.com
? (FYI I know there are Rails plugins that can force SSL
but was hoping to avoid that)
The best way as it described in the official how-to is by using the
return
directive:According to nginx pitfalls, it's slightly better to omit the unnecessary capture, using
$request_uri
instead. In that case, append a question mark to prevent nginx from doubling any query args.This is the correct and most efficient way if you want to keep it all in one server block:
Everything else above, using "rewrite" or "if ssl_protocol" etc is slower and worse.
Here is the same, but even more efficient, by only running the rewrite on the http protocol it avoids having to check the $scheme variable on every request. But seriously, it's such a minor thing that you don't need to separate them.
If you are using the new dual HTTP and HTTPS server definition, you can use the following:
This appears to work for me and doesn't cause redirect loops.
Edit:
Replaced:
with Pratik's rewrite line.
Yet another variant, that preserves the Host: request header and follows the "GOOD" example on nginx pitfalls:
Here are the results. Note that using
$server_name
instead of$host
would always redirect tohttps://site1
.This works better i think. x.x.x.x refers to your server's IP. If you are working with Plesk 12, you can do that by changing the "nginx.conf" file in the directory "/var/www/vhosts/system/domain.tld/conf" for whichever domain you want. Do not forget to restart nginx service after you save the configuration.
I think this is the most simple solution. Forces both non-HTTPS and non-WWW traffic to HTTPS and www only.
EDIT - Apr 2018: Solution w/o IF's can be found in my post here: https://stackoverflow.com/a/36777526/6076984