源地址透传
1. TOA(TCP Option Address)

TOA将源地址放在tcp option字段中。option字段最长40字节,每个选项由三部分组成:op-kind、op-length、op-data,我们最常见的MSS字段就是在option里。目前option使用的op-kind并不多,我们只需要构建一个不冲突的op-kind就可以把clientIP填充进去。IPv4 地址占用 4 个字节,IPv6 占用 16 字节,填充到 option 中是没有问题的,toa格式如下:
+----------+----------+--------------------+
| opcode | opsize | port |
+----------+----------+--------------------+
| clientIP |
+------------------------------------------+
opcode: 254
opsize: toa大小8字节
port: 客户端端口
clientIP: 客户端IP
2. PP(Proxy Protocol)
PP协议原理仅支持tcp协议,原理是在三次握手后,发送请求数据前,在四层头之后插入一个proxy protocol数据包,数据包中可以携带src ip、src port等信息,该协议是由haproxy提出的,目前常见的web服务器都已经支持。
2.1. pp协议格式
TCP三次握手建立连接后,发送第一个数据报文的详细流程如下:
- 客户端向服务器端发送连接请求报文(SYN标志位设置为1,序列号为x)。
- 服务器向客户端响应报文(SYN和ACK标志位设置为1,序列号为y,确认号为x+1)。
- 客户端再次响应报文(ACK标志位设置为1,序列号为x+1,确认号为y+1),三次握手完成。
此时TCP连接已建立,客户端可以向服务器发送第一个数据报文了,这个报文中:
- 不会携带SYN标志位
- 会携带ACK标志位
- 序列号为x+1(上次发送的确认号)
- 确认号为y+1(上次接收的确认号)
后续的数据报文都类似,序列号依次增加,确认号也依次增加。所以TCP三次握手完成后发送的第一个数据报文,必须携带ACK标志位,序列号从客户端第三次握手的确认号开始,确认号为服务器第二次握手的确认号+1。这标志着TCP连接已建立,可以开始数据传输了。PSH为1的情况,一般只出现在 DATA内容不为0的包中,也就是说PSH为1表示的是有真正的TCP数据包内容被传递。
!Tech/Network/其他/nat封装pp协议.md#^group=sK_9CSsIObfXp5KCyzwz-|1000
- nat将发送的数据包送到服务端前,将客户端seq号增加pp_len偏移。
- nat将接受数据包发送到客户端前,将ack的seq号减去pp_len。
pp协议中具体数据格式如下:
+----------+--------------------+----------+
| type | Length | value |
+----------+----------+---------+----------+
| value |
+------------------------------------------+