Shell script - Sudo-permissions lost over time

2020-02-03 09:09发布

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 sleep occurs. Not good for me:

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 sleep with 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?

Thanks

6条回答
Fickle 薄情
2楼-- · 2020-02-03 09:25

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.

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 startsudo before 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 stopsudo kills the loop, clears the signal trap, and invalidates the earlier authentication with 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.

查看更多
走好不送
3楼-- · 2020-02-03 09:25

Get root privileges once for all:

sudo su -
# What I need to do with root 
查看更多
放我归山
4楼-- · 2020-02-03 09:26

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

Defaults timestamp_timeout=#Number of minutes

But it is much easier to run

sudo ./worker.sh
查看更多
5楼-- · 2020-02-03 09:32

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

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!).

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
查看更多
萌系小妹纸
6楼-- · 2020-02-03 09:38

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)
查看更多
贪生不怕死
7楼-- · 2020-02-03 09:43

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
查看更多
登录 后发表回答