pf转发的疑惑

我今天按照pf的手册配置端口转发和负载均衡,但是遇到问题。转发到本机的端口可以,转发到其它主机就不行。后来仔细查了下,发现原理是这样的

假设有这样一条规则

rdr on tl0 proto tcp from 192.0.2.1 to 24.65.1.13 port 80 -> 192.168.1.5 port 8000

那么如果从192.0.2.1 连接24.65.1.13 的tcp 80端口,那么首先192.0.2.1会给24.65.1.13 发一个SYN包。包头如下

  • Source address: 192.0.2.1
  • Source port: 4028 (arbitrarily chosen by the operating system)
  • Destination address: 24.65.1.13
  • Destination port: 80

然后在经过pf执行rdr规则之后,包头如下

  • Source address: 192.0.2.1
  • Source port: 4028
  • Destination address: 192.168.1.5
  • Destination port: 8000

然后这个包会从24.65.1.13某个合适的网卡出去(根据netstat -nr中的路由表规则而定),到达192.168.1.5这台主机。

192.168.1.5 这台主机会给192.0.2.1 回复一个SYN-ACK的包。如果不出意外,192.0.2.1会顺利收到这个包。但是它不会理会。因为它试图与24.65.1.13的80端口建立连接,但是得到的回复却是来自于192.0.1.5。于是192.0.2.1继续发SYN包,192.0.1.5继续回复,直到timeout。

此时用pfctl -s state查看,会得到这样的信息

self tcp 192.0.1.5:8000 <- 24.65.1.13:80 <- 192.0.2.1:4028 CLOSED:SYN_SENT

如果192.0.1.5的所有向外的数据都是通过24.65.1.13进行nat出去的,那么连接就可以顺利建立。因为此时192.0.2.1看到的是24.65.1.13的IP。

如果转发是在同一台主机上发生,那么就可以看到一个有趣的现象,用netstat/sockstat看到的连接状态是不对称的。会看到一条LOCAL ADDRESS为127.0.0.1:59165 、FOREIGN ADDRESS 为127.0.0.1:80的连接而与之对应的却是FOREIGN ADDRESS为127.0.0.1:59165但LOCAL ADDRESS为8080的连接。原因是发生了一条从80到8080的转发。

唉,如果是想转发到其它机房一台不相关的主机上呢?rdr加nat?

此博客中的热门博文

少写代码,多读别人写的代码

在windows下使用llvm+clang

tensorflow distributed runtime初窥