Reputation: 939
I'm trying to test my SSL setup before migrating over a site from Heroku to a (Digital Ocean) VPS, so I'm using a self-signed certificate as per these instructions.
I used the following command to create the certificates, and they are present in the appropriate directory:
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt
Here are the relevant lines from the server
block on my nginx.conf:
server {
listen 80 default_server;
listen 443 ssl;
server_name migration.my_domain.com;
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
Additionally, in production.rb
I've used the following line:
config.force_ssl = true
my_domain
(not the actual domain name) and its subdomain migration
are both set up in my DNS and are correctly pointing to my server's IP address. At present, when I access via http://migration.my_domain.com
pages get served up. But when I access via https://migration.my_domain.com
, I'm getting an error in Chrome:
This site can’t be reached
migration.my_domain.com refused to connect.
Try:
Reloading the page
Checking the connection
Checking the proxy and the firewall
ERR_CONNECTION_REFUSED
Any idea what I'm missing here?
Upvotes: 2
Views: 1302
Reputation: 939
Figured it out. First, I'm deploying via Capistrano which I had mistakenly thought was restarting nginx after a deploy. Turns out it doesn't. So I needed to do that manually. So deployed with this at the beginning of my server
block:
server {
listen 443 ssl default_server deferred;
server_name migration.my_domain.com;
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
Deployed that, but after restarting nginx, first got the warning from Chrome about a self-signed certificate and that the site can't be trusted (which is fine and expected). After moving past that got a message about too many redirects. Turns out that the line from above in my production.rb
file:
config.force_ssl = true
was causing a problem. Saw this which from what I can tell means that what nginx sends through to puma does not contain whether it's ssl or not, so puma redirects everything, even the https requests because it just doesn't know what it's getting. So, now I have two near-duplicate server
blocks. The first one which handles http
requests has the following relevant statements:
server {
listen 80;
server_name migration.my_domain.com;
# ...bunch of non-relevant config...
location @puma {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://puma;
}
}
This handles all the 80 requests which puma will redirect all of to ssl (I believe) thanks to config.force_ssl = true
in production.rb
. Nginx will then receive an https request for the same URL which will be handled by this block:
server {
listen 443 ssl;
server_name migration.my_domain.com;
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
# ...bunch of non-relevant config...
location @puma {
proxy_set_header X-Forwarded-Proto https; # IMPORTANT!! I believe this tells puma that everything sent through via this block is https. Thus, puma no longer redirects.
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://puma;
}
}
This seems to work correctly, albeit with all the appropriate warnings one should get in the browser when receiving a self-signed certificate. I'm confident that once I switch in my actual certificates, I will now have a functioning ssl setup.
Thanks again @doon!
Upvotes: 2