如何在一行SSH


21

如何通过SSH在一行中连接到另一台计算机?如果我这样做的话 ssh host@IP,它需要我在第二行输入密码。我以为我可以这样做: ssh host@IP | echo password,但是在要求输入密码之前输入密码。


2
这种想法来自telnet和期待的时代,当互联网是一个更安全的地方时。艾伦的答案是正确的,Jakuje的答案在技术上是正确的,但在大多数地方并不是工作的工具。
Criggie

3
这是设置无密码登录的好问题。我要求你重温你接受的答案。哪个Jakuje的答案是正确的,并且能够正常工作,正确的方法是使用SSH密钥,Allan的答案中描述了这一点。
Scot

如果 ssh 会从stdin读取密码 echo password | ssh host@IP 会工作,但通常SSH尝试直接从终端读取。
Paŭlo Ebermann

Answers:


76

您应该使用SSH密钥进行身份验证,而不是将密码放在命令行上 非常 不安全的。

这种方式的工作方式是,一旦设置了SSH密钥,您所要做的就是发出命令:

ssh user@host

如果没有输入其他内容,您将自动登录。


从MACOS将SSH公钥复制到Mac / FreeBSD / Linux

这假设您可以通过基于密码的身份验证(输入密码)访问远程服务器,并且您已经生成了私有/公共密钥对(如果没有,请参阅下文)。在以下示例中,我们使用RSA。首先让我们复制密钥(请注意,“home”目录在macOS,Linux,BSD等之间有所不同):

使用SCP:

scp ~/.ssh/id_rsa.pub username@hostname:/Users/username/.ssh/

或者只是cat-in文件 authorized_keys (我更喜欢这种方法):

cat id_rsa.pub | ssh username@hostname ' cat >>.ssh/authorized_keys'

(您的密钥名称可能不同)如果远程服务器上不存在.ssh目录,则需要登录并创建它。

现在密钥已经从mac复制到了 远程 服务器。 为远程服务器上的SSH公钥设置正确的权限:

chmod 600  ~/.ssh/id_rsa.pub

接下来将密钥添加到SSH authorized_keys文件,如果该文件不存在则创建它。

如果是文件 authorized_keys 已存在于 ~/.ssh 使用以下命令:

cat id_rsa.pub >> authorized_keys

如果该文件不存在,请输入以下命令:

cat id_rsa.pub > authorized_keys

chmod 600 authorized_keys
chown user:group authorized_keys


在macOS上生成SSH公钥/私钥

通过转到应用程序打开终端 - >实用程序 - >终奌站

在终端中,使用以下命令启动密钥生成

ssh-keygen -t rsa

接下来,系统将提示您提供要创建私钥文件的位置:

输入要保存密钥的文件( /Users/username/.ssh/id_rsa ):

将其留空以在默认位置创建密钥,即 /Users/username/.ssh/id_rsa。公钥文件将在同一位置创建,并且名称相同,但扩展名为.PUB。

系统将提示您选择密码。这是密码 可选的 使用私钥。

Enter passphrase (empty for no passphrase):

您的SSH密钥已生成。

现在,请记住,如果您输入密码,则每次连接时都需要输入密码。实用程序 ssh-agent 将密码保留在内存中,减少每次连接时手动输入密码的需要。有关详细信息,请参阅 man ssh-agent


6
绝对这 - 键可以而且应该完全取代通过互联网进行任何ssh访问的密码。我建议你扩展对私钥安全性的需求,这不是你所有计算机上的东西。
Criggie

+1这是一个非常好的答案,不仅因为它的内容,而且还因为你如何解释它。任何更容易让用户关注并帮助他们更安全的东西都是我书中的优势!
Monomeeth

7
很好的答案。只是想补充一点 ssh-copy-id 是一个很好的自动化上述一些工具。
Scot

提一下 SSH代理 也许会有所帮助。 OS X / macOS的大多数(全部?)版本都带有它,即使密钥受密码保护,它也允许无密码登录。
Qsigma

1
@Scot - 默认情况下它不是macOS的一部分,必须是 通过Homebrew或MacPorts安装 。我不是安装软件的粉丝,可以通过一行或一个简短的自编脚本完成,因为我认为这不在答案的范围内。然而,这是一个很好的小实用程序,值得一提。
Allan

11

有几种可能性。您的示例显然不起作用,但您可以使用类似的东西 sshpass 效用:

sshpass -p password ssh host@IP

注意, 这是不推荐的 因为 password 将在其他进程或shell历史记录中可见。

更好的方法是使用SSH密钥设置无密码身份验证。 简而言之:

ssh-keygen -t rsa -f ~/.ssh/id_rsa
ssh-copy-id IP

我试过了 sshpass 正如你的建议,但它说没有找到命令。
Ben A.

8
嗯......您可能需要安装它。不,我不推荐它。使用ssh密钥设置无密码身份验证。
Jakuje

4
@BenA。通过定义公共/私人键盘并在所涉及的两台计算机上进行设置来设置无密码身份验证。这比任何密码都容易(实际上更安全)
nohillside

8
一千次没有。 sshpass是一个脏黑客,用于连接到说ssh但没有正确执行密钥的设备,它的主要用途是设置脚本。您不会在多用户计算机上使用sshpass ps auxw | grep sshpass 将告诉其他用户ssh密码。
Criggie

1
@Criggie,不完全是。虽然我100%支持基于密钥的解决方案,但我还是使用了几个仅限内部的Raspberry Pis(用于随机任务,并由随机客户端访问;传递密钥仅供内部使用是一件麻烦事)。运行命令会提供以下输出: pi@sshbox:~ $ ps auxw | grep sshpass pi 4891 0.0 0.3 2256 1560 pts/0 S+ 06:29 0:00 sshpass -p zzzzzzzz ssh pi@192.168.0.208。该 zzzzzzzz 是文字; sshpass掩盖了密码的内容。也许早期的迭代不太隐私。
flith

3

运用 expect 登录到测试套件以外的任何其他东西的ssh连接是完全错误的。

@ ben-a正在寻找的内容已在ssh中实现。诀窍是如何使用它。所以这里:

  1. 使用生成公钥/私钥对 ssh-keygen。使用ECDSA或RSA作为 -t (或类型)和RSA使用2048或4096作为 -b (或BITS长度)。这应该在写作的那一刻就足够了。总是使用密码!
  2. 利用 ssh-copy-id 或者上面提到的方法在你登录的机器上创建(也就是服务器) ~/.ssh/authorized_keys 文件。在您刚刚生成的公钥的副本中。
  3. 现在在您使用的机器上登录打开文件的“服务器”(或客户端) ~/.ssh/config。如果它不存在,您可以创建它。
  4. 在此文件中,您可以根据需要添加以下内容

    host <name you want to use for this connection>
        Hostname <DNS or IP of the server>
        user <user name you want to use>
        identitiesonly yes
        identityfile <path to the private key>
    
  5. 你现在可以使用 ssh <name> 设置连接,但它仍然需要密钥的密码。要解决此问题,请使用for-this-purpose开发和包含的ssh-agent。要将密钥添加到代理,只需使用 ssh-add <path to keyfile>。系统将要求您输入密码,它将为您安全地存储密钥。如果它产生错误“找不到ssh-agent”(或类似的),这意味着代理可能尚未启动。您可以使用此会话启动它 ssh-agent bash。这将启动一个新的shell,其中代理处于活动状态。

使用这些步骤时,您不仅要让某人通过劫持您的凭据来模仿您,而且还要保持可用性(比普通密码更容易使用)。


2

我花了很长时间寻找答案。尽管它不安全,所有这些人都告诉你使用RSA密钥( 这是一个更安全可靠的想法 ), 这是很有可能。

使用一个名为的程序 expect 为了这。 Expect将为您监视stdout(我认为stderr,如果配置正确),等待某些消息并通过输出响应它们。期望它本身实际上是一种脚本语言,当我做同样的事情时,由于时间安排,我很难让自己的脚本正常工作。但是,期望还包括一个方便的实用工具 autoexpect

使用autoexpect,它会监视您并为您生成一个期望脚本。只需运行autoexpect和您想要的命令:

autoexpect ssh host@ip 

并做你通常做的事情。退出程序时(通过键入 exit 在ssh'd shell中,它将生成脚本。如果您不希望编写的整个脚本位于expect脚本中,则可以从autoexpect编辑脚本(调用 script.exp )在键入之前退出 exit 命令进入shell。要移动以更改脚本结尾的行是:

expect eof

这意味着期待文件结束。希望这可以帮助!


1
如果还没有其他人说过:欢迎提出不同的问题!
Synoli
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.