源地址透传

1. TOA(TCP Option Address)

image.png
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 ipsrc port等信息,该协议是由haproxy提出的,目前常见的web服务器都已经支持。

2.1. pp协议格式

TCP三次握手建立连接后,发送第一个数据报文的详细流程如下:

  1. 客户端向服务器端发送连接请求报文(SYN标志位设置为1,序列号为x)。
  2. 服务器向客户端响应报文(SYN和ACK标志位设置为1,序列号为y,确认号为x+1)。
  3. 客户端再次响应报文(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                     |
+------------------------------------------+