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