# 使用者身份切换
身份变化可能有以下几个原因:
使用一般账户:系统平时操作的好习惯
为了安全,一般都会建议尽量以一般身份使用者来操作 Linux 的日常工作。等到需要设置系统环境时,才切换成 root 来管理系统,相对比较安全,避免误操作一些严重的指令,例如
rm -rf /
用较低权限启动系统服务
比如:apache 软件,创建一个 apache 用户来启动它,就算该软件被攻破了,至少不至于损坏整个系统;
软件本身的限制
在远古时代的 telnet 程序中,默认是不允许使用 root 身份登录的,若发现是 UID=0 的登录直接拒绝登录;此外 ssh 也可以设置拒绝 root 登录的
由于上述考虑,没有系统设定等的特殊需求下,都是使用的一般账户登录,如果有则可以变换身份,主要有两种方式:
su
:以su -
指令直接将身份变成 root该指令需要 root 密码,输入验证成功后才可以切换成 root 身份
sudo
:以sudo 指令
执行指令串由于 sudo 需要实现设置,且 sudo 需要输入用户自己的密码,因此多人共同管理同一部主机时, sudo 要比 su 好,至少 root 密码不会流传出去
# su
最简单的身份切换指令,可以进行任何身份的切换
su [-lm] [-c 指令] [username]
选项与参数:
-
:单纯使用su -
表示使用 login-shell 的变量文件读取方式来登录系统,若使用者名称没有加上去,则代表切换为 root 身份-l
:与-
类似,单后面需要加要切换的使用者账户,也是 login-shell 的方式m
:与-p
是一样的,表示:使用目前的环境设置,而不读取新使用者的配置文件-c
:仅进行一次指令,所以-c
后面可以加上指令
前面讲解过 login-shell 是啥,这里有没有加上 -
的指令涉及到了 login-shell 与 non-login shell 的变量读取方式,下面以例子说明
# 范例 1: 假设现在身份是 mrcode , 想要使用 non-login shell 的方式变成 root
[mrcode@study ~]$ su # 注意提示字符是 mrcode 身份
Password:
[root@study mrcode]# id
# id 识别的确是 root 身份
uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
# 查看环境变量中
[root@study mrcode]# env | grep 'mrcode'
HOSTNAME=study.centos.mrcode
USER=mrcode # 当前用户还是 mrcode
PATH=/usr/lib64/qt-3.3/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/mrcode/.local/bin:/home/mrcode/bin # 这个影响最大,只找了 /home/mrcode
MAIL=/var/spool/mail/mrcode # 信箱也是
PWD=/home/mrcode # 也并非是 root 的家的目录
LOGNAME=mrcode
XDG_DATA_DIRS=/home/mrcode/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share
# 虽然 UID 已经具有 root 的身份,但是还有一堆变量是原本 mrcode 的身份,所以还是有很多数据无法直接利用
# 离开当前的 su 环境
[root@study mrcode]# exit
exit
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
所以单纯的使用 su 切换成 root 方式,。读取的变量设定方式为 non-login shell 的方式,这种方式很多原本的变量不会被改变,尤其是很重要的 PATH 变量,由于没有改变为 root 环境,因此很多 root 管惯用的指令就只能使用绝对路径来执行。所以执行切换身份时,务必使用以下范例
# 范例 2:使用 login shell 的方式切换为 root 的身份并观察变量
[mrcode@study ~]$ su -
Password: # 输入 root 密码登录
Last login: Tue Feb 25 10:47:26 CST 2020 on pts/1
[root@study ~]# env | grep root
USER=root
MAIL=/var/spool/mail/root
PATH=/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
PWD=/root
HOME=/root
LOGNAME=root
XDG_DATA_DIRS=/root/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share
XAUTHORITY=/root/.xauthL0s7Pj
# 可以看到环境变量都变成 root 的了
[root@study ~]# env | grep mrcode
HOSTNAME=study.centos.mrcode
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
同样可以使用 exit 指令离开 root 身份,如果只是想使用 root 执行一次命令,就恢复原本的身份可以使用 -c
选项
# 范例 3:mrcode 要执行 hread -n 3 /etc/shadow 一次,已知 root 密码
[mrcode@study ~]$ head -n 3 /etc/shadow
head: cannot open '/etc/shadow' for reading: Permission denied
[mrcode@study ~]$ su - -c "head -n 3 /etc/shadow"
Password: # 输入 root 密码
root:$6$eC75oi.rU.wJPhgN$C.C.qFXTvmJ64qFnez88TdcsHuuQAqtAYrukgBYBspgSZbCgzvJuv4OVJ9gaEfA2/.T7e68AZW7RoZt6ubeHD0::0:99999:7:::
bin:*:17834:0:99999:7:::
daemon:*:17834:0:99999:7:::
[mrcode@study ~]$ # 注意看这里的身份还是 mrcode
2
3
4
5
6
7
8
9
10
那么怎么切换为其他账户呢?
# 范例 4:原本是 mrcode 使用者,想要变换身份为 mrcode1
[mrcode@study ~]$ su -l mrcode1
Password: # 输入 mrcode1 的密码
Last login: Mon Feb 24 17:35:35 CST 2020 from 192.168.4.170 on pts/2
[mrcode1@study ~]$ su -
密码: # 输入 root 的密码,切换到 root
上一次登录:二 2月 25 10:58:09 CST 2020pts/1 上
[root@study ~]# id sshd # 查看这个账户,发现有该账户
uid=74(sshd) gid=74(sshd) 组=74(sshd)
[root@study ~]# su -l sshd
This account is currently not available. # 提示无法切换到 sshd
[root@study ~]# finger sshd # 查看他的信息如下
Login: sshd Name: Privilege-separated SSH
Directory: /var/empty/sshd Shell: /sbin/nologin # 这里的 nologin 问题
Last login 二 2月 25 11:00 (CST) on pts/1
No mail.
No Plan.
[root@study ~]# exit
登出 # 离开第 2 次的 su
[mrcode1@study ~]$ exit
登出 # 离开第 1 次的 su
[mrcode@study ~]$ # 这里又回到了最初的 mrcode 身份
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 小结用法
- 若要完整的切换到新使用者的环境,比如要使用
su - username 或 su -l username
,才会连同 PATH、USER、MAIL 等变量都转成新用户的环境 - 如果仅想要执行一次 root 的指令,可以利用
su -c "指令串"
的方式来处理 - 使用 root 切换称为任何使用者时,并不需要输入新用户的密码
# sudo
相对于 su 需要了解切换用户的密码(常常是 root 的密码),而 sudo 的执行仅需要自己的密码,还可以设置不需要密码就可以执行 sudo;由于 sudo 可以让你以其他用户的身份执行指令,(通常是利用 root 身份执行命令),所以并非所有人都能够执行 sudo,而是需要规范到 /etc/sudoers
内的用户才能够执行 sudo 指令
TIP
一般用户能够具有 sudo 的使用权,是经过管理员审核通过后,也就是受信任的账户,否则一般用户默认是不能操作 sudo 的
# sudo 的指令用法
由于系统默认仅有 root 可以执行 sudo,因此下面的范例先使用 root 来执行。等谈到 visudo 时,再已一般使用者来讨论其他 sudo 的用法
TIP
最初情况下是只有 root 能执行 sudo 的,但是在安装 CentOs 时,创建了一个用户,这个用户也具有 sudo 的权限
sudo [-b][-u 新使用者账户]
选项与参数:
-b:将后续的指令放到背景中让系统自动执行,而不与目前的 shell 产生影响
-u:后面可以接要切换的使用者账户,若没此项,则表示切换到 root 身份
2
3
4
5
# 范例 1:想要以 sshd 的身份在 /tmp 下创建一个名为 myssh 的文件
[root@study ~]# sudo -u sshd touch /tmp/mysshd
您在 /var/spool/mail/root 中有新邮件
[root@study ~]# ll /tmp/mysshd
-rw-r--r--. 1 sshd sshd 0 2月 25 13:04 /tmp/mysshd
# 可以看到是由 ssh 创建的
# 范例 2:以 mrcode1 的身份创建 ~Vbird1/www 并在其中创建 index.html 文件
[root@study ~]# sudo -u mrcode1 sh -c "mkdir ~mrcode1/www; cd ~mrcode1/www; echo 'This is index.html' > index.html"
[root@study ~]# ll -a ~mrcode1/www/
总用量 4
drwxr-xr-x. 2 mrcode1 mrcode1 24 2月 25 13:15 .
drwx------. 7 mrcode1 mrcode1 201 2月 25 13:15 ..
-rw-r--r--. 1 mrcode1 mrcode1 19 2月 25 13:15 index.html
# 注意上面 那个 sh -c "" 这一串不是 sudo 的参数,是指令;sh --help 可以看到 sh -c "指令串",是利用 sh 执行命令
2
3
4
5
6
7
8
9
10
11
12
13
14
15
范例 2 使用 sh -c 来执行多重指令。
为什么 sudo 预设仅有 root 能使用?是因为 sudo 的执行流程如下:
- 当用户执行 sudo 时,系统与
/etc/sudoers
文件中搜索该使用者是否有执行 sudo 的权限 - 若使用者具有可执行 sudo 的权限后,便让使用者「输入用户自己的密码」来确认
- 若密码输入成功,变开始进行 sudo 后续接的指令(root 执行 sudo 时不需要密码)
- 若要切换的身份与执行者身份相同,也不需要输入密码
所以是否能使用 sudo ,必须要看 /etc/sudoers
中是否有配置,这种文件都有自己的规范,所以提供了一个 visudo 指令来帮助管理该文件
# visudo 与 /etc/sudoers
使用 visudo 来修改,在结束离开时,会校验 /etc/sudoers
的语法,来避免修改错误的语法导致 sudo 无法使用
一般来说,visduo 的设置方式有几种简单的方法,下面介绍几个简单的例子来说明
# 单一用户使用 sudo
单一用户可进行 root 所有指令,与 sudoers 文件语法:
# 让 mrcode1 账户可以使用 root 的任何指令,基本上有两种方式:
# 1. 直接修改 /etc/sudoers
[root@study ~]# visudo
:set nu # 显示行号
100 root ALL=(ALL) ALL
101 mrcode1 ALL=(ALL) ALL # 在 100 行后,添加 mrcode1 的数据
# 然后保存离开
2
3
4
5
6
7
其实 visudo 利用 vi 将文件打开修改。
使用者账户 登陆者的来源主机名=(可切换的身份) 可下达的指令
root ALL=(ALL) ALL
2
各字段含义如下:
- 使用者账户:系统中那个账户可以使用 sudo 指令
- 登陆者的来源主机名:就是信任哪一台网络主机可以联机,这个值可以指定客户端计算机。默认的 ALL 是允许任何一台网络主机
- 可切换的身份:这个账户可以切换成什么身份来下达后续的指令。默认 root 可以切换成任何人
- 可下达的指令:可用该身份下达什么指令?这个指令请务必使用绝对路径,预设 root 可以切换任何身份且下达任何指令
All 是特殊的关键词,代表任何身份、主机、指令
# 进行测试
[mrcode1@study ~]$ tail -n 1 /etc/shadow # 这里是 mrcode1 登录的
# 提示权限不足
tail: cannot open '/etc/shadow' for reading: Permission denied
# 使用 sudo 来执行
[mrcode1@study ~]$ sudo tail -n 1 /etc/shadow
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 mrcode1: # 然后输入 mrcode1 自己的密码,就可以执行了
pro3:$6$oku6c8Az$GUOVL1SkmFnSnVHvUCKnToNv8l7094dQ17/GOw/R5mdxqiE0THtkFaO4GpzFMxJy30rZbpWgQcNSpMqHN8KWT/:18316:0:99999:7:::
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
利用 wheel 群组以及免密码的功能处理 visudo
# wheel 群组使用 sudo
之前曾建立过 pro1、pro2、pro3 让这 3 个用户也可以使用 sudo,但是通过群组的方式来支持
# 1. 使用 visudo 设置 whell 群组
visudo
99 ## Allow root to run any commands anywhere
100 root ALL=(ALL) ALL
101 mrcode1 ALL=(ALL) ALL
102
103 ## Allows members of the 'sys' group to run networking, software,
104 ## service management apps and more.
105 # %sys ALL = NETWORKING, SOFTWARE, SERVICES, STORAGE, DELEGATING, PROCESSES, LOCATE, DRIVERS
106
107 ## Allows people in group wheel to run all commands
108 %wheel ALL=(ALL) ALL
# 在最左边增加 % 表示是一个群组,注意在编辑的时候,当时笔者吧 $wheel 这一行写在 上面 root 后面,报错就报错说有语法错误,不知道是否也有识别,需要写到这个 Allows people in group wheel to run all commands 这一行下面呢?
# 注意: whell 这个配置默认已经配置过了,并且该组也已经存在了。应该是系统初始化就有的
# 2. 将 pro1 添加进 wheel 群组
[root@study ~]# usermod -a -G wheel pro1
# 3. 切换到 pro1 、pro2 并执行 sudo 命令查看
[root@study ~]# su -l pro1
[pro1@study ~]$ sudo tail -n 1 /etc/shadow
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 pro1:
pro3:$6$oku6c8Az$GUOVL1SkmFnSnVHvUCKnToNv8l7094dQ17/GOw/R5mdxqiE0THtkFaO4GpzFMxJy30rZbpWgQcNSpMqHN8KWT/:18316:0:99999:7:::
# 切换到 pro2
[root@study ~]# su -l pro2
[pro2@study ~]$ export LANG=C
[pro2@study ~]$ sudo tail -n 1 /etc/shadow
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 pro2:
pro2 is not in the sudoers file. This incident will be reported.
# 提示 pro2 不在 sudoers 文件中
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
那么这里对群组进行了支持,pro2 和 pro3 也要支持 sudo 的话,直接使用 usermod 将他们添加到 wheel 组中即可
前面说安装系统创建的用户,直接设置为了管理员的话,也是可以使用 sudo 指令的,这个操作就是将那个账户添加到了 wheel 组了
[mrcode@study ~]$ id mrcode
uid=1000(mrcode) gid=1000(mrcode) groups=1000(mrcode),100(users)
[mrcode@study ~]$ id pro1
uid=1505(pro1) gid=1508(pro1) groups=1508(pro1),10(wheel),1507(projecta)
[mrcode@study ~]$ sudo cat /etc/shadow
[sudo] password for mrcode:
mrcode is not in the sudoers file. This incident will be reported.
# 我们这里看到,这里的账户并没有加入 wheel 这个组,实际执行 sudo 的话,也会提示不支持;
# 这就说明当时我并没有选择添加为管理员
2
3
4
5
6
7
8
9
10
11
12
从 Centos 7 开始, %wheel
这行默认存在,并且也有这个组
# 免密使用 sudo
既然管理员都信任这些用户了,是否可以提供:不需要密码就可以使用 sudo 呢?
[root@study ~]# visudo
## Allows people in group wheel to run all commands
# %wheel ALL=(ALL) ALL
## Same thing without a password
%wheel ALL=(ALL) NOPASSWD: ALL
2
3
4
5
6
7
找到上述地方,在第三个字段,将 NOPASSWD 哪一行放开,把上面原始的注释掉。也就是在可下达的指令前使用 NOPASSWD:
来标识不需要密码
# 有限制的指令操作
上面的配置可以让使用者利用 root 身份进行任何事情,如果要配置只能够允许进行一部分事情的话,比如 myuser1 只能帮 root 修改其他用户的密码,可以如下做
[root@study ~]# visudo
## Allow root to run any commands anywhere
root ALL=(ALL) ALL
mrcode1 ALL=(ALL) ALL
myuser1 ALL=(ALL) /usr/bin/passwd # 使用绝对路径,来给定使用的指令
# 再使用 myuser1 来测试是否成功
[myuser1@study ~]$ sudo cat /etc/shadow
[sudo] password for myuser1:
Sorry, user myuser1 is not allowed to execute '/bin/cat /etc/shadow' as root on study.centos.mrcode.
# 可以看到不支持 /bin/cat 指令
# 再使用 sudo passwd ,发现可以执行
[myuser1@study ~]$ sudo passwd myuser3
Changing password for user myuser3.
New password:
BAD PASSWORD: The password is shorter than 8 characters
Retype new password:
passwd: all authentication tokens updated successfully.
# 上面修改了 myuser3 的密码
# 这里不加参数,发现可以直接修改 root 的密码,这样就不行了
[myuser1@study ~]$ sudo passwd
Changing password for user root.
New password:
# 还可以限制指令的参数
myuser1 ALL=(ALL) !/usr/bin/passwd, !/usr/bin/passwd root, /usr/bin/passwd [A-Za-z]*
# 不可执行的指令添加上了感叹号 !
# 上面直接执行 passwd 和 passwd root 都不允许,后面一个用正则规定了参数,必须使用字母开头的参数
# 测试,就会提示不被允许执行
[myuser1@study ~]$ sudo passwd
Sorry, user myuser1 is not allowed to execute '/bin/passwd' as root on study.centos.mrcode.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 通过别名建立 visudo
比如我有 15 个用户加入刚刚的管理员,那么是否都需要将上述限制命令的代码复制 15 行配置到 visudo 中呢?
可以通过 visudo 的别名功能,可以是:指令别名、账户别名、主机别名等。这里仅介绍账户别名
# 假设 pro1、pro2、pro3 与 myuser1、myuser2 要加入上述的密码管理员的 sudo 列表中
# 那么可以创建一个账户别名为 ADMPW,然后配置该账户别名
## 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
# User_Alias ADMINS = jsmith, mikem
User_Alias ADMPW = pro1, pro2, pro3, myuser1, myuser2
## Command Aliases
## These are groups of related commands...
Cmnd_Alias ADMPWCOM = !/usr/bin/passwd, !/usr/bin/passwd root, /usr/bin/passwd [A-Za-z]*
## Allow root to run any commands anywhere
root ALL=(ALL) ALL
mrcode1 ALL=(ALL) ALL
myuser1 ALL=(ALL) !/usr/bin/passwd, !/usr/bin/passwd root, /usr/bin/passwd [A-Za-z]*
ADMPW ALL=(ALL) ADMPWCOM
# 上面定义了 User_Alias 用户别名 和 Cmnd_Alias 命令别名
# 并在之前配置用户的地方使用上了这两个别名
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
别名建议使用大写;后续对用户的维护直接修改别名中的即可
# sudo 的时间间隔问题
如果使用同一个账户在极短时间内重复操作 sudo 来运行指令的话,在第二次执行 sudo 时,并不需要输入自己的密码!也可以正常运行
这是因为有一个机制,sudo 两次操作间隔超过 5 分钟,那么就需要重新输入一次密码。这个机制也是为了安全,比如你输入密码执行过一次 sudo,这个时候去厕所了,超过了 5 分钟还没有回来,防止别人动你的电脑执行 sudo
# sudo 搭配 su 的使用方式
有时候需要大量执行很多 root 的工作,一直使用 sudo 就很麻烦,可以通过下面的方式结合 su,并且还使用用户自己的密码来变成 root
visudo
User_Alias ADMINS = pro1, pro2, pro3, myuser1
ADMINS ALL=(root) /bin/su -
# 创建一个 ADMINS 的用户别名,再限制该用户只能切换到 root,并且只能执行 su -
# 注意使用是:用 sudo 命令来执行 su
[pro2@study ~]$ sudo su -
[sudo] password for pro2:
Last login: Tue Feb 25 15:09:19 CST 2020 on pts/1
[root@study ~]# # 看这里的提示,变成了 root
2
3
4
5
6
7
8
9
10
11
这个方式是这样的:
- 限制了可切换为 root,那么这些用户只能切换到 root
- 并且这些用户只能通过 sudo 执行
su -
的操作 - sudo 需要输入用户自己的密码,通过之后相当于是 root 身份了,用 root 身份执行 su - 切换到 root 身份,就不需要 root 密码了(root 使用 su 不需要密码)
通过中方式也能授权管理员账户。