背景
通常情况下,我们会使用Nginx作为反向代理服务器。在这种架构下,后端的服务器接收到的请求来源IP地址实际上是Nginx服务器的IP地址,而非客户端的真实IP地址。但在某些场景下,上游服务器(即后端服务器)需要获取到客户端的真实IP地址以便进行正确处理和访问控制等操作。为此,我们需要对Nginx进行特殊的配置以传递客户端真实IP地址给后端服务器。图片
正文
配置
Nginx 确保安装yum -y install pcre-devel
nginx
nginx.conf:
stream {
upstream udp-test{
server 192.168.207.130:3333;
}
server {
listen 2222 udp;
proxy_responses 1;
proxy_bind $remote_addr transparent;
proxy_timeout 20s;
proxy_pass udp-test;
}
UDP:
# 创建一条IP规则,当数据包标记为0x2333时,优先级为100,并使用自定义路由表100进行路由
ip rule add fwmark 0x2333/0x2333 pref 100 table 100
# 在路由表100中添加一个本地路由规则,所有匹配的数据包通过本地回环接口(lo)处理,不经过网络转发
ip route add local default dev lo table 100
# 在iptables的mangle表PREROUTING链上增加一条规则,对源端口为1111的UDP流量设置标记并透明代理至本地127.0.0.1:2222的服务
iptables -t mangle -A PREROUTING -p udp --sport 1111 -j TPROXY --tproxy-mark 0x2333/0x2333 --on-ip 127.0.0.1 --on-port 2222
TCP:
ip rule add fwmark 1 lookup 100
ip route add local 0.0.0.0/0 dev lo table 100
iptables -t mangle -A PREROUTING -p tcp -s 192.168.207.0/24 --sport 1111 -j MARK --set-xmark 0x1/0xffffffff
TProxy:
/sbin/iptables -F
# 新建一个 DIVERT 给包打标签
/sbin/iptables -t mangle -N DIVERT
/sbin/iptables -t mangle -A DIVERT -j MARK --set-mark 1
/sbin/iptables -t mangle -A DIVERT -j ACCEPT
# 把tcp的包给DIVERT处理
/sbin/iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT
# 有标签的包去查名为 100 的路由表
/sbin/ip rule add fwmark 1 lookup 100
# 100的路由表里就一条默认路由,把所有包都扔到lo网卡上去
/sbin/ip route add local 0.0.0.0/0 dev lo table 100
通过以上配置,将所有发往Proxy的tcp包,重定向到本地环路(lo)上。然后由TProxy内核补丁来对这些网络包进行处理,进而成功将后端server返回包路由回源客户端
服务端
修改路由到客户端地址或地址段的IP消息指向Nginx服务器地址的默认路由
route add -host 192.168.207.128 gw 192.168.207.129 dev eth0