为什么我的 IPTables 规则不适用于端口 445(SMB)?

为什么我的 IPTables 规则不适用于端口 445(SMB)?

考虑在我的路由器上运行以下规则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而不是444socat永远停留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解决了这个问题。

相关内容