Forcing HTTPS when using opsworks nginx and ELB to terminate SSL
Using standard Opsworks setup / recipes for a Rails application that runs through a Unicorn / nginx layer. SSL terminates in Elastic Load Balancer - so traffic to rails app from ELB is always http. So far, so good. I would like to receive any request from http://domain.com to redirect to https://domain.com
ELB has two listeners, one with port 80 and one with 443.
I know that if I were to run my own nginx I could set a redirect rule ... However, I want to stay inside the opponent to do something if possible.
source to share
I think the only way to do this in OpsWorks is to create a custom recipe that changes /etc/nginx/sites-available/#{application}
. In your custom cookbook:
somecookbook / recipes / nginx.rb
node[:deploy].each do |application, deploy|
service "nginx" do
supports :status => true
action :nothing
end
# Add HTTP => HTTPS redirect
template "/tmp/http_redirect.conf" do
source "nginx/http_redirect.conf.erb"
end
execute "redirect HTTP to HTTPS" do
cwd "/etc/nginx/sites-available"
command "cat #{application} /tmp/http_redirect.conf > /tmp/#{application}.conf && cat /tmp/#{application}.conf > #{application}"
notifies :restart, "service[nginx]", :immediately
end
end
end
Then in config:
somecookbook / templates / default / nginx / http _redirect.conf.erb
server {
listen 80;
rewrite ^(.*) https://$host$1 permanent;
}
source to share
I'm pretty sure you need to use nginx on your app server to handle the http -> https redirect. Here are two ways to fix this problem.
-
redirect all requests from 80 to
https
:server { listen 80; return 301 https://example.com/$request_uri; }
-
ELB maintains a header called X-FORWARDED-PROTO. All HTTPS requests going through the ELB will have X-FORWARDED-PROTO = "HTTPS":
server { listen 80; location / { if ($http_x_forwarded_proto != 'https') { rewrite ^ https://$host$request_uri? permanent; } } }
source to share