考虑在我的路由器上运行以下规则192.168.1.1
(是的,它们是非常规的):
iptables -t filter -I INPUT 1 -p tcp --source 192.168.0.0/16 --destination-port "$PORT" --jump ACCEPT
iptables -t nat -I INPUT 1 -p tcp --source 192.168.0.0/16 --destination-port "$PORT" --jump SNAT --to-source 192.168.2.1
iptables -t nat -I PREROUTING 1 -p tcp --source 192.168.0.0/16 --destination-port "$PORT" --jump DNAT --to-destination 192.168.1.1
$PORT
什么时候不是 445
(例如,当它是 时444
),这些规则可以正常工作。但是
当$PORT
它是445
(SMB) 时,这些规则不起作用。
请注意,我确实不是在路由器上运行 Samba(或任何其他关注端口 445 的程序),但您应该能够从socat
下面没有监听冲突的事实推断出这一点。
(不,我没有任何其他iptables
有关端口的规则445
。)
例如,我在路由器上观察到以下内容
$ socat -d -d tcp-listen:444 - # this is on the router
socat[29117] N listening on AF=2 0.0.0.0:444
socat[29117] N accepting connection from AF=2 192.168.2.1:42339 on AF=2 192.168.1.1:444
socat[29117] N reading from and writing to stdio
socat[29117] N starting data transfer loop with FDs [6,6] and [0,1]
socat[29117] N socket 1 (fd 6) is at EOF
socat[29117] N exiting with status 0
当我在本地机器上运行以下命令时:
netcat -w 1 -t -n -z "$(dig +short myip.opendns.com @resolver1.opendns.com)" 444 <<<"" && echo Success || echo Failed
然而,如果我这样做和上面一模一样使用端口445
而不是444
,socat
永远停留listening on AF=2 0.0.0.0:445
并在短暂停顿后netcat
打印。Failed
所以,我怀疑路由器内核出了问题正在过滤到端口 的公共流量445
,可能是出于安全原因(是的,我很清楚安全问题)。
但是,这显然只是猜测,我不知道如何检查/禁用正在发生的事情。
这是怎么发生的以及我该如何验证呢?
以下是一些可能有帮助的信息。假设我启用了日志记录
iptables -v -t nat -I INPUT -d "$MACHINE_IP" -j LOG
iptables -v -t nat -I OUTPUT -d "$MACHINE_IP" -j LOG
iptables -v -t nat -I PREROUTING -d "$MACHINE_IP" -j LOG
iptables -v -t nat -I POSTROUTING -d "$MACHINE_IP" -j LOG
iptables -v -t nat -I INPUT -s "$MACHINE_IP" -j LOG
iptables -v -t nat -I OUTPUT -s "$MACHINE_IP" -j LOG
iptables -v -t nat -I PREROUTING -s "$MACHINE_IP" -j LOG
iptables -v -t nat -I POSTROUTING -s "$MACHINE_IP" -j LOG
其中$MACHINE_IP
只是我的本地机器的 IP。现在如果我运行
netcat -w 1 -t -n -z "$PUBLIC_IP" 444 <<<"Test" && echo Success || echo Failed
我得到了以下内容(我已根据需要格式化和删除):
kernel: IN=br0 OUT= MAC="$MAC" SRC="$MACHINE_IP" DST="$PUBLIC_IP" LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=51334 DF PROTO=TCP SPT=42366 DPT=444 WINDOW=29200 RES=0x00 SYN URGP=0
kernel: ACCEPT IN=br0 OUT= MAC="$MAC" SRC="$MACHINE_IP" DST=192.168.1.1 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=51334 DF PROTO=TCP SPT=42366 DPT=444 SEQ=496897934 ACK=0 WINDOW=29200 RES=0x00 SYN URGP=0 OPT (<redacted>)
kernel: IN=br0 OUT= MAC="$MAC" SRC="$MACHINE_IP" DST=192.168.1.1 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=51334 DF PROTO=TCP SPT=42366 DPT=444 WINDOW=29200 RES=0x00 SYN URGP=0
kernel: ACCEPT IN=br0 OUT= MAC="$MAC" SRC="$MACHINE_IP" DST=192.168.1.1 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=51335 DF PROTO=TCP SPT=42366 DPT=444 SEQ=496897934 ACK=0 WINDOW=29200 RES=0x00 SYN URGP=0 OPT (<redacted>)
但如果我跑
netcat -w 1 -t -n -z "$PUBLIC_IP" 445 <<<"Test" && echo Success || echo Failed
然后我只会得到:
kernel: IN=br0 OUT= MAC="$MAC" SRC="$MACHINE_IP" DST="$PUBLIC_IP" LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=40192 DF PROTO=TCP SPT=39617 DPT=445 WINDOW=29200 RES=0x00 SYN URGP=0
kernel: IN=br0 OUT= MAC="$MAC" SRC="$MACHINE_IP" DST="$PUBLIC_IP" LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=40193 DF PROTO=TCP SPT=39617 DPT=445 WINDOW=29200 RES=0x00 SYN URGP=0
奇怪的是,$PUBLIC_IP
第二个版本根本没有翻译。为什么会发生这种情况?等等。
答案1
我终于自己搞明白了。这是一个内核模块。echo 0 > /proc/net/lfpctrl
解决了这个问题。