拦截与改写 — netfilter 钩子、连接跟踪、NAT
一句话总结
nftables规则发生在数据包经过的五个拨号(prerouting·input·forward·output·postrouting)中之一。状态跟踪(conntrack)识别“已经打开的连接的数据包”,所以允许响应为一行,NAT在相同的conntrack上更改和反向更改地址。
为什么需要这个?
防火墙不是规则列表,而是基本值和顺序。如果政策是drop,那么丢失的东西就会被阻止,如果是accept,那么丢失的东西就会被打开。而且规则是有方向的——如果服务器打开了进入的SYN,那么服务器发送的响应不会自动打开。以前所以用双倍的规则,这就是状态跟踪产生的原因。ct state established,related accept因为一行的意思是“已经打开的连接可以通过”,所以只要选择第一次打开的SYN就可以了。
私人地址在互联网上不会被路由。但是家、公司、云、容器管理平台都是私人地址。如果他们要和外面沟通,就必须在边界处更改地址,然后收到回复后才能返回。要返回,必须记住“这个回复原来是谁”,而这个记忆是conntrack。NAT设备重新启动时,所有连接都会中断,这就是原因。
怎么行动
坠落是位置。传送到自己的数据包是prerouting → input,发给自己的数据包是output → postrouting,转发别人的数据包时经过prerouting → forward → postrouting。锁定服务器的规则是input,锁定路由器的规则是forward。锁定路由器自己的input的话,连管理连接都无法通过。
链子是type filter hook input priority 0; policy drop像这样做。规则是从上面开始看,以第一次比赛的判定(accept/drop)结束。counter贴上后数一下挂了几个,log粘贴的话会留在内核日志中(如果不在命名空间的话nf_log_all_netns=1需要这个)。
掩码放在postrouting上——因为这是在路由结束后知道要通过哪个接口出去的地方。ip saddr 10.30.0.0/24 oifname "enp1s0" masquerade当该频段作为uplink出去时,将出发地更改为uplink地址。DNAT留给prerouting——在路由之前更改目的地才能找到经过更改的目的地的路径。Docker的-p 8080:80这个制作就是这个规则。NAT链只乘坐连接的第一个数据包,其余的由conntrack处理。
在现场相遇的样子
**自我锁定。**用SSH登录policy drop打开了。会话冻结了。established没有先放入允许,所以自己的会话的响应就死了。顺序就是安全——先放入允许,然后放入政策。
可以设置NAT,但不能出去。 虽然添加了面具规则,但专用网络不能上网。forward链的政策是drop。NAT只是改变地址,不允许通过——两个链是不同的。ip_forward0的人也有同样的症状。
处理防火墙规则的纪律
比起规则本身,如何改变规则决定了思维。前面看到的自我锁定几乎可以通过一个程序来消除。
**先拿起退缩装置。**在远程更改规则时,先设置几分钟后自动恢复旧规则的预约,然后开始。如果成功的话,取消,如果锁定的话,等待后再进入。这种习惯可以消除“无法进入服务器,所以发送了人”的情况。
**规则以文件的形式管理,并全部应用。**用手逐行输入的话,没有人知道现在的状态是什么,重新启动的话就会消失。如果留着包含全部规则的文件,从原子级切换的话,现在运行和文件总是一样的。
**先打开并关闭日志。**如果对新规则不确定什么会被阻止,而不是关闭,counter哇log粘上后观察几天。如果没有被捕的话,这时将判断改为drop。和前面看到的Pod Security Admission的warn → enforce一样顺序。
而且要经常意识到防火墙在哪里。最近系统中数据包经过多层过滤器。云的安全组、主机的nftables、容器运行时生成的规则,以及服务消息的政策。如果不知道在哪个层被阻止,只修复一层的话,没有任何变化,然后就会说“先打开所有”。正如前面所看到的,如果知道是拒绝还是超时,以及各个层的计数器是否上升,就可以缩小到哪个层。
最后在规则上留注释。 nftables 在规则上comment可以粘贴。没有写明为什么打开的规则,没有人能删除,在如此堆积的规则中,越来越难找到真正需要的东西。
下次实习要做的事情
在名称空间内的服务器上创建input链,从基本drop开始,依次打开lo·established·icmp·80·来源限制2222,并发送被丢弃为counter的信号。然后将VM作为路由器,用伪装方式将专用名称空间发送到互联网上,抓住两端接口出发地的变化,用DNAT将端口转发到内部服务器。