本頁面提供使用 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 Manual」。
如要瞭解如何管理及使用 visudo
編輯器,請參閱 Visudo 手冊。
問題的後果
sudoers
檔案中的問題會造成負面影響,並可能影響整個系統的功能。
「
sudo
」指令已失效。這是
sudoers
檔案發生問題時最明顯的後果。 這會導致使用者無法使用提升的權限,進而阻礙他們在伺服器上的活動。不過,如果依賴
sudo
指令的應用程式發生故障,後果可能更具破壞性且難以預測。在某些情況下,這可能會導致應用程式完全失敗,進而產生非預期的行為、異常終止或資料遺失。另一個例子是 OS 開機順序期間,應用程式呼叫sudo
指令失敗。這可能會導致作業系統故障,或啟動順序停滯。系統可能遭到未經授權的存取。
另一個風險是,
sudoers
檔案中的問題可能會導致系統遭到未經授權的存取。如果sudoers
檔案中的規則賦予某些使用者或群組過多的權限,就可能發生邏輯錯誤。系統擁有者也可能為了登入並修正問題,暫時停用或削弱系統防禦機制,導致這種情況發生。
發生問題時的復原方式
如果失去提升的使用者權限,或因 sudoers
檔案發生問題而無法使用 sudo
指令,請使用超級使用者帳戶進行復原。
在類 Unix 作業系統中,超級使用者是 ID 等於 0 的特殊使用者帳戶,通常稱為 root
。超級使用者可完整存取系統資源,且不受限制地執行任何管理工作。雖然代表超級使用者與 OS 互動通常被視為不安全,但對於某些工作 (例如復原 sudoers
檔案) 而言,這可能是唯一選項。
直接以超級使用者身分登入會使作業系統暴露於風險中。為避免這項風險,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。