前言
回答一下关于 nftables和iptables的问题,在lala群里面提问的。
下文可能简称 nftables 为nft,iptables 为 ipt。
介绍下 nftables 和 iptables
先介绍下,nftables和iptables 都是linux下的netfilter用户态管理工具,底层都使用的是netfilter。
###区别
nftables 相较于 iptables 更加的新颖和现代(吐槽: 虽然如此 nftables 也有着很多年了),iptables维护了四表五链,而nftables可以让用户自定义表,内部维护了一个虚拟机来操作netfiler。同时集合了ebtables,ip6tables,arptables等等,功能更加强大。
###相关链接
nftables iptables netfilter
nft与bbr
nftables是 Linux 内核转发,不进入用户态,也不开启 socket ,所以转发使用什么控制算法(bbr,cubic) 是无关的,与落地有关,落地开了 BBR 就可以享受到 BBR 加速。
如果你使用 socat/gost/realm 等 转发,不仅要看落地是否有 BBR 也要看专线是否有 BBR
教程
nftables端口转发
nftables是支持直接写入文件的,只需要在文件头包含下面代码,这里我直接使用文件来描述后面教程了。 
#!/usr/bin/nft -f
首先需要写一份nft文件, 通常是写在 /etc/nftables.conf文件里面。
第一次打开可能是这样。
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority filter;
}
chain forward {
type filter hook forward priority filter;
}
chain output {
type filter hook output priority filter;
}
}
这里我们可以直接使用现有的表来实现端口转发,你也可以自己写一个表。
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
# 这三个链条如果你懂就可以动,不然就不动。
chain input {
type filter hook input priority filter;
}
chain forward {
type filter hook forward priority filter;
}
chain output {
type filter hook output priority filter;
}
# 首先处理 dnat
chain port-dnat {
type nat hook prerouting priority dstnat;policy accept;
ip protocol { tcp,udp } th dport 这里写Lala入站端口 counter dnat to 这里写落地ip端口(例如: 12.34.56.78:9012)
}
# 再处理 snat
chain port-snat {
type nat hook postrouting priority srcnat;policy accept;
ip daddr 落地ip(只有ip) masquerade
}
}
写完过后执行下命令。
nft -f /etc/nftables.conf
这样过后就完成了正常转发了,对于其他小鸡,这样就可以实现端口转发了。
但是如果你使用 Lala这样的机器,还有一步需要做。 
注意 : 上面的操作会使得nftables现有的规则清空,例如docker等可能会无法使用,需要在执行完毕过后重启。使用podman也需要重启。
lala转发的问题 
使用过 Lala 家专线的都知道需要配置路由表,需要查看文档配置。
同时还需要持久化(教程使用的是corn在@reboot时间的时候应用,可以用systemd配置其实,评论区补充)。
Lala家专线是不对称路由(具体是什么可以问ai),所以需要自己vnc手动配置下路由。
Q1: 为什么vnc可以用,但是ssh不能用。
A1: vnc是直接从虚拟机的tty输出了,不需要经过小鸡网络,只经过了Lala专线网关的网络。
Q2: 为什么不用 socat/gost/realm 之类的软件,简单方便。
A2: nft是内核态的转发,非用户态,严格意义上来说延迟更低(我相信大部分人都是跑转发的)。具体可以了解下计算机网络 TCP/IP
Q3: 为什么使用其他论坛大佬的`nftables`/`iptables` 无法使用。
A3: 因为是非对称路由。
还记得教程的配置吗,教程让创建了一个路由表,这里我拿移动的来举例。
echo "101 CM" >> /etc/iproute2/rt_tables
ip route add default via 192.168.47.1 dev eth0 table CM
ip rule add from 192.168.47.XX table CM
注意看,路由表的名称是 CM,因为路由问题,我们需要强制落地机的流量发到这个路由表,强制走 eth0这个网卡出去。使用下面的命令即可,
# 这里配置了 Linux 的策略路由,强制落地机的流量通过入口返回。
# 注意把 CM 替换成你配置的路由表,不同入口的 IEPL 不同。
ip rule add from 这里写落地机ip lookup CM
这样一来,就可以使用 nftables 转发了。如果还想要添加多个落地机。
可以直接在刚才的 nftables文件写多条规则。
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
# 这三个链条如果你懂就可以动,不然就不动。
chain input {
type filter hook input priority filter;
}
chain forward {
type filter hook forward priority filter;
}
chain output {
type filter hook output priority filter;
}
# 首先处理 dnat
chain port-dnat {
type nat hook prerouting priority dstnat;policy accept;
ip protocol { tcp,udp } th dport 这里写Lala入站端口(一) counter dnat to 这里写落地ip端口(例如: 12.34.56.78:9012)(一)
ip protocol { tcp,udp } th dport 这里写Lala入站端口(二) counter dnat to 这里写落地ip端口(例如: 12.34.56.78:9012)(二)
ip protocol { tcp,udp } th dport 这里写Lala入站端口(三) counter dnat to 这里写落地ip端口(例如: 12.34.56.78:9012)(三)
}
set dst-ip {
type ipv4_addr
flags interval
elements = {落地ip(一),落地ip(二),落地ip(三)} # 注意使用英文逗号分开
}
# 再处理 snat
chain port-snat {
type nat hook postrouting priority srcnat;policy accept;
ip daddr @dst-ip masquerade
}
}
同时不要忘记配置策略路由。 
ip rule add from 这里写落地机ip(一) lookup CM
ip rule add from 这里写落地机ip(二) lookup CM
ip rule add from 这里写落地机ip(三) lookup CM
实际测试。
首先是去 itdog 测试,tcping 是可以通过的。
再测试延迟,我转发到 HKT ,是延迟能从250左右降低到150左右,好的时候有120,效果非常好。
速度可以自测,我测下来如果落地开bbr效果是差不多的。

尾序
今天上午才来到 Nodeseek ,之前没有账号,都是游客一直在看,现在有了 Nodeseek 号,可以更好的融入 Nodeseek 这个大论坛了。
如果大家对 nftables 感兴趣,我会在后面给大家写一篇教程,同时如果对 Grafana也感兴趣,也可以有教程,看多久有时间了。
最后请大家多给点鸡腿,收藏。 
编辑后补充
#55 楼的方案更加清晰,同时易懂,如果会用 firewalld 的可以试试,但是不要忘记策略路由。
#48 楼指出了一个错误,如果你配置了过后无法打通可以试试这个楼的方案。同时这哥们写了一份简明的教程
另外,有些反馈如果配置了过后,会掉速度,现在具体原因未知,延迟是有降低的。
可能最大适合打游戏了。 


这里发一下上文提到的,使用
systemd来开机配置路由Unit文件
把 Exec 后面的命令自己替换成文档教程的参数。
可以使用如下命令一键配置
firewalld底层默认使用nftables。这样写是等效的:
要让firewalld转发生效需要三个条件,sysctl.conf中启用forwarding,
firewall规则中启用伪装和转发。
sysctl.conf我有洁癖不去修改它,而是写在这里(文件名随便写,目录必须是这里):/etc/sysctl.d/99-forwarding.conf
sysctl调优是核心,rmem和wmem要根据实际可用内存计算,还要填窗口存活期,balabala一堆,我写一个我自己用的(2G内存):
好,正式开始配置规则,这里是日常运维的部分了(--permanent参数是持久化的意思,临时调试可以不用加,不加的话也不要执行覆盖命令firewall-cmd --reload
修改的话原始文件在/etc/firewald/zones/public.xml
好了,再列一个我花了几天用gpt调教出来的一段脚本,可用的。别忘了使用前先配置好sysctl的forwarding参数