我正在运行Ubuntu server 22.04
,并且本地计算机有一个特殊的端口转发问题。本机有两个以太网接口,连接的enp1s0
接口有一个IP 地址192.168.1.50
。完整的ip配置如下:
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:e0:4f:68:02:bb brd ff:ff:ff:ff:ff:ff
inet 192.168.1.50/24 metric 100 brd 192.168.1.255 scope global enp1s0
valid_lft forever preferred_lft forever
inet6 240f:74:de92::d1e/128 scope global dynamic noprefixroute
valid_lft 35597sec preferred_lft 35597sec
inet6 fd41:d8b6:99ba::d1e/128 scope global dynamic noprefixroute
valid_lft 35597sec preferred_lft 35597sec
inet6 fd41:d8b6:99ba:0:2e0:4fff:fe68:2bb/64 scope global mngtmpaddr noprefixroute
valid_lft forever preferred_lft forever
inet6 240f:74:de92:0:2e0:4fff:fe68:2bb/64 scope global dynamic mngtmpaddr noprefixroute
valid_lft 98462sec preferred_lft 98462sec
inet6 fe80::2e0:4fff:fe68:2bb/64 scope link
valid_lft forever preferred_lft forever
3: eno1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
link/ether 00:e0:4c:68:01:6e brd ff:ff:ff:ff:ff:ff
altname enp2s0
4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:55:86:e6:e5 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
我已经为我的路由器设置了端口转发规则,以便任何传入的 TCP 或 UDP 数据from wan to port 22211
包forwarded to lan 192.168.1.50 port 22211
在我的ufw
配置中,我允许此端口的路由:
$ sudo ufw status
[sudo] password for *
Status: active
To Action From
-- ------ ----
22211/tcp ALLOW Anywhere
22211/tcp (v6) ALLOW Anywhere (v6)
nc -l -p 22211
现在,如果我为此端口启动一个简单的 netcat 套接字 ( ),我可以telnet
通过本地网络中的另一台机器访问它。这是tcudump
我从另一台本地计算机远程登录时的日志。我连接并发送一封信a
并按 Enter 键:
$ sudo tcpdump -pnvvi enp1s0 port 22211
tcpdump: listening on enp1s0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
21:01:48.350024 IP (tos 0x0, ttl 64, id 59572, offset 0, flags [DF], proto TCP (6), length 60)
192.168.1.196.38840 > 192.168.1.50.22211: Flags [S], cksum 0x527d (correct), seq 3440167578, win 32120, options [mss 1460,sackOK,TS val 3772353734 ecr 0,nop,wscale 7], length 0
21:01:48.350139 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60)
192.168.1.50.22211 > 192.168.1.196.38840: Flags [S.], cksum 0x3a60 (correct), seq 495600843, ack 3440167579, win 65160, options [mss 1460,sackOK,TS val 102903428 ecr 3772353734,nop,wscale 7], length 0
21:01:48.351892 IP (tos 0x0, ttl 64, id 59573, offset 0, flags [DF], proto TCP (6), length 52)
192.168.1.196.38840 > 192.168.1.50.22211: Flags [.], cksum 0x66b7 (correct), seq 1, ack 1, win 251, options [nop,nop,TS val 3772353737 ecr 102903428], length 0
21:01:50.698846 IP (tos 0x0, ttl 64, id 59574, offset 0, flags [DF], proto TCP (6), length 55)
192.168.1.196.38840 > 192.168.1.50.22211: Flags [P.], cksum 0xf275 (correct), seq 1:4, ack 1, win 251, options [nop,nop,TS val 3772356082 ecr 102903428], length 3
但是,当我在本地网络之外尝试 telnet 形式时,由于某种原因,连接从未建立。在很长一段时间里,我确信我的端口转发配置已关闭(尽管同一路由器将其他端口转发到本地网络中的另一台计算机就很好,而且我基本上只是将配置镜像到另一个端口),但是正如您从tcpdump
日志中看到的下面,数据包到达接口enp1s0
:
$ sudo tcpdump -pnvvi enp1s0 port 22211
tcpdump: listening on enp1s0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
20:58:05.448829 IP (tos 0x0, ttl 50, id 0, offset 0, flags [DF], proto TCP (6), length 64)
126.33.109.168.9875 > 192.168.1.50.22211: Flags [S], cksum 0x4448 (correct), seq 2086171535, win 65535, options [mss 1240,nop,wscale 6,nop,nop,TS val 560510789 ecr 0,sackOK,eol], length 0
20:58:06.593532 IP (tos 0x0, ttl 50, id 0, offset 0, flags [DF], proto TCP (6), length 64)
126.33.109.168.9875 > 192.168.1.50.22211: Flags [S], cksum 0x405f (correct), seq 2086171535, win 65535, options [mss 1240,nop,wscale 6,nop,nop,TS val 560511790 ecr 0,sackOK,eol], length 0
20:58:07.613818 IP (tos 0x0, ttl 50, id 0, offset 0, flags [DF], proto TCP (6), length 64)
126.33.109.168.9875 > 192.168.1.50.22211: Flags [S], cksum 0x3c76 (correct), seq 2086171535, win 65535, options [mss 1240,nop,wscale 6,nop,nop,TS val 560512791 ecr 0,sackOK,eol], length 0
20:58:08.603603 IP (tos 0x0, ttl 50, id 0, offset 0, flags [DF], proto TCP (6), length 64)
126.33.109.168.9875 > 192.168.1.50.22211: Flags [S], cksum 0x388c (correct), seq 2086171535, win 65535, options [mss 1240,nop,wscale 6,nop,nop,TS val 560513793 ecr 0,sackOK,eol], length 0
20:58:09.563590 IP (tos 0x0, ttl 50, id 0, offset 0, flags [DF], proto TCP (6), length 64)
126.33.109.168.36371 > 192.168.1.50.22211: Flags [S], cksum 0xcd21 (correct), seq 2086171535, win 65535, options [mss 1240,nop,wscale 6,nop,nop,TS val 560514795 ecr 0,sackOK,eol], length 0
我还可以看到 netcat 正在监听所有接口(0.0.0.0 部分):
$ sudo ss -tulpn | grep 22211
tcp LISTEN 0 1 0.0.0.0:22211 0.0.0.0:* users:(("nc",pid=3344,fd=3))
路由表如下所示:
$ sudo route -vn
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.1.254 0.0.0.0 UG 0 0 0 enp1s0
0.0.0.0 192.168.1.1 0.0.0.0 UG 100 0 0 enp1s0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
192.168.1.0 0.0.0.0 255.255.255.0 U 100 0 0 enp1s0
192.168.1.1 0.0.0.0 255.255.255.255 UH 100 0 0 enp1s0
所以我不知道为什么来自外部网络的数据包永远不会到达端口 22211 中的本地套接字...是否有一些我应该配置的额外防火墙配置?
编辑:有趣的是,确实ping 8.8.8.8
超时了(例如 ping google.com 工作正常)
答案1
长话短说
如果复杂的东西不起作用,那么首先要确保基础功能正常运行。
加长版
前言
这是如何提问的一个很好的例子。
有背景信息,例如它运行的是Ubuntu 22.04,机器有两个以太网接口。
提供详细信息,例如 ip 配置信息。
显示了工作和非工作示例。
调试问题。
纠正误解。
OP 表示“所以我不知道为什么来自外部网络的数据包永远不会到达端口 22211 中的本地套接字。”当数据显示数据包到达时,响应并未从该接口发出。
OP说它有两个接口。 IP 信息显示第二个接口已关闭,但也许机器期望从另一个接口发送响应?
第一次请求提供更多信息。
“路由表是否显示到 126.33.189.168 的路由是通过已启动的接口 (enp1s0) 进行的?” OP 通过添加路由表来回应,还说
“我将路由表信息添加到原始消息中。此外,我还确定另一个接口 eno1 已关闭,但似乎没有任何变化”
第二次请求提供更多信息。
路由表中有符号名称,而不是数字地址。在不知道映射的情况下,这不是很有用,所以
- “您能否更改您的编辑以显示输出
sudo route -vn
以显示数值?”
以响应者自然的方式提问。
有评论建议使用ip route
而不是route -vn
.我已经使用了ip route
很多年,并且断言它是一个更好的工具。要问的问题是“我们是在尝试教 OP 更好的工具还是在尝试帮助他解决问题?”。我认为开始引入新工具会分散注意力。
第二次请求提供更多信息 - 继续。
“您能否确认您可以从 192.168.1.50 ping 某个众所周知的地址,例如 8.8.8.8?”这引起了回应
“你是对的,由于某种原因 ping 8.8.8.8 失败了!但 ping google.com 工作正常。”
调试为什么ping google.com
有效
- “ping google.com 选择什么 IP 地址?(它显示在第一行中。)这听起来好像您已经将自己设置为远离 IPv4,但仍然拥有功能齐全的 IPv6。”
我不会使用这个词firewalled
。由于路由表显示 2 条具有不同指标的默认路由,现在几乎可以肯定这是一个路由问题。
第三次请求提供更多信息。
大多数人只有一个互联网连接,但尽量不要做出任何毫无根据的假设。
- “您是否希望拥有 2 个路由器,每个路由器都可以访问互联网(可能有 2 个不同的 ISP)?”
当答案是否定的时,只需告诉OP修复路由问题(使用他们熟悉的命令)即可,一切正常。预期答案并将说明与问题放在一起可以节省延迟。
- “能够 ping 通 8.8.8.8 是您最重要的问题。解决这个问题很可能会解决所有问题。”
实际问题。
当数据包需要发送到互联网而不是本地网络时,它们被告知要通过不存在的机器发送。
为了将数据包发送到这台不存在的机器,主机正在发送 ARP 数据包,但没有得到响应。
最终主机放弃尝试联系不存在的机器并向 ping 命令报告错误,或者没有向传入连接发送确认。
修复路由表以通过正确的地址将数据包发送到互联网使一切正常。