防火墙的目标地址转换和源地址转换

遇到一起防火墙故障,对防火墙的工作原理和目标地址转换、 源地址转换有了进一步的了解,记录于此。

结果说在前面

网络结构非常简单:外网-防火墙-内网。内网中架有网站,在外网使用域名访问。 内网中机器需要上外网,也需要用域名互访。 在这种情况下,地址转换规则应当这样配:

  • 外网访问内网,只需要做目标地址转换,不需要做源地址转换。
  • 内网通过域名访问内网,除了做目标地址转换,还必须做源地址转换。

上面第一条有一种“例外”情况,就是网关配置错误的情况,比如我们遇到的: 内网6有 2 块网卡,都配置了同一网段的内网地址,并且每块网卡都配置了网关。 由于是同一网段,所以两个网关是一样的。 在这种情况下,外网访问也必须做源地址转换, 否则内网能收到请求,但处理结果无法返回外网,外网看到的结果是没有回应。

防火墙数据包转换发送原理

为什么会这样?这要从防火墙的原理说起。 上面的外网访问内网,正常处理过程应该是这样的:

  1. 防火墙收到外网访问请求数据包,格式中包含【防火墙外网IP 外网用户IP】
  2. 防火墙进行目标地址转换,数据包变成【内网IP 外网用户IP】
  3. 内网服务器收到请求,进行处理,返回结果数据包【外网用户IP 内网IP】, 由于目标地址是外网IP,所有经过路由,此数据包被发向网关(防火墙)
  4. 针对返回数据包,防火墙做目标地址转换的反操作, 数据包变成【外网用户IP 防火墙外网IP】
  5. 数据包发回请求用户。

刚才说到的“例外”情况,问题就出在步骤 3,内网服务器返回结果数据包中, 内网IP 不是防火墙指向的那个 IP,而是这太内网服务器的另一个 IP 地址, 也就是说内网服务器通过网卡1接受了请求,却从网卡2发送返回数据。 这样的数据包到了防火墙之后,目标地址转换的反操作会失败(内网IP 不一致), 所以数据依然会通过防火墙发给用户,但却是一个新的 TCP 会话/连接, 无法和原先的用户请求包对应。 结果就是新的数据包到了用户那里,不知道是给谁的, 而用户原先发送的请求,也一直“收不到”回应数据包。 外在表现就是用户看到请求发送成功,却没有回应。

在这种情况下,如果同时做了源地址转换是能够通的,处理过程如下:

  1. 防火墙收到外网访问请求数据包,格式中包含【防火墙外网IP 外网用户IP】
  2. 防火墙进行目标地址转换,数据包变成【内网IP 外网用户IP】, 进行源地址转换,数据包变成【内网IP 防火墙/网关IP】
  3. 内网服务器收到请求,进行处理,返回结果数据包【防火墙/网关IP 内网IP】, 由于目标地址仍然是防火墙/网关IP,所以防火墙能够找到相应的连接, 会接受数据包并进行处理。
  4. 针对返回数据包,防火墙 做源地址转换的反操作,数据包变成【外网用户IP 内网IP】, 做目标地址转换的反操作, 数据包变成【外网用户IP 防火墙外网IP】(R)
  5. 数据包发回请求用户。

可以看到,即使(R)操作失败,由于防火墙已经将内网服务器返回数据包和 防火墙接收的外网用户请求连接成功对应, 结果数据包的目标地址也成功转换成了外网用户IP, 所以数据能够成功发回请求用户,并和用户请求会话/连接相对应。

从另外一个角度看,外网访问做双向地址转换虽然可行,但有一个缺点, 就是数据包到达内网服务器时,外网用户IP 被转换成了防火墙/网关IP, 这样内网中的应用程序就无法获取外网用户的真实IP了, 只能看到请求来自防火墙/网关IP。

内网通过域名访问内网

上面的都理解之后,内网通过域名访问内网为什么必须要做双向转换就清楚了。 问题同样出在接受请求的服务器处理完,发送返回数据包时。

内网1 通过域名访问内网6,在没有做源地址转换时的情形:

  • 由于是通过域名访问,所以请求数据通过防火墙转发给内网6, 用户IP是内网地址(这是关键)
  • 内网6处理完毕发送结果数据包,返回数据包的目标地址就是内网1的地址 由于同在一个子网内,数据包会通过交换机直接发向内网1,不过防火墙

问题产生了,在内网1 上,请求数据直接发向防火墙,返回数据直接来自内网6, 不对应,又是一宗没有回应数据包的情形。

如果同时做了源地址转换,问题就能够解决。因为内网1 的请求数据在通过防火墙时, 用户地址(内网1 IP)会被转换成防火墙/网关IP, 返回数据包也就会发往防火墙/网关IP,再被防火墙转换发回 内网1, 不存在内网1 和内网6 的直接对话, TCP 数据包也能对应上,访问就没有问题了。

不同品牌、类型的防火墙工作机制也许不同,但原理都差不多。 不专业的地方,还请过路仙人不吝赐教。