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

本文详细描述了如何在NGINX中配置同一端口同时支持HTTP和HTTPS,以及如何通过SSL预读协议实现IP白名单限制,并通过iptables和iproute规则确保客户端IP转发。最终实现了后端服务的真实IP地址显示和安全策略的实施。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一,需求来源

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协议的服务使用不同的端口指向后端服务

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

}

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

stream {
  upstream http_gateway {
    server  127.0.0.1:20036;
  }
  upstream https_gateway {
    server  127.0.0.1:20037;
  }
  map $ssl_preread_protocol $upstream{
    default http_gateway;
    "TLSv1.0" https_gateway;
    "TLSv1.1" https_gateway;
    "TLSv1.2" https_gateway;
    "TLSv1.3" https_gateway;
  }

  server {
    listen 9000;
    ssl_preread on;
    #proxy_bind $remote_addr transparent;  #这行先注释
    proxy_pass $upstream;
  }
}

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

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

proxy_bind $remote_addr transparent;  

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

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

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

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

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

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

多次测试后成功。

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

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

IP Transparency and Direct Server Return with NGINX Plus

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

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值