su與sudo用法詳解
1. su和sudo詳解:切換用戶身份
在實際使用中,因為root功能過於強大,因此我們一般使用普通用戶進行系統管理和運行程序,當需要運行特權指令時則需要切換到root用戶進行操作,我們可以使用su - root直接切換到root身份運行命令,但是這種方式需要我們知道root密碼才可以操作;也可以使用sudo對用戶進行授權來實現,無需知道root密碼也可以實現提權操作。
1.1 shell登錄類型和環境配置文件
在介紹su命令前我們首先需要了解一下shell的登錄用戶類型和用戶登錄系統時需要讀取的配置文件。
-
shell登錄類型
- login shell:取得bash時需要完整的登錄流程,需要輸入用戶名密碼才能進入系統,例如從tty1-tty6進行登錄。
- non-login shell:取得bash時不需要完整的登錄流程,無需輸入用戶名密碼就能進入系統,例如在bash中運行bash開啟新會話。
-
shell登錄環境配置文件
shell登錄環境配置文件為用戶登錄shell時讀取的配置文件,共有以下幾類:
-
profile類文件:主要用於設定環境變量,登錄前運行的腳本和命令,主要有以下幾個文件:其中主目錄下的為用戶配置文件,只針對本用戶生效。/etc下的為全局配置文件,針對所有用戶生效。
-
/etc/profile
該文件主要設置系統變量,例如PATH,MAIL,HOSTNAME.USER等
-
/etc/profile.d/*.sh
該文件主要設置bash語系,顏色,vi別名,which別名,ls別名等,還可自定義變量
-
~/bash_profile
-
-
bashrc類文件:主要用於設定用戶別名,設定本地變量,主要有以下幾個文件:其中主目錄下的為用戶配置文件,只針對本用戶生效。/etc下的為全局配置文件,針對所有用戶生效。
-
/etc/bashrc
該文件主要設置PS1變量,umask值等
-
~/.bashrc
[root@xuzhichao ~]# cat ~/.bashrc # .bashrc # User specific aliases and functions alias rm='rm -i' alias cp='cp -i' alias mv='mv -i' # Source global definitions if [ -f /etc/bashrc ]; then . /etc/bashrc fi [root@xuzhichao ~]# cat ~/.bash_profile # .bash_profile # Get the aliases and functions if [ -f ~/.bashrc ]; then . ~/.bashrc fi # User specific environment and startup programs PATH=$PATH:$HOME/bin export PATH
-
-
-
對於login shell讀取配置文件的順序依次為:/etc/profile -> /etc/profile.d/*.sh -> ~/.bash_profile -> ~/.bashrc -> /etc/bashrc
-
對於non-login shell讀取配置文件的順序依次為:~/.bashrc -> /etc/bashrc -> /etc/profile.d/*.sh
1.2 su進行身份切換
su命令的語法格式為:
su [options] [-] [USER [arg]...]
su命令的常用選項如下:
選項 | 說明 |
---|---|
-,-l | 使用login shell方式切換用戶,未指定用戶,默認為root |
-c | 以切換的用戶身份執行命令而無需切換到該用戶 |
su命令的使用主要事項:
- su - username為login shell方式的切換,會讀取目標用戶的配置文件,切換至用戶家目錄,完全切換;
- su username為non-login shell方式的切換,不會讀取目標用戶的配置文件,不改變當前工作目錄,非完全切換;
- 切換用戶時一般使用bash shell方式的切換,即su - username;
- root用戶切換到普通用戶無需輸入普通用戶的密碼;
- 普通用戶切換到root用戶時需要輸入root用戶的密碼才可切換成功;
- su切換到新用戶相當於新開啟了一個bash子進程,要回到切換前用戶使用exit退出即可;
su的使用示例如下:
#示例一:登錄式切換和非登陸式切換的區別,登錄式切換的工作目錄和PATH都會重新讀取用戶配置文件而發生變化,而非登陸式切換不會變化。
[root@xuzhichao ~]# echo $PATH
/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@xuzhichao ~]# pwd
/root
[root@xuzhichao ~]# su xu
bash: colorscheme: command not found
[xu@xuzhichao root]$ echo $PATH
/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[xu@xuzhichao root]$ pwd
/root
[xu@xuzhichao root]$ exit
exit
[root@xuzhichao ~]# su - xu
Last login: Sun May 30 22:10:09 CST 2021 on pts/0
-bash: colorscheme: command not found
[xu@xuzhichao ~]$ echo $PATH
/usr/lib64/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/xu/.local/bin:/home/xu/bin
[xu@xuzhichao ~]$ pwd
/home/xu
#示例二:su -c選項
[root@xuzhichao ~]# su - xu -c "pwd"
/home/xu
1.3 sudo命令詳解
su命令切換到root用戶時需要知道root用戶的密碼才能切換,並不適合管理使用,使用sudo可以實現普通用戶無需root密碼而執行特權指令。
使用sudo時,需要root用戶首先在sudo配置文件/etc/sudoers中對用戶進行授權才可實現。
普通用戶使用sudo命令的所有操作的審計日志均放置在/var/log/secure中。
[root@xuzhichao ~]# tail /var/log/secure
Jun 1 01:39:42 localhost sudo: xu : TTY=pts/2 ; PWD=/home/xu ; USER=root ; COMMAND=list
Jun 1 01:40:10 localhost sudo: pam_unix(sudo:auth): conversation failed
Jun 1 01:40:10 localhost sudo: pam_unix(sudo:auth): auth could not identify password for [xu]
Jun 1 01:40:12 localhost sudo: xu : command not allowed ; TTY=pts/2 ; PWD=/home/xu ; USER=root ; COMMAND=on %h for user %p:” sleep 100
Jun 1 01:40:25 localhost sudo: xu : command not allowed ; TTY=pts/2 ; PWD=/home/xu ; USER=root ; COMMAND=/bin/sleep 100
Jun 1 01:44:55 localhost sudo: xu : TTY=pts/2 ; PWD=/home/xu ; USER=root ; COMMAND=/sbin/useradd zabbix
Jun 1 01:44:55 localhost sudo: pam_unix(sudo:session): session opened for user root by root(uid=0)
Jun 1 01:44:55 localhost useradd[4911]: new group: name=zabbix, GID=1007
Jun 1 01:44:55 localhost useradd[4911]: new user: name=zabbix, UID=1007, GID=1007, home=/home/zabbix, shell=/bin/bash
Jun 1 01:44:55 localhost sudo: pam_unix(sudo:session): session closed for user root
1.3.1 visudo
visudo命令用戶編輯/etc/sudoers,類似於vi /etc/sudoers。
通過visudo命令編輯配置文件,具有語法檢查功能。
使用export EDITOR=vim,可以使visodu命令調用vim,默認調用vi
使用visudo編輯配置文件功能,如果修改存在錯誤,保存時會出現報錯提示。
[root@xuzhichao ~]# visudo
/etc/sudoers: syntax error near line 103 <<<
What now?
Options are:
(e)dit sudoers file again <==再次編輯
e(x)it without saving changes to sudoers file <==不保存退出
(Q)uit and save changes to sudoers file (DANGER!) <==保存退出
visudo –c 檢查語法,故意將配置文件修改錯,執行命令:
[root@xuzhichao ~]# visudo -c
/etc/sudoers: syntax error near line 103 <<<
parse error in /etc/sudoers near line 103
visudo -f選型可以編輯子配置文件:
[root@xuzhichao ~]# visudo -f /etc/sudoers.d/xu
1.3.2 /etc/sudoers配置文件
sudo的配置文件為/etc/sudoers以及/etc/sudoers.d/下的文件。
/etc/sudoers文件中對用戶授權的格式為:
user host=(runas) command
格式說明:
-
user: 被授權者的用戶身份,可以是如下形式
- username:用戶名,如xu
- #uid:如#1111
- %group:用戶組,如%wheel
- %#gid:組id,如%#1000
-
host: 被授權者在哪些主機上進行操作
- ip地址:192.168.1.1
- 主機名:maipu.com
- 網段:10.0.0.0/24
-
(runas):以哪個用戶的身份運行后面的命令,如果為空,默認為root
- username:用戶名,如xu
- #uid:如#1111
- %group:用戶組,如%wheel
- %#gid:組id,如%#1000
-
command: 被授權運行的命令
- 命令:/bin/mount,注意:命令需要使用絕對路徑;當授權的命令帶參數時會嚴格匹配命令參數,當授權命令不帶參數時,會允許命令加參數執行。
- 目錄:/sbin,允許用戶指定目錄下的命令
-
在/etc/sudoers中有特殊的兩項內容:
root ALL=(ALL) ALL
表示配置文件中存在此項,意思是root永久為管理員
%wheel ALL=(ALL) ALL
表示wheel組的成員可以在所有客戶端執行所有操作,因此可以將普通用戶加入wheel組即可用戶root權限。注意:wheel需要為用戶的基本組時才有效,而不能是附加組
/etc/sudoers文件的使用示例:
#示例一:授權用戶xu可以使用root身份執行任何操作
[root@xuzhichao ~]# visudo
xu ALL=(root) ALL
#示例二:授權xu1用戶特定的命令
#寫入配置文件
[root@xuzhichao ~]# visudo
xu1 ALL=(root) /bin/mount /dev/sr0 /mnt
#切換到用戶xu1
[root@xuzhichao ~]# su - xu1
#授權過后也不能直接執行
[xu1@xuzhichao ~]$ mount /dev/sr0 /mnt/
mount: only root can do that
#使用sudo的命令是需要嚴格遵守配置文件中的命令的,例如/mnt后面多個一個/,命令的執行就會失敗。
[xu1@xuzhichao ~]$ sudo mount /dev/sr0 /mnt/
We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:
#1) Respect the privacy of others.
#2) Think before you type.
#3) With great power comes great responsibility.
[sudo] password for xu1: <==此處輸入的是xu1用戶的密碼,不是root密碼。
Sorry, user xu1 is not allowed to execute '/bin/mount /dev/sr0 /mnt/' as root on xuzhichao.
#命令執行成功
[xu1@xuzhichao ~]$ sudo mount /dev/sr0 /mnt
[sudo] password for xu1:
mount: /dev/sr0 is write-protected, mounting read-only
[xu1@xuzhichao ~]$ df
Filesystem 1K-blocks Used Available Use% Mounted on
devtmpfs 914464 0 914464 0% /dev
tmpfs 931520 0 931520 0% /dev/shm
tmpfs 931520 10128 921392 2% /run
tmpfs 931520 0 931520 0% /sys/fs/cgroup
/dev/mapper/centos-root 52403200 6521028 45882172 13% /
/dev/sda1 508580 171960 336620 34% /boot
tmpfs 186304 0 186304 0% /run/user/0
/dev/sr0 10032746 10032746 0 100% /mnt
#對於未授權的命令則不允許執行
[xu1@xuzhichao ~]$ sudo umount /dev/sro
[sudo] password for xu1:
Sorry, user xu1 is not allowed to execute '/bin/umount /dev/sro' as root on xuzhichao.
#示例三:授權多個命令,命令之間用逗號隔開即可
[root@xuzhichao ~]# visudo
xu1 ALL=(root) /bin/mount /dev/sr0 /mnt,/bin/umount
#此時用戶xu1執行umount成功
[xu1@xuzhichao ~]$ sudo umount /dev/sr0
[xu1@xuzhichao ~]$ df
Filesystem 1K-blocks Used Available Use% Mounted on
devtmpfs 914464 0 914464 0% /dev
tmpfs 931520 0 931520 0% /dev/shm
tmpfs 931520 10120 921400 2% /run
tmpfs 931520 0 931520 0% /sys/fs/cgroup
/dev/mapper/centos-root 52403200 6520836 45882364 13% /
/dev/sda1 508580 171960 336620 34% /boot
tmpfs 186304 0 186304 0% /run/user/0
-
在/etc/sudoers中支持通配符:
符號 含義 ? 任意單一字符 * 匹配任意長度字符 [wxc] 匹配其中一個字符 [!wxc] 除了這三個字符的其它字符 \x 轉義 [[:alpha:]] 字母 通配符的使用示例如下:
#示例一: #授權xu1用戶允許查看/var/log/messages文件 [root@xuzhichao ~]# visudo xu1 ALL=(root) /bin/cat /var/log/messages #用戶xu1可以查看/var/log/messages文件 [xu1@xuzhichao ~]$ sudo cat /var/log/messages [sudo] password for xu1: May 31 21:54:16 localhost systemd: Reached target Remote File Systems. May 31 21:54:16 localhost systemd: Starting Crash recovery kernel arming... May 31 21:54:16 localhost systemd: Starting Permit User Sessions... May 31 21:54:16 localhost systemd: Starting Availability of block devices... May 31 21:54:16 localhost rpc.statd[1225]: Version 1.3.0 starting ...... #但是無法查看/var/log/messages-20210506文件 [xu1@xuzhichao ~]$ sudo cat /var/log/messages-20210506 [sudo] password for xu1: Sorry, user xu1 is not allowed to execute '/bin/cat /var/log/messages-20210506' as root on xuzhichao. #如果需要讓xu1可以查看上述文件,可以授權如下: [root@xuzhichao ~]# visudo xu1 ALL=(root) /bin/cat /var/log/messages* #xu1可以查看/var/log/messages-20210506文件 [xu1@xuzhichao ~]$ sudo cat /var/log/messages-20210506 [sudo] password for xu1: May 5 23:30:01 centos7-8 systemd: Started Session 18 of user root. May 5 23:40:01 centos7-8 systemd: Started Session 19 of user root. May 5 23:50:01 centos7-8 systemd: Started Session 20 of user root. May 5 23:53:01 centos7-8 systemd: Started Session 21 of user root. May 6 00:00:01 centos7-8 systemd: Started Session 22 of user root. May 6 00:01:01 centos7-8 systemd: Started Session 23 of user root. May 6 00:10:01 centos7-8 systemd: Started Session 24 of user root. ...... #但是上述配置存在重大漏洞,用戶xu1可以查看/etc/passwd文件內容 [xu1@xuzhichao ~]$ sudo cat /var/log/messages /etc/passwd ...... root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown ...... #因此需要嚴格規定授權命令,即/var/log/messages后不能加空格 [root@xuzhichao ~]# visudo xu1 ALL=(root) /bin/cat /var/log/messages* !/bin/cat /var/log/messages* * #用戶xu1無法查看重要文件 [xu1@xuzhichao ~]$ sudo cat /var/log/messages /etc/passwd Sorry, user xu1 is not allowed to execute '/bin/cat /var/log/messages /etc/passwd' as root on xuzhichao.
#示例二:授權xu2用戶可以使用passwd命令修改密碼,但是不能修改root的密碼 [root@xuzhichao ~]# visudo xu2 ALL=(ALL) /usr/bin/passwd,/usr/bin/passwd [a-zA-Z]*,!/usr/bin/passwd root [root@xuzhichao ~]# su - xu2 #修改root密碼失敗 [xu2@xuzhichao root]$ sudo passwd We trust you have received the usual lecture from the local System Administrator. It usually boils down to these three things: #1) Respect the privacy of others. #2) Think before you type. #3) With great power comes great responsibility. [sudo] password for xu2: Sorry, user xu2 is not allowed to execute '/bin/passwd' as root on xuzhichao. #可以修改其他用戶的密碼 [xu2@xuzhichao root]$ sudo passwd xu1 [sudo] password for xu2: Changing password for user xu1. New password: Retype new password: passwd: all authentication tokens updated successfully.
-
NOPASS的用法:以上示例中發現使用sudo執行命令時需要輸入自己的密碼,使用NOPASSWD可以執行命令時不需輸入密碼。
#示例:授權用戶xu2可以使用passwd,useradd,usermod命令,其中useradd無需輸入密碼就可使用 [root@xuzhichao ~]# visudo xu2 ALL=(ALL) /usr/bin/passwd,/usr/bin/passwd [a-zA-Z]*,!/usr/bin/passwd root,NOPASSWD:/usr/sbin/useradd,/usr/sbin/usermod #使用useradd命令無需輸入自身密碼 [xu2@xuzhichao root]$ sudo useradd wang1 [xu2@xuzhichao root]$ id wang1 uid=1018(wang1) gid=1018(wang1) groups=1018(wang1)
-
sudoedit命令:授權普通用戶可以編輯配置文件
#允許xu3用戶自行修改/etc/sudoers文件 [root@xuzhichao ~]# visudo xu3 ALL=(ALL) sudoedit #用戶xu3自行修改/etc/sudoers文件完成授權 [root@xuzhichao ~]# su - xu3 [xu3@xuzhichao root]$ sudoedit /etc/sudoers [sudo] password for xu3:
-
使用sudo配合su可以實現多人共同管理一台主機
#示例:允許xu4用戶使用sudo切換到root用戶 [root@xuzhichao ~]# visudo xu4 ALL= /usr/bin/su - #xu4用戶輸入自己密碼就會進入root身份 [root@xuzhichao ~]# su - xu4 [xu4@xuzhichao ~]$ sudo su - [sudo] password for xu4: Last login: Tue Jun 1 08:47:44 CST 2021 from 192.168.20.1 on pts/3 [root@xuzhichao ~]#
1.3.3 別名的用法
當用戶和授權命令比較多時,可以使用別名方式簡化授權的配置。
-
/etc/sudoers文件中支持的別名有四種:
- User_Alias:用戶別名
- Runas_Alias:運行身份的別名
- Host_Alias:主機別名
- Cmnd_Alias:命令別名
-
別名命名要求:
開頭必須為大寫字母,后續為大寫字母或數字加下划線組合[A-Z]([A-Z][0-9]_)*
-
別名定義格式:
Alias_Type NAME1 = item1, item2, item3 : NAME2 = item4, item5
先定義別名類型,如User_Alias。NAME1為別名的=名稱,后續將別名的內容一個一個以逗號隔開;
可以一次定義多個通類型的別名,中間冒號隔開。
-
別名的示例如下:
#示例1:定義的別名可以包含n個內容,以逗號分隔 [root@xuzhichao ~]# visudo #定義運行命令用戶別名為NETADMIN User_Alias NETADMIN= xu1,xu2 #定義授權操作別名為NETCMD Cmnd_Alias NETCMD = /usr/sbin/ip,/usr/sbin/ifconfig #授權配置如下,允許用戶xu1,xu2在所有主機上以root身份執行ip,ifconfig命令 NETADMIN ALL=(root) NETCMD #示例2:同類型別名可以疊加使用,中間以逗號分隔 #定義運行命令用戶別名為SYSADER,包含wang,mage,%admins被授權者 User_Alias SYSADER=wang,wang1,%admins #定義運行命令用戶tom別名為DISKADER User_Alias DISKADER=tom #定義主機別名為SERS,內容如下 Host_Alias SERS=www.maipu.com,172.16.0.0/24 #定義匹配用戶別名為OP Runas_Alias OP=root #定義2個授權操作別名,分別為SYDCMD和DSKCMD Cmnd_Alias SYDCMD=/bin/chown,/bin/chmod Cmnd_Alias DSKCMD=/sbin/parted,/sbin/fdisk #授權配置如下: 用戶SYSADER匹配root身份,在SERS主機上,授權操作 SYDCMD,DSKCMD SYSADER SERS= SYDCMD,DSKCMD #用戶DISKADER,在所有主機上匹配OP,授權DSKCMD DISKADER ALL=(OP) DSKCMD #示例3:一次定義同一類型多個別名,中間以冒號分隔 User_Alias SYSADER=wang,mage,%admins : DISKADER=tom #示例4:默認用戶配置 #默認用戶配置格式,表示默認運行用戶wang,匹配的用戶為tom Defaults:wang runas_default=tom #設置默認配置后,如下配置表示匹配用戶tom wang ALL= ALL
1.3.4 sudo命令的用法
sudo命令的語法格式為:
sudo [-u user] COMMAND
sudo命令的常用選項如下:
選項 | 說明 |
---|---|
-u user | 表示切換到user用戶執行后續命令,可以省略,省略后默認表示切換到root用戶執行命令。 |
-l | 列出當前用戶在主機上可用的命令和被禁止的命令 |
-v | 再延長密碼有效期限5分鍾,更新時間戳,也就是下次驗證時間 |
-k | 清除時間戳(1970-01-01),下次需要重新輸密碼 |
-K | 與-k類似,還要刪除時間戳文件 |
-b | 在后台執行指令,例如執行sleep時 |
-p | 改變詢問密碼的提示符號,系統默認格式為[sudo] password for %p : |
-V | 顯示sudo的版本和其他詳細信息 |
sudo的使用示例如下:
#示例一:查看當前用戶可以支持使用的sudo命令
[xu@xuzhichao ~]$ sudo -l
......
User xu may run the following commands on xuzhichao:
(root) /usr/bin/passwd, /usr/bin/passwd [a-zA-Z]*, !/usr/bin/passwd root, NOPASSWD: /usr/sbin/useradd, /usr/sbin/usermod
#示例二:修改詢問密碼的提示符號,%p代表用戶名,%h代表主機名
[xu@xuzhichao ~]$ sudo -p "password on %h for user %p:" useradd wang
password on xuzhichao for user xu:
-
sudo的密碼時間問題:
授權用戶使用sudo時,需要驗證身份,輸入自己的登錄密碼通過驗證。默認5分鍾內無需輸入密碼即可執行sudo命令,如果長時間不操作(默認等待5分鍾),系統就會從新驗證用戶身份。
/run/sudo/ts/下的文件用於記錄每個用戶使用sudo時的時間戳信息,時間戳文件的文件名就是用戶名,文件創建的時間就是用戶輸入sudo密碼的時間。
#示例: #編輯xu用戶授權信息 [root@xuzhichao ~]# visudo xu ALL= /usr/bin/passwd,/usr/bin/passwd [a-zA-Z]*,!/usr/bin/passwd root,NOPASSWD:/usr/sbin/useradd,/usr/sbin/usermod #切換到xu用戶,執行命令 [root@xuzhichao ~]# su - xu [xu@xuzhichao ~]$ sudo useradd wang [sudo] password for xu: #上述命令需要輸入xu用戶,此時會在/run/sudo/ts/中生成一個以xu為用戶名的文件,時間就是輸入密碼的時間。 [root@xuzhichao ~]# ll /run/sudo/ts/ total 4 -rw-------. 1 root xu 112 Jun 1 01:19 xu #之后5分鍾內使用sudo都無需輸入密碼,但是當超過5分鍾未使用sudo,再次使用sudo時會再次提示輸入密碼,同時會更新/run/sudo/ts/xu文件的時間戳。 [xu@xuzhichao ~]$ sudo useradd wang1 #sudo -v命令可以延長密碼有效期限5分鍾,也就是更新/run/sudo/ts/xu文件的時間戳 [xu@xuzhichao ~]$ sudo -v [sudo] password for xu: [root@xuzhichao ~]# ll /run/sudo/ts/ total 4 -rw-------. 1 root xu 112 Jun 1 01:35 xu #sudo -k可以清除時間戳,下次使用sudo強制輸入密碼,-K會同時刪除時間戳文件 [xu@xuzhichao ~]$ sudo -K [root@xuzhichao ~]# ll /run/sudo/ts/ total 0