這個頁面提供使用 sudo 指令列公用程式、管理 sudoers 外掛程式,以及避免或修正問題的提示。
問題原因
每次執行 sudo 指令時,系統都會進行下列程序,驗證 sudoers 檔案:
- 系統會檢查語法是否正確。
- 系統會分析內容,排除部分邏輯錯誤。
- 系統會檢查擁有權和權限。
sudoers 檔案驗證失敗的可能原因如下:
語法錯誤
變更 sudoers 檔案時,必須遵循特定語法規則。如果檔案語法有任何偏差 (包括但不限於缺少或多餘的字元,或使用不當的半形逗號),檔案就會無效。檔案失效後,就無法使用 sudo 公用程式。
解決方案
解決方法是使用 visudo 公用程式編輯 sudoers 檔案。系統會在儲存前驗證檔案內容,並在發生問題時通知你。這個
visudo公用程式的用途是安全地編輯檔案。
以下範例顯示正確和不正確的語法範例:
正確語法
user ALL=(ALL) ALL
語法錯誤
user ALL=(ALL), ALL
語法錯誤範例
$ sudo useradd username
/etc/sudoers:20:17: syntax error
user ALL=(ALL), ALL
^
邏輯錯誤
這類錯誤的原因可能如下:
- 誤解
sudoers外掛程式的原則。 - 與正確語法有出入。
不過,驗證期間不會辨識出邏輯錯誤,因為這類錯誤不會違反語法規則,因此難以偵測。
解決方案
編輯檔案時,請務必詳閱官方說明文件並遵守相關原則。
Google 也建議使用 visudo 公用程式編輯 sudoers 檔案,因為這項工具可以偵測某些類型的邏輯錯誤,例如:
- 未定義或未使用的別名
- 循環參照
- 重複項目
如果偵測到任何問題,系統會顯示警告訊息。
以下範例顯示邏輯正確和不正確的樣本:
邏輯正確
barbara ALL=(ALL:ALL) /usr/bin/ls
邏輯不正確
barbara ALL=(4LL:ALL) /usr/bin/ls
^
barbara ALL=(ALL;ALL) /usr/bin/ls
^
bar6ara ALL=(ALL:ALL) /usr/bin/1s
^ ^
權限不正確
除了 sudoers 檔案內容造成的錯誤外,檔案權限過多或擁有權不正確也可能導致 sudo 公用程式失敗。
解決方案
失敗的 sudo 指令輸出內容會顯示這些錯誤的說明。請詳閱錯誤訊息說明,並進行必要修正。
以下是正確檔案權限和擁有權的範例
$ ls -l /etc/sudoers
-r--r----- 1 root root 700 Jan 1 12:00 /etc/sudoers
$ sudo useradd username
以下範例顯示「所有使用者」權限群組有多餘權限時,系統顯示的錯誤訊息:
$ ls -l /etc/sudoers
-r--r---w- 1 root root 700 Jan 1 12:00 /etc/sudoers
$ sudo useradd username
sudo: /etc/sudoers is world writable
sudo: no valid sudoers sources found, quitting
sudo: error initializing audit plugin sudoers_audit
以下範例顯示因擁有權不正確而出現的錯誤。在這個範例中,檔案擁有者的 ID 不是 0 (或使用者不是 root):
$ ls -l /etc/sudoers
-r--r----- 1 user user 700 Jan 1 12:00 /etc/sudoers
$ sudo useradd username
sudo: /etc/sudoers is owned by uid 1000, should be 0
sudo: no valid sudoers sources found, quitting
sudo: error initializing audit plugin sudoers_audit
如要進一步瞭解 sudoers 檔案的設定,請參閱 Sudoers 手冊。
如要瞭解如何管理及使用 visudo 編輯器,請參閱 Visudo 手冊。
問題的後果
sudoers 檔案中的問題會造成負面影響,並可能影響整個系統的功能。
「
sudo」指令已無法使用。這是
sudoers檔案發生問題時最明顯的後果。 這會導致使用者無法使用進階權限,進而無法在伺服器上執行活動。不過,如果應用程式依賴
sudo指令,一旦發生故障,後果可能更具破壞性,也更難以預測。在某些情況下,這可能會導致應用程式完全失敗,造成非預期行為、當機或資料遺失。另一個例子是應用程式在 OS 開機順序期間呼叫sudo指令,但失敗。這可能會導致 OS 故障或開機程序停滯。系統可能遭到未經授權的存取。
另一個風險是,
sudoers檔案中的問題可能導致系統遭到未經授權的存取。如果sudoers檔案中的規則授予部分使用者或群組過多權限,就可能發生邏輯錯誤。這也可能是因為系統擁有者為了登入並修正問題,暫時停用或削弱系統防禦機制。
發生問題時的復原方式
如果失去提升的使用者權限,或因 sudoers 檔案發生問題而無法使用 sudo 指令,請使用超級使用者帳戶進行復原。
在類 Unix 作業系統中,超級使用者是 ID 等於 0 的特殊使用者帳戶,通常稱為 root。超級使用者可完整存取系統資源,且不受限制地執行任何管理工作。雖然代表超級使用者與 OS 互動通常被視為不安全,但對於某些工作 (例如復原 sudoers 檔案),這可能是唯一的選擇。
直接以超級使用者身分登入會使 OS 暴露於風險中。為避免這項風險,Google 建議您使用開機指令碼功能,因為這類指令碼會以超級使用者的身分執行。
進一步瞭解 Compute Engine 開機指令碼。
如要使用開機指令碼復原 sudoers 檔案,請按照下列步驟操作:
如果目前已在使用開機指令碼,請建立備份副本。備份方法取決於開機指令碼的設定方式。
startup-script
如果指令碼內容是直接在中繼資料值中設定,您可以將指令碼內容複製到 Cloud Storage bucket、本機檔案或任何其他暫時私人儲存空間。
startup-script-url
如果指令碼內容已儲存在遠端儲存空間,且使用其網址,則只要暫時移除
startup-script-url中繼資料鍵,即可停用目前的開機指令碼。使用下列指令序列更新開機指令碼:
mv /etc/sudoers /etc/sudoers.backup.$(date +"%s") && echo "%google-sudoers ALL=(ALL:ALL) NOPASSWD:ALL" > /etc/sudoers && chown 0:0 /etc/sudoers && chmod 0440 /etc/sudoers進一步瞭解指令的用途
-
mv /etc/sudoers /etc/sudoers.backup.$(date +"%s") -
這個指令會複製
/etc/sudoers檔案並重新命名,然後刪除原始檔案。新檔案的名稱結尾會加上時間戳記,確保名稱不重複 (例如sudoers.backup.1672527600)。 -
echo "%google-sudoers ALL=(ALL:ALL) NOPASSWD:ALL" > /etc/sudoers -
這個指令會建立先前刪除的檔案
/etc/sudoers,並使用單一規則,允許有權存取 VM 的 Google Cloud 使用者代表任何系統使用者執行任何指令。這個規則預設一律存在於額外檔案/etc/sudoers.d/google_sudoers中。 -
chown 0:0 /etc/sudoers -
這項指令會將
/etc/sudoers檔案的擁有者設為 ID 為0的使用者,並將擁有者群組設為 ID 為0的群組。 -
chmod 0440 /etc/sudoers -
這項指令會將
/etc/sudoers檔案的權限設為唯讀,且只允許檔案擁有者和擁有者群組讀取檔案。
-
停止 VM (如果正在執行)。重新啟動 VM,觸發開機指令碼執行。
連線至 VM 並編輯損壞的
sudoers檔案,即可復原。sudo visudo /etc/sudoers.backup.TIMESTAMP儲存變更,並將目前的
/etc/sudoers檔案替換成您剛編輯的檔案。sudo mv /etc/sudoers.backup.TIMESTAMP /etc/sudoers請確認使用
sudo指令和提升權限時的原始問題已修正。移除暫時的開機指令碼,並還原原始指令碼 (如有使用)。
後續步驟
- 瞭解如何復原無法存取或已損毀的 VM。
- 瞭解如何將現有磁碟新增至其他 VM。