© 2025 Rocky. All rights reserved.

|浙ICP备2025179428号-3|友情链接|

魔法施展中...

技术文章

技术分享

dokku下nginx两级转发https请求时的坑

2024-03-28
5 分钟
...

最近遇到一个让我排查了好一阵子的问题。

问题描述:

我是用dokku来部署的,因此nginx 生成了应用的nginx.conf,这个应用工作于7000端口。 我自己手工写了一个配置文件,监听443端口来服务https请求,这个服务就是定制了一些转发,期中"/"路径是转发给7000端口的。 后端应用是rails写的,有大量的redirect请求的场景。 完整的路径是:

用户 => nginx 443 => nginx(7000)=> rails

nginx 443转发到7000端口的时候,是用的proxy_pass http://localhost:7000/ 这个设定,从https转到了http转发。 现在问题来了,当有转发的时候,浏览器页面是https://a.example.com/,收到的是location: http://a.example.com/somepage这个。这时候浏览器拒绝响应了,不执行这个来自服务端的重定向。可能是一个安全策略,https页面不允许重定向到http页面。 于是我把rails的 force_ssl 设置为true了。结果问题更严重了,所有请求都报错,说重定向次数太多。 排查最终发现问题出在Nginx配置的这一行:

proxy_set_header X-Forwarded-Proto $scheme;

nginx 443的host收到用户的https请求,将协议改成http转发给7000,同时加上了X-Forwarded-Proto: https 这个头。 nginx 7000端口的host收到的是一个http请求,带有一个X-Forwarded-Proto: https的头,但是整个请求是http的,不是https的。这个时$scheme 是http,nginx 这时发给rails 的是 X-Forwarded-Proto: http这个头。 于是rails的强制转https的部分工作了,给客户端下发了一个Location: https://${host}/${path} 的响应。 但是请求本身已经是https了啊,于是就不断地循环这个过程了。

解决方案:

将第二层也就是nginx监听7000端口的配置,从proxy_set_header X-Forwarded-Proto $scheme; 直接改成 proxy_set_header X-Forwarded-Proto "https";。方案粗暴了一些, 但是好像也没有好的办法。 但是,dokku应用的nginx配置文件,在每次deploy之后都会重新生成,因此我们要找个稳妥的方案,保证生成的nginx配置就写的是https而不是$scheme 这个变量。

dokku的nginx模板,其实都是来自于/var/lib/dokku/plugins/enabled/nginx-vhosts/templates/nginx.conf.sigil 这个文件。 打开这个文件,找到

{{ else if eq $scheme "https"}}

这后面,将这一行

proxy_set_header X-Forwarded-Proto {{ $.PROXY_X_FORWARDED_PROTO }};

强制改一下,写死https。

 proxy_set_header X-Forwarded-Proto 'https';

感谢阅读!如果您觉得这篇文章有帮助,欢迎分享给更多的朋友。

上一篇
技术实践

优化 dokku 在国内主机上的发版速度

通过配置代理优化 dokku 在国内主机上的发版速度,解决部署缓慢的问题。

下一篇
技术实践

在google cloud platform上收录dokku 生成的日志

Google Cloud Platform (GCP) 上有类似于阿里云 SLS(Simple Log Service)的日志收集和分析服务。在 GCP 上,这个服务主要由 Cloud Logging 和 Cloud Monitoring 组成,它们共同提供了强大的日志管理和分析能力。

📮 订阅更新
每周收到最新文章推送,不错过精彩内容

💡 我们尊重您的隐私,不会将邮箱用于其他用途

加载中...

猜你喜欢

生活随笔

问题的边界

- 有时候问题不好解决,是我们没有定义好问题的边界,想要的太多。不如想想怎样够用就好,或者只解决一个最重要的问题。

2021-12-23
技术分享

目标、方法、克制

今年对我影响最大的一篇文章,我忘记了出处,但是总结起来就这么一句:

2020-06-04
技术实践

避免情绪化、穿越周期,才是真正的长期主义

投资的要义,我以前以为是挑一只好股票,现在看来,是『避免情绪化、穿越周期』。

2022-06-08