![带 nftables 的路由器运行不正常](https://linux22.com/image/193172/%E5%B8%A6%20nftables%20%E7%9A%84%E8%B7%AF%E7%94%B1%E5%99%A8%E8%BF%90%E8%A1%8C%E4%B8%8D%E6%AD%A3%E5%B8%B8.png)
我有 Debian 4.19.194-1 作为路由器服务器,具有 LAN、WAN、PPPOE(作为网关)和 LAN 网络中的 COMPUTER1,应该可以通过 Debian 路由器访问互联网。
作为防火墙,我使用 nftables 和规则:
#!/usr/sbin/nft -f
flush ruleset
define EXTIF = "ppp0"
define LANIF = "enp1s0"
define WANIF = "enp4s0"
define LOCALIF = "lo"
table firewall {
chain input {
type filter hook input priority 0
ct state {established, related} counter accept
ct state invalid counter drop
ip protocol icmp counter accept
ip protocol igmp counter accept comment "Accept IGMP"
ip protocol gre counter accept comment "Accept GRE"
iifname { $LOCALIF, $LANIF } counter accept
tcp dport 44122 counter accept
udp dport 11897 counter accept
udp dport 1194 counter accept
udp dport {67,68} counter accept comment "DHCP"
counter reject
}
chain forwarding {
type filter hook forward priority 0
# teleguide.info for ntf monitor
ip daddr 46.29.166.30 meta nftrace set 1 counter accept
ip saddr 46.29.166.30 meta nftrace set 1 counter accept
udp dport 1194 counter accept
tcp dport 5938 counter accept
udp dport 5938 counter accept
ip daddr 10.10.0.0/24 counter accept
ip saddr 10.10.0.0/24 counter accept
ip protocol gre counter accept comment "Accept GRE Forward"
counter drop comment "all non described Forward drop"
}
chain outgoing {
type filter hook output priority 0
oifname $LOCALIF counter accept
}
}
table nat {
chain prerouting {
type nat hook prerouting priority 0
iifname $EXTIF udp dport 1194 counter dnat to 10.10.0.4
}
chain postrouting {
type nat hook postrouting priority 0
ip saddr 10.10.0.0/24 oifname $EXTIF counter masquerade
}
}
lsmod:
tun 53248 2
pppoe 20480 2
pppox 16384 1 pppoe
ppp_generic 45056 6 pppox,pppoe
slhc 20480 1 ppp_generic
binfmt_misc 20480 1
i915 1736704 0
ppdev 20480 0
evdev 28672 2
video 49152 1 i915
drm_kms_helper 208896 1 i915
iTCO_wdt 16384 0
iTCO_vendor_support 16384 1 iTCO_wdt
parport_pc 32768 0
coretemp 16384 0
sg 36864 0
serio_raw 16384 0
pcspkr 16384 0
drm 495616 3 drm_kms_helper,i915
parport 57344 2 parport_pc,ppdev
i2c_algo_bit 16384 1 i915
rng_core 16384 0
button 20480 0
nft_masq_ipv4 16384 3
nft_masq 16384 1 nft_masq_ipv4
nft_reject_ipv4 16384 1
nf_reject_ipv4 16384 1 nft_reject_ipv4
nft_reject 16384 1 nft_reject_ipv4
nft_counter 16384 25
nft_ct 20480 2
nft_connlimit 16384 0
nf_conncount 20480 1 nft_connlimit
nf_tables_set 32768 3
nft_tunnel 16384 0
nft_chain_nat_ipv4 16384 2
nf_nat_ipv4 16384 2 nft_chain_nat_ipv4,nft_masq_ipv4
nft_nat 16384 1
nf_tables 143360 112 nft_reject_ipv4,nft_ct,nft_nat,nft_chain_nat_ipv4,nft_tunnel,nft_counter,nft_masq,nft_connlimit,nft_masq_ipv4,nf_tables_set,nft_reject
nf_nat 36864 2 nft_nat,nf_nat_ipv4
nfnetlink 16384 1 nf_tables
nf_conntrack 172032 8 nf_nat,nft_ct,nft_nat,nf_nat_ipv4,nft_masq,nf_conncount,nft_connlimit,nft_masq_ipv4
nf_defrag_ipv6 20480 1 nf_conntrack
nf_defrag_ipv4 16384 1 nf_conntrack
ip_tables 28672 0
x_tables 45056 1 ip_tables
autofs4 49152 2
ext4 745472 2
crc16 16384 1 ext4
mbcache 16384 1 ext4
jbd2 122880 1 ext4
fscrypto 32768 1 ext4
ecb 16384 0
crypto_simd 16384 0
cryptd 28672 1 crypto_simd
glue_helper 16384 0
aes_x86_64 20480 1
raid10 57344 0
raid456 172032 0
async_raid6_recov 20480 1 raid456
async_memcpy 16384 2 raid456,async_raid6_recov
async_pq 16384 2 raid456,async_raid6_recov
async_xor 16384 3 async_pq,raid456,async_raid6_recov
async_tx 16384 5 async_pq,async_memcpy,async_xor,raid456,async_raid6_recov
xor 24576 1 async_xor
raid6_pq 122880 3 async_pq,raid456,async_raid6_recov
libcrc32c 16384 3 nf_conntrack,nf_nat,raid456
crc32c_generic 16384 5
raid0 20480 0
multipath 16384 0
linear 16384 0
raid1 45056 2
md_mod 167936 8 raid1,raid10,raid0,linear,raid456,multipath
sd_mod 61440 6
ata_generic 16384 0
ata_piix 36864 4
libata 270336 2 ata_piix,ata_generic
psmouse 172032 0
scsi_mod 249856 3 sd_mod,libata,sg
ehci_pci 16384 0
i2c_i801 28672 0
uhci_hcd 49152 0
lpc_ich 28672 0
ehci_hcd 94208 1 ehci_pci
mfd_core 16384 1 lpc_ich
usbcore 299008 3 ehci_pci,ehci_hcd,uhci_hcd
r8169 90112 0
realtek 20480 2
libphy 77824 2 r8169,realtek
usb_common 16384 1 usbcore
ntf 监视器跟踪(到处都接受结论):
trace id 2c2a8923 ip firewall forwarding packet: iif "enp1s0" oif "ppp0" ether saddr xxx ether daddr xxx ip saddr 10.10.0.96 ip daddr 46.29.166.30 ip dscp cs0 ip ecn not-ect ip ttl 127 ip id 32611 ip length 52 tcp sport 62489 tcp dport https tcp flags == syn tcp window 8192
trace id 2c2a8923 ip firewall forwarding rule ip daddr 46.29.166.30 nftrace set 1 counter packets 0 bytes 0 accept (verdict accept)
trace id 2c2a8923 ip nat postrouting packet: oif "ppp0" @ll,xxx ip saddr 10.10.0.96 ip daddr 46.29.166.30 ip dscp cs0 ip ecn not-ect ip ttl 127 ip id 32611 ip length 52 tcp sport 62489 tcp dport https tcp flags == syn tcp window 8192
trace id 2c2a8923 ip nat postrouting rule ip saddr 10.10.0.0/24 oifname "ppp0" counter packets 0 bytes 0 masquerade (verdict accept)
trace id 73f8f405 ip firewall forwarding packet: iif "ppp0" oif "enp1s0" ip saddr 46.29.166.30 ip daddr 10.10.0.96 ip dscp af32 ip ecn not-ect ip ttl 58 ip id 0 ip length 52 tcp sport https tcp dport 62489 tcp flags == 0x12 tcp window 29200
trace id 73f8f405 ip firewall forwarding rule ip saddr 46.29.166.30 nftrace set 1 counter packets 0 bytes 0 accept (verdict accept)
trace id ca8ec4f5 ip firewall forwarding packet: iif "enp1s0" oif "ppp0" ether saddr xxx ether daddr xxx ip saddr 10.10.0.96 ip daddr 46.29.166.30 ip dscp cs0 ip ecn not-ect ip ttl 127 ip id 32612 ip length 40 tcp sport 62489 tcp dport https tcp flags == ack tcp window 256
我不知道为什么,但有些网站在 COMPUTER1 上工作正常,但有些网站不符合这样的规则。
例如:https://google.com
在服务器和计算机 1 上运行良好,但https://teleguide.info
在服务器 (wget) 上运行良好,但在计算机 1 上运行不佳。
知道出了什么问题吗?
答案1
防火墙规则并未导致问题。相反,这是由于“普通”以太网和 PPPoE 中的 MTU 差异造成的。由于PPP头占用(至少)8字节,而通常以太网本身的MTU是1500字节,那么这种情况下PPPoE的MTU最多为1492字节。
我不太了解 MTU 的知识,无法详细说明,但据我所知,如果 TCP SYN 数据包通告的 MSS 大于应答将通过的接口的 MTU 的大小,则回复流量可能会导致实际进入时遇到麻烦。
AFAIK,它与路由器/服务器本身工作良好的原因是,MSS 源自其出站接口 ( ppp0
) 的 MTU,而另一方面,COMPUTER1 的出站接口是普通以太网。
对于 TCP 流量,可以通过在hook forwarding
链中添加一条规则来解决该问题:
tcp flags syn tcp option maxseg size set 1452
1452
来自1500 - 8 - 40
,其中 40 是 IPv4 标头的大小。对于 IPv6,您可能需要1500 - 8 - 60
= 1432
。
您可能需要将规则排序在任何accept
规则之前。 (我认为,这可能取决于规则集的整体结构。)
PS 不确定您是否需要对 UDP 流量采取任何措施。
或者,您可以将此“路由器”(及其LANIF
)的所有 LAN“客户端”的以太网接口的 MTU 设置为1492
。这可能是一种不太“解决方法”的方法,但可能会很麻烦。