高防IP获取客户端真实IP

业务请求经过高防 IP 4 层转发后,业务服务器端接收到报文后,其看到的源 IP 地址是高防 IP 的出口 IP 地址。为了让服务器端能够获取到用户端实际的 IP 地址,可以使用如下 TOA 的方案。在业务服务的 Linux 服务器上,安装对应的 TOA 内核包,并重启服务器后。业务侧就可以获取到用户端实际的 IP 地址。

TOA 原理

高防转发后,数据包同时会做 SNAT DNAT,数据包的源地址和目标地址均修改。
TCP
协议下,为了将客户端 IP 传给服务器,会将客户端的 IPport 在转发时放入了自定义的 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

内核包安装步骤

Centos 6.x

安装步骤


下载安装包
Centos 6.x 下载


安装包文件


    Centos 6安装命令:rpm -hiv kernel-2.6.32-220.23.1.el6.toa.x86_64.rpm --force    


    Centos 7安装命令:rpm -hiv kernel-3.10.0-693.el7.centos.toa.x86_64.rpm --force  如果提示冲突报错安装下面依赖组件

    Centos 7安装依赖组件:yum -y install dracut linux-firmware xfsprogs kmod kexec-tools              


安装完成之后重启主机


    reboot


执行命令检查 toa 模块是否加载成功



    lsmod | grep toa


没有加载的话手工开启


   modprobe toa

可用下面的命令开启自动加载 toa 模块


    echo modprobe toa >> /etc/rc.d/rc.local


 


Centos 7.x/其他版本

根据上 Linux 的版本,下载对应的 TOA 包解压:

  1. 解压完成后,执行 cd 命令进入到刚解压的文件夹里,执行加载模块的指令:
    insmod toa.ko
  2. 执行下面指令确认是否已加载成功:
    lsmod | grep toa
  3. 如已加载成功,最后在启动脚本里面加载 toa.ko 文件即可(重启机器 ko 文件需要重新加载)。

如果上述下载文件中没有您的操作系统版本对应的安装包,可以下载 Linux 通用版的源码包,编译后获取,该版本支持 Centos6.9 和 Centos7、Ubuntu14.04 等绝大多数的 Linux 发行版:

  1. 获取源码包
centos7.0 及以上源码包

wget "http://thunder-pro-mainland-1258348367.cos.ap-guangzhou.myqcloud.com/gaap-toa%E6%BA%90%E7%A0%81(centos7%E4%BB%A5%E4%B8%8A).zip"

centos7.0 以下源码包

wget "http://thunder-pro-mainland-1258348367.cos.ap-guangzhou.myqcloud.com/gaap-toa%E6%BA%90%E7%A0%81(centos7%E4%BB%A5%E4%B8%8B).zip"


  1. 编译文件
    yum install gcc
    yum install kernel-headers
    yum install kernel-devel
  2. 加载 toa.ko 文件
    tar -zxvf linux_toa.tar.gz
    cd toa
    make
    mv toa.ko /lib/modules/`uname -r`/kernel/net/netfilter/ipvs/toa.ko
    insmod /lib/modules/`uname -r`/kernel/net/netfilter/ipvs/toa.ko

如果编译报错,有可能是安装的内核版本和 uname -r 展示版本不一致,进入到 /lib/modules/ 目录,查看本机上真实安装的内核版本,修改 Makefile 文件里面的 uname -r 为真实的内核版本,重新编译。