【问题标题】:How to pass the password to su/sudo/ssh without overriding the TTY?如何在不覆盖 TTY 的情况下将密码传递给 su/sudo/ssh?
【发布时间】:2010-09-18 23:50:15
【问题描述】:

我正在编写一个 C Shell 程序,它将执行 susudossh。他们都希望在控制台输入(TTY)而不是标准输入或命令行中输入密码。

有人知道解决办法吗?

设置无密码sudo 不是一种选择。

可能是一个选项,但它不存在于我的精简系统中。

【问题讨论】:

标签: expect linux ssh passwords sudo su


【解决方案1】:

对于 sudo,有一个 -S 选项用于接受来自标准输入的密码。这是男人的条目:

    -S          The -S (stdin) option causes sudo to read the password from
                the standard input instead of the terminal device.

这将允许您运行如下命令:

echo myPassword | sudo -S ls /tmp

至于 ssh,我已经做了很多尝试来自动化/脚本化它的使用,但没有成功。似乎没有任何内置方法可以在不提示的情况下将密码传递给命令。正如其他人所提到的,“expect”实用程序似乎旨在解决这一难题,但最终,设置正确的私钥授权是尝试自动执行此操作的正确方法。

【讨论】:

  • 幸运的是,Ruby 有一个内置的 SSH 客户端,允许您指定密码。你可以试试 ruby​​ -e "require 'net/ssh' ; Net::SSH.start('example.com', 'test_user', :password => 'secret') do |ssh| puts 'Logged in successfully' ; while cmd=gets ; puts ssh.exec!(cmd) ; end end"
  • 我讨厌在这里成为派对的大便者,但这样做会使您的密码显示在进程列表中。我试图确定一种更好的方法,偶然发现了这篇文章,很惊讶没有人指出它。很好的解决方案,但要注意风险。
  • 关于ssh,你试过在连接字符串中传递密码吗?喜欢nonroot:yourpassword@hostname.com?当然,如果您使用密钥身份验证和密钥管理器,事情会容易得多。
  • 避免密码出现在进程列表或日志文件中,方法是把它放在一个文件中并使用cat; 'cat pw | sudo -S <command>,以及后来的rm pw
  • 另一种方法是使用 netcat 并通过套接字传递密码 - nc -l 12345 | sudo -S <command>。在发送方; echo myPassord | nc <target> 12345。这只是将密码处理问题转移到了主控制台,您可以在其中有更多选择。
【解决方案2】:

我编写了一些 Applescript,它通过对话框提示输入密码,然后构建了一个自定义 bash 命令,如下所示:

echo <password> | sudo -S <command>

我不确定这是否有帮助。

如果 sudo 接受预先加密的密码,那就太好了,这样我就可以在我的脚本中对其进行加密,而不必担心回显明文密码。但是,这对我和我的情况都有效。

