当前位置:   article > 正文

Nginx使用同一端口兼容http和https并实现客户端真实IP获取_nginx upstream http 同一个接口

nginx upstream http 同一个接口

一,需求来源

1,因历史原因需要在同一个端口实现http和https的同时支持

2,因安全需求需要对部分接口URL添加白名单IP限制,需要将真实客户端IP转发到后端服务上

二,实现原由

1,同一端口实现兼容http和https主要使用的是nginx的stream->map $ssl_preread_protocol->server转发。

2,IP透传主要使用的是proxy_bind $remote_addr transparent;和iptables+ip route规则实现。

三,实现过程

1,后端真实服务监听端口在: 192.168.0.101:9000

2,前端NGINX代理运行在: 192.168.0.100:9000

3,在NGINX服务上建两个分别为HTTP和HTTPS协议的服务使用不同的端口指向后端服务

  1. server {
  2. listen 20036; # http
  3. listen 20037 ssl; # https
  4. ssl_certificate /etc/nginx/cert.pem; #证书。
  5. ssl_certificate_key /etc/nginx/cert.key; #证书。
  6. ssl_session_timeout 5m;
  7. ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; #使用此加密套件。
  8. ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #使用该协议进行配置。
  9. ssl_prefer_server_ciphers on;
  10. location / {
  11. proxy_set_header Host $http_host;
  12. proxy_set_header X-Real-IP $remote_addr;
  13. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  14. proxy_set_header X-Forwarded-Proto $scheme;
  15. client_body_buffer_size 100M;
  16. client_max_body_size 100M;
  17. proxy_buffer_size 512k;
  18. proxy_buffers 64 512k;
  19. proxy_busy_buffers_size 1m;
  20. proxy_connect_timeout 300;
  21. proxy_http_version 1.1;
  22. proxy_set_header Connection "";
  23. chunked_transfer_encoding off;
  24. proxy_pass http://192.168.0.101:9000;
  25. }
  26. }

4,在NGINX服务上建立stream通过ssl_preread_protocol自适应客户端请求类型进行转发。此时用http和https均能正常访问到后端服务。但是在后端服务的访问日志中可以看到所有的来源IP地址都是192.168.0.100。

  1. stream {
  2. upstream http_gateway {
  3. server 127.0.0.1:20036;
  4. }
  5. upstream https_gateway {
  6. server 127.0.0.1:20037;
  7. }
  8. map $ssl_preread_protocol $upstream{
  9. default http_gateway;
  10. "TLSv1.0" https_gateway;
  11. "TLSv1.1" https_gateway;
  12. "TLSv1.2" https_gateway;
  13. "TLSv1.3" https_gateway;
  14. }
  15. server {
  16. listen 9000;
  17. ssl_preread on;
  18. #proxy_bind $remote_addr transparent; #这行先注释
  19. proxy_pass $upstream;
  20. }
  21. }

5,使用以下方法将客户端地址和连接透传到后端服务上。

在NGINX服务器上stream的server中配置启用以下:

proxy_bind $remote_addr transparent;  

该行启用后客户端访问NGINX时会卡在连接状态无法连接成功,需要进后行续处理。

6,NGINX服务器上添加iptables规则和ip route路由

  1. #1,添加路由到lo口,100
  2. ip route add local 0.0.0.0/0 dev lo table 100
  3. #2,mark标记为1的使用100路由规则
  4. ip rule add fwmark 1 lookup 100

7,后端服务器上添加规则

  1. #1,允许流量
  2. iptables -I INPUT -i bond0 -j ACCEPT
  3. #2,禁用101主机上的reverse path filter,避免无法回复非本地网段数据包
  4. echo "net.ipv4.conf.all.rp_filter = 0" >> /etc/sysctl.conf
  5. echo "net.ipv4.conf.bond0.rp_filter = 0" >> /etc/sysctl.conf
  6. #3,对源地址和端口为本机服务的打mark为1
  7. iptables -t mangle -A OUTPUT -p tcp --src 192.168.0.101 --sport 9000 -j MARK --set-xmark 0x1/0xffffffff
  8. #4,添加路由到前端代理服务器,100
  9. ip route add default via 192.168.0.100 table 100
  10. #5,mark匹配的使用该100路由转发回前端代理主机
  11. ip rule add fwmark 1 lookup 100

8,重启nginx(reload不生效)观察访问日志结果。

多次测试后成功。

四,参考资源和原理说明:

nginx的tcp透明代理设置 - 简书

IP Transparency and Direct Server Return with NGINX Plus

记玄妙莫测的透明代理_tproxy-CSDN博客

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/671973
推荐阅读
相关标签
  

闽ICP备14008679号