DDoS 高防 IP 使用非网站业务转发规则时,源站需使用 toa 模块获取客户端的真实 IP。
业务请求经过高防 IP 的 4 层转发后,业务服务器端接收到报文后,其看到的源 IP 地址是高防 IP 的出口 IP 地址。为了让服务器端能够获取到用户端实际的 IP 地址,可以使用如下 TOA 的方案。在业务服务的 Linux 服务器上,安装对应的 TOA 内核包,并重启服务器后。业务侧就可以获取到用户端实际的 IP 地址。
高防转发后,数据包同时会做 SNAT 和 DNAT,数据包的源地址和目标地址均修改。
TCP 协议下,为了将客户端 IP 传给服务器,会将客户端的 IP,port 在转发时放入了自定义的 tcp option 字段。
#define TCPOPT_ADDR 200
#define TCPOLEN_ADDR 8 /* |opcode|size|ip+port| = 1 + 1 + 6 */
/*
*insert client ip in tcp option, now only support IPV4,
*must be 4 bytes alignment.
*/
struct ip_vs_tcpo_addr {
__u8 opcode;
__u8 opsize;
__u16 port;
__u32 addr;
};
Linux 内核在监听套接字收到三次握手的 ACK 包之后,会从 SYN_REVC
状态进入到 TCP_ESTABLISHED
状态。这时内核会调用 tcp_v4_syn_recv_sock
函数。 Hook 函数 tcp_v4_syn_recv_sock_toa
首先调用原有的tcp_v4_syn_recv_sock
函数,然后调用 get_toa_data
函数从 TCP OPTION 中提取出 TOA OPTION,并存储在 sk_user_data
字段中。
然后用 inet_getname_toa hook inet_getname
,在获取源 IP 地址和端口时,首先调用原来的inet_getname
,然后判断 sk_user_data
是否为空,如果有数据从其中提取真实的 IP 和 port,替换 inet_getname
的返回。
客户端程序在用户态调用 getpeername,返回的 IP 和 port 即为客户端的原始 IP。
rpm -hiv kernel-2.6.32-220.23.1.el6.toa.x86_64.rpm --force
reboot
lsmod | grep toa
modprobe toa
echo "modprobe toa" >> /etc/rc.d/rc.local
dpkg -i linux-image-4.4.87.toa_1.0_amd64.deb
Headers 包可不装,如需要做相关开发则安装。lsmod | grep toa
检查 toa 模块是否加载 没有加载的话 modprobe toa
开启。echo "modprobe toa" >> /etc/rc.d/rc.local
CONFIG_IPV6=M
改成 CONFIG_IPV6=y
。make modules_install
。make install
。lsmode | grep toa
检查 toa 模块是否加载 没有加载的话 modprobe toa
开启。您可自己制作 rpm 包,也可由我们提供。
rpm -hiv kernel-2.6.32-220.23.1.el6.src.rpm
rpmbuild -bp ~/rpmbuild/SPECS/kernel.spec
cd ~/rpmbuild/BUILD/kernel-2.6.32-220.23.1.el6/ cp -a linux-2.6.32-220.23.1.el6.x86_64/ linux-2.6.32-220.23.1.el6.x86_64_new
cd ~/rpmbuild/BUILD/kernel-2.6.32-220.23.1.el6/linux-2.6.32-220.23.1.el6.x86_64_new/
patch -p1 < /usr/local/src/linux-2.6.32-220.23.1.el6.x86_64.rs/toa-2.6.32-220.23.1.el6.patch
sed -i 's/CONFIG_IPV6=m/CONFIG_IPV6=y/g' .config
echo -e '\n# toa\nCONFIG_TOA=m' >> .config
cp .config ~/rpmbuild/SOURCES/config-x86_64-generic
cd ~/rpmbuild/BUILD/kernel-2.6.32-220.23.1.el6/linux-2.6.32-220.23.1.el6.x86_64
rm -rf .config
cd ~/rpmbuild/BUILD/kernel-2.6.32-220.23.1.el6/
diff -uNr linux-2.6.32-220.23.1.el6.x86_64 linux-2.6.32-220.23.1.el6.x86_64_new/ >
~/rpmbuild/SOURCES/toa.patch
vim ~/rpmbuild/SPECS/kernel.spec
在 ApplyOptionPath 下添加如下两行(还可修改 buildid 等自定义内核包名): Patch999999: toa.patch
ApplyOptionalPatch toa.patch
rpmbuild -bb --with baseonly --without kabichk --with firmware --without debuginfo --target=x86_64 ~/rpmbuild/SPECS/kernel.spec
rpm -hiv kernel-xxxx.rpm --force
DDoS 高防 IP 使用网站业务转发规则时,可利用 HTTP 头部的 X-Forwareded-For 字段获取客户端真实 IP。
X-Forwareded-For:是一个 HTTP 头部扩展字段,目的是使服务器可以识别通过代理等方式链接的客户端真正的 IP。
格式为:X-Forwareded-For:Client,proxy1,proxy2,proxy3……
当高防 IP 将用户的访问请求转到后端服务器时,会把请求用户的真实 IP 记录在 X-Forwareded-For 字段的首位。因此,源站应用只需要获取 HTTP 头部的 X-Forwarded-For 字段的内容即可。
更多详情请参考 七层转发获取来访真实 IP 的方法。
本页内容是否解决了您的问题?