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


21

数据

  • 我希望操作员用户在此计算机上安装自己的CIF共享
  • 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 ¹没有把shsudoers的文件,也没有建立一个永久/临时文件???

注意1:请不要使用python,perl,C,Go,...?
注意2:我知道我可以通过sudoers文件删除密码,但是我试图加强安全性,而不是放松安全性,而又不放弃便利性...


2
怎么printf "%s\n" "$szPassword" "$szPassword" | sudo -S mount -t cifs / ...
muru 2015年

现在尝试!@Muru
Fabby 2015年

Answers:


24

您应该改为让用户使用sudo作为调用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

不要试图捕获用户密码。


1
也许我遗漏了一些东西,但是您能解释一下如何将密码提示的数量从两个减少到一个吗?否则,我看不出这如何回答问题。
Oliphaunt-恢复莫妮卡2015年

@Oliphaunt我看不到两个密码提示,您能解释一下吗?另外,这个答案不是OP想要的,而是它需要的。当您需要以root用户身份运行命令以及其他实用程序的工作方式(检查是否为root用户,否则请纾困)时,这是一种清洁且正确的解决方案
Braiam 2015年

1
OP的问题(据我所知)是提示用户输入密码sudo,然后提示(成功进行身份验证)mount。在他们的用例中,这些密码是相同的,因此我可以了解为什么OP希望用户只需要输入一次该密码。我不认为您的解决方案有帮助。我确实同意不应捕获密码。
Oliphaunt-恢复莫妮卡2015年

谢谢,但是我可能会稍微简化一下这个问题:它已经是一个脚本,已经包含该测试(除外1>&2),位于自动启动中,它以前只是一个cifs共享,但是现在是三个,所以实际上是一个密码是必需的。 (它已经包含该测试,以防其他人(而不是操作员组的成员)尝试运行该测试)
Fabby 2015年

@Fabby我仍然认为您无法正确解决该问题。对于这些情况~/.smbcredentials,即使没有sudo(如果使用gvfs,umount或polkit),也可以使用助手来安全地“记住” CIFS / SMB共享的密码(例如,进行编辑)。
Braiam

7

我好笨!

以下脚本:

#!/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. 无需授予额外的特权。 :-)

1
1个问题:是否将命令回显到进程列表中?
Rinzwind

3
@Rinzwind是内置的,不应放在bash或zsh中。但是,mount命令可以。
muru

<<<也可以代替printf ,但更好的方法是将其read全部删除,然后全部使用sudo --stdin。诸如“ $ printf "Type out your password\n" && sudo --stdin apt-get update 用户”之类的内容仍可以输入sudo密码。并且不会将其放入进程列表中。但是,当然还有无限可能的其他安全问题,例如键盘记录程序,中的潜在漏洞sudo以及等等,等等,以及无限发展
Sergiy Kolodyazhnyy

@SergiyKolodyazhnyy:随时编辑,伙计!
Fabby

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=*

@Fabby抱歉,这有什么危险呢?另外,我不确定是否暗示有讽刺意味。
Oliphaunt-恢复莫妮卡2015年

好吧,即使sudo不需要密码,挂载可能仍然需要密码。/ etc / sudoers文件可用于仅使sudo不需要密码。这不会影响mount是否要求输入密码。如果一个人无法挂载,那么sudo只会运行失败的命令,这可能不是问题。
TOOGAM 2015年

@TOOGAM那是我的意图。一个密码,而不是两个。
Oliphaunt-恢复莫妮卡2015年

我的意图是在sudoers文件中保留一个“操作员”组,因此,如果操作员尝试装载自己的东西,他们仍然必须输入密码,但是要装载“标准”操作员装载,他们只需键入密码一次而不是5次...但是您的解决方案可能对其他人有用,因此被投票...(并删除了原始注释)
Fabby 2015年

1

这些问题的一般解决方案是将以下序言放在需要脚本的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运行,那么这里的特权就不必要了。

无论如何,以为我会分享这个小技巧。最好的事情是,如果您已经是有效的uid根用户(例如,如果您已经在sudo下调用了它),它就可以正确地执行操作。也给出错误并强迫您重新键入/重新运行(使用sudo)不太友好。

您可能还需要检出timestamp_timeout变量,man 5 sudoers该变量告诉sudo您在有限的分钟内(并且可以是分数)记住用户凭据。


我过分简化了脚本,以得到一个简单的答案:该脚本已包含: #test if root: if not: bail out if [[ $EUID -ne 0 ]]; then echo "This script must be run as root, use sudo "$0" instead" 1>&2 exit 1 fi 重点是它还包含多个具有相同密码的安装文件(再次:已删除),但还是要感谢...
Fabby 2015年

1
关键是上述解决方案只需要输入一种密码(对于sudo)。它不需要其他任何内容。另外,对于所有类似的问题,即使它们需要多个(两个以上)特权命令,它也是通用的(比给出错误并必须使用sudo重新键入命令更优雅)。
arielf

应该,但它;-)这是因为每个cifs共享挂载也需要密码。(因为它可以与Ubuntu密码不同,但是在这种情况下不是因为操作员保持Windows和Ubuntu密码同步)
Fabby 2015年
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.