如何在一个命令中通过B通过SSH连接到机器A?

我想访问一台计算机,比如机器A ,它位于我大学的网络中。 但是,这台计算机只能通过大学的内部网络访问,因此我不能直接在家中使用SSH到这台计算机。

这就是我现在所做的:

  1. 登录到不同的大学机器,比如机器B.

    (这台机器B可以从家用电脑通过SSH访问。)

  2. 在B上使用SSH连接到A.

有没有办法更快地做到这一点? 仅使用一个ssh命令。

是的,在SSH配置中使用ProxyCommand

在主目录中创建SSH配置文件(除非您想在系统范围内创建), ~/.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(Dolphin):使用fish://user@internalmachine/

笔记

hostname.or.IP.address.internal.machine和端口( 22 )更改为您想要访问的计算机,就像从unibroker计算机那样。

根据unibroker主机上的netcat版本,必须省略-q0选项。 关于认证; 你基本上是从你的工作站设置两个SSH连接。 这意味着unibroker主机和internalmachine主机相互validation/validation(对于密钥对/密码和主机密钥validation)。

说明

这种使用ProxyCommand和’netcat’的方法只是一种方法。 我喜欢这个,因为我的SSH客户端直接与目标机器对话,以便我可以从我的客户端validation主机密钥,我可以使用我的公钥认证,而无需使用代理上的其他密钥。

每个Host定义新主机部分的开始。 Hostname是该Hostname的目标主机名或IP地址。 User是您在ssh user@hostname作为用户部分提供的内容。

ProxyCommand将用作目标计算机的管道。 通过使用SSH到第一台机器并直接从那里设置一个简单的’netcat’( nc )到目标,这基本上只是从那些之间的代理向内部机器转发的明文。 -q选项可以使任何输出静音(仅限个人偏好)。

确保在代理上安装了netcat(默认情况下通常在Ubuntu上可用) – netcat-openbsd 安装netcat-openbsd 或者netcat-traditional 安装netcat-traditional

请注意,您仍在使用SSH加密两次。 虽然netcat通道是纯文本,但PC上的SSH客户端将使用最终目标计算机设置另一个加密通道。

一气呵成

我在其他答案中提供的ProxyCommand方法的一个明显替代方案是直接“跳跃”到目标机器:

 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

缺点是,现在所有的配置,validation和身份validation都在机器B进行,出于安​​全考虑,我真的不喜欢这种情况。 我喜欢自己的PC上的密钥对,并从我自己的PCvalidation并validation最终的目标机器。 此外,您只能将交互式shell用于SSH,因此这不会处理SCP等其他工具或使用GUI文件管理器。

由于上述所有原因,我强烈推荐使用ProxyCommand方法 ,但为了快速连接,这种方法很好。

尝试使用

 Host  Controlmaster auto User  hostname  port  IdentityFile ~/.ssh/ Host  ProxyCommand ssh -q -W :  

在你的〜/ .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及更高版本中可用。

ProxyCommand是一个干净的解决方案,适用于在两个系统中都允许shell访问的情况。 我们希望通过代理(B)为远程用户提供对内部计算机(A)的访问权限,但不允许用户对B进行shell访问以提高安全性。 这工作:

替换登录shell

使用以下脚本(存储在文件中)替换代理上的extuser的登录shell(使用chsh ):

 #!/bin/sh # this is essential to avoid Exec format error ssh internaluser@A 

如果远程用户没有在extuser @ B中设置密码登录,并且在extuser @ B的internaluser @ A中没有设置密码登录,则执行以下命令将直接将远程用户设置为A

 ssh extuser@B 

提示 :在更改为自定义登录shell之前,在extuser @ B中创建必要的无密码登录authorized_keys设置。 在更改之后,由于任何人都无法通过shell访问此帐户,因此只有sudoer @ B可以通过直接编辑来更改文件authorized_keys。

 sudo vi ~extuser/.ssh/authorized_keys sudo touch ~extuser/.hushlogin 

最后一行是从B压缩登录横幅显示,因此远程用户可以透明地访问A.

这是一个非常有用的建议。 在搞乱了几个小时后,我发现了这个说明,并确认这完全符合记录。 要从远程machineC通过MachineA连接到MachineB:

例如:[xuser @ machineC~] ssh -t MachineA ssh MachineB

“-t”是关键,如果不存在则ssh失败。 您将收到两次提示,首先是MachineA上的密码,然后是MachineB的第二次。 另请注意,这假设您在所有三台计算机上都定义了用户“xuser”。 如果没有,只需使用ssh语法:“yuser @ MachineA …”。 另请注意,如果您愿意,可以使用点分四元组原始IP#。 如果您通过使用未向世界公开的IP的私有本地网络进行链接,这将非常有用 – 即。 不在您的本地主机文件或任何DNS中。 要从MachineB获取文件到远程machineC,您可以从MachineB scp到MachineA,然后从MachineA到远程machineC。 (例如,远程machineC可以ping MachineA,但不能ping MachineB。)警告:我用Fedora和WindowsXP测试过,MachineA是运行ICS(Internet连接共享)的XP-Box,而MachineB和远程machineC是Fedora-Linux盒子。 这个建议解决了我的一个关键问题 – 即。 限制,监控远程访问我的远程站点局域网。 另请注意,当您从MachineB“注销”时,您应该看到两个“连接到xxx.xxx.xxx.xxx已关闭”。 消息。