考虑在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在下面没有监听冲突的事实中推断出这一点。
(不,我没有任何关于端口445其他iptables规则。)
例如,我在路由器上观察以下内容
$ 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 。
因此, 我怀疑路由器的内核中的某些东西可能是出于安全原因(是的,我非常了解安全问题)将公共stream量过滤到端口445 。
但是,这显然只是一个猜测,我不知道如何检查/禁用正在发生的事情。
以下是一些可能有所帮助的更多信息。 比方说,我启用日志logging
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在第二个中根本不会被翻译。 为什么会发生? 等等
我终于明白了自己。 这是一个内核模块。 echo 0 > /proc/net/lfpctrl修复了这个问题。