2011-05-03 41 views
7

我做了一個簡單的bash腳本,需要在整個腳本中保持超級用戶權限。不幸的是,當sleep發生時,該腳本丟失了它的sudo擴展權限。對我不好:Shell腳本 - Sudo權限隨時間流逝

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

我想到了一個while循環,保持須藤活着更換sleep,但我敢肯定,有更好的選擇,能夠充分利用本sudo -permissions留在整個腳本?

感謝

+2

爲什麼不讓用戶運行'sudo'? – CharlesB 2011-05-03 08:22:28

回答

10

sudo的靈活性被廣泛低估。這導致很差的做法(如sudo su - canon-ball手術方法)。

一個更好的方法是specificly允許你打算讓無需使用密碼的命令:

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

您可以選擇從特定的主機特定用戶運行做到這一點作爲特定的管理用戶。您甚至可以阻止用戶將shell轉義作爲參數傳遞。您可以讓sudo阻止啓動的程序動態執行更多應用程序等。您將需要read the man-page for sudoers (and be sure to read the procedures for editing this special file!)

這裏是東西小情趣,(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 
5

您可以通過添加到/ etc調整此超時/ sudoers文件

Defaults timestamp_timeout=#Number of minutes 

但是它是非常容易運行

sudo ./worker.sh 
4

這裏有一個解決方法:

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) 
+2

如果你打算這樣破解,至少要確保kill和'sudo -k'在腳本中註冊爲信號陷阱。這是要求大的安全漏洞。 (用Ctrl-C中止腳本,sudo默默無聲地保持活動狀態) – sehe 2011-05-03 09:41:15

0

取得root特權一次:

sudo su - 
# What I need to do with root 
2

這是我的方式:

#!/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 
+1

這看起來像一個有效的答案,但將用戶的密碼保存到文件似乎相當不安全。另外,'srm'命令是做什麼的?我的Linux發行版沒有它。 – 2015-05-30 13:10:00

2

工作嚴格意義上的腳本中(而不是編輯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 
} 

基本上,它定義了一對函數來啓用和禁用sudo模式。在運行使用sudo的代碼之前調用startsudo,使用sudo進行身份驗證,分叉後臺sudo刷新循環,保存循環的PID,並設置信號陷阱以在按Ctrl + C時停止sudo模式。調用stopsudo殺死循環,清除信號陷阱,並使用sudo使早期認證無效。

將這些函數複製到您的腳本後,像這樣使用它們。

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

我要感謝@karl內聯須藤刷新環和@sehe的簡單的指出一個信號陷阱應該用來殺死循環,如果它不能正常死亡。這兩個想法都改進了my btrfs backup script,它使用sudo-refreshing循環來避免在子卷的備份花費的時間超過sudo的超時時間後重新提示用戶。