详情页标题前

腾讯云负载均衡混合云部署场景下通过 TOA 获取客户端真实 IP

详情页1

本文介绍混合云部署场景和 NAT64 CLB 场景下的 CLB 的四层(仅 TCP)服务如何通过 TOA 获取客户端真实源 IP。控制台开启 TOA 加载 TOA 模块 适配后端服务 (可选)监控 TOA 模块状态 说明:仅北京、上海、广州地域的 NAT64 CLB 支持通过 TOA 获取客户端真实源 IP。仅四层 TCP 支持通过 TOA 获取客户端真实源 IP,UDP 和七层(HTTP/HTTPS)不支持获取。该功能目前处于内测中,如需使用,请提交 工单申请

应用场景

混合云部署场景

混合云部署 中,IDC 的 IP 和云上 VPC 的 IP 可能会有地址重叠,因此需要配置 SNAT IP,进行 SNAT 转换源 IP。对于服务端而言,无法获得真实源 IP,因此需要通过 TOA 进行获取。

NAT64 CLB 场景

在 NAT64 CLB 场景中,客户端真实的 IPv6 源 IP 会被转换成 IPv4 的公网 IP,因此对于真实的服务端的服务而言,无法获得真实的客户端 IPv6 IP。
腾讯云 NAT64 CLB 提供获取客户端真实 IP 的功能,即将客户端真实的源 IP 放入 TCP 协议的自定义 option 中,当被嵌入真实源 IP 的 TCP 数据包发往服务端时,服务端插入的 TOA 内核模块可提取 TCP 数据包中的真实客户端源 IP,此时客户端应用只需要调用 TOA 内核模块提供的接口即可获取真实客户端源 IP。

限制说明

资源限制编译 TOA 内核模块环境的内核版本需要与服务所在环境的内核版本一致。容器环境下需要在宿主机中加载 TOA 内核模块。加载 TOA 内核模块的环境需拥有 root 权限。兼容性限制UDP 监听器不支持通过 TOA 获取源 IP。若客户端和真实服务端中间的设备有其他已经进行过 TOA 相关操作的设备,则可能存在冲突,无法保证服务端获取真实 IP 的有效性。插入 TOA 后,只对插入后的新建连接生效,对存量已有连接无效。由于 TOA 模块需要对 TCP option 中的地址进行提取等额外处理,因此 TOA 模块会引起服务端部分的性能下降。腾讯云的 TOA 模块无法保证和其他用户自定义的内核模块兼容,也无法保证与其他厂商或开源的 TOA 模块兼容。腾讯自研的 TencentOS 内嵌的 TOA 模块支持混合云部署场景下获取真实源 IP,因此若服务端的系统为 TencentOS 且为混合云部署时,可尝试直接执行 modprobe toa 命令进行加载使用。需要注意的是,TencentOS 与其他发行版 Linux 系统是两套 TOA,不支持混用。

控制台开启 TOA

1. 已创建 NAT64 版本的 CLB 实例,详情请参见 创建 IPv6 NAT64 负载均衡实例2. 登录 负载均衡控制台,创建 TCP 监听器,详情请参见 配置 TCP 监听器3. 在“创建监听器”对话框中,开启 TOA 开关。

腾讯云负载均衡混合云部署场景下通过 TOA 获取客户端真实 IP



加载 TOA 模块

1. 根据腾讯云上 Linux 的版本,下载对应的 TOA 包解压。centosCentOS 8.0 64CentOS 7.6 64
CentOS 7.2 64debianDebian 9.0 64suse linuxSUSE 12 64
SUSE 11 64ubuntuUbuntu 18.04.4 LTS 64
Ubuntu 16.04.7 LTS 642. 解压完成后,执行 cd 命令进入到刚解压的文件夹里,执行以下命令加载模块:

insmod toa.ko

3. 执行以下命令确认 TOA 模块是否加载成功。若提示“toa load success”,则说明已加载成功。

dmesg -T | grep TOA

4. 加载成功以后,在启动脚本中加载 toa.ko 文件(重启机器 ko 文件需要重新加载)。5. (可选)若不再需要使用 TOA 模块,执行以下命令进行卸载。

rmmod toa

6. (可选)执行以下命令确认 TOA 模块是否卸载成功。若提示“TOA unloaded”,则说明卸载成功。

dmesg -T

若上述下载文件中没有您的操作系统版本对应的安装包,则可以下载 Linux 通用版的源码包,编译后获取对应的 ko,该版本支持 Centos8、Centos7、Ubuntu18.04、Ubuntu16.04 等绝大多数具有代表性的 Linux 发行版。说明 由于 Linux 内核版本众多,且 Linux 发行版操作系统市场庞大,版本繁多,因此考虑到内核模块的兼容性问题,建议在使用的系统上对 TOA 源码包进行编译后使用。1. 下载源码包注意Linux 与 腾讯 TLinux 的 TOA 模块不能混用,请根据对应系统选择对应的 TOA 模块源码包。Linux

wget "https://clb-toa-1255852779.file.myqcloud.com/tgw_toa_linux.tar.gz"

腾讯 TLinux

wget "https://clb-toa-1255852779.file.myqcloud.com/tgw_toa_tlinux.tar.gz"

2. 编译 TOA 内核模块的 Linux 环境需先安装 GCC 编译器、Make 工具和内核模块开发包。CentOS 环境下的安装操作

yum install gcc
yum install make
//安装内核模块开发包,开发包头文件与库的版本需要与内核版本一致
yum install kernel-devel-`uname -r`yum install devtoolset-8 

Ubuntu、Debian 环境下的安装操作

apt-get install gcc
apt-get install make
//安装内核模块开发包,开发包头文件与库的版本需要与内核版本一致
apt-get install linux-headers-`uname -r`apt-get install devtoolset-8 

SUSE 环境下的安装操作

zypper install gcczypper install make//安装内核模块开发包,开发包头文件与库的版本需要与内核版本一致zypper install kernel-default-develzypper install devtoolset-8

3. 修改 PATH 环境变量为PATH=/opt/rh/devtoolset-8/root/bin:$PATH。编译前请确认内核 gcc 编译版本,gcc 版本需与编译版本保持一致,可使用dmesg | grep 'Linux version'命令查看内核 gcc 编译版本信息。4. 编译源码,生成 toa.ko 文件。编译过程中未提示 warningerror,则说明编译成功。以 Linux 系统对应的源码包为例:

tar zxvf tgw_toa_linux_ver.tar.gzcd tgw_toa_linux_ver//进入解压后的tgw_toa目录make

5. 编译 toa.ko 成功后,执行上文 步骤2 中的加载 TOA 模块的操作。

适配后端服务

混合云部署场景在混合云部署场景下适配后端服务时,无需进行代码改造,只需调用 Linux 网络编程中标准的接口即可获取访问用户的真实源 IP。例如以下的 C 代码样例。

struct sockaddr v4addr;  len = sizeof(struct sockaddr);  //get_peer_name 为 Linux 网络编程中标准接口。if (get_peer_name(client_fd, &v4addr, &len) == 0) {      inet_ntop(AF_INET, &(((struct sockaddr_in *)&v4addr)->sin_addr), from, sizeof(from));      printf("real client v4 [%s]:%d\n", from, ntohs(((struct sockaddr_in *)&v4addr)->sin_port));   }

NAT64 CLB 场景在 NAT64 CLB 场景中,使用 TOA 源地址透传功能,后端服务器在插入 toa.ko 内核模块后,还需对应用程序的源码进行改造以适配获取真实源 IP 的功能。1. 首先定义一个用来保存地址的数据结构。

struct toa_nat64_peer {      struct in6_addr saddr;      uint16_t sport;  };  ....  struct toa_nat64_peer client_addr;  ....

2. 其次定义消息并调用函数获取真实的 IPv6 源地址。

enum {      TOA_BASE_CTL            = 4096,      TOA_SO_SET_MAX          = TOA_BASE_CTL,      TOA_SO_GET_LOOKUP       = TOA_BASE_CTL,      TOA_SO_GET_MAX          = TOA_SO_GET_LOOKUP,  };  getsockopt(client_fd, IPPROTO_IP, TOA_SO_GET_LOOKUP, &client_addr, &len);

3. 最后获取地址。

real_ipv6_saddr = client_addr.saddr;  real_ipv6_sport = client_addr.sport;

完整示例如下所示:

//需要定义一个调用获取真实 IP 的函数的消息,值为4096即可。enum {      TOA_BASE_CTL            = 4096,      TOA_SO_SET_MAX          = TOA_BASE_CTL,      TOA_SO_GET_LOOKUP       = TOA_BASE_CTL,      TOA_SO_GET_MAX          = TOA_SO_GET_LOOKUP,  };  //需要定义一个用来保存地址的数据结构。struct toa_nat64_peer {      struct in6_addr saddr;      uint16_t sport;  };  //声明用来保存地址的变量,类型为自定义用来保存地址的数据结构。  struct toa_nat64_peer client_addr;  .……  //获取客户端的文件描述符,其中 listenfd 为服务端的监听文件描述符。  client_fd = accept(listenfd, (struct sockaddr*)&caddr, &length);  //调用函数获取对应 NAT64 场景下的用户真实源 IP。  char from[40];  int len = sizeof(struct toa_nat64_peer);  if (getsockopt(client_fd, IPPROTO_IP, TOA_SO_GET_LOOKUP, &client_addr, &len) == 0) {      inet_ntop(AF_INET6, &client_addr.saddr, from, sizeof(from));      //获取源IP和源port的信息      printf("real client [%s]:%d\n", from, ntohs(client_addr.sport));  }  

混合云部署与 NAT64 CLB 混合场景在混合云部署与 NAT64 CLB 混用场景中,使用 TOA 源地址透传功能,后端服务器在插入 toa.ko 内核模块后,还需对应用程序的源码进行改造以适配获取真实源 IP 的功能。完整示例如下所示:

//需要定义一个调用获取真实 IP 的函数的消息,值为4096即可。  enum {      TOA_BASE_CTL = 4096,      TOA_SO_SET_MAX = TOA_BASE_CTL,      TOA_SO_GET_LOOKUP = TOA_BASE_CTL,      TOA_SO_GET_MAX = TOA_SO_GET_LOOKUP,   };  
//需要定义一个用来保存地址的数据结构。 struct toa_nat64_peer { struct in6_addr saddr; uint16_t sport; }; 
//声明用来保存地址的变量,类型为自定义用来保存地址的数据结构。 struct toa_nat64_peer client_addr_nat64; ....... //获取客户端的文件描述符,其中 listenfd 为服务端的监听文件描述符。 //调用函数获取对应 NAT64 场景下真实的用户源 IP。 char from[40]; int len = sizeof(struct toa_nat64_peer); int ret; ret = getsockopt(client_fd, IPPROTO_IP, TOA_SO_GET_LOOKUP, &client_addr_nat64, &len); if (ret == 0) { inet_ntop(AF_INET6, &(client_addr_nat64.saddr), from, sizeof(from)); //获取源 IP 和源 Port 的信息。 printf("real client v6 [%s]:%d\n", from, ntohs(client_addr_nat64.sport)); } else if (ret != 0) { struct sockaddr v4addr; len = sizeof(struct sockaddr); //获取源 IP 和源 Port 的信息,注意此函数获取的源地址对于: //经过混合云部署场景的 SNAT IP 的链接而言为真正的源地址; //不经过混合云部署场景的 SNAT IP 也不经过 NAT64 的链接而言是客户端地址,同样是真正的源地址。 //因此此函数的语义便为获取真正的客户端地址、端口。 if (get_peer_name(client_fd, &v4addr, &len) == 0) { inet_ntop(AF_INET, &(((struct sockaddr_in *)&v4addr)->sin_addr), from, sizeof(from)); printf("real client v4 [%s]:%d\n", from, ntohs(((struct sockaddr_in *)&v4addr)->sin_port)); } }

(可选)监控 TOA 模块状态

为保障 TOA 内核模块运行的稳定性,TOA 内核模块还提供了监控功能。在插入 toa.ko 内核模块后,可以在容器所在的宿主机通过以下两种方式监控 TOA 模块的工作状态。方式一:查看 TOA 保存的连接的 IPv6 地址执行以下命令查看 TOA 保存的连接的 IPv6 地址。注意:此命令有可能会引起性能下降,请勿频繁调用此命令查看。

cat /proc/net/toa_table

方式二:查看 TOA 相关的计数状态执行以下命令查看 TOA 相关的计数状态。

cat /proc/net/toa_stats

其中主要的监控指标对应的含义如下所示:

指标名称 说明
syn_recv_sock_toa 接收带有 TOA 信息的连接个数。
syn_recv_sock_no_toa 接收并不带有 TOA 信息的连接个数。
getname_toa_ok 调用 getsockopt 获取源 IP 成功即会增加此计数,另外调用 accept 函数接收客户端请求时也会增加此计数。
getname_toa_mismatch 调用 getsockopt 获取源 IP 时,当类型不匹配时,此计数增加。例如某条客户端连接内存放的是 IPv4 源 IP,并非为 IPv6 地址时,此计数便会增加。
getname_toa_empty 对某一个不含有 TOA 的客户端文件描述符调用 getsockopt 函数时,此计数便会增加。
ip6_address_alloc 当 TOA 内核模块获取 TCP 数据包中保存的源 IP、源 Port 时,会申请空间保存信息。
ip6_address_free 当连接释放时,toa 内核模块会释放先前用于保存源 IP、源 port 的内存,在所有连接都关闭的情况下,所有 CPU 的此计数相加应等于 ip6_address_alloc 的计数。



FAQ

为什么在 NAT64 CLB 场景下插入了 TOA 模块后仍需要改造服务端程序?这是由于 IP 类型发生了变化导致的。在混合云部署场景下,做了 IPv4 的 Fullnat 转换,在此场景下,客户端的真实源 IP 仍然是从 IPv4 的 IP 转换成另外一个 IPv4 的 IP,因此 IP 的类型没有发生变化。但是在 NAT64 CLB 场景下,客户端真实源 IP 是从 IPv6 转换成了 IPv4,IP 类型发生了变化,因此服务端为了理解此 IPv6 的 IP,必须要对服务端程序进行改造才可以理解此 IPv6 地址的含义。如何确定所用的系统是基于 Linux 的发行版还是腾讯 TLinux 的内核?执行以下命令查看内核版本。若执行结果的版本中包含 tlinux,则为 TLinux 系统。反之则为 Linux 发行版。

uname -a

还可以执行以下命令,若执行结果中包含 tlinux 或者是 tl2,则为 TLinux 系统。

rpm -qa | grep kernel

无法获取源地址,如何进行初步的排查?1. 执行以下命令确认 TOA 模块是否已经加载。

lsmod | grep toa

2. 确认服务端程序是否已经正确调用接口获取源地址,请参见以上 适配后端服务 内容。3. 在服务端抓包排查,确认是否已经有携带真实源地址的 TCP 包抵达。若 tcp option 中存在 unknown-200 的提示,则说明经过 SNAT 后,真实的源 IP 已经插入到 TCP option 中。若存在 unknown-253,则说明在 NAT64 场景下的真实 IPv6 的源 IP 已经插入。

腾讯云负载均衡混合云部署场景下通过 TOA 获取客户端真实 IP

4. 在上一步的操作中,若确定携带 TOA 地址的包进入了服务端,则将 toa.ko 编译出 DEBUG 版本,通过内核日志便可进一步定位。在下载出的 TOA 源码目录中,将 Makefile 中添加 DEBUG 编译选项。

腾讯云负载均衡混合云部署场景下通过 TOA 获取客户端真实 IP

5. 执行以下命令重新编译。

make cleanmake

6. 执行以下命令卸载原有 ko,并重新插入编译出的最新 ko。

rmmod toa insmod ./toa.ko

7. 执行以下命令观察内核日志。

dmesg -Tw

若提示以下内容,则说明 TOA 模块正常工作,请进一步排查服务端程序是否有调用接口获取真实源 IP,或是是否接口使用错误。

腾讯云负载均衡混合云部署场景下通过 TOA 获取客户端真实 IP

8. 若以上步骤皆没有排查出具体原因,请 联系我们

负载均衡官网1折活动,限时活动,即将结束,速速收藏
同尘科技为腾讯云授权服务中心。
购买腾讯云产品享受折上折,更有现金返利。同意关联立享优惠

转转请注明出处:https://www.yunxiaoer.com/139807.html

(0)
上一篇 2023年12月9日 上午1:08
下一篇 2023年12月9日
详情页2

相关推荐

  • 阿里云RDS数据库什么是RDS PostgreSQL-云淘科技

    本文简单介绍RDS PostgreSQL及相关概念。 声明 本文档中描述的部分产品特性或者服务可能不在您的购买或使用范围之内,请以实际商业合同和条款为准。本文档内容仅作为指导使用,文档中的所有内容不构成任何明示或暗示的担保。 RDS PostgreSQL 阿里云关系型数据库RDS(Relational Database Service)支持PostgreSQ…

    阿里云数据库 2023年12月9日
  • 在83服务器上部署了一个Flink1.17把后面的任务链接的数据库服务器改为了63可以正常提交吗?-云小二-阿里云

    请教个问题,我在83服务器上部署了一个Flink1.17 ,然后我有两个mysql数据库,分别部署在63服务器和81服务上了,我在往83提交cdc作业时(链接的是81服务器上的数据库),前面几个任务能正常提交,后面再提交报超时(jdbc模式可以正常提交),为了验证cdc连接数,我把后面的任务链接的数据库服务器改为了63,可以正常提交,有人遇到过吗? 以下为热…

    2024年1月4日
  • 信息流广告,信息流部分建议宽度830px,只针对默认列表样式,顺序随机
  • 腾讯云高性能计算平台使用限制-云小二

    目前高性能计算平台(TencentCloud High Performance Computing,THPC)支持使用云 API 接入,本文介绍使用的过程中的相关限制。 节点设置 目前高性能计算平台支持管控节点和登录节点为同一台云服务器实例。管控/登录节点限制如下表所示: 限制项 限制 计费类型 包年包月、按量计费 包年包月时⻓ 支持月数1、2、3、4、5、…

    腾讯云 2023年12月9日
  • 大数据计算MaxCompute创建外部表,local指定目录需要开通什么服务,具体有文档说明吗?-云小二-阿里云

    大数据计算MaxCompute创建外部表,local指定目录需要开通什么服务,具体有文档说明吗? 以下为热心网友提供的参考意见 在MaxCompute中,您可以创建OSS(Object Storage Service)外部表,并与存储服务在MaxCompute中,您可以创建OSS(Object Storage Service)外部表,并与存储服务OSS上的目…

    2023年12月10日
  • 阿里云容器服务ACK产品优势-云淘科技

    本文介绍容器服务ACK的优势以及自建Kubernetes的劣势。 ACK的优势 优势 说明 强大的集群管理 三种集群形态:ACK专有集群、ACK托管集群、ACK Serverless集群。 ACK托管集群的管控节点默认为3个可用区的高可用部署。 单集群支持千量级ECS节点。详细配额,请参见配额限制。 支持跨可用区集群以及注册外部集群。关于注册集群的介绍,请参…

    阿里云容器服务 2023年12月9日

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信
本站为广大会员提供阿里云、腾讯云、华为云、百度云等一线大厂的购买,续费优惠,保证底价,买贵退差。