问题描述
我想访问一台计算机,比如机器A,它位于我大学的网络中。但是,这台计算机只能通过大学的内部网络访问,因此我不能直接在家中使用SSH到这台计算机。
这就是我现在所做的:
-
登录到不同的大学机器,例如机器B(可以通过SSH从我的家用计算机访问该机器B.)
-
在B上使用SSH连接到A.
有没有办法更快地做到这一点?仅使用一个ssh命令。
最佳解决思路
是的,在SSH配置中使用ProxyCommand
。
在主目录中创建SSH配置文件(除非您要创建此system-wide),~/.ssh/config
:
Host unibroker # Machine B definition (the broker)
Hostname 12.34.45.56 # Change this IP address to the address of the broker
User myusername # Change this default user accordingly
# (`user@unibroker` can overwrite it)
Host internalmachine # Machine A definition (the target host)
ProxyCommand ssh -q unibroker nc -q0 hostname.or.IP.address.internal.machine 22
现在您可以直接使用机器A.
ssh user@internalmachine
另请注意,现在您有一个SSH主机目标名称,您也可以在其他应用程序中使用它。例如。:
-
SCP复制文件。
scp somefile user@internalmachine:~/
-
在GUI应用程序中:使用
sftp://user@internalmachine/
作为在计算机上浏览的位置。 KDE-based(海豚):使用fish://user@internalmachine/
说明
将hostname.or.IP.address.internal.machine
和端口(22
)更改为您想要的机器,就像您从unibroker
机器那样。
根据unibroker主机上的netcat版本,必须省略-q0
选项。关于认证;你基本上是从你的工作站设置两个SSH连接。这意味着unibroker主机和internalmachine主机相互验证/验证(对于密钥对/密码和主机密钥验证)。
Explanation
这种使用ProxyCommand
和’netcat’的方法只是一种方法。我喜欢这个,因为我的SSH客户端直接与目标机器对话,以便我可以从我的客户端验证主机密钥,我可以使用我的公钥认证,而无需使用代理上的其他密钥。
每个Host
定义新主机部分的开始。 Hostname
是该主机的目标主机名或IP地址。 User
是您在ssh user@hostname
中作为用户部分提供的内容。
ProxyCommand
将用作目标机器的管道。通过使用SSH到第一台机器并直接从那里设置一个简单的’netcat'(nc
)到目标,这基本上只是从那些之间的代理向内部机器转发的明文。 -q
选项可以使任何输出静音(仅限个人喜好)。
确保在代理上安装了netcat(默认情况下通常在Ubuntu上可用) – netcat-openbsd或netcat-traditional。
请注意,您仍在使用SSH加密两次。虽然netcat通道是纯文本,但PC上的SSH客户端将使用最终目标计算机设置另一个加密通道。
次佳解决思路
一气呵成
我在my other answer中提供的ProxyCommand方法的一个明显替代方案是’hopping’直接到目标机器:
ssh -t user@machineB ssh user@machineA
请注意第一个ssh
命令中的-t
。没有它,它将失败:
Pseudo-terminal will not be allocated because stdin is not a terminal.
ssh_askpass: exec(/usr/bin/ssh-askpass): No such file or directory
Permission denied, please try again.
[...]
它将强制分配一个真正的TTY
缺点是,现在所有的配置,验证和身份验证都在机器B进行,出于安全考虑,我真的不喜欢这种情况。我喜欢自己的PC上的密钥对,并从我自己的PC验证并验证最终的目标机器。此外,您只能将交互式shell用于SSH,因此这不会处理SCP等其他工具或使用GUI文件管理器。
由于上述所有原因,我强烈推荐the ProxyCommand approach,但为了快速连接,这可以正常工作。
第三种解决思路
尝试使用
Host <visible hostname alias>
Controlmaster auto
User <user>
hostname <visible hostname>
port <port>
IdentityFile ~/.ssh/<id file>
Host <private LAN hostname alias>
ProxyCommand ssh -q -W <private LAN hostname>:<private LAN port> <visible hostname alias>
在你的〜/.ssh /config中,一次性完成所有操作,只有你的计算机上只有密钥。
第四种思路
您可以使用-J
命令行选项:
ssh -J user@machineB user@machineA
来自man ssh
:
-J [user@]host[:port]
Connect to the target host by first making a ssh connection to
the jump host and then establishing a TCP forwarding to the
ultimate destination from there. Multiple jump hops may be
specified separated by comma characters. This is a shortcut to
specify a ProxyJump configuration directive.
它是在OpenSSH 7.3版(2016年8月发布)中引入的。它在Ubuntu 16.10及更高版本中可用。