Linux - sudoers的深入剖析

Linux是多用戶多任務的操作系統, 共享該系統的用戶往往不只一個。
出於安全性考慮, 有必要通過useradd創建一些非root用戶, 只讓它們擁有不完全的權限; 如有必要,再來提升權限執行。

sudo就是來解決這個需求的: 這些非root用戶不需要知道root的密碼,就可以提權到root,執行一些root才能執行的命令。

執行sudo -u <用戶名> <命令>, 將允許當前用戶,提權到<用戶名>的身份,再執行後面的<命令>, 即使<命令>原本需要root權限。
提權到<用戶名>身份時,是以<用戶名>的身份來執行命令的,因此創建的文件默認屬於<用戶名>用戶。

因此,當userB執行如下命令時:

sudo -u userA touch /tmp/belong-to-who.tmp

創建的/tmp/belong-to-who.tmp 文件屬於用戶userA。

如果不帶-u, 則默認使用root用戶,而大多數時候sudo都是要提權到root的,所以-u <用戶名>可以省略爲:

sudo <命令>

需要注意的是: 執行sudo時輸入的密碼是當前用戶的密碼, 並非<用戶名>的密碼。
sudo -u <用戶名>su - <用戶名>相比:
前者需要輸入當前用戶的密碼,提權到<用戶名>身份執行命令後返回當前用戶;
後者則是輸入目標用戶的密碼,切換到目標用戶。

賦予用戶sudo操作的權限

關於Linux用戶和用戶組管理的知識點不是本篇文章要討論的, 如對useradd、 usermod、 passwd、 groupadd等指令生疏,可移步鏈接, 那裏有詳細的講解了。
通過useradd添加的用戶,並不具備sudo權限。在ubuntu/centos等系統下, 需要將用戶加入admin組或者wheel組或者sudo組。

以root用戶身份執行如下命令, 將用戶加入wheel/admin/sudo組:

usermod -a -G wheel <用戶名>

如果提示wheel組不存在, 則還需要先創建該組:

groupadd wheel


用公式講解/etc/sudoers的內容

sudo的權限控制可以在/etc/sudoers文件中查看到。

如果想要控制某個用戶(或某個組用戶)只能執行root權限中的一部分命令, 或者允許某些用戶使用sudo時不需要輸入密碼,就需要對該文件有所瞭解。

一般來說,通過cat /etc/sudoers指令來查看該文件, 會看到如下幾行代碼:

root   ALL=(ALL:ALL) ALL
%wheel ALL=(ALL) ALL
%sudo  ALL=(ALL:ALL) ALL

/etc/sudoers文件進行編輯的代碼公式可以概括爲:

授權用戶/組 主機=[(切換到哪些用戶或組)] [是否需要輸入密碼驗證] 命令1,命令2,...

凡是[ ]中的內容, 都能省略; 命令和命令之間用,號分隔;

爲了方便說明, 將公式的各個部分稱呼爲字段1 - 字段5:

授權用戶/組 主機  =[(切換到哪些用戶或組)] [是否需要輸入密碼驗證] 命令1,命令2,...
字段1      字段2  =[(字段3)] [字段4] 字段5

字段3、字段4,是可以省略的。

在上面的默認例子中, "字段1"不以%號開頭的表示"將要授權的用戶", 比如例子中的root
%號開頭的表示"將要授權的組", 比如例子中的%wheel組 和 %sudo組。

"字段2"表示允許登錄的主機, ALL表示所有; 如果該字段不爲ALL,表示授權用戶只能在某些機器上登錄本服務器來執行sudo命令. 比如:

jack mycomputer=/usr/sbin/reboot,/usr/sbin/shutdown

表示: 普通用戶jack在主機(或主機組)mycomputer上, 可以通過sudo執行reboot和shutdown兩個命令。"字段3"和"字段4"省略。

"字段3"如果省略, 相當於(root:root),表示可以通過sudo提權到root; 如果爲(ALL)或者(ALL:ALL), 表示能夠提權到(任意用戶:任意用戶組)

請注意,"字段3"如果沒省略,必須使用( )雙括號包含起來。這樣才能區分是省略了"字段3"還是省略了"字段4"。

"字段4"的可能取值是NOPASSWD:。請注意NOPASSWD後面帶有冒號:。表示執行sudo時可以不需要輸入密碼。比如:

lucy ALL=(ALL) NOPASSWD: /bin/useradd

表示: 普通用戶lucy可以在任何主機上, 通過sudo執行/bin/useradd命令, 並且不需要輸入密碼.

又比如:

peter ALL=(ALL) NOPASSWD: ALL

表示: 普通用戶peter可以在任何主機上, 通過sudo執行任何命令, 並且不需要輸入密碼。

"字段5"是使用逗號分開一系列命令,這些命令就是授權給用戶的操作; ALL表示允許所有操作。

你可能已經注意到了, 命令都是使用絕對路徑, 這是爲了避免目錄下有同名命令被執行,從而造成安全隱患。

如果你將授權寫成如下安全性欠妥的格式:

lucy ALL=(ALL) chown,chmod,useradd

那麼用戶就有可能創建一個他自己的程序, 也命名爲userad, 然後放在它的本地路徑中, 如此一來他就能夠使用root來執行這個"名爲useradd的程序"。這是相當危險的!

命令的絕對路徑可通過which指令查看到: 比如which useradd可以查看到命令useradd的絕對路徑: /usr/sbin/useradd

公式還要擴充

例子1:

papi ALL=(root) NOPASSWD: /bin/chown,/usr/sbin/useradd

表示: 用戶papi能在所有可能出現的主機上, 提權到root下執行/bin/chown, 不必輸入密碼; 但運行/usr/sbin/useradd 命令時需要密碼.

這是因爲NOPASSWD:隻影響了其後的第一個命令: 命令1.

上面給出的公式只是簡化版,完整的公式如下:

授權用戶/組 主機=[(切換到哪些用戶或組)] [是否需要輸入密碼驗證] 命令1, [(字段3)] [字段4] 命令2, ...

在具有sudo操作的用戶下, 執行sudo -l可以查看到該用戶被允許和被禁止運行的命令.

通配符和取消命令

例子2:

papi ALL=/usr/sbin/*,/sbin/*,!/usr/sbin/fdisk

用例子2來說明通配符*的用法, 以及命令前面加上!號表示取消該命令。

該例子的意思是: 用戶papi在所有可能出現的主機上, 能夠運行目錄/usr/sbin和/sbin下所有的程序, 但fdisk除外.

開始編輯

“你講了這麼多,但是在實踐中,我去編輯/etc/sudoers文件,系統提示我沒權限啊,怎麼辦?”

這是因爲/etc/sudoers的內容如此敏感,以至於該文件是隻讀的。所以,編輯該文件前,請確認清楚你知道自己正在做什麼。

強烈建議通過visudo命令來修改該文件,通過visudo修改,如果配置出錯,會有提示。

不過,系統文檔推薦的做法,不是直接修改/etc/sudoers文件,而是將修改寫在/etc/sudoers.d/目錄下的文件中。

如果使用這種方式修改sudoers,需要在/etc/sudoers文件的最後行,加上#includedir /etc/sudoers.d一行(默認已有):

#includedir /etc/sudoers.d

注意了,這裏的指令#includedir是一個整體, 前面的#號不能丟,並非註釋,也不能在#號後有空格。

任何在/etc/sudoers.d/目錄下,不以~號結尾的文件和不包含.號的文件,都會被解析成/etc/sudoers的內容。

文檔中是這麼說的:

# This will cause sudo to read and parse any files in the /etc/sudoers.d
# directory that do not end in '~' or contain a '.' character.

# Note that there must be at least one file in the sudoers.d directory (this
# one will do), and all files in this directory should be mode 0440.

# Note also, that because sudoers contents can vary widely, no attempt is
# made to add this directive to existing sudoers files on upgrade.

# Finally, please note that using the visudo command is the recommended way
# to update sudoers content, since it protects against many failure modes.


其他小知識

輸入密碼時有反饋

當使用sudo後輸入密碼,並不會顯示任何東西 —— 甚至連常規的星號都沒有。有個辦法可以解決該問題。

打開/etc/sudoers文件找到下述一行:

Defaults env_reset

修改成:

Defaults        env_reset,pwfeedback

修改sudo會話時間

如果你經常使用sudo 命令,你肯定注意到過當你成功輸入一次密碼後,可以不用再輸入密碼就可以運行幾次sudo命令。
但是一段時間後,sudo 命令會再次要求你輸入密碼。默認是15分鐘,該時間可以調整。添加timestamp_timeout=分鐘數即可。
時間以分鐘爲單位,-1表示永不過期,但強烈不推薦。

比如我希望將時間延長到1小時,還是打開/etc/sudoers文件找到下述一行:

Defaults env_reset

修改成:

Defaults        env_reset,pwfeedback,timestamp_timeout=60

 

https://segmentfault.com/a/1190000007394449?utm_source=tag-newest

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章