Linux 用户身份切换

发布时间 2023-12-08 17:13:45作者: 酒哥-颢远

Linux 用户身份切换
什么?在Linux系统当中还要作身份切换?这是为什么?可能有下面几个原因

安全性:身份切换可以限制用户的权限,防止恶意操作和数据泄漏。
多用户环境:在多用户环境中,每个用户拥有自己的账户和权限,需要通过身份切换来切换用户。
程序运行:某些程序需要以不同的权限运行,例如管理员权限或普通用户权限,需要通过身份切换来切换权限。
系统管理:系统管理员需要在不同的身份之间切换,以便执行不同的系统管理任务。
学习和实践:学习Linux系统管理需要了解身份切换的操作和原理,以便更好地管理和维护系统。
那么如何让一般用户变身份成为root呢?主要有两种方式

通过【su -】直接将身份变成root即可,但是这个命令却要root的密码,也就是说,如果你要通过su变成root的话,你的一般用户就必须要知道root的密码才行。

通过【sudo命令】执行root的命令串,由于sudo需要事先设置妥当,且sudo需要输入用户自己的密码,因此多人共管一台主机时,sudo要比su要来的好,至少root密码不会流出去

su
在Linux系统中,su命令用于切换用户身份,其语法如下:

su [选项] [用户名]
1
选项 解释
- 表示切换到目标用户的环境变量,即切换到目标用户的家目录
-l 与-相同,表示切换到目标用户的环境变量
-c 执行完命令后,退出目标用户身份,返回原用户身份
-m -m与-p是一样的,表示【使用目前的环境设置,而不读取新使用者的配置文件】
使用案例
假设你原本是zhw的身份,想要使用su 命令把自己变成root

[zhw@root ~]$ su # 现在是zhw的身份使用su切换root
密码: # 输入密码
[root@root zhw]# id # 查看提示字符是root
uid=0(root) gid=0(root) 组=0(root) 环境=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 # 确实是root身份
[root@root zhw]# env |grep 'zhw'
USER=zhw <== 竟然还是zhw这个身份
PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/zhw/.local/bin:/home/zhw/bin <==这个影响最大
MAIL=/var/spool/mail/zhw
PWD=/home/zhw <== 并非root的家目录
LOGNAME=zhw
# 虽然你的UID已经是具有root身份,但是看到上面的输出信息了吗?
# 还是有一堆变量为原本zhw的身份,所以很多数据还是无法直接利用
[root@root zhw]# exit <== 这样可以退出su的环境 也可以Ctrl + D

单纯的使用【su】切换成root身份,读取的变量设置方式为非登录shell的方式,这种方式很多原本的变量不会被修改,由于没有修改成root的环境,因此很多root常用的命令只能使用绝对路径来执行。还有MAIL这个变量,你输入mail时,收到的邮件竟然是zhw用户的,而不是root本身的邮件,所以切换身份时务必使用如下案例

使用login shell的方式切换为root的身份

[zhw@root ~]$ su -
密码:
上一次登录:二 4月 11 14:52:22 CST 2023pts/2 上
[root@root ~]# env |grep root
HOSTNAME=root
USER=root
MAIL=/var/spool/mail/root
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
PWD=/root
HOME=/root
LOGNAME=root
# 了解差异了吧?下次切换成为root时,记得最好用 su -
[root@root ~]# exit <== exit退出su的环境


上述的做法是让用户的身份变成root并开始使用系统,如果想要退出root的身份则得要利用exit才行,那我如果至少想要执行【一个只有root才能执行的命令,且执行完毕就恢复原本的身份】呢?

zhw想要执行【head -n 3 /etc/shadow】一次,且知道root密码

[zhw@root ~]$ head -n 3 /etc/shadow
head: 无法打开"/etc/shadow" 读取数据: 权限不够
[zhw@root ~]$ su - -c 'head -n 3 /etc/shadow'
密码:
root:$6$0x0W5U0lAIGfNePS$fQegjEeiYdvyV7xK7zyhR9jsXzAwkB6XoA6RxpGo0X/uz8uPhblK9frf36sRtpdyNgJY4jZPQplMR1b/Hqgb9/::0:99999:7:::
bin:*:18353:0:99999:7:::
daemon:*:18353:0:99999:7:::
[zhw@root ~]$ # 注意看 这里执行完命令还是zhw的身份

