# 在 Linux 中免密碼使用 sudo `sudo apt update` `sudo systemctl restart nginx` `sudo reboot` 在使用 [[Linux]] 時,你會頻繁地使用到 `sudo` 指令。然而,每次都輸入密碼實在是令人感到厭煩。 當這種厭煩感達到頂點時,你最終會決定動手設定,讓 `sudo` 無需輸入密碼。想必點進這篇文章的你,也一定有過與我相似的感受。 在這篇文章中,我將整理出如何免除 `sudo` 密碼輸入的方法。 ![Linux 的 Tux 和金鑰安全](/media/whitedec/blog_img/vaBoSfdn.webp) ## sudo 設定檔在哪裡?又該如何修改? sudo 的主要設定檔位於: `/etc/sudoers` sudo 設定的語法一旦出錯,將會非常麻煩。如果設定不當導致 `sudo` 無法使用,恢復過程會很惱人。因此,我們建議使用專用指令 `visudo`。 ```bash sudo visudo ``` `visudo` 在儲存時會進行語法檢查,並即時提示錯誤。就連官方手冊也強調務必使用 `visudo`。 ## 但請不要直接修改 /etc/sudoers 當你輸入 `sudo visudo` 時,`/etc/sudoers` 檔案會立即開啟,你可以直接進行修改。 然而,直接開啟並修改 `/etc/sudoers` 檔案並不是一個好習慣。 我通常偏好不更動主要的設定檔,而是在 `/etc/sudoers.d/` 這個目錄下建立新的設定檔。 這樣日後要查找自己修改了哪些地方,或是要還原設定都會更加方便。 sudo 的設計允許它包含 `sudoers.d` 目錄中檔案的額外設定。 實際上,在 `/etc/sudoers` 檔案的最後一行,你會看到 `include /etc/sudoers.d/`。 ```bash sudo visudo -f /etc/sudoers.d/no-password-common-commands ``` 你可以自由命名檔案,只要能讓你日後輕鬆辨識即可。 不過,建議不要取得太隨便,否則日後可能會為自己帶來困擾。 喔!順帶一提,包含 `~` 或 `.` 的檔案名稱會被 sudoer 忽略。這個資訊可以在目錄中的 README 檔案註解裡找到。 ## 了解設定格式 sudoers 的設定大致遵循以下格式: 這語法實在是...很難記住。建議你把它寫下來,或者直接將這篇部落格文章加入書籤。 雖然不常用,但偶爾需要用到時,就是會想不起來。 ```bash 使用者名稱 主機=(執行身分) 選項: 指令 ``` 舉例來說,如果使用者名稱是 `potter`,並且希望免密碼執行 `apt update`,你可以這樣寫: ```bash potter ALL=(ALL) NOPASSWD: /usr/bin/apt ``` 各部分的說明如下: * potter : 要套用設定的使用者名稱。 * ALL : 表示在所有主機上套用。 * (ALL) : 表示可以以哪種使用者權限執行。我偶爾也會看到有人寫 (root)。我個人偏好使用 ALL。 * NOPASSWD: 表示不詢問密碼。 * /usr/bin/apt : 允許執行的指令「絕對路徑」。 如果你不確定指令的路徑,可以使用 `which` 來查詢。 ```bash ~$which apt /usr/bin/apt ~$which apt-get /usr/bin/apt-get ~$which reboot /usr/sbin/reboot ~$which systemctl /usr/bin/systemctl ``` ## 開放 ALL 的誘惑 此時,一個強烈的誘惑會浮現: ```bash potter ALL=(ALL) NOPASSWD: ALL ``` 這樣做非常簡潔。所有 `sudo` 指令都能免密碼執行,非常方便,簡直是太方便了。 雖然這是個人選擇,但我認為最好還是克制一下。因為我光是想像一個錯誤輸入的指令,就能直接以 root 權限執行,就感到不寒而慄。 即使腳本出現異常,也沒有密碼輸入這個最後的防線。如果你只是暫時開啟終端機,而有人動了它,那一切就都完了。世界上奇怪的人實在太多了... 選擇權在你。 ## 僅允許常用指令免密碼執行 我個人傾向於「只開放常用指令」的折衷方案。這種方式相當不錯。 舉例來說,假設你只想讓 `apt`、`apt-get`、`reboot` 和 `systemctl` 等指令免密碼執行。 首先,開啟設定檔: ```bash sudo visudo -f /etc/sudoers.d/no-password-common-commands ``` 然後,像下面這樣撰寫: ```ini potter ALL=(ALL) NOPASSWD: /usr/bin/apt, /usr/bin/apt-get, /usr/sbin/reboot, /usr/bin/systemctl ``` 現在,使用者 `potter` 就可以免密碼執行以下指令了: ```bash sudo apt update sudo apt -y upgrade sudo apt-get update sudo reboot sudo systemctl reload nginx ``` 如果你覺得開放所有 `systemctl` 指令會造成負擔,也可以只允許特定的指令: ```bash potter ALL=(ALL) NOPASSWD: /usr/bin/systemctl reload nginx, /usr/bin/systemctl status nginx ``` ## 分行撰寫,提高可讀性 當指令過多時,一行會顯得雜亂。此時,你可以使用 `\` 來分行。 儘管這是 Linux 使用者常見且習慣的分行方式,但奇怪的是,實際操作時卻不常使用 `\`。不過,使用了確實能提升可讀性。 ```bash potter ALL=(ALL) NOPASSWD: \ /usr/bin/apt, \ /usr/bin/apt-get, \ /usr/sbin/reboot, \ /usr/bin/systemctl ``` 看起來既美觀又整潔。 ## 套用至特定群組 這項設定也相當實用。在多人管理的伺服器中,以群組為基礎的權限管理會更加方便。 如果想套用至特定群組,可以使用 `%群組名稱` 的格式。 例如,如果是 `admin` 群組,則會像這樣: ```bash %admin ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx, /usr/bin/apt, /usr/bin/apt-get ``` ## 延長密碼輸入的有效時間 如果你對完全取消密碼輸入感到不安,還有另一種方法:調整密碼再次詢問的時間。 基本上,一旦輸入密碼,系統在 10 到 15 分鐘內不會再次詢問,這個時間是可以調整的。 這可以透過 `timestamp_timeout` 設定來實現。 舉例來說,這樣設定就能讓 `sudo` 在 60 分鐘內不再詢問密碼: ```bash Defaults timestamp_timeout=60 ``` 單位是「分鐘」,但如果設定為「0」,那將會是個惡夢,因為每次都必須輸入密碼。 如果設定為「-1」,則一旦輸入 `sudo` 密碼,直到關閉終端機前都不會再詢問。這幾乎與 `ALL` 設定提供同樣強大的便利性,但使用時仍會有些許不安。 當然,免密碼執行與延長有效時間這兩種設定是可以並存的。 例如,你可以這樣混合使用: ```bash Defaults timestamp_timeout=30 potter ALL=(ALL) NOPASSWD: /usr/bin/apt, /usr/bin/apt-get, /usr/sbin/reboot ``` 常用指令免密碼,其他 `sudo` 指令則在驗證一次後維持 30 分鐘有效。 我認為這在便利性與安全性之間,取得了相當不錯的平衡點。 減少麻煩固然是好事,但我不想以增加不安感為代價。 ## 總結 取消 `sudo` 密碼輸入其實並不難。 雖然上面的說明比較長,但簡要概括如下: 1. 使用 `visudo` 在 `/etc/sudoers.d/` 下建立一個獨立的設定檔。 ```bash sudo visudo -f /etc/sudoers.d/no-password-common-commands ``` 2. 添加 `NOPASSWD` 規則即可。 ```ini Defaults timestamp_timeout=30 potter ALL=(ALL) NOPASSWD: \ /usr/bin/apt, \ /usr/bin/apt-get, \ /usr/sbin/reboot ``` 至於要開放到什麼程度,則取決於個人判斷,但我希望你能記住這一點: > 唯有手指的便捷與內心的平靜同時獲得滿足,才是真正的舒適。