sudo 是 Linux 權限提升的基石,正確配置能實現「最小權限原則」,避免 root 帳號外洩、誤操作擴散。本文系統解析 /etc/sudoers 語法、常用別名、日誌審計、免密場景與企業級管理模式。
核心優勢:為什麼不用 su / 直接登 root?
| 維度 | su - | sudo |
| 密碼知悉者 | 需知 root 密碼 | 用自己密碼(或免密) |
| 權限粒度 | 全 root 權限 | 可限定指令/參數/主機 |
| 審計追蹤 | 無原生日誌 | 完整記錄 who/what/when |
| 會話殘留 | 易忘記 exit 留在 root | 單指令提權,自動回落 |
| 自動化友善 | 需 expect 處理互動 | 支援 NOPASSWD、-n 非互動 |
/etc/sudoers 寫法速查(務必用 visudo 編輯)
# 別名定義
User_Alias ADMINS = alice, bob, charlie
Cmnd_Alias NETWORK = /usr/sbin/ip, /usr/bin/ss, /bin/ping
Cmnd_Alias STORAGE = /usr/sbin/lvs, /usr/sbin/vgs, /usr/sbin/lvcreate
Host_Alias WEBSRV = web01, web02, web03
# 基本授權:用戶 主機=(以誰身份) 指令
alice ALL=(ALL) ALL # 全權限(慎用)
bob ALL=(ALL) NOPASSWD: NETWORK # 免密執行網路指令
charlie WEBSRV=(root) STORAGE # 僅在 web 主機以 root 跑存儲指令
%wheel ALL=(ALL) ALL # wheel 群組全權限
# 預設值
Defaults env_reset, timestamp_timeout=15, logfile=/var/log/sudo.log
Defaults !lecture, !tty_tickets
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
關鍵 Defaults 參數
| 參數 | 說明 | 建議值 |
timestamp_timeout | 免密緩存時間(分鐘),0=每次問密碼,-1=永不超時 | 15 |
logfile | 獨立 sudo 日誌檔(需 syslog 支援) | /var/log/sudo.log |
log_input / log_output | 記錄輸入/輸出內容(含密碼風險,慎開) | off |
requiretty | 強制需 TTY(破壞腳本自動化,建議關閉) | off |
secure_path | 指令搜尋路徑,防 PATH 注入 | 系統標準路徑 |
env_keep | 保留環境變數(如 HTTP_PROXY、LANG) | 按需添加 |
常用選項速查
| 選項 | 作用 | 範例 |
-u user | 以指定用戶身份執行 | sudo -u postgres psql |
-g group | 以指定群組身份執行 | sudo -g docker docker ps |
-i | 模擬登入 shell(載入 .profile、切換家目錄) | sudo -i |
-s | 啟動 shell(保留當前環境) | sudo -s |
-n | 非互動模式,無緩存則失敗(適合腳本檢查) | sudo -n true |
-l | 列出當前用戶可執行的 sudo 指令 | sudo -l |
-k | 清除時間戳緩存,下次必問密碼 | sudo -k |
-b | 背景執行 | sudo -b updatedb |
企業級管理模式:sudoers.d 模組化 + 版控
# 1. 主檔僅保留核心配置,include 目錄
echo "#includedir /etc/sudoers.d" >> /etc/sudoers
# 2. 每個角色/服務一個檔案
cat > /etc/sudoers.d/01-admins <<'EOF'
%admins ALL=(ALL) ALL
EOF
cat > /etc/sudoers.d/10-deploy <<'EOF'
# CI/CD 部署帳號:僅允許系統管理指令,免密
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx, /usr/bin/systemctl reload php-fpm, /bin/cp -r /opt/build/* /var/www/
EOF
cat > /etc/sudoers.d/20-monitoring <<'EOF'
# 監控採集帳號:唯讀系統資訊
telegraf ALL=(ALL) NOPASSWD: /usr/sbin/dmidecode, /usr/sbin/smartctl, /usr/bin/ipvsadm -L
EOF
# 3. 語法檢查(部署前必跑)
visudo -c -f /etc/sudoers.d/10-deploy
# 4. 納入 Git 管理,CI 跑 visudo -c 當作 Gate
審計與合規
journalctl -u sudo 或 grep sudo /var/log/secure 查看提權記錄
- 關鍵指令(
useradd, passwd, iptables, reboot)建議**不給 NOPASSWD**,保留密碼確認
- 定期審查
sudo -l -U ,回收離職/專案結束帳號的多餘授權
避坑指南
| 坑 | 後果 | 修正 |
直接 vim /etc/sudoers 存檔語法錯 | 全員無法 sudo,需單用戶模式救援 | 永遠用 visudo 或 visudo -f /etc/sudoers.d/xxx |
ALL=(ALL) NOPASSWD: ALL 發給開發 | 等同 root 外洩,合規不通過 | 最小化指令清單,必要時用 sudo -i 臨時提權 |
環境變數注入(LD_PRELOAD, PATH) | 權限提升漏洞 | Defaults env_reset, secure_path=...,env_keep 白名單 |
| sudo 版本過舊(< 1.8.21) | CVE-2019-14287 (sudo -u#-1 繞過) | 升級 sudo ≥ 1.8.21 或打補丁 |
結語: sudo 不是「給方便用的」,是「給可控、可審計、可回收的權限」。用 sudoers.d 模組化、Git 版控、visudo -c 當 Gate、關鍵指令保留密碼確認,才是成熟團隊的權限管理姿態。