那么如果我是root或是其他人,我想要切换成为某些特殊账户,可以使用如下的方法来切换

原本是zhw的用户,想要切换成pro1时?

[zhw@root ~]$ su -l pro1
密码:
-bash-4.2$ env |grep pro1
USER=pro1
MAIL=/var/spool/mail/pro1
PWD=/home/pro1
HOME=/home/pro1
LOGNAME=pro1
-bash-4.2$ su -
密码:
上一次登录:二 4月 11 15:19:01 CST 2023pts/2 上
[root@root ~]# su -l sshd
This account is currently not available. <== 竟然说此账户无法切换?
[root@root ~]# finger sshd
Login: sshd Name: Privilege-separated SSH
Directory: /var/empty/sshd Shell: /sbin/nologin # <== 原来shell是/sbin/nologin
Last login 二 4月 11 15:24 (CST) on pts/2
No mail.
No Plan.

[root@root ~]# exit <== 退出第二次的 su
-bash-4.2$ exit <== 退出第一次的 su
[zhw@root ~]$ <== 这个才是最初的环境



su命令的优点:

su命令可以允许用户临时切换为另一个用户身份,方便执行需要特定权限的命令。

su命令可以避免用户频繁登录和退出,提高了系统使用效率。

su命令可以控制用户对系统的访问权限,增强了系统安全性。
su命令的缺点:

su命令需要用户输入目标用户的密码,如果密码被泄露,可能导致系统安全问题。

su命令切换为root用户身份后,用户可以执行任何命令,可能会造成系统的损坏或数据的丢失。

su命令无法控制用户对系统的访问权限范围,如果目标用户拥有过多的权限,可能会导致系统的安全性降低。

sudo
相对于su需要了解新切换的用户密码(常常是root的密码),sudo的执行则仅需要自己的密码即可,甚至可以设置不需要密码即可执行sudo。由于sudo可以让你以其他用户的身份执行命令(通常是使用root的身份来执行命令),因此并非所有人都能够执行sudo,而是仅有规范到/etc/sudoers内的用户才能够执行sudo这个命令。下面介绍一下sudo

sudo [选项] [命令]
选项
-u:指定要切换到的用户身份
-b:以后台模式运行命令

使用案例
想要以sshd的身份在/tmp 下创建一个名为mysshd的文件

[root@root zhw]# sudo -u sshd touch /tmp/mysshd
[root@root zhw]# ll /tmp/mysshd
-rw-r--r--. 1 sshd sshd 0 4月 11 15:47 /tmp/mysshd
# 留意以下,这个文件的权限是由sshd所建立的

但是使用sudo默认仅有root能使用,为什么?因为sudo的执行是这样的流程

sudo命令的执行流程如下:

用户输入sudo命令,并指定要执行的命令。
系统检查用户是否在sudoers文件中有相应的权限,如果没有,则提示用户无权执行该命令。
如果用户有权限执行该命令,则要求用户输入自己的密码,而不是目标用户的密码。
系统检查密码是否正确,如果正确,则将用户切换为目标用户身份,并执行命令。
执行完命令后,返回原用户身份。
所以说,sudo的执行的重点是【能否使用sudo,必须要看/etc/sudoers的设置值】由于能否使用与/etc/sudoers有关,所以我们当然要去编辑sudoers文件,不过该文件的内容有一定的规范,所以直接使用vi去编辑是不好的,此时,我们要通过visudo去修改这个文件

visudo与/etc/sudoers
从上面说明我们可以知道,除了root之外的其外账号,若想要使用sudo执行属于root的权限命令,则root需要先使用visudo去修改/etc/sudoers,让账号能够使用全部或部分的root命令功能,为什么要使用visudo呢??

