我有两台服务器。服务器 A 具有公共 IP 地址 ( 43.24.24.29
)。服务器 B 有一个私有 IP 地址 ( 10.10.10.1
)。
服务器A可以通过其公网IP地址连接到服务器B(可能有一些静态路由),因此服务器A可以访问服务器B。
现在我想使用另一台PC连接ssh
到服务器B,因此,在服务器A中,我添加了一个ssh端口转发:
[ldl@ServerA ~]$ sudo ssh -N -f -L 222:43.24.24.29:22 [email protected]
现在它在服务器中启动:
[ldl@ ServerA ~]$ ps -ef | grep ssh
root 10228 1 0 4th mon 13 ? 00:03:19 /usr/sbin/sshd -D
root 91304 10228 0 04:46 ? 00:00:01 sshd: ldl [priv]
ldl 91308 91304 0 04:46 ? 00:00:00 sshd: ldl@pts/0
root 100491 1 0 10:57 ? 00:00:00 ssh -N -f -L 222:43.24.24.29:22 [email protected]
root 100501 10228 1 10:57 ? 00:00:00 sshd: root [priv]
sshd 100502 100501 0 10:57 ? 00:00:00 sshd: root [net]
ldl 100505 91309 0 10:57 pts/0 00:00:00 grep --color=auto ssh
[ldl@ServerA ~]$ netstat -tlnp | grep 222
(No info could be read for "-p": geteuid()=1000 but you should be root.)
tcp 0 0 127.0.0.1:222 0.0.0.0:* LISTEN -
tcp6 0 0 ::1:222 :::* LISTEN -
但是,在我的本地 PC 中,我尝试 ssh 到服务器 A 的端口 222,但收到此“连接被拒绝”错误:
aircrafts-MBP:~ ldl$ ssh [email protected] -p 222 -vvv
OpenSSH_7.7p1, LibreSSL 2.7.3
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 48: Applying options for *
debug2: resolve_canonicalize: hostname 43.24.24.29 is address
debug2: ssh_connect_direct: needpriv 0
debug1: Connecting to 43.24.24.29 [43.24.24.29] port 222.
debug1: connect to address 43.24.24.29 port 222: Connection refused
ssh: connect to host 43.24.24.29 port 222: Connection refused
这43.24.24.29
是我的演示 IP 地址。
编辑-01
我尝试了命令:
ssh -N -f -L 2222:localhost:22 [email protected]
当我连接它时,我收到此错误:ssh_exchange_identification: read: Connection reset by peer
。详细地说:
aircrafts-MBP:~ ldl$ ssh 43.24.24.29 -p2222 -vvv
OpenSSH_7.7p1, LibreSSL 2.7.3
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 48: Applying options for *
debug2: resolve_canonicalize: hostname 43.24.24.29 is address
debug2: ssh_connect_direct: needpriv 0
debug1: Connecting to 43.24.24.29 [43.24.24.29] port 2222.
debug1: Connection established.
debug1: identity file /Users/ldl/.ssh/id_rsa type 0
debug1: key_load_public: No such file or directory
debug1: identity file /Users/ldl/.ssh/id_rsa-cert type -1
debug1: key_load_public: No such file or directory
debug1: identity file /Users/ldl/.ssh/id_dsa type -1
debug1: key_load_public: No such file or directory
debug1: identity file /Users/ldl/.ssh/id_dsa-cert type -1
debug1: key_load_public: No such file or directory
debug1: identity file /Users/ldl/.ssh/id_ecdsa type -1
debug1: key_load_public: No such file or directory
debug1: identity file /Users/ldl/.ssh/id_ecdsa-cert type -1
debug1: key_load_public: No such file or directory
debug1: identity file /Users/ldl/.ssh/id_ed25519 type -1
debug1: key_load_public: No such file or directory
debug1: identity file /Users/ldl/.ssh/id_ed25519-cert type -1
debug1: key_load_public: No such file or directory
debug1: identity file /Users/ldl/.ssh/id_xmss type -1
debug1: key_load_public: No such file or directory
debug1: identity file /Users/ldl/.ssh/id_xmss-cert type -1
debug1: Local version string SSH-2.0-OpenSSH_7.7
ssh_exchange_identification: read: Connection reset by peer
答案1
当您为远程主机进行转发时,您必须使用以下命令进行远程端口转发:-R参数而不是 -L,这将在本地(localhost)建立隧道;否则,您将创建的所有隧道都将指向本地主机。此外,您应该确保您已GatewayPorts yes
在/etc/sshd_config
文件中建立了参数10.10.10.1服务器,否则不会进行转发。
确保 GatewayPorts 参数为 yes 后尝试此操作:
ssh -N -f [email protected] -R 222:43.24.24.29:22
然后(编辑):
ssh [email protected] -p 222
答案2
当端口转发时,有两对 IP/端口:
<from IP>:<from PORT>:<to IP>:<to PORT>
如果您只设置一个 IP,那么这将显示为
<from PORT>:<to IP>:<to PORT>
这会让人感到困惑,因为“从 ip 来自端口”到 ssh 客户端和“到 ip 到端口”来自服务器。
从服务器 A 尝试此操作:
ssh -N -f -L 2222:localhost:22 [email protected]
那么你可以
ssh 43.24.24.29:2222
这是可行的,因为 SSH 连接是从服务器 A 到服务器 B。因此在上面的命令中,“localhost”指的是服务器 B。
答案3
第一次尝试时出现的错误是因为您的命令使 ServerA 仅侦听 127.0.0.1,即所谓的“localhost”地址,该地址只能由其自身访问。实际上,您只能从 ServerA 本身访问 ServerA 的端口 222。
另外,通过指定-L 222:43.24.24.29:22
它实际上会让 ServerB (10.10.10.1) 连接回 ServerA 的端口 22.. 我认为这不是很有用。
您的第二次尝试(EDIT-01)更好,但它仍然使 ServerA 仅在本地主机上侦听。因此我无法想象什么进程可能收到了通往 ServerA 端口 2222 的连接,显然不是 ssh 服务器。您可能需要以前失败的尝试中 ServerA 上可能存在的kill
所有ssh -N ...
命令,并确保您使用的端口(示例中为 2222)不得已在使用中。
鉴于这一切,你需要做的是:
[ldl@ ServerA ~]$ ssh -N -f -L :2222:localhost:22 [email protected]
上面告诉 ServerA 设置端口 2222(高于 1023,你不需要运行它sudo
)来监听全部它的地址(注意:
前面的 2222)并使用特意建立的连接[电子邮件受保护](ServerB) 连接到端口 22 的服务器B的“本地主机”。
这就是-L
工作原理:您首先告诉它:2222
您要在“本地计算机”(上例中的 ServerA)上设置什么地址和端口(在上面的示例中)以及您想要的位置远程机器连接到。 “远程机器”是 ssh 命令通过该[email protected]
语法连接到的机器。
尽管乍一看很尴尬,但请记住,ssh 的端口转发并不是被设计为转发 ssh 协议本身的好方法,更不是作为从一个主机跳转到另一个主机的解决方案。
因此,如果您需要做的只是使用 ServerA 作为您的飞机-MBP 到 ServerB 的跃点,我宁愿建议您这样做:
ssh -t [email protected] 'ssh [email protected]'
直接从飞机-MBP。
答案4
您最初的尝试存在两个问题:
[ldl@ServerA ~]$ sudo ssh -N -f -L 222:43.24.24.29:22 [email protected]
这会以 root 身份运行 SSH,因此仅侦听本地端口号 >=1024 的限制不适用。但由于您没有指定bind_address
,SSH 客户端遵循客户端 GatewayPorts 默认设置,即仅在本地主机上侦听,这就是您无法从 PC 连接到它的原因。
另外,您将隧道的远程端指定为 43.24.24.29:22,因此即使您可以使用隧道,它也只会直接连接回 ServerA 的sshd
.
要解决这个问题:
[ldl@ServerA ~]$ sudo ssh -N -f -L "*:222:localhost:22" [email protected]
额外的*:
部分告诉 SSH 客户端允许从任何 IP 地址(而不仅仅是从本地主机)连接到隧道。添加双引号是为了防止 shell 对星号进行通配符扩展。并且“localhost:22”的隧道目标将应用于此 SSH 连接的远程端,该连接已经位于 ServerB 处。
然后,在您的 PC 上,您应该能够执行以下操作:
aircrafts-MBP:~ ldl$ ssh [email protected] -p 222
...possibly a SSH host key warning and/or a password prompt...
[root@ServerB ~]#
如果不需要专门使用端口 222,则使用大于 1023 的端口号将不需要sudo
.
[ldl@ServerA ~]$ ssh -N -f -L "*:2222:localhost:22" [email protected]
aircrafts-MBP:~ ldl$ ssh [email protected] -p 2222
...possibly a SSH host key warning and/or a password prompt...
[root@ServerB ~]#
还有另一种方法可以给这只猫剥皮。您可以在您的 PC 上执行此操作:
aircrafts-MBP:~ ldl$ ssh -L 2222:10.10.10.1:22 [email protected]
[ldl@ServerA ~]$
...在 ServerA 上获取可用的 shell,同时转发到 ServerB。
然后在另一个终端窗口中:
aircrafts-MBP:~ ldl$ ssh -p 2222 root@localhost
...possibly a SSH host key warning and/or a password prompt...
[root@ServerB ~]#
在此设置中,PC 上的第一个 SSH 会话在 PC 上以 TCP/2222 建立侦听代理,将所有流量转发到 ServerA,然后建立从 ServerA 到 ServerB 的端口 22 的“普通”TCP 连接以通过进入客户端侦听端口的流量。但由于使用代理的第二个会话也是 SSH 会话,因此从 PC 到 ServerA 的跃点将是 SSH-with-SSH,而从 ServerA 到 ServerB 将只是 SSH。