【问题标题】:Providing Sudo Password in bash Script在 bash 脚本中提供 Sudo 密码
【发布时间】:2021-07-19 21:55:33
【问题描述】:

我正在尝试编写一个 bash 脚本来登录 ssh 并登录到 sudo

SSH 登录工作正常,但我在登录 sudo 时遇到问题。这是我的命令

ssh -tt empId@env.linuxbox.com << EOF
echo "Password\n" | sudo -S su - airbust 
cd ../builds
EOF

i)我收到错误,因为提供了空密码

ii)我提供的用户名是'airbust',而它以用户名作为'empId'

S su - airbustpost-lapp1941(Linux-RENO::TEST):/tmp]$ echo "Password\n" | sudo - 
[sudo] password for : Sorry, try again.
[sudo] password for empId: 
sudo: no password was provided
sudo: 1 incorrect password attempt

【问题讨论】:

  • 这能回答你的问题吗? How to supply sudo with password from script?
  • 还是这个? *.com/questions/233217/…
  • @NicoHaase 我无法使用 visudo,因为我无法在文件中对密码进行硬编码。我还尝试了 echo myPassword | sudo -S su - airbust 类似于 sudo -S ls /tmp 。但是切换用户没有像 ls 命令那样执行。所以我仍然面临这个问题
  • 注意,当您运行sudo 时,您必须提供当前用户的密码,所以在您的情况下,sudo 需要 empId 的密码。
  • @meuh 当我在终端中手动运行它时,我提供了 airbust 的密码。例如: sudo su - airbust ; [sudo] airbust 的密码:密码

标签: bash shell sudo


【解决方案1】:

您可以使用expect 来自动化它。您只需将其安装在您的计算机上。下面有个小脚本会自动登录并执行sudo -S su -c 'whoami'并插入密码。

#! /bin/bash

USER=user
HOST=server.org

read -s -p "Password  : " PASS
echo

expect 2>&1 <<-EOF
                set timeout -1
                spawn ssh ${USER}@${HOST}
                expect {
                        "yes/no" { send "yes\r"; exp_continue }
                        "*password: " { send "${PASS}\r" }
                }
                expect "*$ " { send "sudo -S su -c 'whoami'\r" }
                expect "*password for ${USER}: " { send "${PASS}\r" }
                expect "*$ " { send "exit 0\r" }
                expect eof
                catch wait result
                exit [lindex \$result 3]
EOF
exit $?

此外,使用此代码,无需通过命令行将密码回显到 sudo,这将成为您的 bash 历史记录的一部分。相反,密码是通过 ssh 发送到 sudo 的,就像人类输入密码一样。

示例输出:

$ ./expect.sh 

Password  : spawn ssh user@server.org
user@server.org's password: 

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Tue May 11 14:52:17 2021 from <some ip>
user@server:~$ sudo -S su -c 'whoami'
[sudo] password for user: 
root
user@server:~$ exit 0
logout
Connection to server.org closed.
$

【讨论】:

    【解决方案2】:

    首先,您的“airburst”用户是否允许使用 sudo?您没有提及它是否在您的目标系统上运行。

    否则,无论如何,一切都会失败。如果我记得,如果您不是允许的用户或组,sudo 甚至会提示您输入密码,并在后记告诉您您没有使用 sudo 的权限。您可能需要检查 /etc/sudoers 中的设置和 /etc/sudoers.d 中的包含,使用一些命令配置组。 /etc/sudoers 文件实际上有一些注释设置,您可以轻松地根据需要进行调整。

    我得到了一个使用 bash 内置“读取”的场景的模拟。这是为我工作的简短脚本

    #!/bin/bash
    read -s -p "pass? "
    sudopas=${REPLY}; unset REPLY
    #echo $sudopas | $(which sudo) --stdin ls -l /root/tmp
    $(which sudo) ls -l /root/tmp
    unset sudopas
    

    打破这个;读取命令通过“pass?”从用户那里获取密码。提示,该字符串被转储到一个变量中。 $REPLY 变量未设置(清除)。然后使用我们想要的命令运行 sudo。然后取消设置包含密码的变量。

    当你从另一台主机运行命令时;

    $ ssh -t REMOTE_HOST '/bin/sh test.sh'
    pass? total 0
    -rw-r--r-- 1 root root 0 Apr 27 14:38 file1
    -rw-r--r-- 1 root root 0 Apr 27 14:38 file2
    -rw-r--r-- 1 root root 0 Apr 27 14:38 file3
    -rw-r--r-- 1 root root 0 Apr 27 14:38 file4
    Connection to REMOTE_HOST closed.
    

    ssh 命令行调用 /bin/sh 来执行脚本。使用 'sudo --stdin' 也可以,但似乎没有必要,因为 sudo 已经具有该功能。应该使用 'sudo -t' 标志

    请注意,我在测试主机之间为我的用户设置了基于密钥的身份验证,因此没有用户和 ssh 密码提示。我的用户位于允许使用“sudo”运行命令的主要组中,通过 /etc/sudoers 配置。

    【讨论】:

    • 我可以在脚本本身中硬编码sudo密码,执行sudo登录操作后,我想在linux box中执行一些操作,这就是我需要帮助的地方