使用visudo命令修改sudoers文件可以避免语法错误、竞争条件和自动备份,提高sudoers文件修改的安全性和正确性,方便了系统管理员对sudoers文件的管理

一般来说,visudo的设置有几种简单的方法,下面我们以几个简单的例子来说明:

单一用户可使用root所有命令,与sudoers文件语法
假如我们要让zhw这个账号可以使用root的任何命令,基本有两种语法,第一张是直接修改/etc/sudoers文件

[root@root zhw]# visudo
...(前面省略)...
root ALL=(ALL) ALL # 搜索到这一行
zhw ALL=(ALL) ALL # 这一行是增加的
...(后面省略)...

我们来解释一下上面的参数(root ALL=(ALL) ALL)

第一个组件:表示授权的用户或用户组,这里是root用户。
第二个组件:表示用户或用户组执行命令的主机,这里是ALL,表示可以在任何主机上执行命令。
第三个组件:表示用户或用户组可以切换到的目标用户,这里是ALL,表示可以切换到任何用户的身份。
第四个组件:表示用户或用户组可以执行的命令,这里是ALL,表示可以执行任何命令。
修改后保存退出,登录到zhw用户,进行测试看看

[zhw@root ~]$ tail -n 5 /etc/shadow
tail: 无法打开"/etc/shadow" 读取数据: 权限不够
# 因为不是root,所以当然不能查询/etc/shadow
[zhw@root ~]$ sudo tail -n 5 /etc/shadow # 通过sudo执行
[sudo] zhw 的密码: # 输入自己的密码
myuser2:$6$WHRvq32S$d40vM5Qgw8q7zelrSyCPaeugrRQE94KLICed2RHjWaru3aN6gHoycRN6PTpRIL/rx271Oiqds/M5p2me2IUd11:19458:0:99999:7:::
myuser3:$6$1EIWjK3Y$V07xoA9T2zWtWjbq.C8zbfH1jD6uF5PzqGHS2JANbJyLcLVmNr6mNTJlD6Du7O2369k756FUbouyrQJUsRwqj0:19458:0:99999:7:::
pro1:$6$JyB/VQok$uLn7kywLiGZzYE1CpwZprx5U1fc8EX6JJv2f1e50lJNByJ7Out/JidM8C4GxpAJgESpufvDQxU3iUfYEJGoMG.:19458:0:99999:7:::
pro2:$6$tStx6sam$nn6PawgEIgeqK886H1iWtuhC98h2s0BkawWMFfX98W.RyWcwaeZmL1kesXC3gRFCLf8/5TPqCr8.KzwXOogA50:19458:0:99999:7:::
pro3:$6$IAko7jZE$Mw6oy.c80tcqc/.WpXTLK3Zm7QkHCCKiX.DxyAhUARQY1N5tRAPQEPBXe0oFssxeDFxFGglSdcEud/ij8VEt/.:19458:0:99999:7:::
# 看执行成功了可以查询shadow了

zhw输入自己的密码能够执行root的命令了,另外,一个一个设置太麻烦了,能不能使用用户组的方式来设置?参考下面方案

利用wheel用户组以免密码的功能处理visudo
之前的案例博客地址 , 任务一和任务二

我们在之前的账户管理案例中建立了pro1,pro2,pro3,能否通过用户组的功能让这三个人可以管理系?可以很简单,如下案例

[root@root zhw]# visudo
...(前面省略)...
%wheel ALL=(ALL) ALL # 把这行的#拿掉
# 在最左边加上%,代表后面接的是一个【用户组】,改完保存退出
...(后面省略)...
[root@root zhw]# usermod -aG wheel pro1 # 将pro1加入wheel的支持

上面的设置值会造成【任何加入wheel这个用户组的用户,就能够使用sudo切换任何身份来操作任何命令】,也可以将wheel改成你想要的组名,接下里分别切换身份成功pro1,pro2,试试sudo的运行

[pro1@localhost ~]$ sudo tail -n 5 /etc/shadow # 这里的身份是pro1
[sudo] pro1 的密码:
zhw:!!:19459:0:99999:7:::
csq:!!:19459:0:99999:7:::
pro1:$6$8XzICuAG$PCIjmv4s13f4x4IRcb4thG96JX6Tnl.Ots08wlnmc6Ndkgrq4u9e2EYfhWn5YLksFgEX.ySPSGlfj839f7eyh/:19459:0:99999:7:::
pro2:$6$3.4UjuHd$v1lUPlXjpZ6vn9ewVN1NicSGv5tx9BhyCmrWNWd/xBAsxlXdJJJbovrB/ohR5AUeB5VRRSHcRSGv5o3AcuhS01:19459:0:99999:7:::
pro3:$6$ARlJULFa$BVrVHjmRQp7IgS5c4ViqpgN8DDN9O5b2qbnxhzPQvxessejHO0iVqmDcEikNMelu.Mni76NIfh.V3JlUn6nTQ0:19459:0:99999:7:::

[pro2@localhost ~]$ sudo tail -n 5 /etc/shadow # 这里的身份是pro2
[sudo] pro2 的密码:
pro2 不在 sudoers 文件中。此事将被报告。
[pro2@localhost ~]$


这样就立即用户组了吧?如果你想要pro3也支持这个sudo的话,不需要重新使用visudo,只要利用usemod去修改pro3的用户组支持,让pro3用户加入wheel用户组,那它就能够进行sudo了。

Centos7开始,在sudoers文件中,默认已经开发%wheel那一行,以前的Centos旧版本都没有启用

不过,既然我们都信任这些sudo的用户了,能否实现【不需要密码即可使用sudo】呢?

可通过一下方式实现:

[root@localhost ~]# visudo
.....
..
%wheel ALL=(ALL) NOPASSWD: ALL # 找到这行把前面的#去掉
...
....

重点是NOPASSWD 该关键字是免除密码输入的意思

有限制的命令操作
以上两点都可以让用户能够利用root的身份进行任何事情,这样总是不太好,如果我想让用户仅能够进行部分任系统任务。比如说,系统上面的myuser1仅能够帮root修改其他用用户的密码时,即【当用户仅能使用passwd这个命令帮忙root修改其他用户密码】时,该如何编写?可以这样做

[root@localhost ~]# visudo
....
..
myuser1 ALL=(ALL) /usr/bin/passwd # 添加这一行内容,后面的路径务必用绝对路径!
...
..


上述内容,设置值指的是 【myuser1可以切换为root使用passwd命令】,要注意必须要写绝对路径,否则visudo会出现语法错误

我们测试一下passwd是否可用:

[myuser1@localhost ~]$ sudo passwd myuser3 # 这里的身份是myuser1
[sudo] myuser1 的密码: # 输入myuser1的密码
更改用户 myuser3 的密码 。 # 更改myuser3的密码
新的 密码:
重新输入新的 密码:
passwd:所有的身份验证令牌已经成功更新。
[myuser1@localhost ~]$ sudo passwd root # 发现能改root的密码!怎么会这样的?
更改用户 root 的密码 。
新的 密码:
无效的密码: 密码是一个回文
重新输入新的 密码:
passwd:所有的身份验证令牌已经成功更新。

root的密码竟然能被myuser1的用户修改,下次root登录就登录不上去了,欲哭无泪,所以我们就要加上限制用户的命令参数,修改方法如下

[root@localhost ~]# visudo
....
..
myuser1 ALL=(ALL) !/usr/bin/passwd,/usr/bin/passwd [A-Za-z]*,!/usr/bin/passwd root
....
..

在设置值中加上感叹号【 ! 】代表【不可执行】的意思。因此上面这一行会变成:可以执行【passwd 任意字符】,但是【passwd】与【passwd root】这两个命令例外,如此一来myuser1就无法修改root的密码了。这位用户可以具有root的能力,帮助root修改其他用户的密码,却不能随意修改root的密码。

通过别名创建visudo
如上述的第三点,如果我有15个用户需要加入刚刚的管理员行列,那么我是否要将上述那长长的设置15行呢?而且如果想要修改命令或者是新增命令,每一行都要设置很麻烦。有没有更简单的方法呢?可以设置别名,visudo的别名可以是【命令别名、账号别名、主机别名】等。这里仅介绍一下账号别名

