经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 数据库/运维 » Nginx » 查看文章
多级nginx代理,获取客户端真实ip
来源:cnblogs  作者:熔遁丶螺旋手里剑  时间:2018/9/25 19:08:11  对本文有异议

今天服务里的微信公众号支付业务突然不能用了,报错为网络环境未能通过安全验证,请稍后再试。检查后端日志,没有任何问题,看来是成功创建支付订单,但是调起支付时出现了问题。上网查了一下,这个报错的直接原因是传入的客户端ip与调起支付的ip不符。但是印象中我在代码中获取的是X-Forwarded-For,就是请求来源的客户端IP,就查看日志发现传给微信的ip为172.17.0.1,也就是宿主机ip,这是才恍然大悟,在升级线上环境时我们将所有服务放进了docker,并且在docker里装了nginx来分发请求给对应的服务,也就是说我们是两级nginx代理,我们的服务是没法拿到最外层客户端ip的。只好改进nginx将每级代理的ip都记录起来,而不是直接覆盖。

改进方法:

对第一级nginx代理

location ~ ^/test {
         proxy_pass http://127.0.0.1:8888;
         proxy_set_header Host            $host;
         proxy_set_header X-real-ip  $remote_addr;
         proxy_set_header X-Forwarded-For $remote_addr;
   }

第一级nginx代理不需要改动,直接将原始客户端ip记录到X-Forwarded-For即可

 

对于第二级,以及之后可能存在的更多级代理

location ~ ^/test {
         proxy_pass http://127.0.0.1:12000;
         proxy_set_header Host            $host;
         proxy_set_header X-real-ip  $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
   }

这样就将新一级代理的ip接到X-Forwarded-For的尾部,并用逗号分割。也就是说X-Forwarded-For是一个逗号拼接的ip字符串,想拿到原始ip只需要按逗号分割,取第一位ip即可。

 

Golang业务中读取原始客户端ip代码

 

  1. real_ip := r.Header.Get("X-Forwarded-For")
  2. ip_list := strings.Split(real_ip, ",")
  3. if len(ip_list) > 1 {
  4. real_ip = ip_list[0]
  5. }

 

 

就是这么简单啦,希望对大家有所帮助~

 

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号