让用户仅使用GUI(隐藏终端)为bash脚本输入密码的正确方法


8

我制作了一个bash脚本,专门使用kdialog与用户进行交互。它是从“ .desktop”文件启动的,因此用户永远不会看到终端。它看起来100%像一个GUI应用程序(即使它只是一个bash脚本)。它仅在KDE(Kubuntu 12.04)中运行。

我唯一的问题是安全,方便地处理密码输入。我找不到令人满意的解决方案。

该脚本旨在以普通用户身份运行,并在首次需要sudo命令时提示输入密码。这样,大多数不需要sudo权限的命令都以普通用户身份运行。发生的情况(从终端运行脚本时)是提示用户输入一次密码,并且默认的sudo超时允许脚本完成,包括所有其他sudo命令,而无需再次提示用户。这也是我希望它也可以在GUI后运行的方式。

主要问题是使用kdesudo启动我的脚本(这是标准的GUI方式)意味着整个脚本由root用户执行。因此,文件所有权分配给了根用户,我不能~/在路径中依赖它,而其他许多事情都不理想。以root用户身份运行整个脚本只是一个非常不令人满意的解决方案,我认为这是一个不好的做法。

我非常感谢让用户通过GUI一次输入sudo密码而不以root身份运行整个脚本的任何想法。谢谢。

Answers:


14

-Asudo的选项允许你指定一个辅助程序(在SUDO_ASKPASS变量),将要求输入密码。

创建一个脚本询问密码(myaskpass.sh):

#!/bin/bash
zenity --password --title=Authentication

然后在脚本的开头插入以下行:

export SUDO_ASKPASS="/path/to/myaskpass.sh"

并用替换所有出现的sudo <command>情况:

sudo -A <command>

您可以使用所需的任何密码询问程序来代替zenity。我必须将其封装在脚本中,因为SUDO_ASKPASS必须指向文件,因此它不适用于--password所需的选项zenity

如果它是从命令行运行的,或者在文件管理器中双击脚本文件后选择在终端中运行,则上述命令的工作原理就像一个超级按钮。但是,如果您选择运行或尝试从.desktop文件启动它,则每个命令sudo都会要求再次输入密码。


如果您根本不需要终端窗口,则可以将密码存储在变量中,然后将其输送到sudo -S。也许有一些安全问题,但是我认为这很安全(请阅读有关此答案的评论)。

在脚本的开头插入以下行:

PASSWD="$(zenity --password --title=Authentication)\n"

并用替换所有出现的sudo <command>情况:

echo -e $PASSWD | sudo -S <command>

谢谢。那很有趣。但是,使用此方法时,通常的sudo超时(例如15分钟)会丢失。我的脚本具有50多个sudo命令,现在提示输入用户密码50次以上!我在Google上搜索了一下,但没有找到解决方案。你认识一个吗
MountainX

感谢更新。您建议的替代方法是出于安全方面的考虑而已被我排除在外,但从阅读您提供的链接上的评论后,我认为它可能已经足够安全了。这是解决问题的简便方法。谢谢。
MountainX

在我的系统上进行测试必须是sudo -s(小写s),而不是sudo -S(大写s)。
WinEunuuchs2Unix

0

这是基于Eric Carvalho的出色回答。我将其发布以详细说明我遇到的问题。具体来说,使用此方法时,通常的sudo超时(例如15分钟)会丢失。我的脚本(包含50多个sudo命令)现在提示输入用户密码50次以上!

这是解决方案所有部分的完整工作示例。它由bash脚本,Eric建议的“ myaskpass”脚本和“ .desktop”文件组成。整个过程应该是100%GUI(完全没有终端交互),因此.desktop文件至关重要(afaik)。

$ cat myaskpass.sh 
#!/bin/bash
kdialog --password "Please enter your password: "
exit 0


$ cat askpasstest1.desktop 
#!/usr/bin/env xdg-open
[Desktop Entry]
Comment=SUDO_ASKPASS tester1
Exec=bash /home/user/test/askpasstest1.sh
GenericName=SUDO_ASKPASS tester1
Name=SUDO_ASKPASS tester1
NoDisplay=false
Path[$e]=
StartupNotify=true
Terminal=false
TerminalOptions=
Type=Application
Categories=Application;Utility;
X-KDE-SubstituteUID=false
X-KDE-Username=

还有测试脚本本身。使用此解决方案时,此用户将两次询问您的密码。(通常,由于默认的sudo超时,它只会询问一次。)

#!/bin/bash

sudo -k
SUDO_ASKPASS="/home/user/test/myaskpass.sh" sudo -A touch filemadeas_askpass1
touch filemadeas_regularuser1
SUDO_ASKPASS="/home/user/test/myaskpass.sh" sudo -A touch filemadeas_askpass2
touch filemadeas_regularuser2
ls -la filemadeas* > /home/user/test/fma.log
kdialog --title "Files Created" --textbox /home/user/test/fma.log 640 480
sudo rm filemadeas_*
rm fma.log

exit 0

从命令行运行此脚本,仅询问一次密码。从GUI运行(在文件管理器中单击.desktop或.sh),都会sudo -A重新输入密码。我会尝试解决这个问题。
埃里克·卡瓦略

我刚刚更新了答案。
埃里克·卡瓦略

埃里克(Eric)...您找到解决问题的方法了吗?
安东尼

0

以下脚本通过命令行,桌面文件或双击运行,仅要求输入一次密码,并且命令模式sudo -Sp '' <your command here> <<<${sudo_password}可在文件中的任何位置多次使用:

    # get sudo password
    sudo_password=$( gksudo --print-pass --message="Provide permission to make system changes: Type your password or press Cancel." -- : 2>/dev/null )
    # check for null entry or cancellation
    if [[ ${?} != 0 || -z ${sudo_password} ]]
    then
        exit 4
    fi
    if ! sudo -kSp '' [ 1 ] <<<${sudo_password} 2>/dev/null
    then
        exit 4
    fi
    # command
    sudo -Sp '' gedit "/etc/hosts" <<<${sudo_password}
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.