简体   繁体   English

在 bash 脚本中为 ssh 命令提供密码,无需使用公钥和 Expect

[英]Provide password to ssh command inside bash script, Without the usage of public keys and Expect

I want to use SSH inside a script, but this script is not going to be executed on my machine.我想在脚本中使用SSH ,但该脚本不会在我的机器上执行。

In my implementation there are two limitations.在我的实现中有两个限制。

  • I can not work outside shell's standards,therefore i can not use expect because i do not know if it will be available on this machine.我不能在 shell 的标准之外工作,因此我不能使用expect因为我不知道它是否可以在这台机器上使用。
  • I can not expect that this machine will have public keys for the SSH .我不能指望这台机器会有SSH public keys

What are the possible options-solutions ?可能的选项-解决方案是什么?

How can i provide ssh with the requested password with an automated and secure way without adding extra dependencies?如何在不添加额外依赖项的情况下以自动且安全的方式向 ssh 提供请求的密码?

Will it be possible to provide the password inside the script?是否可以在脚本中提供密码?

Thank you all in advance :)谢谢大家 :)

安装 sshpass,然后启动命令:

sshpass -p "yourpassword" ssh -o StrictHostKeyChecking=no yourusername@hostname

For security reasons you must avoid providing password on a command line otherwise anyone running ps command can see your password.出于安全原因,您必须避免在命令行上提供密码,否则任何运行 ps 命令的人都可以看到您的密码。 Better to use sshpass utility like this:好像这样使用sshpass实用程序:

#!/bin/bash

export SSHPASS="your-password"
sshpass -e ssh -oBatchMode=no sshUser@remoteHost

You might be interested in How to run the sftp command with a password from Bash script?您可能对如何使用 Bash 脚本中的密码运行 sftp 命令感兴趣

First of all: Don't put secrets in clear text unless you know why it is a safe thing to do (ie you have assessed what damage can be done by an attacker knowing the secret).首先:除非您知道为什么这样做是安全的(即您已经评估了知道该秘密的攻击者可以造成什么损害),否则不要将秘密放在明文中

If you are ok with putting secrets in your script, you could ship an ssh key with it and execute in an ssh-agent shell:如果您可以将机密放入脚本中,则可以随附一个 ssh 密钥并在ssh-agent shell 中执行:

#!/usr/bin/env ssh-agent /usr/bin/env bash
KEYFILE=`mktemp`
cat << EOF > ${KEYFILE}
-----BEGIN RSA PRIVATE KEY-----
[.......]
EOF
ssh-add ${KEYFILE}

# do your ssh things here...

# Remove the key file.
rm -f ${KEYFILE}

A benefit of using ssh keys is that you can easily use forced commands to limit what the keyholder can do on the server.使用 ssh 密钥的一个好处是您可以轻松地使用强制命令来限制密钥持有者可以在服务器上执行的操作。

A more secure approach would be to let the script run ssh-keygen -f ~/.ssh/my-script-key to create a private key specific for this purpose, but then you would also need a routine for adding the public key to the server.更安全的方法是让脚本运行ssh-keygen -f ~/.ssh/my-script-key来创建专用于此目的的私钥,但是您还需要一个例程来将公钥添加到服务器。

AFAIK there is no possibility beside from using keys or expect if you are using the command line version ssh . AFAIK 除了使用密钥之外没有其他可能性,或者如果您使用命令行版本ssh But there are library bindings for the most programming languages like C, python, php, ... .但是对于大多数编程语言(如 C、python、php 等)都有库绑定。 You could write a program in such a language.你可以用这种语言编写程序。 This way it would be possible to pass the password automatically.这样就可以自动传递密码。 But note this is of course a security problem as the password will be stored in plain text in that program请注意,这当然是一个安全问题,因为密码将在该程序中以纯文本形式存储

I completely agree with everybody who says this is almost certainly a terrible idea .我完全同意每个人都说这几乎肯定是一个糟糕的主意 It is extremely likely to allow others to attack your computers.极有可能允许他人攻击您的计算机。

USE AT YOUR OWN RISK AFTER EVALUATING THE SECURITY HAZARDS在评估安全隐患后自行承担使用风险

Answer回答

Make a program /path/to/saypass which outputs the password, such as制作一个输出密码的程序/path/to/saypass ,例如

#!/bin/sh
echo 'secret'

Make it executable with使其可执行

chmod +x /path/to/saypass

Then this is the main command:然后这是主要命令:

SSH_ASKPASS="/path/to/saypass" DISPLAY=anything setsid ssh username@hostname [farcommand]

This

  • sets the two environment variables SSH_ASKPASS and DISPLAY设置两个环境变量SSH_ASKPASSDISPLAY
    • and then runs setsid然后运行setsid
      • which then runs ssh without a controlling terminal然后在没有控制终端的情况下运行ssh
        • which connects to the far hostname连接到远hostname
        • ... runs saypass locally to get the password ...在本地运行saypass以获取密码
        • ... tells it to the far server ... 告诉远端服务器
        • ... and assuming it's correct ...并假设它是正确的
          • which then runs farcommand (if given), or an interactive shell.然后运行farcommand (如果给定)或交互式 shell。

I normally test with date or hostname for the optional farcommand .我通常使用datehostname来测试可选的farcommand

There are lots of places for this to go wrong.有很多地方会出错。

Explanation解释

The trick to this is that standard Linux command line ssh has a couple of environment variables you can use to choose a program which gets executed to supply the password.诀窍是标准的 Linux 命令行ssh有几个环境变量,您可以使用它们来选择执行以提供密码的程序。

ssh(1) manual page says: ssh(1)手册页说:

SSH_ASKPASS If ssh needs a passphrase, it will read the passphrase from the current terminal if it was run from a terminal. SSH_ASKPASS如果ssh需要密码,如果它是从终端运行的,它将从当前终端读取密码。 If ssh does not have a terminal associated with it but DISPLAY and SSH_ASKPASS are set, it will execute the program specified by SSH_ASKPASS and open an X11 window to read the passphrase.如果ssh没有与之关联的终端,但设置了DISPLAYSSH_ASKPASS ,它将执行SSH_ASKPASS指定的程序并打开 X11 窗口以读取密码。

So: you need a program (shell script or any other kind) which will output the password.所以:您需要一个程序(shell 脚本或任何其他类型)来输出密码。 Then you need to convince ssh to use it:然后你需要说服ssh使用它:

  • With SSH_ASKPASS set to /path/to/saypassSSH_ASKPASS设置为/path/to/saypass
  • With DISPLAY set to something sillyDISPLAY设置为愚蠢的东西
  • With no controlling terminal (this is what setsid does)没有控制终端(这就是setsid所做的)

Which you put together in the following sh command:您将其放在以下sh命令中:

SSH_ASKPASS="/path/to/saypass" DISPLAY=anything setsid ssh username@hostname [command]

ssh will execute ssh将执行

/path/to/saypass "username@hostname's password:"

Fingerprint check指纹检查

If the fingerprint is needed, where you'd normally see the message如果需要指纹,您通常会在此处看到消息

The authenticity of host '*hostname* (*ipaddress*)' can't be established.
ECDSA key fingerprint is SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
Are you sure you want to continue connecting (yes/no)? 

Then ssh will run your command like this:然后ssh会像这样运行你的命令:

/path/to/saypass "Please type 'yes' or 'no':"

All-in-one script一机多用的脚本

The following is a single script for creating, using, and removing a saypass within the main script.以下是用于在主脚本中创建、使用和删除saypass脚本。 Everyone will tell you do not put plaintext passwords in files and also never hardcode a password .每个人都会告诉您不要将明文密码放在文件中,也不要对密码进行硬编码 They tell you this for good reason: it will cause you a lot of trouble.他们有充分的理由告诉你:这会给你带来很多麻烦。 Use at your own risk.使用风险自负。

#!/bin/sh

echo "#!/bin/sh\necho 'secret';rm -f /tmp/saypass.$$" > /tmp/saypass.$$
chmod 775 /tmp/saypass.$$
SSH_ASKPASS="/tmp/saypass.$$" DISPLAY=anything setsid ssh "$@"

SCP SCP

This also works for scp , the copy program on top of ssh :这也适用于scp ,即ssh之上的复制程序:

SSH_ASKPASS=/path/to/saypas DISPLAY=anything setsid scp username@hostname:/path/to/farfile .

Caveat警告

Really don't use this except in dire, dire, circumstances, such as where you have hundreds of computers and you can't install anything like ssh keys, sshpass even expect .真的不要使用这个,除非在可怕的、可怕的情况下,比如你有数百台计算机并且你不能安装任何东西,比如 ssh 密钥, sshpass甚至expect

If you do use it, please don't tell anyone I told you how to do it.如果您确实使用了它,请不要告诉任何人我告诉过您如何使用它。 It really is terrible.这真的很可怕。

I don't know what the man page means about "open an X11 window", no such thing happens in my testing.我不知道手册页关于“打开 X11 窗口”是什么意思,在我的测试中没有发生这样的事情。

Tested on经过测试

  • OpenSSH_6.6.1p1 Ubuntu-2ubuntu2, OpenSSL 1.0.1f 6 Jan 2014 on Ubuntu 14.04.1 LTS, OpenSSH_6.6.1p1 Ubuntu-2ubuntu2,OpenSSL 1.0.1f 2014 年 1 月 6 日在 Ubuntu 14.04.1 LTS 上,
  • OpenSSH_7.2p2 Ubuntu-4ubuntu2.1, OpenSSL 1.0.2g 1 Mar 2016 on Ubuntu 16.04.2 LTS OpenSSH_7.2p2 Ubuntu-4ubuntu2.1、OpenSSL 1.0.2g 2016 年 3 月 1 日在 Ubuntu 16.04.2 LTS 上
  • OpenSSH_7.6p1 Ubuntu-4ubuntu0.3, OpenSSL 1.0.2n 7 Dec 2017 on Ubuntu 18.04.5 LTS OpenSSH_7.6p1 Ubuntu-4ubuntu0.3、OpenSSL 1.0.2n 2017 年 12 月 7 日在 Ubuntu 18.04.5 LTS 上

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM