简体   繁体   中英

Elastic Load Balancer on port 443 works for forced SSL Ruby On Rails application, but why?

My ruby on Rails application is configured with the following:

config.force_ssl = true

And I set up the following elastic load balancer:

在此处输入图片说明

With this configuration everything works, but I do not understand why? with the code above, my application instance will return a 301 redirect in response to HTTP request. When the HTTP request is handled by the load balancer, it is forwarded on to to the instance as a HTTP request. Shouldn't this result in another 301, and therefore an endless loop?

EDIT I thought a bit about my answer and decided to get in to some more detail with it.

Network communication is usually composed of several layers, among which are the physical layer , which is the cable/radio channel where information travels through, the transport layer which is often TCP/IP, the protocol layer which in our case is usually HTTP or HTTPS and finally the application layer which is what our rails app handles.

Rails usually never gets in touch with the actual HTTPS data stream, as this is handled by your webserver. So how does force_ssl work at all?

The protocol layer is handled by the webserver (nginx, mongrel...) and this is who could care first about forcing ssl. When the webserver hands over a request to the application layer (hence, the rails app), it also provides a lot of meta data, which includes requester IP, request path, request format, a lot of header variables and also information about the used protocol.

When a request arrives at your webserver on port 443 (and uses HTTPS protocol), the webserver sets the header flag SERVER_PROTOCOL to https .

If a proxy server (like load balancer is) receives a request on 443 and forwards it to 80, it adds the X-FORWARDED-PROTO=https header to the request, which is made available for your rails app by the webserver.

Now, long story short: config.force_ssl requires SERVER_PROTOCOL OR X-FORWARDED-PROTO to denote https .

ORIGINAL ANSWER The rails force_ssl method does not really force a request to arrive on port 443 on your server, it is satisfied when the original (client) request was sent over ssl through the internet. The load balancer (as a proxy) sets the header X-FORWARDED-PROTO to "https". rails trusts that information and that is why this is working.

More info on that can be found in the elastic load balancer docs: http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/TerminologyandKeyConcepts.html#x-forwarded-for

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM