IPA TOA 的使用背景:
TOA 模块是为了让后端的 realserver 能够看到真实的 clientip 而不是负载均衡器或者 proxy 的代理 ip;
阿里云的全站加速产品天然的支持 TOA 的透明转发,且性能测试满足企业高并发访问性能,接下来看下如何进行 toa 使用。
1、安装
aliyun toa 支持 opcode=28/254
https://github.com/aliyun/alibabacloud-cdn-tool-toa
2、全站加速支持现状
opcode=28的tcp option格式是:
nop(8 bits)
opcode(8 bits) = 28
opsize(8 bits) = 7
opversion(8 bits) = 1
ip(32 bits, big endian)
opcode=254的格式是:
tcp option(ipv4):
opcode(8 bits) = 254
opsize(8 bits) = 8
port(16 bits, big endian)
ip(32 bits, big endian)
tcp option(ipv6):
opcode(8 bits) = 254
opsize(8 bits) = 20
port(16 bits, big endian)
ip(128 bits, big endian)
huawei toa opcode=8/254
https://github.com/Huawei/TCP_option_address
对 TOA 不太了解的同学可以看下面的说明,熟悉的可以略过
3、TOA 基本原理
TOA 名字全称是 tcp option address,是 FullNat 模式下能够让后端服务器获取 ClientIP 的一种实现方式,它的基本原理比较简单。
1、客户端用户请求数据包到达 LVS 时,LVS 在数据包的 tcp option 中插入 src ip 和 src port 信息
2、数据包到达后端服务器(装有 toa 模块)后,应用程序正常调用 getpeername 系统函数来获取连接的源端 IP 地址
3、由于在 toa 代码中 hook(修改)了 inet_getname 函数(getpeername 系统调用对应的内核处理函数),该函数会从 tcp option 中获取 lvs 填充的 src 信息
4、这样后端服务器应用程序就获取到了真实客户端的 ClientIP,而且对应用程序来说是透明的。
TCP 协议栈中处理三次握手的 ack 数据包的函数是 tcp_v4_syn_recv_sock,完成连接的建立,并创建 newsock。 tcp_v4_syn_recv_sock_toa hook 在 tcp_v4_syn_recv_sock,第三次 TCP 握手时 ACK 报文到达 Server 段后,调用 sock* tcp_v4_syn_recv_sock_toa 函数,代码逻辑走到原有的 tcp_v4_syn_recv_sock 函数,如果是非 TOA 逻辑则执行 if (newsock) sock_reset_flag(newsock, SOCK_TOA_IPV4);
否则解析 tcp option 内容,获取到 ip 端口 等信息后挂到 newsock 中
tdata.opcode = TCPOPT_TOA;
tdata.opsize = TOA_V4_LEN - 1;
tdata.opversion = TOA_IPV4;
tdata.ip = ip;
memcpy(&ptr, &tdata, sizeof(struct toa_data));
newsock->sk_user_data = ptr;
sock_set_flag(newsock, SOCK_TOA_IPV4);
TOA_INC_STATS(ext_stats, SYN_RECV_SOCK_TOA_CNT);
4、测试用例
4.1 客户端
● nc 模式 tcp/udp 发包的强大工具,或者 telnet 直接探测
● curl / wget 模拟 http 请求
4.2 代理:
阿里云全站加速(DCDN)配置如下,ipa 对等转发,配置的回源端口和测试端口保持一致
本文介绍的是 TOA 透传,所以开启的是 TOA ,如果是 Proxy protocol 需要原站能支持 PP (https://docs.nginx.com/nginx/admin-guide/load-balancer/using-proxy-protocol/?spm=5176.11220512.help.18.cacf72f0ZfQK8t)