代理、转发等多种场景下,如何获取用户真实IP?(2)
响应的数据是通过黄色线直接返回给用户,而不是通过红色线原路返回,这样好像是一个正常的数据轮回,用户也接收到了数据,但是来源IP变了,不是期望的10.0.3.254,而是从新DNS服务器直接返回,但这个数据会认为是不合法的,所以被用户端丢弃了,返回报错信息,不是期望的来源IP(这里用wireshark抓包可以可以看到有正常的智能解析响应包): NAT原理已经限制在那里了,虽然有进行多次的NAT修改和iprule的策略路由修改来测试,但是都行不通,成功再次失败. 1.5.3 成功识别 看起来无法解决的技术难题最终还是解决好了. 之前D机器只做PREROUTING,不做POSTROUTING,已经是个大概模型了,可以正常NAT,也可以正常识别到源IP,用户也会收到正确的解析回应,只是因为与TCP期望的返回源IP不对被应用层丢弃而已. 解决的关键点D机器到C机器的网络拓扑,因为是返回的不是期望的IP来源,所以如果能让返回的数据包也经过一下D机器,从D返回给用户就可以了. 但是C机器返回信息给用户会走默认网关,不会按照预期的线路返回,如果让他正常走D回来就必须添加POSTROUTING修改用户源IP,这里两者不可兼得. 不过让返回的数据包不直接走网关的方式还有另外一个实现方式就是架设一个直通的网络隧道,尝试在C和D之间架设一个上次《VPN杂谈》里面谈到的GRE隧道来通讯. 新架构如图: 相关操作也简单明了. C机器命令: modprobe ip_gre ip tunnel add gre1 mode gre remote 10.0.3.254 local 172.16.10.17 ttl 255 ip link set gre1 up ip addr add 192.10.10.2 peer 192.10.10.1 dev gre1 D机器命令: modprobe ip_gre ip tunnel add gre1 mode gre remote 172.16.10.17 local 10.0.3.254 ttl 255 ip link set gre1 up ip addr add 192.10.10.1 peer 192.10.10.2 dev gre1 在C和D之间有直通的网络隧道之后,D在做PREROUTING转发的时候转发到对方的GRE隧道IP: -A PREROUTING -d 10.0.3.254 -p udp –dport 53 -j DNAT –to-destination 192.10.10.2:53 简单测试下可以发现用户的中转流量已经通过隧道转过来了,但是响应的数据没有回去. 通过抓包可以看到没有回去是因为没有加这个特殊网络的回去路由,再在C机器上加个策略路由,让从隧道来的流量再从隧道返回去: #新增策略路由gre表 echo “101 gre” >> /etc/iproute2/rt_tables #添加具体策略 /sbin/ip route add default via 192.10.10.2 table gre /sbin/ip rule add from 192.10.10.0/24 table gre 路由加好之后效果立竿见影,数据包通过隧道成功原路返回: 用户端通过NAT之后成功智能解析的效果: 问题解决. 另外,做NAT不但是Linux可以做,Windows也可以做NAT,添加“网络策略和访问服务“即可,效果也大同小异. 2 结语经过一番折腾,文章开始说的BGP转发如果一定要实现保留用户原始IP的话思路也很清晰了. 在B和C机器创建GRE隧道,然后NAT地址指向C机器的GRE隧道IP就可以解决了,如果是内网环境还可以直接拉网线解决,直接两个网卡对接一条网线或者经过同一个交换机在同一个网段即可. 文章来自微信公众号:运维军团 (编辑:ASP站长网) |