【发布时间】:2012-08-25 12:26:42
【问题描述】:
我需要创建一个脚本,自动将密码输入到 OpenSSH ssh 客户端。
假设我需要使用密码a1234b SSH 到myname@somehost。
我已经试过了……
#~/bin/myssh.sh
ssh myname@somehost
a1234b
...但这不起作用。
如何将这个功能加入到脚本中?
【问题讨论】:
我需要创建一个脚本,自动将密码输入到 OpenSSH ssh 客户端。
假设我需要使用密码a1234b SSH 到myname@somehost。
我已经试过了……
#~/bin/myssh.sh
ssh myname@somehost
a1234b
...但这不起作用。
如何将这个功能加入到脚本中?
【问题讨论】:
首先你需要安装sshpass。
apt-get install sshpass
yum install sshpass pacman -S sshpass
示例:
sshpass -p "YOUR_PASSWORD" ssh -o StrictHostKeyChecking=no YOUR_USERNAME@SOME_SITE.COM
自定义端口示例:
sshpass -p "YOUR_PASSWORD" ssh -o StrictHostKeyChecking=no YOUR_USERNAME@SOME_SITE.COM:2400
注意事项:
sshpass 也可以在传递-f 标志时从文件中读取密码。
-f 可防止在执行ps 命令时密码可见。【讨论】:
ps -aux 等命令,但您通常不应通过输入密码来运行命令,因为同一台计算机上的其他用户可能会通过以下方式查看密码运行ps -aux。如果可行,您还想改用公钥身份验证,如另一个答案中所述。这使您可以将身份验证信息与脚本分开,这样您就可以放心地与其他人共享您的脚本,然后决定在您的 ~/.ssh 文件夹上启用加密而不加密您的脚本。
在寻找这个问题的答案几个月后,我终于找到了一个更好的解决方案:编写一个简单的脚本。
#!/usr/bin/expect
set timeout 20
set cmd [lrange $argv 1 end]
set password [lindex $argv 0]
eval spawn $cmd
expect "password:"
send "$password\r";
interact
发给/usr/bin/exp,这样就可以使用了:
exp <password> ssh <anything>exp <password> scp <anysrc> <anydst>完成!
【讨论】:
使用公钥认证:https://help.ubuntu.com/community/SSH/OpenSSH/Keys
在源主机中只运行一次:
ssh-keygen -t rsa # ENTER to every field
ssh-copy-id myname@somehost
就是这样,之后你就可以在没有密码的情况下进行ssh了。
【讨论】:
您可以使用期望脚本。我已经很久没有写过一篇了,但它应该如下所示。您需要使用 #!/usr/bin/expect 来领导脚本
#!/usr/bin/expect -f
spawn ssh HOSTNAME
expect "login:"
send "username\r"
expect "Password:"
send "password\r"
interact
【讨论】:
/bin/myssh.sh: 2: spawn: not found /bin/myssh.sh: 3: expect: not found /bin/myssh.sh: 4: send: not found /bin/myssh.sh: 5: expect: not found /bin/myssh.sh: 6: send: not found
which expect
#!/usr/bin/env expect
interact,因此 ssh 会话实际上是交互式的
变体 I
sshpass -p PASSWORD ssh USER@SERVER
变体 II
#!/usr/bin/expect -f
spawn ssh USERNAME@SERVER "touch /home/user/ssh_example"
expect "assword:"
send "PASSWORD\r"
interact
【讨论】:
SYNOPSIS sshpass [-ffilename|-dnum|-ppassword|-e] [options] command arguments
yum -y install epel-release 然后yum -y install sshpass
已经提到的sshpass 的一个不错的好处是您可以将它与autossh 一起使用,从而消除更多的交互效率低下。
sshpass -p mypassword autossh -M0 -t myusername@myserver.mydomain.com
这将允许自动重新连接,例如关闭笔记本电脑会中断 wifi。
【讨论】:
-f 添加到 autossh,因为 when used with autossh, ssh will be *unable* to ask for passwords or passphrases. harding.motd.ca/autossh/README.txt 也是 superuser.com/questions/1278583/…
-M0 标志禁用监控我的连接在一段时间后失败,autossh 没有意识到它;如果我省略该标志,那么它也可以工作,直到连接失败,此时我的密码被服务器拒绝
sshpass 具有更好的安全性我在寻找一种通过 ssh 进入陷入困境的服务器的方法时偶然发现了这个线程——处理 SSH 连接尝试花了一分钟多的时间,并且在我输入密码之前就超时了。在这种情况下,我希望能够在提示可用时立即提供我的密码。
(如果不是很清楚:如果服务器处于这种状态,那么设置公钥登录为时已晚。)
sshpass 来救援。但是,有比sshpass -p 更好的方法来解决这个问题。
我的实现直接跳到交互式密码提示(不会浪费时间查看是否可以进行公钥交换),并且从不以纯文本形式显示密码。
#!/bin/sh
# preempt-ssh.sh
# usage: same arguments that you'd pass to ssh normally
echo "You're going to run (with our additions) ssh $@"
# Read password interactively and save it to the environment
read -s -p "Password to use: " SSHPASS
export SSHPASS
# have sshpass load the password from the environment, and skip public key auth
# all other args come directly from the input
sshpass -e ssh -o PreferredAuthentications=keyboard-interactive -o PubkeyAuthentication=no "$@"
# clear the exported variable containing the password
unset SSHPASS
【讨论】:
trap 以防止ctrl-C 泄漏SSHPASS 变量
PreferredAuthentications=keyboard-interactive 不起作用,但是用PreferredAuthentications=password 替换它起作用了。
ssh,使用相同的密码。现在我正在使用export SSHPASS=$SSHPASS 将SSHPASS 导出到远程机器中。有没有更安全的方法?为了提供一些上下文,我 ssh 进入一个机器集群,设置 ssh 密钥,然后将它们分发到集群中的其他计算机。所有这些都从单台计算机中的脚本运行。所以我需要2级ssh。
我认为我没有看到任何人建议这样做,而 OP 只是说“脚本”所以......
我需要解决同样的问题,而我最熟悉的语言是 Python。
我使用了 paramiko 库。此外,我还需要使用sudo 发出需要升级权限的命令。事实证明 sudo 可以通过“-S”标志通过标准输入接受其密码!见下文:
import paramiko
ssh_client = paramiko.SSHClient()
# To avoid an "unknown hosts" error. Solve this differently if you must...
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# This mechanism uses a private key.
pkey = paramiko.RSAKey.from_private_key_file(PKEY_PATH)
# This mechanism uses a password.
# Get it from cli args or a file or hard code it, whatever works best for you
password = "password"
ssh_client.connect(hostname="my.host.name.com",
username="username",
# Uncomment one of the following...
# password=password
# pkey=pkey
)
# do something restricted
# If you don't need escalated permissions, omit everything before "mkdir"
command = "echo {} | sudo -S mkdir /var/log/test_dir 2>/dev/null".format(password)
# In order to inspect the exit code
# you need go under paramiko's hood a bit
# rather than just using "ssh_client.exec_command()"
chan = ssh_client.get_transport().open_session()
chan.exec_command(command)
exit_status = chan.recv_exit_status()
if exit_status != 0:
stderr = chan.recv_stderr(5000)
# Note that sudo's "-S" flag will send the password prompt to stderr
# so you will see that string here too, as well as the actual error.
# It was because of this behavior that we needed access to the exit code
# to assert success.
logger.error("Uh oh")
logger.error(stderr)
else:
logger.info("Successful!")
希望这对某人有所帮助。我的用例是一次在大约 300 台服务器上创建目录、发送和解压缩文件以及启动程序。因此,自动化至关重要。我试过sshpass、expect,然后想出了这个。
【讨论】:
# create a file that echo's out your password .. you may need to get crazy with escape chars or for extra credit put ASCII in your password...
echo "echo YerPasswordhere" > /tmp/1
chmod 777 /tmp/1
# sets some vars for ssh to play nice with something to do with GUI but here we are using it to pass creds.
export SSH_ASKPASS="/tmp/1"
export DISPLAY=YOURDOINGITWRONG
setsid ssh root@owned.com -p 22
【讨论】:
admin 对系统进行自动化处理,这很好
这是我登录服务器的方式:
ssp <server_ip>
alias ssp='/home/myuser/Documents/ssh_script.sh'cat /home/myuser/Documents/ssh_script.shssp:
#!/bin/bash
sshpass -p mypassword ssh root@$1
因此:
ssp server_ip
【讨论】:
如果您在 Windows 系统上执行此操作,则可以使用 Plink(PuTTY 的一部分)。
plink your_username@yourhost -pw your_password
【讨论】:
我正在使用以下解决方案,但为此您必须安装 sshpass 如果尚未安装,请使用 sudo apt install sshpass 安装它
现在你可以这样做了,
sshpass -p *YourPassword* shh root@IP
您也可以创建一个 bash 别名,这样您就不必一次又一次地运行整个命令。 请按照以下步骤操作
cd ~
sudo nano .bash_profile
在文件末尾添加以下代码
mymachine() { sshpass -p *YourPassword* shh root@IP }
source .bash_profile
现在只需从终端运行mymachine 命令,您将无需密码提示进入您的机器。
注意:
mymachine 可以是您选择的任何命令。【讨论】:
.bash_profile 通常是文字可读的。所以把你的密码放在那里不是一个好主意。
这基本上是 abbotto 答案的扩展,有一些额外的步骤(针对初学者)可以让你从你的 linux 主机启动你的服务器变得非常容易:
- 编写一个简单的 bash 脚本,例如:
#!/bin/bash
sshpass -p "YOUR_PASSWORD" ssh -o StrictHostKeyChecking=no YOUR_USERNAME@SOME_SITE.COM
- 保存文件,例如'startMyServer',然后通过在终端中运行它来使文件可执行:
sudo chmod +x startMyServer
- 将文件移动到“PATH”变量中的文件夹(在终端中运行“echo $PATH”以查看这些文件夹)。因此,例如将其移至“/usr/bin/”。
瞧,现在您可以通过在终端中输入“startMyServer”来进入您的服务器。
附: (1) 这不是很安全,请查看 ssh 密钥以获得更好的安全性。
附: (2) SMshrimant 的答案非常相似,对某些人来说可能更优雅。但我个人更喜欢使用 bash 脚本。
【讨论】:
我的工作如下
.ssh/config 被修改以消除是/否提示 - 我在防火墙后面,所以我不担心被欺骗的 ssh 密钥
host *
StrictHostKeyChecking no
为期望创建响应文件,即 answer.expect
set timeout 20
set node [lindex $argv 0]
spawn ssh root@node service hadoop-hdfs-datanode restart
expect "*?assword {
send "password\r" <- your password here.
interact
创建你的 bash 脚本并在文件中调用 expect
#!/bin/bash
i=1
while [$i -lt 129] # a few nodes here
expect answer.expect hadoopslave$i
i=[$i + 1]
sleep 5
done
使用新配置刷新 128 个 hadoop 数据节点 - 假设您为 hadoop/conf 文件使用 NFS 挂载
希望这对某人有所帮助 - 我是 Windows 笨蛋,我花了大约 5 个小时才弄明白!
【讨论】:
我有一个更好的解决方案,包括使用您的帐户登录,而不是更改为 root 用户。 这是一个 bash 脚本
http://felipeferreira.net/index.php/2011/09/ssh-automatic-login/
【讨论】:
@abbotto 的答案对我不起作用,不得不做一些不同的事情:
【讨论】:
我设法让它与它一起工作:
SSH_ASKPASS="echo \"my-pass-here\""
ssh -tt remotehost -l myusername
【讨论】:
在下面的示例中,我将编写我使用的解决方案:
场景:我想使用 sh 脚本从服务器复制文件:
#!/usr/bin/expect
$PASSWORD=password
my_script=$(expect -c "spawn scp userName@server-name:path/file.txt /home/Amine/Bureau/trash/test/
expect \"password:\"
send \"$PASSWORD\r\"
expect \"#\"
send \"exit \r\"
")
echo "$my_script"
【讨论】:
这行得通:
#!/usr/bin/expect -f
spawn ssh USERNAME@SERVER "touch /home/user/ssh_example"
expect "assword:"
send "PASSWORD\r"
interact
但是!!!如果您遇到如下错误,只需使用 expect 启动您的脚本,而不是 bash,如下所示:expect myssh.sh
而不是bash myssh.sh
/bin/myssh.sh: 2: spawn: not found /bin/myssh.sh: 3: expect: not found /bin/myssh.sh: 4: send: not found /bin/myssh.sh: 5: expect: not found /bin/myssh.sh: 6: send: not found
【讨论】:
在脚本中使用此脚本 tossh,第一个参数是主机名,第二个参数是密码。
#!/usr/bin/expect
set pass [lindex $argv 1]
set host [lindex $argv 0]
spawn ssh -t root@$host echo Hello
expect "*assword: "
send "$pass\n";
interact"
【讨论】:
要通过 shell 脚本连接远程机器,请使用以下命令:
sshpass -p PASSWORD ssh -o StrictHostKeyChecking=no USERNAME@IPADDRESS
其中IPADDRESS、USERNAME 和PASSWORD 是需要在脚本中提供的输入值,或者如果我们想在运行时提供,请使用“读取”命令。
【讨论】:
StrictHostKeyChecking=no。
这在大多数情况下应该会有所帮助(您需要先安装 sshpass!):
#!/usr/bin/bash
read -p 'Enter Your Username: ' UserName;
read -p 'Enter Your Password: ' Password;
read -p 'Enter Your Domain Name: ' Domain;
sshpass -p "$Password" ssh -o StrictHostKeyChecking=no $UserName@$Domain
【讨论】:
StrictHostKeyChecking=no。
在 linux/ubuntu 中
ssh username@server_ip_address -p port_number
按回车键,然后输入您的服务器密码
如果您不是 root 用户,请在命令开头添加 sudo
【讨论】: