如何在需要 sudo 的 bash 脚本中仅输入一次密码

如何在需要 sudo 的 bash 脚本中仅输入一次密码

数据

  • 我希望这台机器上的操作员用户安装他们自己的 cifs 共享
  • sudoers文件已包含/bin/mount -t cifs //*/* /media/* -o username=*所有操作员的命令
  • 我希望用户cifs通过脚本挂载共享时只需输入一次密码,而不是两次。
  • sudo 密码和 cifs 密码相同。

我已经拥有的

该脚本有效:

#!/bin/bash
sudo 'mount -t cifs //192.168.1.1/home /media/$USER/home -o username=$USER'

...但它要求用户输入两次相同的密码!

  • 一次sudo
  • 一次用于坐骑本身

这也行得通:

#!/bin/bash
echo -n Password: 
read -s szPassword
echo $szPassword | sudo -S sh -c 'echo $szPassword | mount -t cifs //192.168.1.1/home /media/$USER/home -o username=$USER'

...但这需要我允许所有操作员用户能够sudo sh(重大安全问题)

问题

如何挂载 cifs 共享在 bash 中¹ 无需sh放入sudoers文件也没有创建永久/临时文件???

注1:请不要使用 python、perl、C、Go 等吗?
笔记2:我知道我可以通过文件删除密码sudoers,但是我正在尝试加强安全,而不是放松安全,同时又不放弃便利......

答案1

您应该让用户使用 sudo as 进行调用sudo script。只需检查脚本是否以 root 身份运行,如果没有,则要求它

if [[ $EUID -ne 0 ]]; then
   echo "This script must be run as root, use sudo "$0" instead" 1>&2
   exit 1
fi

不要试图获取用户的密码。

答案2

我很笨!

以下脚本:

#!/bin/bash
read -p "Password: " -s szPassword
printf "%s\n" "$szPassword" | sudo --stdin mount -t cifs //192.168.1.1/home /media/$USER/home -o username=$USER,password="$szPassword"

正常运行并且:

  1. 不创建任何包含密码的文件
  2. 允许用户为多个共享(包括 Windows 共享)仅输入一个密码
  3. 无需授予额外特权。 :-)

答案3

执行此命令不需要sudo密码;密码提示仍然mount存在。

sudoers,包括类似

ALL        ALL = NOPASSWD: /bin/mount -t cifs //*/* /media/* -o username=*

包含此项后,sudo将不再要求为此特定命令输入密码;用户仍然需要向该mount命令提供密码。

笔记:我逐字逐句地从您在问题中包含的内容中获取了该命令;我没有检查其通配符是否会允许用户执行恶意操作。请阅读sudoers手册页以了解恶意操作的示例。 特别要注意的是,此行sudoers允许用户-o向中添加任意数量的开关或其他参数mount 您可能需要重新考虑您的方法,例如通过添加 @Braiam 建议的脚本并允许在无需额外身份验证的情况下运行该脚本。然后,该脚本可确保用户只能运行您希望他们运行sudo的特定形式。mount

此外,除了允许所有用户使用此功能外,您还可以将其限制为特定组的成员,例如,您可以创建一个组cifsmount,然后

%cifsmount ALL = NOPASSWD: /bin/mount -t cifs //*/* /media/* -o username=*

答案4

解决这些问题的一般方法是将以下序言放在需要 sudo 的脚本的顶部:

#!/bin/bash
case $EUID in
   0) : cool we are already root - fall through ;;
   *) # not root, become root for the rest of this session
      # (and ask for the sudo password only once)
      sudo $0 "$@" ;;
esac
# now the present process is effective-UID  (root)
# so there's no need to put sudo in front of commands

any more commands here will run as superuser ...

显然,这有一个缺点,如果脚本中的某些命令不需要sudo运行,那么这里就会出现不必要的权限提升。

无论如何,我想分享这个小技巧。最棒的是,如果你已经是有效用户 ID 根 (例如,如果你已经在 sudo 下调用它),它会优雅地做正确的事情。此外,给出错误并强迫你重新输入/重新运行 (使用 sudo) 不太友好。

您可能还想检查一下其中的timestamp_timeout变量,man 5 sudoers它告诉sudo在有限的几分钟内记住用户凭据(可以是小数)。

相关内容