NAT转换过程中会存在的问题

MSS和MTU问题

MTU(maximum transmission unit)

  • 最大传输单元,由硬件规定,如以太网的MTU为1500字节。
  • 一个IP数据报在以太网中传输,如果它的长度大于该MTU值,就要进行分片传输,使得每片数据报的长度小于MTU。分片传输的IP数据报不一定按序到达,但IP首部中的信息能让这些数据报片按序组装。
  • IP数据报的分片与重组是在网络层进完成的。

MSS:maximum segment size

  • 最大分段大小,为TCP数据包每次传输的最大数据分段大小,一般由发送端向对端TCP通知对端在每个分节中能发送的最大TCP数据。
  • MSS值为MTU值减去IP头部(20 Byte)和TCP头部(20 Byte)得到,一般情况下为1460字节。
  • TCP报文段的分段与重组是在运输层完成的。

NAT转换中MSS问题

  • IP报文里是有五元组的(源ip,目的ip,源端口,目的端口,协议号),当报文在分片的时候由于不会保留TCP/UDP报文所有的标识信息,比如端口号等,这种情况下,如果设备又实现了NAT转换操作(NAT转换过程中,会随机地做端口转换),并且应用又是基于TCP/UDP的这就导致报文不能正确组包。
  • TCP中的MSS参数就是用于协商TCP报文大小的,如果协商出来的TCP MSS的参数值小于设备的MTU的值时,TCP报文在设备上就不会被分片,否则就会出现报文分片并导致上述现象的发生,因此,为了避免上述情况的发生,一定要保证协商的TCP MSS参数小于设备的MTU的值。

  • 有些系统在传输信息的过程中为了增加传输的速度,内部进程间传输数据会用UDP协议传输来往的数据包,那么为了防止内部传输时候数据包分片一般情况写会把MSS设置的比正常的MSS小一些,减去内部UDP传输使用的ip头部(20 Byte)和UDP头部(8 Byte),为1432 字节

源地址复现问题

LVS的VS/NAT介绍

  • LVS是Linux Virtual Server的简称,也就是Linux虚拟服务器, 用现在的观点来看就是个4层(传输层tcp/udp)的负责均衡器。
  • LVS技术要达到的目标是:通过LVS提供的负载均衡技术和Linux操作系统实现一个高性能、高可用的服务器群集,它具有良好可靠性、可扩展性和可操作性。从而以低廉的成本实现最优的服务性能。
  • LVS中有一种调度方法为VS/NAT: 即(Virtual Server via Network Address Translation)
    也就是网络地址翻译技术实现虚拟服务器,当用户请求到达调度器时,调度器将请求报文的目标地址(即虚拟IP地址)改写成选定的Real Server地址,同时报文的目标端口也改成选定的Real Server的相应端口,最后将报文请求发送到选定的Real Server。在服务器端得到数据后,Real Server返回数据给用户时,需要再次经过负载调度器将报文的源地址和源端口改成虚拟IP地址和相应端口,然后把数据发送给用户,完成整个负载调度过程。

TOA的作用
- 在LVS的FULLNAT转发模式下, LVS对数据包同时做SNAT和DNAT,将数据包的源IP、源端口更换为LVS本地的IP和端口,将数据包的目的IP和目的端口修改为RealServer的IP和端口,从而不再依赖特定网络拓朴转发数据包。
- 那么现在就有一个问题RealServer无法获得用户IP,淘宝通过叫TOA的方式解决的,FULLNAT模式在转发包的时候,在TCP包中添加一个option,来传递客户端的真实地址。RealServer中通过内核模块toa令应用层程序获取真实的客户端地址

struct toa_data
{
    __u8   opcode;      //option的opcode为254(0xfe)
    __u8   size;        //option长度8字节为8(0x08)
    __u16  real_port;   //用户的真实端口
    __u32  readl_ip;    //用户的真实ip
}
  • 函数调用hook_toa_functions函数HOOK两个函数:
    • inet_getname
      应用层程序调用getpeername()时就可以获取到真实的客户端地址了
    • tcp_v4_syn_recv_sock
      RS侧收到建连报文时,取出toa里面的client ip和port 存放在socket的use_data

由于本篇不对LVS做详细介绍,如果想更深入了解LVS可以参考这篇文章:LVS原理介绍

X-Forwarded-For

  • X-Forwarded-For(XFF)是用来识别通过HTTP代理或负载均衡方式连接到Web服务器的客户端最原始的IP地址的HTTP请求头字段。
  • 如果没有XFF或者另外一种相似的技术,所有通过代理服务器的连接只会显示代理服务器的IP地址,而非连接发起的原始IP地址,这样的代理服务器实际上充当了匿名服务提供者的角色,如果连接的原始IP地址不可得,恶意访问的检测与预防的难度将大大增加。XFF的有效性依赖于代理服务器提供的连接原始IP地址的真实性,因此,XFF的有效使用应该保证代理服务器是可信的,比如可以通过创建可信服务器白名单的方式。
  • 这一HTTP头一般格式如下:
    X-Forwarded-For: client1, proxy1, proxy2

  • 在代理转发的场景中,你可以通过内部代理链以及记录在网关设备上的IP地址追踪到网络中客户端的IP地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值