假如我的pro1、pro2、pro3、与myuser1、myuser2要加入上述的密码管理员的sudo列表中,那我可以创建一账号,别名为ADMPW,然后将这个名称处理一下,处理的方式如下

[root@localhost ~]# visudo # 这里是root身份
....
..
User_Alias ADMPW = pro1, pro2, pro3, myuser1, myuser2
Cmnd_Alias ADMPWCOM = !/usr/bin/passwd,/usr/bin/passwd [A-Za-z]*, !/usr/bin/passwd root
ADMPW ALL = (root) ADMPWCOM
....

我通过User_Alias 建立一个新账号,这个账号名称一定要使用大写字符来处理,包括Cmnd_Alias(命令别名),Host_Alias(来源主机别名),都需要使用大写字符。

User_Alias ADMPW = pro1, pro2, pro3, myuser1, myuser2

这行指定了一个名为ADMPW的用户别名,它包含了5个用户: pro1、pro2、pro3、myuser1和myuser2

Cmnd_Alias ADMPWCOM = !/usr/bin/passwd,/usr/bin/passwd [A-Za-z]* , !/usr/bin/passwd root
这行指定了一个名为ADMPWCOM的命令别名,它包含了3个命令: !/usr/bin/passwd、/usr/bin/passwd [A-Za-z]* !/usr/bin/passwd root。其中,!/usr/bin/passwd表示禁止使用passwd命令,/usr/bin/passwd [A-Za-z]* 表示使用passwd命令修改非root用户的密码,!/usr/bin/passwd root表示禁止使用passwd命令修改root用户的密码。

ADMPW ALL = (root) ADMPWCOM
这行指定了一个授权策略,它允许ADMPW用户别名中的所有用户,在所有主机上以任何方式(ALL)执行ADMPWCOM命令别名中的命令,但必须以root用户身份执行。也就是说,只有ADMPW用户别名中的用户才能执行ADMPWCOM命令别名中的命令,并且必须以root用户身份执行。

== 未来要修改时,我们只要修改 User_Alias以及Cmnd_Alias 这两行即可,设置方面比较有弹性 ==

sudo的时间间隔问题
或许你已经发现了,那就是如果我们使用同一个账号在短时间内重复操作sudo来运行命令的话,在第二次执行sudo时,并不需要自己的密码,sudo还是会正确的运行。为什么呢?第一次执行sudo需要输入密码,是担心由于用户暂时离开座位,但有人跑来你座位使用你的账号操作系统,所以需要你输入密码重新确认一次身份。

二次执行sudo的间隔在5分钟内,那么再次执行sudo时就不需要重新输入密码了,这是因为系统相信你在5分钟内不会离开,不过两次sudo操作时间间隔超过5分钟,那就得重新输入一次你的密码了

sudo搭配su的使用方式
很多的时候我们需要大量执行很多root的工作,所以一直执行sudo觉得很烦,那么有没有办法使用sudo搭配su,一口气将身份转为root,而且还用用户自己的密码来变成root呢?如下

[root@localhost ~]# visudo
User_Alias ADMPW = pro1, pro2, pro3, myuser1, myuser2
ADMPW ALL = (root) /bin/su -

[pro2@localhost ~]$ sudo su -
[sudo] pro2 的密码:
上一次登录:三 4月 12 17:36:49 CST 2023pts/2 上
[root@localhost ~]#

我们只要输入【sudo su -】并且输入【自己的密码】,就立刻会成为root身份。不但root密码不会外流,用户管理也很方便。这些你加入的用户,全部都是你能够信任的用户才行

总结:

sudo命令更加安全和灵活,能够提供更细粒度的授权控制,适用于多用户环境下的权限管理;

su命令则更加方便,可以在命令行上直接切换身份,适用于单用户环境下的工作。在使用这两个命令时,需要根据实际情况选择合适的方法,避免因误操作造成不必要的麻烦。

本文参考《鸟哥的Linux私房菜》这本书