【讨论】:

    【解决方案3】:

    对于ssh,您可以使用sshpasssshpass -p yourpassphrase ssh user@host

    你只需要先下载 sshpass :)

    $ apt-get install sshpass
    $ sshpass -p 'password' ssh username@server
    

    【讨论】:

      【解决方案4】:

      对于 sudo,您也可以这样做:

      sudo -S <<< "password" command
      

      【讨论】:

        【解决方案5】:

        我有:

        ssh user@host bash -c "echo mypass | sudo -S mycommand"
        

        为我工作。

        【讨论】:

        • 对我不起作用。仍然 ssh 提示输入密码。
        • 太好了,终于可以用了!谢谢。我在启动 ssh 会话并将 sudo 命令传递给客户端的 bash 脚本中使用它。我的脚本有解析为: ssh -t username@hostname bash -c "sudo echo fartjuice"
        【解决方案6】:

        此问题的通常解决方案是设置一个帮助应用程序来执行需要超级用户访问权限的任务: http://en.wikipedia.org/wiki/Setuid

        Sudo 不适合离线使用。

        稍后编辑:SSH 可以与私钥-公钥身份验证一起使用。如果私钥没有密码,则无需提示输入密码即可使用 ssh。

        【讨论】:

          【解决方案7】:

          这可以通过在您要连接的目标主机上设置公钥/私钥来完成。 第一步是为在本地主机上运行脚本的用户生成一个 ssh 密钥,方法是:

          ssh-keygen
          Enter file in which to save the key (/home/myuser/.ssh/id_rsa): <Hit enter for default>
          Overwrite (y/n)? y
          

          然后输入一个空白密码。之后,将您的 ssh 密钥复制到您将要连接的目标主机上。

          ssh-copy-id <remote_user>@<other_host>
          remote_user@other_host's password: <Enter remote user's password here>
          

          注册 ssh 密钥后,您将能够从本地主机执行静默 ssh remote_user@other_host

          【讨论】:

            【解决方案8】:

            也许你可以使用expect 命令?:

            expect -c 'spawn ssh root@your-domain.com;expect password;send "your-password\n";interact
            

            该命令自动提供密码。

            【讨论】:

            • 看起来不错,但是如何在没有root权限的机器上启用expect命令?
            • @Radon8472 如果您没有安装权限,可执行文件可能会添加到 ~/bin。如果您的系统没有自动将 ~/bin 添加到您的 PATH 中,您可以使用 export PATH="$PATH:~/bin" 手动添加,或者将该命令添加到您的配置文件以自动添加。如果您不想更改 PATH,可以改为使用其绝对路径执行命令:~/bin/expect [arguments] 请务必记住设置其可执行位:chmod +x ~/bin/expect跨度>
            【解决方案9】:

            如果没有更好的选择(如其他人所建议的那样),那么 man socat 可以提供帮助:

               (sleep 5; echo PASSWORD; sleep 5; echo ls; sleep 1) |
               socat - EXEC:'ssh -l user server',pty,setsid,ctty
            
                      EXEC’utes an ssh session to server. Uses a pty for communication
                      between socat and ssh, makes it ssh’s  controlling  tty  (ctty),
                      and makes this pty the owner of a new process group (setsid), so
                      ssh accepts the password from socat.
            

            所有 pty、setsid、ctty 的复杂性都是必要的,虽然您可能不需要睡觉那么久,但您需要睡觉。 echo=0 选项也值得一看,在 ssh 的命令行上传递远程命令也是如此。

            【讨论】:

            • 这实际上也适用于susu 没有 -S (stdin) 选项。
            • 是否可以避免睡觉而改用更可靠的东西?
            【解决方案10】:

            看看expect linux 实用程序。

            它允许您根据标准输入上的简单模式匹配将输出发送到标准输出。

            【讨论】:

              【解决方案11】:
              ssh -t -t me@myserver.io << EOF
              echo SOMEPASSWORD | sudo -S do something
              sudo do something else
              exit
              EOF
              

              【讨论】:

              • 如果您可以使用 ssh 密钥作为用户登录,对于 sudo 访问就可以了:ssh -t user@host "echo mypassword | sudo -S sudocommand"
              【解决方案12】:

              为公钥身份验证设置 SSH,密钥上没有密码。网络上的大量指南。那时您不需要密码即可登录。然后,您可以根据客户端主机名限制密钥的连接。提供合理的安全性,非常适合自动登录。

              【讨论】:

                【解决方案13】:

                更好的sshpass 替代方案是:passh https://github.com/clarkwang/passh

                登录远程服务器

                 $ passh -p password ssh user@host
                

                在远程服务器上运行命令

                 $ passh -p password ssh user@host date
                

                其他传递密码的方法

                -p 密码(默认:`password')

                -p env:从环境变量中读取密码

                -p 文件:从文件中读取密码

                here我解释了为什么它比 sshpass 和其他解决方案更好。

                【讨论】:

                  【解决方案14】:

                  还可以传递各种参数,如下:

                  echo password | echo y | sudo -S pacman -Syu

                  (虽然这是个坏主意,但这只是一个例子)

                  【讨论】:

                    【解决方案15】:
                    echo <password> | su -c <command> <user> 
                    

                    这是有效的。

                    【讨论】:

                    • 这是 Fedora 中唯一适合我的。人们仅仅因为他们不适合他们的情况而对答案投反对票?
                    • "su: 必须从终端运行" (RPi1B, Raspbian)
                    • 不幸的是,这在su 的最新版本中没有,而是从 stdio 读取密码。
                    【解决方案16】:

                    我遇到了同样的问题。用于在远程 PC 上创建目录的对话框脚本。 与 ssh 的对话很容易。我使用 sshpass(之前安装的)。

                       dialog --inputbox "Enter IP" 8 78 2> /tmp/ip
                    
                       IP=$(cat /tmp/ip)
                    
                    
                       dialog --inputbox "Please enter username" 8 78 2> /tmp/user
                    
                       US=$(cat /tmp/user)
                    
                    
                       dialog --passwordbox "enter password for \"$US\" 8 78 2> /tmp/pass
                    
                       PASSWORD = $(cat /tmp/pass)
                    
                    
                       sshpass -p "$PASSWORD" ssh $US@$IP mkdir -p /home/$US/TARGET-FOLDER
                    
                    
                       rm /tmp/ip
                    
                       rm /tmp/user
                    
                       rm /tmp/pass
                    

                    来自德国的问候

                    提图斯

                    【讨论】:

                      【解决方案17】:

                      基于@Jahid 的回答,这在 macOS 10.13 上对我有用:

                      ssh <remote_username>@<remote_server> sudo -S <<< <remote_password> cat /etc/sudoers
                      

                      【讨论】:

                        【解决方案18】:

                        我曾经有一个用例,我需要在同一个命令中运行 Sudo 和 ssh,而不需要 stdin 指定所有需要的变量。

                        这是我使用的命令

                        echo sudopassword | sudo -S -u username sshpass -p  extsshpassword ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no  username@ipaddress " CMD on external machine"
                        

                        将该命令分解成碎片!

                        这将允许您使用超级用户通过您的机器运行命令:

                        echo password | sudo -S -u username
                        

                        这将允许您传递 ssh 密码并在外部机器上执行命令:

                        sshpass -p  sshpassword  ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no  username@ipaddress " CMD on external machine"
                        

                        确保在您的机器上安装了 sudo 和 openssh 软件包。

                        【讨论】:

                          【解决方案19】:

                          一种方法是使用 read -s 选项 .. 这样密码字符就不会回显到屏幕上。我为一些用例编写了一个小脚本,您可以在我的博客中看到它: http://www.datauniv.com/blogs/2013/02/21/a-quick-little-expect-script/

                          【讨论】:

                            【解决方案20】:

                            使用:

                            echo password | sudo command
                            

                            例子:

                            echo password | sudo apt-get update; whoami
                            

                            希望对你有帮助..

                            【讨论】:

                              【解决方案21】:

                              您可以提供密码作为期望脚本的参数。

                              【讨论】:

                                【解决方案22】:
                                su -c "Command" < "Password"
                                

                                希望对你有所帮助。

                                【讨论】:

                                • 不是。 “su: must be run from a terminal”就是这个问题的答案。
                                猜你喜欢
                                • 1970-01-01
                                • 2016-07-22
                                • 1970-01-01
                                • 1970-01-01
                                • 2018-09-11
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                相关资源
                                最近更新 更多