bash Shell 脚本 - Sudo 权限随着时间的推移而丢失

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5866767/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 23:55:26  来源:igfitidea点击:

Shell script - Sudo-permissions lost over time

bashshellubuntusudo

提问by Industrial

I've made a simple bash script that need to keep it's super-user privileges throughout the script. Unfortunately, but understandable the script looses its sudo-eleveted permissions when the sleepoccurs. Not good for me:

我制作了一个简单的 bash 脚本,需要在整个脚本中保持超级用户权限。不幸的是,但可以理解的是,脚本会sudosleep发生这种情况时失去其提升的权限。对我不好:

sudo echo "I am sudo!" # Asks for passwords
sleep(60)
sudo echo "I am sudo!" # Need to enter password again.

I thought about replacing the sleepwith a while-loop that keeps the sudo alive, but I am pretty sure that there's better options available to make the sudo-permissions stay throughout the script?

我想sleep用一个使 sudo 保持活动的 while 循环替换,但我很确定有更好的选项可以使sudo-permissions 在整个脚本中保持不变?

Thanks

谢谢

回答by sehe

The flexibility of sudo is widely under-estimated. This leads to very poor practices (like the sudo su -canon-ball surgery method).

sudo 的灵活性被广泛低估。这会导致非常糟糕的做法(如sudo su -炮弹手术方法)。

A much better method is to specificly allow the commands you intend to allow without use of a password:

更好的方法是在不使用密码的情况下专门允许您打算允许的命令

phill = NOPASSWD: /bin/ls, /usr/bin/lprm


You can optionally do this for specific users from specific hosts running as specific admin users. You can even prevent users from passing shell escapes as parameters. You can make sudo prevent the launched program to execute further applications dynamically etc. etc. You will want to read the man-page for sudoers (and be sure to read the procedures for editing this special file!).

您可以选择为来自作为特定管理员用户运行的特定主机的特定用户执行此操作。您甚至可以阻止用户将 shell 转义作为参数传递。您可以使 sudo 阻止启动的程序动态执行其他应用程序等等。您将需要阅读 sudoers 的手册页(并确保阅读编辑此特殊文件的过程!)

Here is a small taste of things, (from here):

这是一些小东西,(来自这里):

User_Alias     OPERATORS = joe, mike, jude
Runas_Alias    OP = root, operator
Host_Alias     OFNET = 10.1.2.0/255.255.255.0
Cmnd_Alias     PRINTING = /usr/sbin/lpc, /usr/bin/lprm

OPERATORS ALL=ALL
#The users in the OPERATORS group can run any command from any terminal.

linus ALL=(OP) ALL
# The user linus can run any command from any terminal as any user in the OP group (root or operator).

user2 OFNET=(ALL) ALL
# user user2 may run any command from any machine in the OFNET network, as any user.

user3 ALL= PRINTING
# user user3 may run lpc and lprm from any machine.

go2linux ALL=(ALL) ALL
# user go2linux may run any command from any machine acting as any user. (like Ubuntu)

 If you want not to be asked for a password use this form
go2linux ALL=(ALL) ALL NO PASSWD: ALL

回答by Timofey Stolbov

You can adjust this timeout by adding to /etc/sudoers

您可以通过添加到 /etc/sudoers 来调整此超时

Defaults timestamp_timeout=#Number of minutes

But it is much easier to run

但是跑起来容易多了

sudo ./worker.sh

回答by karl

Here's a workaround:

这是一个解决方法:

sudo echo "I am sudo!" # Asks for passwords
( while true; do sudo -v; sleep 40; done ) &   # update the user's timestamp
sudoPID=$!
# ...
sleep(60)
sudo echo "I am sudo!" # Need to enter password again.
kill -TERM $sudoPID
sudo -k  # invalidate the user's timestamp at end of script (does not require a password)

回答by Mark Haferkamp

Working strictly within a script (and not editing the sudoers file or calling the script via sudo ./script.sh), here's what I think the cleanest method is.

严格在脚本内工作(而不是编辑 sudoers 文件或通过 调用脚本sudo ./script.sh),这是我认为最干净的方法。

startsudo() {
    sudo -v
    ( while true; do sudo -v; sleep 50; done; ) &
    SUDO_PID="$!"
    trap stopsudo SIGINT SIGTERM
}
stopsudo() {
    kill "$SUDO_PID"
    trap - SIGINT SIGTERM
    sudo -k
}

Basically, this defines a pair of functions for enabling and disabling sudo mode. Calling startsudobefore running your sudo-using code authenticates with sudo, forks a background sudo-refreshing loop, saves the loop's PID, and sets a signal trap to stop sudo mode when Ctrl+C is pressed. Calling stopsudokills the loop, clears the signal trap, and invalidates the earlier authentication with sudo.

基本上,这定义了一对用于启用和禁用 sudo 模式的函数。startsudo在运行使用 sudo 的代码之前调用使用 sudo 进行身份验证,分叉后台 sudo 刷新循环,保存循环的 PID,并设置信号陷阱以在按下 Ctrl+C 时停止 sudo 模式。调用会stopsudo终止循环,清除信号陷阱,并使之前使用 sudo 的身份验证无效。

After copying these functions into your script, use them like this.

将这些函数复制到脚本中后,像这样使用它们。

startsudo
echo "Sudo mode is active."
# whatever you want to do with sudo
stopsudo

I would like to thank @karl for the simplicity of inlining the sudo-refreshing loop and @sehe for pointing out that a signal trap should be used to kill the loop if it isn't killed normally. Both of these ideas improved my btrfs backup script, which uses a sudo-refreshing loop to avoid re-prompting the user after a subvolume's backup takes longer than sudo's timeout.

我要感谢 @karl 简单地内联 sudo-refreshing 循环和 @sehe 指出如果循环没有正常终止,应该使用信号陷阱来终止循环。这两个想法都改进了我的 btrfs 备份脚本,它使用 sudo 刷新循环来避免在子卷的备份时间超过 sudo 超时后重新提示用户。

回答by ydk2

This my way:

这是我的方式:

#!/bin/sh
echo "Working..."
# add you pass
echo "yourpass" >> file.pass ;sleep 5 
# Check if root
if [ `cat file.pass | sudo -S su root -c whoami` != "root" ]; then
echo "Not running as root. Exiting..."
sleep 2
echo "Cleaning..."
sleep 1
srm file.pass
echo "Cleaned"
exit 0
else
echo "Running as root. Good"
sleep 2
# and run any sudo with
cat file.pass | sudo -S su root -c ls #<any command>
fi

sleep 5
echo `cat file.pass | sudo -S su root -c whoami` "say bay bay"
# if pass no longer need
srm file.pass
echo "End session :)"
exit 0

回答by Quentin

Get root privileges once for all:

一劳永逸地获得root权限:

sudo su -
# What I need to do with root