Sudo_root - prompt when needed in script
(這是一篇積存的舊文。)
Sudo 是個很好用的工具,讓我們可以盡可能地減少擁有 root 權限的時間,並隱藏 root 密碼,以提升系統安全性[1]。不過,當我們在使用 shell script,而 script 裡只有一小部分需要用到 root 權限時,卻通常是直接用 sudo 或 su 成 root 執行整個 script,讓 script 裡面大部分沒有需要 root 權限的地方,也獲得了 root 權限。如果,我們能夠善用 sudo,只在 script 裡真正需要 root 權限的地方,才切換成 root 身份執行,這樣應該可以降低 script 其他部分,對系統可能的危害。
最簡單的想法,就是在 script 裡,有需要 root 權限的指令前面,加上 sudo 就好了。由於 sudo 會記錄上一次執行的 time-stamp,因此就算我們加上 sudo 的指令,在一個跑上千次的迴圈裡面,我們也只需要輸入密碼一次。好比說:
#!/bin/sh
# backup all configuration files in /etc.
for i in /etc/*; do
sudo cp -f "$i" /backup/etc;
done;
不過,這個作法其實還是可以有改進的空間:
- Sudo 預設的 prompt 只是簡單的
"Password: ",在複雜的 script 執行過程中,如果突然跳出一個"Password: "要使用者輸入密碼,那使用者將很難知道,這裡要輸入的是 sudo 的密碼。因此,我們需要讓 sudo 改變其 prompt,明確指出需要打誰的密碼,以便 sudo 成誰。 - 若一個 script 有太多地方需要 sudo 成 root,如果能夠在一開始的時候,就讓使用者先輸入 sudo 密碼,之後再利用 sudo 的 time-stamp 功能,這樣子整個 script 會比較 user friendly。
對於第一個需求,我們可以用 sudo 的 -p 參數,指定 prompt;而對於第二個需求,則可以在 script 的一開始,利用 sudo 的 -v 參數,讓 sudo 強制更新其 time-stamp。於是,我們就有了以下的 script function:
sudo_root()
{
local opts='';
if [ $# -lt 1 ]; then
opts='-v';
fi;
sudo -p "Need to sudo to '%U', please enter password for '%u': " $opts $@;
}
sudo_root 利用了 sudo 的 -p 參數,將 prompt 強制設定,明確說明要 sudo 成誰(%U[2]),以及需要打誰(%u)的密碼。若沒有給 sudo_root 任何參數,則 sudo_root 會利用 sudo 的 -v 參數,強制更新 timestamp。
不過,人總是貪心的,sudo 除了 root 之外,也可以變身成其他使用者[3],因此,如果我們能夠擴展 sudo_root 的功能,加入變身成其他使用者的功能的話,豈不是更好。不過,問題在於,我們無法知道,究竟跟在 sudo_root 後的第一個參數,是要執行的指令,還是要變身的 user id。因此,只好退而求其次,用另外一個名字 sudo_user 來表現這個功能。事實上,sudo_user 從字義上來看,是 sudo_root 的 superset,在實際上,也是如此。因此,這個 function 就變成了兩個 functions,sudo_root 由 sudo_user 實現:
sudo_user()
{
local user="$1"; shift;
local opts='';
if [ $# -lt 1 ]; then
opts=' -v';
fi;
sudo -p "Need to sudo to '$user', please enter password for '%u': " $opts $@;
}
sudo_root()
{
sudo_user root $@;
}
其中要注意的是,prompt 裡的 %U 改由 $user 呈現,因為在 Linux 上的 sudo 似乎沒有 %U 可以用,但因為 sudo_user 明確知道要 sudo 成誰,因此剛好可以解決這個問題。
後記:FreeBSD 上的 /usr/ports/security/sudo,可以吃 SUDO_PROMPT 環境變數,設定好就自動有 -p 的效果。
- 雖然,也是有人反對使用 sudo:Official Home of IPSC Team: The Anti-Sudo Lackeys。 ↩
- 在 Linux 下的 sudo,似乎沒有
%U這一個 escape。這個相容性問題,可以在之後提到的 sudo_user 裡解決。 ↩ - 既然都拿到 root 權限了,要變身成誰,還不是說一聲就算。 ↩
Random Posts
- None Found
Similar Posts
- None Found
Post a Comment