如何设置密码来在 Linux 中执行命令或脚本?
我需要避免未经授权的用户使用/执行脚本(其中包含用户和密码详细信息)。那么有没有办法设置密码来执行特定的脚本。
答案1
须藤也许是可行的办法。
让您的脚本拥有者并可由特定用户执行,并且不允许其他用户访问,例如 700 权限。
其次,使用编辑 sudoers 文件visudo
并添加一行,如下所示:
%your_group ALL=path_to_script/script
所有能够运行该脚本的用户都必须添加到 your_group 中。
因此,不属于 your_group 的人将无法运行该脚本。另一种方法是您仅指定用户名。
username ALL=path_to_script/script
答案2
您需要确保密码只有授权用户才能读取。不要将密码存储在脚本中,而是将其存储在您从脚本中读取的单独文件中。通过这种方式管理权限要容易得多。如果您将凭据存储在脚本中,则很难确定它们最终会在哪里:它们可能会无意中被复制,它们应该输入到版本控制中,等等。
将凭证与脚本分离还有第二个而且可以说是更重要的好处。它将“执行脚本的权限”与“访问资源的权限”分开,这很好,因为您并不是真正试图阻止人们执行您的脚本,而是试图阻止人们访问资源。因此,相应地设置密码文件的权限,就可以了。
管理权限的简单方法是创建一个组并将有权访问资源的用户放入该组中。我们将该组称为 group seniors
,并允许用户alice
和bob
访问该资源。创建一个名为seniors
(例如)的组addgroup seniors
,并将用户添加到该组(例如adduser alice seniors; adduser bob seniors
)。使密码文件归该组所有seniors
并且只能由该组读取。
chgrp seniors password.txt
chmod u=rw,g=r,o= password.txt # or chmod 640 password.txt for short
也许您希望某些用户能够执行脚本,但不能任意访问资源。您在问题中没有提到这一点,但我会解释如何做到这一点,以防万一。
假设用户charlie
必须dominique
能够执行该特定脚本,但不能以其他方式访问该资源。创建一个名为 的组juniors
并将这些用户放入该组。 (您实际上不需要创建组,但它使管理更容易。)须藤该规则允许组内的用户juniors
获得该组的权限seniors
,但只能执行一个特定的程序——读取密码文件的脚本。运行visudo
以将此行添加到sudoers
文件中:
%juniors ALL = (:seniors) /path/to/script ""
后辈可以通过调用 来执行脚本sudo -g seniors /path/to/script
。然后该脚本将使用该组授予的附加权限运行seniors
。尽管如此,调用的用户sudo
将无法访问密码文件(除非脚本有错误并且可能被欺骗而泄露)。
再次注意,sudo 仅当您需要某些人能够在不知道密码的情况下访问资源时才有用。如果您只想限制某些用户对密码的访问,并且不允许其他人访问该资源,那么它不会为您做任何事情。
答案3
感谢那些回复的人。我实现的最终答案是......我在本网站的其他地方找到了一个将密码与 /etc/shadow 进行比较的例程。
因为我使用的是图形界面,所以我使用 zenity 来提示输入密码。由于自动登录,RPi 上的人不知道他们的密码。输入密码后,将使用用户帐户中的盐将其转换为哈希值,并将生成的哈希值与原始哈希值进行比较。如果它们相同,则运行终端程序。
如果按下 zenity 取消按钮或输入不正确的密码,则不会发生任何情况。
为了运行需要 grep /etc/shadow 文件权限的脚本,我在 /etc/sudoers.d/myfile = UserA ALL=(ALL) NOPASSWD: /opt/myFiles/startTerminal.sh 中有一个条目
脚本是:
USERNAME=UserA
PASSWD=$(zenity --forms --title=" " \
--text="Enter Password" \
--add-password="" )
if [[ $? -eq 0 ]]; then
export PASSWD
ORIGPASS=`grep -w "$USERNAME" /etc/shadow | cut -d: -f2`
export ALGO=`echo $ORIGPASS | cut -d'$' -f2`
export SALT=`echo $ORIGPASS | cut -d'$' -f3`
GENPASS=$(perl -le 'print crypt("$ENV{PASSWD}","\$$ENV{ALGO}\$$ENV{SALT}\$")')
if [ "$GENPASS" == "$ORIGPASS" ]; then
/usr/bin/lxterminal &
exit 0
fi
fi