You need to enable JavaScript to run this app.
导航
安装 TOA 模块获取真实请求来源 IP
最近更新时间:2024.01.29 10:47:24首次发布时间:2024.01.29 10:37:22

如果您的业务通过非网站方式接入 DDoS 高防实例,而且源站非火山引擎云服务器(ECS)或负载均衡(LB)等资源(例如其他云厂商 ECS、线下 IDC 服务器等),源站将无法直接获取真实的请求来源 IP。您可以通过在服务器安装 TOA 模块来获取真实的请求 IP。

实现原理

该 IP 获取机制由高防实例和部署在服务器上的 TOA 模块共同实现。高防实例在返回给源站的报文中携带访问客户端的源 IP 等信息,并由安装在源站服务器上的 TOA 模块从报文中解析出相关信息 ,获取对应的源 IP。

注意事项

  • 本文仅适用于基于 Linux 内核的操作系统,包括 Ubuntu、CentOS 和 Debian。
  • 为了保障系统安全,我们建议您在执行正式安装操作前,先参照本文档在测试环境中进行试运行。确认无误后,再在生产环境中执行安装步骤。
  • 在安装 TOA 模块时,请确保您的服务器系统内核版本与本文提供的 TOA 模块安装包的版本一致。
  • 若您的操作系统中已经安装了 TOA 模块,建议先提前备份再进行火山引擎 TOA 模块安装操作。如遇到重启失败的情况,您可以切换回原有内核以恢复系统。
  • 每次内核升级后,您都需要重新编译和安装 TOA 模块,以免因内核升级导致现有的 TOA 模块不兼容。

前提条件

安装 TOA 模块前请确保您有服务器 root 权限。

操作步骤

  1. 根据服务器系统类型和内核版本,下载对应的 TOA 模块安装包。

    操作系统

    内核版本

    安装包

    Ubuntu

    Ubuntu 16.04.7 4.15.0-142-generic

    toa-Ubuntu 16.04.7 4.15.0-142-generic.tgz
    未知大小

    Ubuntu 16.04.7 4.4.0-151-generic

    toa-Ubuntu 16.04.7 4.4.0-151-generic.tgz
    未知大小

    Ubuntu 18.04 4.15.0-76-generic

    toa-Ubuntu 18.04 4.15.0-76-generic.tgz
    未知大小

    CentOS

    CentOS 7.9 3.10.0-1160.el7.x86_64

    toa-CentOS 7.9 3.10.0-1160.el7.x86_64.tgz
    未知大小

    CentOS 7.6 3.10.0-957.27.2.el7.x86_64

    toa-CentOS 7.6 3.10.0-957.27.2.el7.x86_64.tgz
    未知大小

    CentOS 6.8 2.6.32-642.6.2.el6.x86_64

    toa-CentOS 6.8 2.6.32-642.6.2.el6.x86_64.tgz
    未知大小

    Debian

    Debian 9 4.9

    toa-Debian 9 4.9.tgz
    未知大小

    Debian 10-4.19.0-18-amd64

    toa-Debian 10-4.19.0-18-amd64.tgz
    未知大小
  2. 用 root 身份登录到服务器主机。

  3. 将安装包解压。

    tar -xzvf toa.tgz  #使用安装包实际名称替换toa.tgz。
    
  4. 将解压文件移动至指定目录。

    mv toa /usr/local/  #使用文件实际名称替换toa和路径/usr/local/。
    
  5. 执行安装命令。

    /usr/local/toa/install.sh  #使用文件实际名称替换toa和路径/usr/local/。
    
  6. 查看模块加载是否正常。

    lsmod | grep toa  #使用文件实际名称替换toa。
    
  7. 执行reboot命令重启服务器,服务器重启后将自动加载 TOA 模块。

相关操作

如您需要卸载 TOA 模块,可执行rmmod toa命令,注意使用文件实际名替换toa

示例代码

预期可以通过getpeername接口获取 Client IP 和 Port 信息。

void checksockname(int fd)
{
    struct sockaddr_in6 addr;
    int sin_size = sizeof(addr);
    printf("getpeername: ");
    if (getpeername(fd, (struct sockaddr *)&addr, (socklen_t *)&sin_size) == 0)
        sockaddr_display(&addr);
    else
       printf("error\n");
}