How to redirect http requests to https (nginx)
There appear to be many questions and guides out there that instruct how to setup nginx to redirect http requests to https. Many are outdated, or just flat out wrong.
# MANAGED BY PUPPET
upstream gitlab {
server unix:/home/git/gitlab/tmp/sockets/gitlab.socket;
}
# setup server with or without https depending on gitlab::gitlab_ssl variable
server {
listen *:80;
server_name gitlab.localdomain;
server_tokens off;
root /nowhere;
rewrite ^ https://$server_name$request_uri permanent;
}
server {
listen *:443 ssl default_server;
server_name gitlab.localdomain;
server_tokens off;
root /home/git/gitlab/public;
ssl on;
ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers AES:HIGH:!ADH:!MDF;
ssl_prefer_server_ciphers on;
# individual nginx logs for this gitlab vhost
access_log /var/log/nginx/gitlab_access.log;
error_log /var/log/nginx/gitlab_error.log;
location / {
# serve static files from defined root folder;.
# @gitlab is a named location for the upstream fallback, see below
try_files $uri $uri/index.html $uri.html @gitlab;
}
# if a file, which is not found in the root folder is requested,
# then the proxy pass the request to the upsteam (gitlab puma)
location @gitlab {
proxy_read_timeout 300; # https://github.com/gitlabhq/gitlabhq/issues/694
proxy_connect_timeout 300; # https://github.com/gitlabhq/gitlabhq/issues/694
proxy_redirect off;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Ssl on;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://gitlab;
}
}
I've restarted after every configuration change, and yet I still only get the 'Welcome to nginx' page when visiting http://192.168.33.10
. whereas https://192.168.33.10
works perfectly.
Why will nginx still not redirect http requests to https?
I've also tried the following configurations
listen *:80;
server_name <%= @fqdn %>;
#root /nowhere;
#rewrite ^ https://$server_name$request_uri? permanent;
#rewrite ^ https://$server_name$request_uri permanent;
#return 301 https://$server_name$request_uri;
#return 301 http://$server_name$request_uri;
#return 301 http://192.168.33.10$request_uri;
return 301 http://$host$request_uri;
The logs
tailf /var/log/nginx/access.log
192.168.33.1 - - [22/Oct/2013:03:41:39 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:24.0) Gecko/20100101 Firefox/24.0"
192.168.33.1 - - [22/Oct/2013:03:44:43 +0000] "GET / HTTP/1.1" 200 133 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:24.0) Gecko/20100101 Firefox/24.0"
tailf /var/log/nginx/gitlab_error.lob
2013/10/22 02:29:14 [crit] 27226#0: *1 connect() to unix:/home/git/gitlab/tmp/sockets/gitlab.socket failed (2: No such file or directory) while connecting to upstream, client: 192.168.33.1, server: gitlab.localdomain, request: "GET / HTTP/1.1", upstream: "http://unix:/home/git/gitlab/tmp/sockets/gitlab.socket:/", host: "192.168.33.10"
Resources
https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
How to make nginx redirect
How to force or redirect to SSL in nginx?
nginx ssl redirect
Nginx & Https Redirection
https://www.tinywp.in/301-redirect-wordpress/
How to force or redirect to SSL in nginx?
I've identified the problem.
I had an entry in /etc/hosts that was misconfigured
127.0.0.1 gitlab.localdomain gitlab
As soon as I changed it to the following, https redirects started working
192.168.33.10 gitlab.localdomain gitlab
So in conclusion, this is the working syntax.
server {
listen 80;
server_name gitlab.localdomain;
server_tokens off;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl default_server;
server_name gitlab.localdomain;
server_tokens off;
root /home/git/gitlab/public;
ssl on;
ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers AES:HIGH:!ADH:!MDF;
ssl_prefer_server_ciphers on;
…
Note
The redirect only works when calling the url by name, it does not redirect if navigating to the ip.
2 things ion how to ensure http-to-https-redirects
-
in your HTTPS - section, enable HSTS-Header _> this will ensure your browser send future requests in HTTPS only
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
-
in your http-section: you could either
return 301 https://$server_name$request_uri;
(fastest approach) or rewrite (slower)server { listen 80; server_name _; server_tokens off; return 301 https://$host$request_uri;
}