sudo使用
Linux是多用戶多任務(wù)的操作系統(tǒng), 共享該系統(tǒng)的用戶往往不只一個(gè)。出于安全性考慮, 有必要通過useradd創(chuàng)建一些非root用戶, 只讓它們擁有不完全的權(quán)限; 如有必要,再來提升權(quán)限執(zhí)行。
sudo就是來解決這個(gè)需求的: 這些非root用戶不需要知道root的密碼,就可以提權(quán)到root,執(zhí)行一些root才能執(zhí)行的命令。
執(zhí)行sudo -u <用戶名> <命令>, 將允許當(dāng)前用戶,提權(quán)到<用戶名>的身份,再執(zhí)行后面的<命令>, 即使<命令>原本需要root權(quán)限。提權(quán)到<用戶名>身份時(shí),是以<用戶名>的身份來執(zhí)行命令的,因此創(chuàng)建的文件默認(rèn)屬于<用戶名>用戶。
因此,當(dāng)userB執(zhí)行如下命令時(shí):
sudo -u userA touch /tmp/belong-to-who.tmp
創(chuàng)建的/tmp/belong-to-who.tmp 文件屬于用戶userA。
如果不帶-u, 則默認(rèn)使用root用戶,而大多數(shù)時(shí)候sudo都是要提權(quán)到root的,所以-u <用戶名>可以省略為:
sudo <命令>
需要注意的是: 執(zhí)行sudo時(shí)輸入的密碼是當(dāng)前用戶的密碼, 并非<用戶名>的密碼。
sudo -u <用戶名>和su - <用戶名>相比:
sudo -u <用戶名>:需要輸入當(dāng)前用戶的密碼,提權(quán)到<用戶名>身份執(zhí)行命令后返回當(dāng)前用戶;
su - <用戶名>:則是輸入目標(biāo)用戶的密碼,切換到目標(biāo)用戶。
sudo命令執(zhí)行過程
將當(dāng)前用戶切換到超級用戶下,或切換到指定的用戶下,然后以超級用戶或其指定切換到的用戶身份執(zhí)行命令,執(zhí)行完成后,直接退回到當(dāng)前用戶。
具體工作過程如下:
當(dāng)用戶執(zhí)行sudo時(shí),系統(tǒng)會(huì)主動(dòng)尋找/etc/sudoers文件,判斷該用戶是否有執(zhí)行sudo的權(quán)限
–>確認(rèn)用戶具有可執(zhí)行sudo的權(quán)限后,讓用戶輸入用戶自己的密碼確認(rèn)
–>若密碼輸入成功,則開始執(zhí)行sudo后續(xù)的命令
賦予用戶sudo操作的權(quán)限
通過useradd添加的用戶,并不具備sudo權(quán)限。在ubuntu/centos等系統(tǒng)下, 需要將用戶加入admin組或者wheel組或者sudo組。以root用戶身份執(zhí)行如下命令, 將用戶加入wheel/admin/sudo組:
usermod -a -G wheel <用戶名>
如果提示wheel組不存在, 則還需要先創(chuàng)建該組:
groupadd wheel
/etc/sudoers內(nèi)容詳解
sudo的權(quán)限控制可以在/etc/sudoers文件中查看到。一般來說,通過cat /etc/sudoers指令來查看該文件, 會(huì)看到如下幾行代碼:
root ALL=(ALL:ALL) ALL
%wheel ALL=(ALL) ALL
%sudo ALL=(ALL:ALL) ALL
對/etc/sudoers文件進(jìn)行編輯的代碼公式可以概括為:
授權(quán)用戶/組 主機(jī)=[(切換到哪些用戶或組)] [是否需要輸入密碼驗(yàn)證] 命令1,命令2,...
凡是[ ]中的內(nèi)容, 都能省略; 命令和命令之間用,號分隔,為了方便說明, 將公式的各個(gè)部分稱呼為字段1 - 字段5:
授權(quán)用戶/組 主機(jī) =[(切換到哪些用戶或組)] [是否需要輸入密碼驗(yàn)證] 命令1,命令2,...
字段1 字段2 =[(字段3)] [字段4] 字段5
字段3、字段4,是可以省略的。
在上面的默認(rèn)例子中:
"字段1"不以%號開頭的表示"將要授權(quán)的用戶", 比如例子中的root;以%號開頭的表示"將要授權(quán)的組", 比如例子中的%wheel組 和 %sudo組。
"字段2"表示允許登錄的主機(jī), ALL表示所有; 如果該字段不為ALL,表示授權(quán)用戶只能在某些機(jī)器上登錄本服務(wù)器來執(zhí)行sudo命令. 比如:
jack mycomputer=/usr/sbin/reboot,/usr/sbin/shutdown
表示: 普通用戶jack在主機(jī)(或主機(jī)組)mycomputer上, 可以通過sudo執(zhí)行reboot和shutdown兩個(gè)命令。"字段3"和"字段4"省略。
"字段3"如果省略, 相當(dāng)于(root:root),表示可以通過sudo提權(quán)到root; 如果為(ALL)或者(ALL:ALL), 表示能夠提權(quán)到(任意用戶:任意用戶組)。請注意,"字段3"如果沒省略,必須使用( )雙括號包含起來。這樣才能區(qū)分是省略了"字段3"還是省略了"字段4"。
"字段4"的可能取值是NOPASSWD:。請注意NOPASSWD后面帶有冒號:。表示執(zhí)行sudo時(shí)可以不需要輸入密碼。比如:
lucy ALL=(ALL) NOPASSWD: /bin/useradd
表示: 普通用戶lucy可以在任何主機(jī)上, 通過sudo執(zhí)行/bin/useradd命令, 并且不需要輸入密碼.
又比如:
peter ALL=(ALL) NOPASSWD: ALL
表示: 普通用戶peter可以在任何主機(jī)上, 通過sudo執(zhí)行任何命令, 并且不需要輸入密碼。
"字段5"是使用逗號分開一系列命令,這些命令就是授權(quán)給用戶的操作; ALL表示允許所有操作。
命令都是使用絕對路徑, 這是為了避免目錄下有同名命令被執(zhí)行,從而造成安全隱患。如果你將授權(quán)寫成如下安全性欠妥的格式:
lucy ALL=(ALL) chown,chmod,useradd
那么用戶就有可能創(chuàng)建一個(gè)他自己的程序, 也命名為userad, 然后放在它的本地路徑中, 如此一來他就能夠使用root來執(zhí)行這個(gè)"名為useradd的程序"。這是相當(dāng)危險(xiǎn)的!
命令的絕對路徑可通過which指令查看到: 比如which useradd可以查看到命令useradd的絕對路徑: /usr/sbin/useradd
編輯/etc/sudoers
在實(shí)踐中,去編輯/etc/sudoers文件,系統(tǒng)提示我沒權(quán)限啊,怎么辦?這是因?yàn)?etc/sudoers的內(nèi)容如此敏感,以至于該文件是只讀的。所以,編輯該文件前,請確認(rèn)清楚你知道自己正在做什么。
強(qiáng)烈建議通過visudo命令來修改該文件,通過visudo修改,如果配置出錯(cuò),會(huì)有提示。
不過,系統(tǒng)文檔推薦的做法,不是直接修改/etc/sudoers文件,而是將修改寫在/etc/sudoers.d/目錄下的文件中。如果使用這種方式修改sudoers,需要在/etc/sudoers文件的最后行,加上#includedir /etc/sudoers.d一行(默認(rèn)已有):
includedir /etc/sudoers.d
注意了,這里的指令#includedir是一個(gè)整體, 前面的#號不能丟,并非注釋,也不能在#號后有空格。任何在/etc/sudoers.d/目錄下,不以~號結(jié)尾的文件和不包含.號的文件,都會(huì)被解析成/etc/sudoers的內(nèi)容。
文檔中是這么說的:
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.
命令作用域
papi ALL=(root) NOPASSWD: /bin/chown,/usr/sbin/useradd
表示: 用戶papi能在所有可能出現(xiàn)的主機(jī)上, 提權(quán)到root下執(zhí)行/bin/chown, 不必輸入密碼; 但運(yùn)行/usr/sbin/useradd 命令時(shí)需要密碼.
這是因?yàn)镹OPASSWD:只影響了其后的第一個(gè)命令: 命令1。上面給出的公式只是簡化版,完整的公式如下:
授權(quán)用戶/組 主機(jī)=[(切換到哪些用戶或組)] [是否需要輸入密碼驗(yàn)證] 命令1, [(字段3)] [字段4] 命令2, ...
在具有sudo操作的用戶下, 執(zhí)行sudo -l可以查看到該用戶被允許和被禁止運(yùn)行的命令.
通配符以及取消命令
papi ALL=/usr/sbin/,/sbin/,!/usr/sbin/fdisk
命令前面加上!號表示取消該命令。該例子的意思是: 用戶papi在所有可能出現(xiàn)的主機(jī)上, 能夠運(yùn)行目錄/usr/sbin和/sbin下所有的程序, 但fdisk除外。
輸入密碼時(shí)有反饋
當(dāng)使用sudo后輸入密碼,并不會(huì)顯示任何東西 —— 甚至連常規(guī)的星號都沒有。有個(gè)辦法可以解決該問題。打開/etc/sudoers文件找到下述一行:
Defaults env_reset
修改成:
Defaults env_reset,pwfeedback
修改sudo會(huì)話時(shí)間
如果你經(jīng)常使用sudo 命令,你肯定注意到過當(dāng)你成功輸入一次密碼后,可以不用再輸入密碼就可以運(yùn)行幾次sudo命令。但是一段時(shí)間后,sudo 命令會(huì)再次要求你輸入密碼。默認(rèn)是15分鐘,該時(shí)間可以調(diào)整。添加timestamp_timeout=分鐘數(shù)即可。時(shí)間以分鐘為單位,-1表示永不過期,但強(qiáng)烈不推薦。
比如我希望將時(shí)間延長到1小時(shí),還是打開/etc/sudoers文件找到下述一行:
Defaults env_reset
修改成:
Defaults env_reset,pwfeedback,timestamp_timeout=60
實(shí)踐
針對MySQL數(shù)據(jù)庫的設(shè)置,讓test組中的test用戶具備/etc/init.d/mysqld的權(quán)限:
[root@test ~]# groupadd test
[root@test ~]# useradd -g test -m -d /home/test -s /bin/bash test
[root@test ~]# passwd test
[root@test ~]# visudo
test ALL=(ALL) NOPASSWD: /etc/init.d/mysqld
test ALL=(ALL) /etc/init.d/mysqld
start mysql
[root@test ~]# su test
[test@test ~]$ sudo /etc/init.d/mysqld start
stop mysql
[root@test ~]# su test
[test@test ~]$ sudo /etc/init.d/mysqld stop
針對tomcat的設(shè)置,讓test組中的test用戶具備tomcat操作的權(quán)限:
[root@test ~]# groupadd test
[root@test ~]# useradd -g test -m -d /home/test -s /bin/bash test
[root@test ~]# passwd test
[root@test ~]# visudo
test ALL=(ALL) /usr/local/tomcat/bin/shutdown.sh,/usr/local/tomcat/bin/startup.sh
test ALL=(ALL) NOPASSWD: /usr/local/tomcat/bin/shutdown.sh,/usr/local/tomcat/bin/startup.sh
[root@test ~]# vim /usr/local/tomcat/bin/catalina.sh
JDK
export JAVA_HOME=/usr/local/jdk
export JRE_HOME=$JAVA_HOME/jre
start tomcat
[root@test ~]# su test
[test@test ~] ss -ntlup | grep Java
[test@test ~]$ curl -I http://localhost:8080
stop tomcat
[root@test ~]# su test
[test@test ~]$ sudo /usr/local/tomcat/bin/shutdown.sh
附錄:(sudoers文件詳解)
[root@test ~]# cat /etc/sudoers
Sudoers allows particular users to run various commands as
the root user, without needing the root password.
該文件允許特定用戶像root用戶一樣使用各種各樣的命令,而不需要root用戶的密碼
Examples are provided at the bottom of the file for collections
of related commands, which can then be delegated out to particular
users or groups.
在文件的底部提供了很多相關(guān)命令的示例以供選擇,這些示例都可以被特定用戶或
## 用戶組所使用
This file must be edited with the ‘visudo‘ command.
該文件必須使用"visudo"命令編輯
Host Aliases
主機(jī)別名
Groups of machines. You may prefer to use hostnames (perhap using
wildcards for entire domains) or IP addresses instead.
對于一組服務(wù)器,你可能會(huì)更喜歡使用主機(jī)名(可能是全域名的通配符)
或IP地址代替,這時(shí)可以配置主機(jī)別名
Host_Alias FILESERVERS = fs1, fs2
Host_Alias MAILSERVERS = smtp, smtp2
User Aliases
用戶別名
These aren‘t often necessary, as you can use regular groups
(ie, from files, LDAP, NIS, etc) in this file - just use %groupname
rather than USERALIAS
這并不很常用,因?yàn)槟憧梢酝ㄟ^使用組來代替一組用戶的別名
User_Alias ADMINS = jsmith, mikem
Command Aliases
These are groups of related commands...
指定一系列相互關(guān)聯(lián)的命令(當(dāng)然可以是一個(gè))的別名,通過賦予該別名sudo權(quán)限,
可以通過sudo調(diào)用所有別名包含的命令,下面是一些示例
Networking
網(wǎng)絡(luò)操作相關(guān)命令別名
Cmnd_Alias NETWORKING = /sbin/route, /sbin/ifconfig, /bin/ping, /sbin/dhclient,
/usr/bin/net, /sbin/iptables, /usr/bin/rfcomm, /usr/bin/wvdial, /sbin/iwconfig,
/sbin/mii-tool
Installation and management of software
軟件安裝管理相關(guān)命令別名
Cmnd_Alias SOFTWARE = /bin/rpm, /usr/bin/up2date, /usr/bin/yum
Services
服務(wù)相關(guān)命令別名
Cmnd_Alias SERVICES = /sbin/service, /sbin/chkconfig
Updating the locate database
本地?cái)?shù)據(jù)庫升級命令別名
Cmnd_Alias LOCATE = /usr/sbin/updatedb
Storage
磁盤操作相關(guān)命令別名
Cmnd_Alias STORAGE = /sbin/fdisk, /sbin/sfdisk, /sbin/parted, /sbin/partprobe, /bin/mount, /bin/umount
Delegating permissions
代理權(quán)限相關(guān)命令別名
Cmnd_Alias DELEGATING = /usr/sbin/visudo, /bin/chown, /bin/chmod, /bin/chgrp
Processes
進(jìn)程相關(guān)命令別名
Cmnd_Alias PROCESSES = /bin/nice, /bin/kill, /usr/bin/kill, /usr/bin/killall
Drivers
驅(qū)動(dòng)命令別名
Cmnd_Alias DRIVERS = /sbin/modprobe
環(huán)境變量的相關(guān)配置
Defaults specification
Disable "ssh hostname sudo <cmd>", because it will show the password in clear.
You have to run "ssh -t hostname sudo <cmd>".
Defaults requiretty
Defaults env_reset
Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"
Next comes the main part: which users can run what software on
which machines (the sudoers file can be shared between multiple
systems).
下面是規(guī)則配置:什么用戶在哪臺服務(wù)器上可以執(zhí)行哪些命令(sudoers文件可以在多個(gè)系統(tǒng)上共享)
Syntax:
語法
user MACHINE=COMMANDS
用戶 登錄的主機(jī)=(可以變換的身份) 可以執(zhí)行的命令
The COMMANDS section may have other options added to it.
命令部分可以附帶一些其它的選項(xiàng)
Allow root to run any commands anywhere
允許root用戶執(zhí)行任意路徑下的任意命令
root ALL=(ALL) ALL