我在 NAT 路由器后面有一个 SSH 服务器。与 SSH 服务器位于同一 (NAT 的) 网络上的机器只能使用 LAN IP 连接到 SSH 服务器,而不能使用 WAN IP。为什么?
我的网络如下所示:
(the Internet, via Comcast)
|
| (cable line)
comcast modem. ← External IP of a.b.c.d,
| internal IP of 10.1.10.1 on 10.1.10.0/24
|
|
box running sshd (10.1.10.201)
我在执行 NAT 的 Comcast 路由器后面运行 SSH 服务。使用上面获得的 IP 地址,我可以ssh me@«that IP»
从互联网上的任何地方运行,并接收我的 SSH 服务。如果我从路由器内部的 10.1.10.0/24 网络内运行相同的命令,连接将超时。
康卡斯特路由器设置为在标准端口上对 SSH 机器进行端口转发。
- 康卡斯特路由器会应答内部和外部 IP 上的 ping 命令。
- 盒子运行
sshd
答案 ping
该设备是一块垃圾SMC Networks SMCD3G。
sshd
在尝试ssh 10.1.10.201
提供正常流量的同时,对机器执行 wireshark 。尝试ssh a.b.c.d
提供以下内容:
Source Destination Info
10.1.10.11 10.1.10.201 39946 > ssh [SYN] Seq=0 Win=14600 Len=0 MSS=1460
10.1.10.201 10.1.10.11 ssh > 39946 [SYN, ACK] Seq=0 Ack=1 Win=5792 Len=0
10.1.10.11 10.1.10.201 39946 > ssh [RST] Seq=1 Win=0 Len=0
10.1.10.11 10.1.10.201 39946 > ssh [SYN] Seq=0 Win=14600 Len=0 MSS=1460
10.1.10.201 10.1.10.11 [TCP Previous segment lost] ssh > 39946 [SYN, ACK] Seq=46941561
10.1.10.11 10.1.10.201 39946 > ssh [RST] Seq=1 Win=0 Len=0
(the last three lines repeat)
数据包似乎已经到达目的地,但连接机器正在发送 RST。为什么?
从客户端(运行 SSH 的机器)来看,稍后的尝试如下所示:
Source Destination Info
10.1.10.11 a.b.c.d 40212 > ssh [SYN] Seq=0 Win=14600 Len=0 MSS=1460
10.1.10.201 10.1.10.11 ssh > 40212 [SYN, ACK] Seq=0 Ack=1 Win=5792 Len=0 MSS=1460
10.1.10.11 10.1.10.201 40212 > ssh [RST] Seq=1 Win=0 Len=0
10.1.10.11 a.b.c.d [TCP Retransmission] 40212 > ssh [SYN] Seq=0 Win=14600 Len=0 MSS=1460
10.1.10.201 10.1.10.11 [TCP Previous segment not captured] ssh > 40212 [SYN, ACK] Seq=15635206
10.1.10.11 10.1.10.201 40212 > ssh [RST] Seq=1 Win=0 Len = 0
(the last three lines repeat)
唯一突出的是,我不断收到“未捕获上一个片段”(它没有捕获?似乎就在那里),并且来自客户端的序列号确实是确定性的。(它们不是应该从随机点开始,然后从那里递增吗?)
答案1
就像我在评论中说的。为了能够在 LAN 中使用公共 IP,您需要一个NAT Loopback
也称为NAT hairpinning
或 的东西NAT reflection
。
您可以阅读这里
据我在互联网上找到的,您的那部分...呃......“SMC Networks SMCD3G”不支持“NAT Loopback”。
您有两个选择:
10.1.10.201 fake_or_real_hostname
您可以在 hosts 文件中添加一行。
您可以像这样连接ssh me@fake_or_real_hostname
。您可以运行自己的本地 DNS 服务器。这里是一些解释。
我通过运行自己的本地 DNS 服务器(该服务器递归到非本地域的 OpenDNS)并创建具有本地 DNS A 和 PTR 记录的区域(将我的外部主机名解析为该主机的 LAN IP)解决了您遇到的相同问题。
在这两种情况下,最好使用主机名而不是 IP。如果您的公共 IP 经常变化,您可以使用动态主机名服务来获取主机名(如 myname.dyndns.org)。它也更容易记住。如果您选择选项 1,您可以在主机文件中添加此名称。
我的调制解调器有自动向这些服务注册 IP 更改的选项。还有桌面实用程序可以在公共 IP 更改时更新它。
答案2
答案3
补充 Rik 的回答:这里是我的错误:它只做了部分正确的事情,最后却搞乱了 NAT。
10.1.10.11 a.b.c.d 40212 > ssh [SYN] Seq=0 Win=14600 Len=0 MSS=1460
10.1.10.201 10.1.10.11 ssh > 40212 [SYN, ACK] Seq=0 Ack=1 Win=5792 Len=0 MSS=1460
10.1.10.11 10.1.10.201 40212 > ssh [RST] Seq=1 Win=0 Len=0
请仔细注意此处的连接。首先,我们看到一个 SYN(预期)从 10.1.10.11(ssh 客户端,这是正常的)到 abcd(也是正常的)。但是,服务器将其接收为10.1.10.11 → 10.1.10.201
。目标 IP 已被路由器替换,NAT 方式,正确。但是,源 IP 并未被替换。在这里,我们应该有连接(10.1.10.201
& a.b.c.d
),但实际上,我们有(10.1.10.201
& 10.1.10.11
)。路由器只完成了所需工作的一半。
对于服务器来说,连接是 ( 10.1.10.201
& 10.1.10.11
)。对于客户端来说,连接是 ( 10.1.10.201
& )¹。当客户端收到 ( & )a.b.c.d
的 SYN/ACK 时,操作系统(理所当然地)发送 RST — 它不知道10.1.10.201
10.1.10.11
那联系。
¹请注意,端口号在确定连接时确实很重要,但为了简单起见,我将其省略了。