在AWS Elastic Beanstalk负载均衡器上强制Rails应用使用HTTPS遇错
config.force_ssl = true后的连接重置问题 咱们先把问题的核心理清楚:AWS Elastic Beanstalk的负载均衡器是做SSL终止的——说白了就是用户发的HTTPS请求到负载均衡器就解密了,之后负载均衡器会用HTTP把请求转发给后端的Nginx和Puma。当你开启config.force_ssl = true后,Rails默认只认直接的HTTPS连接,它不知道原始请求其实是通过HTTPS进来的,这就会导致要么重定向循环,要么因为配置不匹配出现连接重置的问题。
下面是具体的修复步骤,一步步来:
1. 调整Rails的force_ssl配置,信任负载均衡器的转发头
打开config/environments/production.rb,别只单纯设置config.force_ssl = true,得加上对负载均衡器转发头的信任配置:
config.force_ssl = true # 信任Elastic Beanstalk负载均衡器的X-Forwarded-Proto头 config.action_dispatch.trusted_proxies = [IPAddr.new("0.0.0.0/0")] # 要是你想更严谨,也可以只信任AWS负载均衡器的IP段,但在EB环境里用0.0.0.0/0是安全的,因为负载均衡器是唯一的请求入口
设置trusted_proxies的目的是让Rails相信来自负载均衡器的X-Forwarded-Proto头,这样Rails就能正确识别原始请求是HTTPS还是HTTP,不会瞎搞重定向,自然也就不会出现连接问题了。
2. 检查并修正Nginx配置
你提到用了awslabs的EB Nginx配置,得确保Nginx正确把负载均衡器的转发头传给Puma。重点看下面这段配置,对比你手里的文件:
在Nginx的server块里,一定要包含这些转发头配置:
location / { proxy_pass http://puma; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 关键:把负载均衡器传来的X-Forwarded-Proto头原封不动传给Rails proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; proxy_set_header X-Real-IP $remote_addr; }
这里的X-Forwarded-Proto $http_x_forwarded_proto是核心——负载均衡器已经把用户原始请求的协议(HTTP/HTTPS)放在这个头里了,Nginx必须把它传给Rails,不然Rails永远不知道用户是用HTTPS进来的。
另外要注意:后端的Nginx只需要监听HTTP端口就行,别配置成只监听HTTPS,因为它和负载均衡器之间是用HTTP通信的。
3. 验证负载均衡器的监听配置
登录AWS控制台,检查你的EB负载均衡器:
- 确保同时监听80(HTTP)和443(HTTPS)端口
- 80端口的转发规则:把请求转发到后端实例的80端口(也就是Nginx监听的端口)
- 443端口的转发规则:同样转发到后端实例的80端口,并且已经关联了你的AWS证书
- 检查安全组:负载均衡器的安全组要允许80、443端口的入站流量;后端实例的安全组要允许来自负载均衡器安全组的80端口入站流量
4. 重启应用和服务器
改完配置后,记得:
- 把修改后的Rails配置和Nginx配置部署到Elastic Beanstalk
- 重启Puma和Nginx服务,或者直接重新部署整个应用
要是还出问题?试试这些排查方法
如果还是有连接重置的情况,可以:
- 看EB的日志,特别是Nginx的错误日志(
/var/log/nginx/error.log)和Puma的日志,里面会有具体的错误信息 - 检查负载均衡器的健康检查是否正常——如果健康检查失败,负载均衡器会直接终止连接,导致“连接重置”
- 确认
config.force_ssl的配置没和Nginx里的其他重定向规则冲突
内容的提问来源于stack exchange,提问作者Juan Fuentes

