Sudo
’echo ‘預設侮辱’ >> /etc/sudoers’ 安全嗎?
這安全嗎?
echo "Defaults insults" >> /etc/sudoers
如果是,我可以這樣做嗎?
echo "## First line" >> /etc/sudoers echo "### Second line" >> /etc/sudoers echo "Defaults insults" >> /etc/sudoers echo "### Totally the last line" >> /etc/sudoers
有沒有更好的方法來做到這一點
visudo
?我正在製作一個 bash 腳本,這一點需要打開和關閉侮辱。
至少有 3 種危險的方式:
- 如果
/etc/sudoers
不以換行符結尾(允許)sudo
,visudo
例如,如果它以非終止#includedir /etc/sudoers.d
行結尾,您的命令將使它:#includedir /etc/sudoers.dDefaults insults
這將破壞它並使其
sudo
無法使用。 2.echo
可能無法寫入完整的字元串,例如,如果文件系統已滿。例如,它可能只能寫Defaults in
. 這又會破壞你的sudoers
文件。 3. 在有多個管理員的機器上,如果同時嘗試修改/etc/sudoers
,他們寫入的數據可能是交錯的。
visudo
避免了這些問題,因為它允許您編輯臨時文件/etc/sudoers.tmp
(執行(原子操作)以將新文件移動到位。因此,它要麼成功更新文件(如果你的編輯器在無法寫入新文件時也保持文件未修改),要麼在不能或語法無效時失敗。rename
visudo
還可以防止多人同時編輯sudoers
文件。現在,
visudo
以自動方式可靠地使用也很棘手。這樣做有幾個問題:
visudo
您可以使用環境變數指定編輯器命令VISUAL
(優先於EDITOR
),但前提是該env_editor
選項未被禁用。- 我的版本
visudo
至少在某些情況下會編輯/etc/sudoers
它包含的所有文件(對所有文件執行$VISUAL
)。所以你必須確保你$VISUAL
唯一的修改/etc/sudoers
。- 如上所示,它不檢查編輯器的退出狀態。所以你需要確保你的編輯器保存的文件要麼被成功寫入,要麼根本沒有被修改。
- 它會在出現問題時提示使用者。
解決所有這些問題有點棘手。您可以這樣做:
NEW_TEXT='Defaults insults' \ CODE=' if [ "$2" = /etc/sudoers.tmp ]; then printf >&2 "Editing %s\n" "$2" umask 077 { cat /etc/sudoers.tmp && printf "\n%s\n" "$NEW_TEXT" } > /etc/sudoers.tmp.tmp && mv -f /etc/sudoers.tmp.tmp /etc/sudoers.tmp else printf >&2 "Skipping %s\n" "$2" fi' \ VISUAL='sh -fc IFS=:;$1 sh eval:eval:"$CODE"' visudo < /dev/null
如果未設置將不起作用
env_editor
。在 GNU 系統上,更好的選擇是使用
sed -i
which 應該保持sudoers.tmp
不變,如果它無法編寫較新的版本:添加
insults
:SED_CODE=' /^[[:blank:]]*Defaults.*insults/,${ /^[[:blank:]]*Default/s/!*\(insults\)/\1/g $q } $a\Defaults insults' \ CODE=' if [ "$2" = /etc/sudoers.tmp ]; then printf >&2 "Editing %s\n" "$2" sed -i -- "$SED_CODE" "$2" else printf >&2 "Skipping %s\n" "$2" fi' \ VISUAL='sh -fc IFS=:;$1 sh eval:eval:"$CODE"' visudo < /dev/null
刪除侮辱:
SED_CODE=' /^[[:blank:]]*Defaults.*insults/,${ /^[[:blank:]]*Defaults/s/!*\(insults\)/!\1/g $q } $a\Defaults !insults' \ CODE=' if [ "$2" = /etc/sudoers.tmp ]; then printf >&2 "Editing %s\n" "$2" sed -i -- "$SED_CODE" "$2" else printf >&2 "Skipping %s\n" "$2" fi' \ VISUAL='sh -fc IFS=:;$1 sh eval:eval:"$CODE"' visudo < /dev/null