How do you configure a secure ECS Rails app to run behind NGINX using Service Connect?


I have a Rails 6.x application that I want to move to ECS / Fargate. I created an ECS Cluster that contains two services, my Rails app (app) and a web server (web). The two services communicate with each other using AWS Service Connect and there is an ALB pointed to the web server (NGINX), which then proxies the requests to the Rails app. Everything seems to work fine, however my Rails app keeps redirecting back to itself due to config.force_ssl = true in the environment file.

See, the way Rails handles secure applications is that it requires HTTPS requests. However, the TLS connection is being terminated at the ALB. The ALB then uses HTTP for all the internal connections. Our NGINX container is configured to pass the X-Forwarded-For and X-Forwarded-Port on to the Rails application to let it know that the original request is secure (HTTPS).

I've checked and double checked the request headers in the Rails app and they all appear to be correct. However, Rails still insists on redirecting all of my requests to HTTPS, even though X-Forwarded-For and X-Forwarded-Port are set correctly.

What is going on here? Is it possible to host a secure Rails app in ECS using NGINX as a reverse proxy? Is Service Connect (Envoy) doing something weird to the request that is confusing Rails? Am I completely wrong in how I've configured the system?

1 Answer


The X-Forwarded-Port and X-Forwarded-For are just headers used to identify the destination port that the client used to connect to the load balancer and the IP address of a client when you use an HTTP or HTTPS load balancer respectively.

It doesn't mean that the application will receive the connection on that port. Instead, what is occurring is that the NGINX container is likely reaching out the Rails application using the HTTP port (without TLS) and it is being redirected due to force_ssl flag.

If you really need to have TLS for all request path, you'll need to configure something like AppMesh or a custom solution using Envoy.

In general, terminating secure connections at the load balancer and using HTTP on the backend might be sufficient for your application. Network traffic between AWS resources can only be listened to by the instances that are part of the connection. However, if you are developing an application that needs to comply with strict external regulations, you might be required to secure all network connections.

profile pictureAWS
answered a year ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions