IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> Linux 之旅 11:Linux 账号管理与 ACL 权限设置 -> 正文阅读

[系统运维]Linux 之旅 11:Linux 账号管理与 ACL 权限设置

Linux 之旅 11:Linux 账号管理与 ACL 权限设置

image-20210821200728975

Linux 的账号与用户组

使用者识别码:UID与GID

关于Linux的账号管理,有两个数字最为重要:

  • UID:(User ID),即账号的唯一识别码
  • GID:(Group ID),即用户组的唯一识别码

LInux通过这两个数字识别系统中的用户以及群组。

要查看当前账号的UID与GID,可以:

[icexmoon@xyz ~]$ id
uid=1000(icexmoon) gid=1000(icexmoon)=1000(icexmoon),10(wheel) 环境=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

查看指定行号的UID与GID:

[icexmoon@xyz ~]$ id root
uid=0(root) gid=0(root)=0(root)

事实上用户的UID和GID等信息都保存在几个账号和群组相关的配置文件中,其中最重要的是/etc/passwd

[icexmoon@xyz ~]$ cat /etc/passwd | grep icexmoon
icexmoon:x:1000:1000:icexmoon:/home/icexmoon:/bin/bash

其中第三个字段是用户的UID,第四个字段是用户的主要群组(初始化群组)的GID。

使用者账号

在用户登录Linux的时候,用户验证的大概流程如下:

  1. 检查登录的用户名是否存在于/etc/passwd文件中,如果有,则读取其对应的UID和GID,以及登录用的shell和账号的家目录等。
  2. 通过/etc/shadow文件比对用户输入的密码是否正确。
  3. 如果没问题就调用对应的登录用shell进行登录。

/etc/passwd

现在看/etc/passwd的详细结构:

[icexmoon@xyz ~]$ head -n 5 /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

该文件由:分隔,每一个字段的含义为:

  • 用户名
  • 密码:早期的Linux使用此字段保存密码,目前已废弃,转移到了/etc/shadow中,所以当前该字段中会用x字符填充。
  • UID:0表示root用户,1~999为系统账号,1000~60000为可以设置的一般性用户账号。
  • GID:用户所属的主用户组(初始化用户组)
  • 用户信息说明:关于用户的描述性信息
  • 家目录
  • Shell:通过登录验证后会使用这里指定的Shell进行登录,部分系统账号会被设置为/sbin/nologin,所以无法登录。

/etc/shadow

用户的密码保存在/etc/shadow中:

[root@xyz ~]# head -n 5 /etc/shadow
root:$6$h5eXZCiKw8ucXyB2$PxxRgKneIDs2TWIpg916ugAfGCfqNf/HJHiXjy0PTPtUmY.pR/e2cUMpjRBqbx5Y0AHNJtjxAf3aOUTek3DpO.::0:99999:7:::
bin:*:18353:0:99999:7:::
daemon:*:18353:0:99999:7:::
adm:*:18353:0:99999:7:::
lp:*:18353:0:99999:7:::

同样以:分隔,字段对应的内容为:

  1. 用户名
  2. 密码:这里存放的是经过加密后的密码,老式的Linux会使用md5,新的Linux会使用SHA或者其它的加密算法。只要稍微修改这里的数据就会导致用户无法正常登录,所以如果需要临时禁止某个用户登录,但是保留其包括登录密码在内的用户信息,就可以在这个字段开始添加一个!字符,如果要恢复登录就取消,很方便。
  3. 最近一次修改密码的日期:格式为以天为单位的时间戳
  4. 可变更密码的间隔天数:刚修改完密码后,需要间隔指定天数才能再次修改密码,通过设置这个字段可以杜绝频繁修改密码的行为,默认为0,表示可以随时修改密码。
  5. 密码过期天数:距离上一次修改密码后超过该天数后会在用户登录时要求用户修改密码。默认为99999,可以看作是永不过期。
  6. 密码过期前多少天进行警告:会在临近过期时,用户登录后会收到密码将要到期的提醒。
  7. 密码过期后的宽限天数:在宽限天数内可以修改密码并登录,如果超过宽限天数,密码将失效,无法修改和登录系统。
  8. 账号失效日期:格式为天为单位的时间戳,到该时间后账户会无条件失效,此字段用于特殊用途,比如将账号作为收费项目提供。
  9. 保留字段

如果一般用户忘记了密码,很好解决,只要用root或者其它管理员账号修改即可,如果root账号的密码忘了,且没有其它的管理员账号可以使用,就比较麻烦了,要么通过单人维护模式之类的方式启动系统,此时会获得root权限,进行密码重置,要么可以用启动U盘之类的启动系统,用挂载文件系统的方式挂载/etc/shadow所在分区,然后清空其中的root密码字段,然后重启系统后就会提示设置root的密码。

如果要查看Linux对密码加密使用的是何种算法,可以:

[root@xyz ~]# authconfig --test | grep hashing
 password hashing algorithm is sha512

关于用户组

/etc/group

用户组相关的信息保存在/etc/group中:

[root@xyz ~]# head -n 5 /etc/group
root:x:0:
bin:x:1:
daemon:x:2:
sys:x:3:
adm:x:4:

这些字段的含义为:

  1. 用户组名称
  2. 用户组密码:此字段已废弃,相关信息移动到了/etc/gshadow
  3. GID
  4. 包含在此用户组中的用户名:例如root:x:0:user1,user2就表明user1user2两个用户包含在root用户组中,一个用户可以加入多个用户组,此外,如果某个用户的主用户组是当前的用户组,则不需要写入这里。

初始化用户组

用户的主用户组,或者说初始化用户组(initial group)是创建用户时所关联的用户组,是不需要将用户名写入/etc/group中的相关字段的:

[root@xyz ~]# grep icexmoon /etc/passwd /etc/shadow /etc/group
/etc/passwd:icexmoon:x:1000:1000:icexmoon:/home/icexmoon:/bin/bash
/etc/shadow:icexmoon:$6$vGNuDgQdXLIv4U19$mnkT6XkbUOAAO9jxxBfzXbRfS6ZA9LpR0fDwRJmfQ2cZ7PyMF18aGosW00KXjlcsv9GbzDpzSqgvqQr5E51aW/::0:99999:7:::
/etc/group:wheel:x:10:icexmoon
/etc/group:icexmoon:x:1000:icexmoon

不过事实上这里是有的:/etc/group:icexmoon:x:1000:icexmoon,是CentOS版本的问题?

有效用户组

使用groups命令可以查看用户所有关联的用户组:

[icexmoon@xyz ~]$ groups
icexmoon wheel

其中第一个为用户的有效用户组(effective group),如果创建新文件,所用的用户组信息就会是这个有效用户组:

[icexmoon@xyz tmp]$ touch test_group
[icexmoon@xyz tmp]$ ll test_group
-rw-rw-r--. 1 icexmoon icexmoon 0 819 21:43 test_group

使用newgrp命令可以切换有效用户组:

[icexmoon@xyz tmp]$ newgrp wheel
[icexmoon@xyz tmp]$ groups
wheel icexmoon
[icexmoon@xyz tmp]$ touch test_grou2
[icexmoon@xyz tmp]$ ll test_grou*
-rw-r--r--. 1 icexmoon wheel    0 819 21:45 test_grou2
-rw-rw-r--. 1 icexmoon icexmoon 0 819 21:43 test_group
[icexmoon@xyz tmp]$ exit
exit

newgrp会打开一个子shell,并改变有效用户组,此时新建文件会使用新的有效用户组。需要注意的是因为是新的子shell,所以在执行完相关操作后需要使用exit退出,并返回之前所在的shell中。

/etc/gshadow

/etc/gshadow主要的用途是保存用户组的密码:

[root@xyz ~]# head -n 5 /etc/gshadow
root:::
bin:::
daemon:::
sys:::
adm:::

这些字段的含义是:

  1. 用户组名称
  2. 用户组密码:如果为用户组设置管理员,则会设置这个字段
  3. 用户组管理员账号
  4. 加入用户组的用户(与/etc/group相同)

所谓的用户组管理员,就是可以帮助root管理对应的用户组,进行增加和删除用户,如果Linux主机上的用户很多,且频繁需要管理用户组,就可能需要设置用户组管理员来帮助管理,不过现在已经很少需要这么做了。

账号管理

添加和移除用户

useradd

使用useradd就可以添加一个新用户:

[root@xyz ~]# useradd user1
[root@xyz ~]# ls -ald /home/user1
drwx------. 3 user1 user1 78 820 18:26 /home/user1
[root@xyz ~]# grep user1 /etc/passwd /etc/shadow /etc/group
/etc/passwd:user1:x:1001:1001::/home/user1:/bin/bash
/etc/shadow:user1:!!:18859:0:99999:7:::
/etc/group:user1:x:1001:

可以看到新用户创建后,会自动创建相应的家目录(一般是/home/xxx),此外还会在前边介绍的几个关键的用户和用户组相关的配置文件中添加相应的信息。

需要注意的是,/etc/shadow中添加的新记录中的密码字段是!!,意味着该用户的密码还未设置,所以需要设置密码后才能使用,可以用root进行设置:

[root@xyz ~]# passwd user1
更改用户 user1 的密码 。
新的 密码:
无效的密码: 密码未通过字典检查 - 它基于字典单词
重新输入新的 密码:
passwd:所有的身份验证令牌已经成功更新。

这里我使用的是一个常见的简单密码,所以被提示未通过字典检查,但是root依然可以通过重复两次的方式强行设置。

默认情况下useradd会给新用户指定一个UID和GID,其中GID是为新用户单独创建的一个新的用户组。如果你有特殊需要,也可以为新用户指定一个UID和一个已存在的用户组作为其主用户组:

[root@xyz ~]# useradd -u 1500 -g users user2
[root@xyz ~]# ls -ald /home/user2
drwx------. 3 user2 users 78 820 18:37 /home/user2
[root@xyz ~]# grep user2 /etc/passwd /etc/shadow /etc/group
/etc/passwd:user2:x:1500:100::/home/user2:/bin/bash
/etc/shadow:user2:!!:18859:0:99999:7:::

上面说的是用于普通用户登录和使用Linux主机的一般账号,此外还可以添加系统账号:

[root@xyz ~]# useradd -r user3
[root@xyz ~]# ls -ald /home/user3
ls: 无法访问/home/user3: 没有那个文件或目录
[root@xyz ~]# grep user3 /etc/passwd /etc/shadow /etc/group
/etc/passwd:user3:x:988:982::/home/user3:/bin/bash
/etc/shadow:user3:!!:18859::::::
/etc/group:user3:x:982:

使用useradd -r可以添加系统账号,可以看到分配的UID是988,小于1000,此外,因为系统账号一般用于运行程序等,并不会被用户登录和使用,所以没有创建对应的家目录。

useradd 参考文件

可以通过useradd -D查看useradd命令创建用户时的默认值:

[root@xyz ~]# useradd -D
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/bash
SKEL=/etc/skel
CREATE_MAIL_SPOOL=yes

其实这些内容是从/etc/default/useradd这个文件读取的。

这些默认值的含义为:

  • GROUP=100

    新建用户时候分配的初始用户组是100。但是CentOS或Redhat系列发行版中,实际上并不会使用这个设置,而是会为新用户创建同名的一个新的用户组作为初始用户组,这种机制称为“私有用户组机制”,而使用这个设置并为新用户指定同一个用户组作为初始用户组的方式称为“公共用户组机制”。

  • HOME=/home

    为新用户创建的家目录的位置,一般为/home/xxx

  • INACTIVE=-1

    这个默认值对应/etc/shadow中的第7个字段“密码过期后的宽限天数”,-1表示永不失效,0表示立即失效,其它值表示具体的宽限天数。

  • EXPIRE

    对应/etc/shadow中的第8个字段,账号会在到达该天数后失效。

  • SHELL=/bin/bash

    新用户默认使用的shell程序,如果为了安全考虑,希望新用户默认都不能登录,可以将这个值改为/sbin/nologin

  • SKEL=/etc/skel

    新用户家目录的模板目录,在创建新用户的时候,会使用这里的模板目录为新用户创建家目录,比如,如果你希望新用户的家目录有一些基础的用户手册或者shell脚本,可以在/etc/skel中设置好对应的文件,这样新建的用户的家目录里也会有一份相关文件的拷贝。

  • CREATE_MAIL_SPOOL=yes

    是否为新用户创建邮箱,也就是/var/spool/mail/xxx

除了这些默认值以外,useradd还需要参考其他的配置文件,比如/etc/login.defs

[root@xyz ~]# cat /etc/login.defs | sed '/^#.*$/d' | sed '/^$/d'
MAIL_DIR        /var/spool/mail
PASS_MAX_DAYS   99999
PASS_MIN_DAYS   0
PASS_MIN_LEN    5
PASS_WARN_AGE   7
UID_MIN                  1000
UID_MAX                 60000
SYS_UID_MIN               201
SYS_UID_MAX               999
GID_MIN                  1000
GID_MAX                 60000
SYS_GID_MIN               201
SYS_GID_MAX               999
CREATE_HOME     yes
UMASK           077
USERGROUPS_ENAB yes
ENCRYPT_METHOD SHA512

这个文件包含这些信息:

  • MAIL_DIR:邮箱目录
  • PASS_MAX_DAYS:密码相关设置中可以设置的最大天数,所以新用户的密码更新天数为99999
  • PASS_MIN_DAYS:密码相关设置的最小天数
  • PASS_MIN_LEN:密码最小长度。因为新版Linux都已使用PAM进行登录验证,所以这里的值已不再起作用。
  • UID_MIN:一般用户可以设置的最小UID值。
  • UID_MAX:一般用户可以设置的最大UID值。
  • SYS_UID_MIN:系统账户可以设置的最小UID值。
  • SYS_UID_MAX:系统账户可以设置的最大UID值。
  • GID_MIN:新建的用户组可以设置的最小GID值。
  • GID_MAX:新建的用户组可以设置的最大GID值。
  • CREATE_HOME:是否默认为新用户创建家目录。
  • UMASK:创建家目录时使用的umask,因为这里是077,所以创建的目录权限自然是700
  • USERGROUPS_ENAB:使用userdel删除用户时是否会删除其初始群组。
  • ENCRYPT_METHOD:密码加密算法。

passwd

使用passwd命令可以修改密码,特别的,root可以修改所有用户的密码,而一般用户只可以修改自己的密码。此外需要注意的是,如果root修改他人的密码,passwd后需要写上对应的用户名,否则就是修改自己的密码。

新的Linux发行版使用PAM进行登录验证,所以一般会对密码有一些基本要求,否则是不允许设置该密码的(root除外):

  • 密码不能与账号同名
  • 不能是常见的简单密码,如123456password之类的,系统有一个常见简单密码本,会进行比对。
  • 密码需要超过8个字符。
  • 不能使用个人信息,如身份证、手机号等作为密码
  • 密码不能使用简单关系,如1+1=2等
  • 密码尽量要使用数字、字母、特殊字符($、-等)的组合。

这里推荐一个大学时某网络安全老师教我们的密码生成方法:想一句话,比如”Today is a good day“,则可以取每个单词的首字母作为密码,即Tiagd,这种密码看起来毫无规律,但实际上只要你记住那句话就能记住密码,这大概就是所谓的容易记住的无规律密码吧。而且这种方法可以有很多衍生版本,比如用拼音,或者不取首字母,取尾字母等。

新版的CentOS为passwd命令加入了一个新的参数--stdin,可以结合管道命令来显式地修改密码:

[root@xyz ~]# echo 'password123' | passwd --stdin user2
更改用户 user2 的密码 。
passwd:所有的身份验证令牌已经成功更新。

使用这种方式可以通过Shell脚本批量创建用户,并设置密码,但缺点是不安全,黑客可以通过命令历史记录看到这些信息(当然也可以执行完脚本后手动清除历史记录)。

如果想查看密码的相关设置,可以:

[root@xyz ~]# passwd -S user2
user2 PS 2021-08-20 0 99999 7 -1 (密码已设置,使用 SHA512 算法。)

这里打印的信息对应/etc/shadow的相关字段,比如上边打印的信息就代表:user2账号的密码最近一次修改时间为2021-08-20,密码可以随时修改,密码会在99999天后过期,过期前7天会提醒用户,账号永远不会失效。

可以对密码的这些设置进行修改:

[root@xyz ~]# passwd -x 60 -i 10 user2
调整用户密码老化数据user2。
passwd: 操作成功
[root@xyz ~]# passwd -S user2
user2 PS 2021-08-20 0 60 7 10 (密码已设置,使用 SHA512 算法。)

现在user2账号被要求在修改密码60天后再次修改密码,如果过期超过10天账户将失效。

之前在介绍/etc/shadow时说过可以通过在密码字段前添加!的方式让用户无法进行登录,起到临时限制登录的目的,事实上不需要手动修改/etc/shadow文件,可以:

[root@xyz ~]# passwd -l user2
锁定用户 user2 的密码 。
passwd: 操作成功
[root@xyz ~]# passwd -S user2
user2 LK 2021-08-20 0 60 7 10 (密码已被锁定。)
[root@xyz ~]# grep user2 /etc/shadow
user2:!!$6$vsrs7fll$UAzw.3Gsu5hODBU/6UOTVy14M6M06NTZXW7//k3MXRYtG7mLwq3K.pWgOHlky1hD692uNvGjMBFUdMGqTr1iO1:18859:0:60:7:10::

可以看到对应的密码字段前被添加了两个!,现在user2就不能登录了。

要解除账户锁定也很简单:

[root@xyz ~]# passwd -l user2
锁定用户 user2 的密码 。
passwd: 操作成功
[root@xyz ~]# passwd -S user2
user2 LK 2021-08-20 0 60 7 10 (密码已被锁定。)
[root@xyz ~]# grep user2 /etc/shadow
user2:!!$6$vsrs7fll$UAzw.3Gsu5hODBU/6UOTVy14M6M06NTZXW7//k3MXRYtG7mLwq3K.pWgOHlky1hD692uNvGjMBFUdMGqTr1iO1:18859:0:60:7:10::

chage

chage(change)命令主要用于修改用户密码的过期信息,也可以用来查看密码过期信息的详情:

[root@xyz ~]# chage -l user2
最近一次密码修改时间                                    :8月 20, 2021
密码过期时间                                    :10月 19, 2021
密码失效时间                                    :10月 29, 2021
帐户过期时间                                            :从不
两次改变密码之间相距的最小天数          :0
两次改变密码之间相距的最大天数          :60
在密码过期之前警告的天数        :7

chage有一个用途比较有用:要求新建的用户在第一次登录后必须修改密码:

[root@xyz ~]# useradd chagetest
[root@xyz ~]# echo "chagetest" | passwd --stdin chagetest
更改用户 chagetest 的密码 。
passwd:所有的身份验证令牌已经成功更新。
[root@xyz ~]# chage -d 0 chagetest
[root@xyz ~]# chage -l chagetest
最近一次密码修改时间                                    :密码必须更改
密码过期时间                                    :密码必须更改
密码失效时间                                    :密码必须更改
帐户过期时间                                            :从不
两次改变密码之间相距的最小天数          :0
两次改变密码之间相距的最大天数          :99999
在密码过期之前警告的天数        :7

看到没,出现了密码必须更改的字样,现在使用chagetest账号通过ssh连接进行登录:

? ssh chagetest@192.168.1.105
chagetest@192.168.1.105's password:
You are required to change your password immediately (root enforced)
WARNING: Your password has expired.
You must change your password now and login again!
更改用户 chagetest 的密码 。
为 chagetest 更改 STRESS 密码。
(当前)UNIX 密码:
新的 密码:
重新输入新的 密码:
passwd:所有的身份验证令牌已经成功更新。
Connection to 192.168.1.105 closed.

在使用初始密码登录后会被强制要求修改密码,且修改完后会立即退出登录,必须使用修改后的密码再重新登录后才能正常使用系统。

这种方式对系统管理员批量创建账号,并使用一个随机密码作为初始密码的情况很有用,可以在相应的用户收到自己的账号和初始密码登录后让其修改为自己习惯的密码,并避免一些可能的密码泄露问题。

usermod

如果在创建完用户后需要对用户信息进行修改,可以使用usermod命令:

[root@xyz ~]# usermod -c 'test_account' user2
[root@xyz ~]# grep user2 /etc/passwd
user2:x:1500:100:test_account:/home/user2:/bin/bash

这里使用-c参数给user2添加了一段描述性文字。

此外usermod也可以修改密码过期相关的设置:

[root@xyz ~]# usermod -e '2021-12-31' user2
[root@xyz ~]# chage -l user2
最近一次密码修改时间                                    :8月 20, 2021
密码过期时间                                    :10月 19, 2021
密码失效时间                                    :10月 29, 2021
帐户过期时间                                            :12月 31, 2021
两次改变密码之间相距的最小天数          :0
两次改变密码之间相距的最大天数          :60
在密码过期之前警告的天数        :7

这里通过-e参数给账户添加了一个账户过期时间。

userdel

userdel命令的用途很明确,就是删除账号:

[root@xyz ~]# userdel -r user2
[root@xyz ~]# ll /home/user2
ls: 无法访问/home/user2: 没有那个文件或目录

参数-r的用途是将用户的家目录一同删除。

对于账户的删除操作需要谨慎,如果只是让账户失效的话,可以通过将账户的过期时间(/etc/shadow中第8个字段)设置为0的方式实现。因为userdel操作可能会删除用户相关的文件,可能会导致一些依赖于该用户的程序无法正常运行,所以如果一定要执行用户删除操作,请先通过find / -user username之类的方式查询该用户相关的文件,确定的确可以删除后再进行删除用户的操作。

用户功能

id

之前介绍过,通过id命令可以查询用户和用户组的相关信息:

[root@xyz ~]# id
uid=0(root) gid=0(root)=0(root) 环境=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[root@xyz ~]# id icexmoon
uid=1000(icexmoon) gid=1000(icexmoon)=1000(icexmoon),10(wheel)

finger

finger同样可以查询用户相关信息,这个命令一般不会默认安装,所以需要先安装:

[root@xyz ~]# yum install finger
已加载插件:fastestmirror, langpacks
Loading mirror speeds from cached hostfile
 * base: mirrors.aliyun.com
 * extras: mirrors.aliyun.com

使用finger查看用户信息:

[root@xyz ~]# finger icexmoon
Login: icexmoon                         Name: icexmoon
Directory: /home/icexmoon               Shell: /bin/bash
On since 五 820 18:16 (CST) on pts/0 from icexmoon-book
   1 second idle
No mail.
No Plan.

包含以下信息:

  • Login:账号名
  • Name:描述文字
  • Directory:家目录
  • Shell:登录用Shell
  • 最后一次登录时间
  • 邮件情况
  • 任务计划:这里关联的是~/.plan的内容

测试一下,写入一个任务计划并使用finger查看:

[icexmoon@xyz ~]$ echo "This is a test plan." > ~/.plan
[icexmoon@xyz ~]$ finger icexmoon
Login: icexmoon                         Name: icexmoon
Directory: /home/icexmoon               Shell: /bin/bash
On since 五 820 18:16 (CST) on pts/0 from icexmoon-book
   3 seconds idle
No mail.
Plan:
This is a test plan.

此外,finger还可以查看当前Linux主机上的登录的用户:

[icexmoon@xyz ~]$ finger
Login      Name       Tty      Idle  Login Time   Office     Office Phone   Host
chagetest             pts/1          Aug 20 21:01                           (icexmoon-book)
icexmoon   icexmoon   pts/0          Aug 20 18:16                           (icexmoon-book)

chfn

chfn(change finger)的用途是修改finger命令查看的相关个人信息:

[icexmoon@xyz ~]$ chfn
Changing finger information for icexmoon.
名称 [icexmoon]: 魔芋红茶
办公 []:
办公电话 []: 123456
住宅电话 []: 123456

密码:
Finger information changed.
[icexmoon@xyz ~]$ finger icexmoon
Login: icexmoon                         Name: 魔芋红茶
Directory: /home/icexmoon               Shell: /bin/bash
Office: 123456, 123456
On since 五 820 18:16 (CST) on pts/0 from icexmoon-book
   5 seconds idle
No mail.
Plan:
This is a test plan.

有点像是个人主页上的那些信息,但一般来说,除非你想在Linux主机上搞个账户社区啥的,这个命令用处不大。

chsh

chsh命令用于修改用户的登录用Shell。

先列出当前Linux上可用的shell:

[chagetest@xyz ~]$ chsh -l
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
/bin/tcsh
/bin/csh

修改自己的登录用shell:

[chagetest@xyz ~]$ chsh -s /bin/csh
Changing shell for chagetest.
密码:
Shell changed.
[chagetest@xyz ~]$ cat /etc/passwd | grep chagetest
chagetest:x:1501:1501::/home/chagetest:/bin/csh
[chagetest@xyz ~]$ chsh -s /bin/bash
Changing shell for chagetest.
密码:
Shell changed.
[chagetest@xyz ~]$ cat /etc/passwd | grep chagetest
chagetest:x:1501:1501::/home/chagetest:/bin/bash

新增与删除用户组

groupadd

使用groupadd可以创建新的用户组:

[root@xyz ~]# groupadd group1
[root@xyz ~]# grep group1 /etc/group /etc/gshadow
/etc/group:group1:x:1502:
/etc/gshadow:group1:!::

默认情况下会分配一个大于1000的GID,这样会造成你之后创建的新用户分配的UID和GID不再是相同数字的值,所以也有教程会建议自行创建用户组时使用小于1000的GID,但事实上保持UID和GID相等并没有什么实际意义。

groupmod

使用groupmod可以修改已有用户组的信息:

[root@xyz ~]# groupmod -g 201 -n mygroup group1
[root@xyz ~]# grep mygroup /etc/group /etc/gshadow
/etc/group:mygroup:x:201:
/etc/gshadow:mygroup:!::

修改用户组的GID需要慎重,因为文件权限等都是与GID直接相关的。

groupdel

使用groupdel可以删除用户组:

[root@xyz ~]# groupdel mygroup
[root@xyz ~]# groupdel user1
groupdel:不能移除用户“user1”的主组

需要注意的是,如果一个用户组是依然存在的某个用户的主用户组(初始用户组),则是不能被删除的。这很好理解,如果删除了,那个用户就没有主用户组了,这显然是不可接受的。

如果依然要删除,可以先给该用户指定一个新的主用户组,或者删除该用户,然后再删除这个用户组。

gpasswd

gpasswd这个命令就是之前将的设置用户管理员的相关命令:

[root@xyz ~]# groupadd grouptest
[root@xyz ~]# gpasswd grouptest
正在修改 grouptest 组的密码
新密码:
请重新输入新密码:
[root@xyz ~]# gpasswd -A user1 grouptest

这里新建了一个用户组grouptest,并将user1用户设置为这个用户组的管理员。

现在使用user1登录系统,并添加用户到该用户组:

? ssh user1@192.168.1.105
user1@192.168.1.105's password:
Last failed login: Sat Aug 21 10:20:30 CST 2021 from icexmoon-book on ssh:notty
There was 1 failed login attempt since the last successful login.
[user1@xyz ~]$ id
uid=1001(user1) gid=1001(user1)=1001(user1) 环境=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[user1@xyz ~]$ gpasswd -a user1 grouptest
正在将用户“user1”加入到“grouptest”组中
[user1@xyz ~]$ gpasswd -a user3 grouptest
正在将用户“user3”加入到“grouptest”组中
[user1@xyz ~]$ grep grouptest /etc/group
grouptest:x:1502:user1,user3
[user1@xyz ~]$ id
uid=1001(user1) gid=1001(user1)=1001(user1) 环境=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

这里需要注意的是:

  • 加入用户组后需要重新登录才会生效。
  • 一个用户组可以有多个管理员。

账号管理实例

任务一

先创建3个用户,并且给前两个用户添加辅助用户组,将第三个用户设置为不能登录:

[root@xyz ~]# groupadd mygroup1
[root@xyz ~]# useradd -G mygroup1 -c '1st user' myuser1
[root@xyz ~]# useradd -G mygroup1 -c '2nd user' myuser2
[root@xyz ~]# useradd -c '3rd user' -s '/sbin/nologin' myuser3
[root@xyz ~]# echo 'password' | passwd --stdin myuser1
更改用户 myuser1 的密码 。
passwd:所有的身份验证令牌已经成功更新。
[root@xyz ~]# echo 'password' | passwd --stdin myuser2
更改用户 myuser2 的密码 。
passwd:所有的身份验证令牌已经成功更新。
[root@xyz ~]# echo 'password' | passwd --stdin myuser3
更改用户 myuser3 的密码 。
passwd:所有的身份验证令牌已经成功更新。

任务二

创立一个项目文件夹,并让三个用户都对该文件夹拥有全部的权限:

[root@xyz ~]# groupadd projecta
[root@xyz ~]# mkdir /srv/projecta
[root@xyz ~]# ll -d /srv/projecta/
drwxr-xr-x. 2 root root 6 821 10:36 /srv/projecta/
[root@xyz ~]# chmod 2770 /srv/projecta/
[root@xyz ~]# chgrp projecta /srv/projecta/
[root@xyz ~]# ll -d /srv/projecta/
drwxrws---. 2 root projecta 6 821 10:36 /srv/projecta/
[root@xyz ~]# useradd -G projecta -c 'project user' pro1
[root@xyz ~]# useradd -G projecta -c 'project user' pro2
[root@xyz ~]# useradd -G projecta -c 'project user' pro3
[root@xyz ~]# echo 'password' | passwd --stdin pro1
更改用户 pro1 的密码 。
passwd:所有的身份验证令牌已经成功更新。
[root@xyz ~]# echo 'password' | passwd --stdin pro2
更改用户 pro2 的密码 。
passwd:所有的身份验证令牌已经成功更新。
[root@xyz ~]# echo 'password' | passwd --stdin pro3
更改用户 pro3 的密码 。
passwd:所有的身份验证令牌已经成功更新。

使用外部身份认证系统

上面讲的都是本地的账号和认证系统,在一些网络构建的系统中,可能会有专门的账号管理和认证服务器,进行登录认证和账号管理,这里不做详细说明。

ACL的使用

什么是ACL

ACL(access control list)是访问控制列表。

之前在介绍文件系统时候介绍的文件权限控制,仅能针对用户、用户组、其他人这三个维度进行粗略控制,如果我们需要这之外的特殊权限控制,比如某个特定用户对某某目录具有读写权限,但又不想讲该用户变为该目录的拥有者。这时候就需要用到ACL。

简单的说,ACL可以针对单一用户、单一文件或目录进行权限设置。

虽然ACL是Linux内核之外的额外功能,但是新的Linux发行版都已默认对ACL提供了支持,要查看系统是否已经开启了ACL,可以:

[root@xyz ~]# dmesg | grep -i acl
[    3.644493] systemd[1]: systemd 219 running in system mode. (+PAM +AUDIT +SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 -SECCOMP +BLKID +ELFUTILS +KMOD +IDN)
[    7.964164] SGI XFS with ACLs, security attributes, no debug enabled

SGI XFS with ACLs表明当前系统已经为xfs文件系统开启了ACL功能。

设置ACL

有两个ACL设置相关的命令:

  • getfacl:获取某个文件/目录的ACL设置选项。
  • setfacl:修改某个文件/目录的ACL设置选项。

setfacl

如果要使用ACL给某个用户添加上某个文件的相关权限,可以:

[root@xyz ~]# cd /tmp
[root@xyz tmp]# touch acl_test
[root@xyz tmp]# ll acl_test
-rw-r--r--. 1 root root 0 821 11:29 acl_test
[root@xyz tmp]# setfacl -m u:user1:rx acl_test
[root@xyz tmp]# ll acl_test
-rw-r-xr--+ 1 root root 0 821 11:29 acl_test
[root@xyz tmp]# setfacl -m u::rwx acl_test
[root@xyz tmp]# ll acl_test
-rwxr-xr--+ 1 root root 0 821 11:29 acl_test

其中setfacl -m u::rwx acl_test这种没有指定用户名的做法,是给文件的拥有者设置相关权限。

可以注意到,设置完ACL权限后,文件的信息栏中最后一位标识变成了+,这表明该文件设置了ACL权限。

getfacl

现在使用getfacl命令查看上面设置好的ACL权限:

[root@xyz tmp]# getfacl acl_test
# file: acl_test
# owner: root
# group: root
user::rwx
user:user1:r-x
group::r--
mask::r-x
other::r--

可以清楚地看到,文件拥有者(root)的权限为user::rwx,而user1的权限为user:user1:r-x。此外需要注意mask这个选项,其作用有点像创建目录和文件时候决定默认权限的umask,但并不完全像,因为这里mask选项的实际用途是决定实际ACL的最终权限,也就是说虽然上边的设置对于root的权限是rwx,但因为maskr-x,所以经过mask的“遮罩”后,实际权限只能是r-x。对于user1来说反而没影响,因为本身的设置就是r-x。因为上边的原因,ACL的mask设置通常被设置成rwx比较容易使用。

上边都是纯理论的讨论,实际上作为文件的拥有者和超级管理员,root自然是对该文件拥有全部权限的。

mask

ACL的mask选项上边已经介绍过了,现在展示如何修改mask的值:

[root@xyz tmp]# setfacl -m m:r acl_test
[root@xyz tmp]# getfacl acl_test
# file: acl_test
# owner: root
# group: root
user::rwx
user:user1:r-x                  #effective:r--
group::r--
mask::r--
other::r--

可以看到使用getfacl打印出的信息中出现了提示#effective:r--,这正是在说因为mask的存在,user1的实际权限是r--,设置中添加的x权限不会真正生效。

实例

现在有一个用户myuser1

[root@xyz tmp]# id myuser1
uid=1502(myuser1) gid=1504(myuser1)=1504(myuser1),1503(mygroup1)

还有一个之前创建的项目目录:

[root@xyz tmp]# ll -d /srv/projecta/
drwxrws---+ 2 root projecta 6 821 10:36 /srv/projecta/

因为myuser1不属于projecta,所以自然是无法进入该目录:

[myuser1@xyz ~]$ cd /srv
[myuser1@xyz srv]$ cd projecta/
-bash: cd: projecta/: 权限不够

如果要在不调整从属用户组和目录权限的情况下让myuser1能进入目录,可以使用ACL权限设置的方式实现:

[root@xyz tmp]# setfacl -m u:myuser1:rx /srv/projecta/
[root@xyz tmp]# getfacl /srv/projecta/
getfacl: Removing leading '/' from absolute path names
# file: srv/projecta/
# owner: root
# group: projecta
# flags: -s-
user::rwx
user:myuser1:r-x
group::rwx
mask::rwx
other::---

使用myuser1用户进入目录:

[myuser1@xyz srv]$ cd projecta/
[myuser1@xyz projecta]$

ACL权限继承

默认情况下所设置的ACL权限是不会继承的:

? ssh pro1@192.168.1.105
pro1@192.168.1.105's password:
[pro1@xyz ~]$ cd /srv/projecta/
[pro1@xyz projecta]$ touch test_file
[pro1@xyz projecta]$ mkdir test_dir
[pro1@xyz projecta]$ ls -al
总用量 0
drwxrws---+ 3 root projecta 39 821 11:59 .
drwxr-xr-x. 4 root root     93 821 10:36 ..
drwxrwsr-x. 2 pro1 projecta  6 821 11:59 test_dir
-rw-rw-r--. 1 pro1 projecta  0 821 11:59 test_file

可以看到虽然/srv/projecta目录设置了ACL权限,但是在其中创建的文件和目录并不会继承ACL权限(权限信息的最后并没有+)。

如果想让子目录或者文件继承目录的ACL权限,可以:

[root@xyz tmp]# setfacl -m d:u:myuser1:rx /srv/projecta/
[root@xyz tmp]# getfacl /srv/projecta/
getfacl: Removing leading '/' from absolute path names
# file: srv/projecta/
# owner: root
# group: projecta
# flags: -s-
user::rwx
user:myuser1:r-x
group::rwx
mask::rwx
other::---
default:user::rwx
default:user:myuser1:r-x
default:group::rwx
default:mask::rwx
default:other::---

getfacl打印出的信息中出现了default的相关内容,那些就是子目录和文件会继承的ACL权限。

重新创建子文件和目录:

[pro1@xyz projecta]$ rmdir test_dir
[pro1@xyz projecta]$ rm -f test_file
[pro1@xyz projecta]$ touch test_file
[pro1@xyz projecta]$ mkdir test_dir
[pro1@xyz projecta]$ ls -al
总用量 0
drwxrws---+ 3 root projecta 39 821 12:04 .
drwxr-xr-x. 4 root root     93 821 10:36 ..
drwxrws---+ 2 pro1 projecta  6 821 12:04 test_dir
-rw-rw----+ 1 pro1 projecta  0 821 12:04 test_file

看到+了,新的子文件和目录有继承ACL权限。

实际测试一下:

? ssh myuser1@192.168.1.105
myuser1@192.168.1.105's password:
Last login: Sat Aug 21 11:48:42 2021 from icexmoon-book
[myuser1@xyz ~]$ cd /srv/projecta/
[myuser1@xyz projecta]$ cd test_dir

删除ACL权限

要想删除一个文件或目录的所有的ACL权限:

[root@xyz tmp]# setfacl -b /srv/projecta/
[root@xyz tmp]# ll /srv/projecta/
总用量 0
drwxrws---+ 2 pro1 projecta 6 821 12:04 test_dir
-rw-rw----+ 1 pro1 projecta 0 821 12:04 test_file
[root@xyz tmp]# ll -d /srv/projecta/
drwxrws---. 3 root projecta 39 821 12:04 /srv/projecta/

需要注意的是默认不会影响到子目录或文件的ACL权限,如果有需要,可以使用-R参数。

如果只想删除个别用户或者ACL继承权限的,可以:

[root@xyz tmp]# setfacl -x u:myuser1 /srv/projecta/
[root@xyz tmp]# setfacl -x d:u:myuser1 /srv/projecta/
[root@xyz tmp]# getfacl /srv/projecta/
getfacl: Removing leading '/' from absolute path names
# file: srv/projecta/
# owner: root
# group: projecta
# flags: -s-
user::rwx
group::rwx
mask::rwx
other::---
default:user::rwx
default:group::rwx
default:mask::rwx
default:other::---

如果想禁止某个用户使用目录或文件,可以:

[root@xyz tmp]# setfacl -m u:pro3:- /srv/projecta/
[root@xyz tmp]# getfacl /srv/projecta/
getfacl: Removing leading '/' from absolute path names
# file: srv/projecta/
# owner: root
# group: projecta
# flags: -s-
user::rwx
user:pro3:---
group::rwx
mask::rwx
other::---
default:user::rwx
default:group::rwx
default:mask::rwx
default:other::---

-表示不拥有任何权限。

用户身份切换

一般用户要想切换到root用户,以执行一些root用户才可以执行的操作,可以:

  • 使用su -命令
  • 使用sudo命令

su

使用su可以切换身份为其他账号,如果不指定账号名,将切换到root账号:

[pro1@xyz projecta]$ su
密码:
[root@xyz projecta]# id
uid=0(root) gid=0(root)=0(root) 环境=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[root@xyz projecta]# env | grep pro1
USER=pro1
PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/pro1/.local/bin:/home/pro1/bin
MAIL=/var/spool/mail/pro1
LOGNAME=pro1
XDG_DATA_DIRS=/home/pro1/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share

需要注意的是,通过这种方式切换到root账户,实际上是使用的是non-login shell,所以虽然id命令显式当前用户的确是root没错,但是与用户相关的环境变量,如USERMAIL等依然是切换之前的信息。

不过万幸的是至少家目录是root的家目录:

[root@xyz projecta]# cd ~
[root@xyz ~]# pwd
/root

但不管怎么说,这种没有通过login shell且没有完全加载用户相关环境变量的情况需要避免,所以如果要切换到root用户,应该使用su -

[pro1@xyz projecta]$ su -
密码:
上一次登录:六 821 15:38:44 CST 2021pts/1 上
[root@xyz ~]# env | grep 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
XDG_DATA_DIRS=/root/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share
[root@xyz ~]#

此外,如果仅是想使用root权限执行一条命令,执行完后回到原来的用户,可以:

[pro1@xyz projecta]$ head -n 5 /etc/shadow
head: 无法打开"/etc/shadow" 读取数据: 权限不够
[pro1@xyz projecta]$ su - -c 'head -n 5 /etc/shadow'
密码:
root:$6$h5eXZCiKw8ucXyB2$PxxRgKneIDs2TWIpg916ugAfGCfqNf/HJHiXjy0PTPtUmY.pR/e2cUMpjRBqbx5Y0AHNJtjxAf3aOUTek3DpO.::0:99999:7:::
bin:*:18353:0:99999:7:::
daemon:*:18353:0:99999:7:::
adm:*:18353:0:99999:7:::
lp:*:18353:0:99999:7:::

这样的使用方式与sudo命令类似,不同的是这里需要root的密码,而sudo命令仅需要当前登录用户的密码。

如果需要切换到非root账号,可以:

[pro1@xyz projecta]$ su -l icexmoon
密码:
上一次登录:六 821 09:55:47 CST 2021从 icexmoon-bookpts/0 上
[icexmoon@xyz ~]$ id
uid=1000(icexmoon) gid=1000(icexmoon)=1000(icexmoon),10(wheel) 环境=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[icexmoon@xyz ~]$ exit
登出

需要注意的是,虽然不使用参数-l同样可以切换:su -l icexmoon。但是这种做法就等同于使用su切换root用户,此种情况下使用的是non-login shell,即不会加载用户相关的环境变量,所以是有问题的,应当避免。

同时,对于账号信息中shell设置为/sbin/nologain的账号,同样是无法切换的:

[root@xyz tmp]# su -l sshd
最后一次失败的登录:六 821 16:08:39 CST 2021pts/1 上
最有一次成功登录后有 1 次失败的登录尝试。
This account is currently not available.
[root@xyz tmp]# finger sshd
Login: sshd                             Name: Privilege-separated SSH
Directory: /var/empty/sshd              Shell: /sbin/nologin
Last login 六 821 16:09 (CST) on pts/0
No mail.
No Plan.

sudo

事实上并非所有人都可以使用sudo命令,只有符合配置文件/etc/suders中的设置的账号才可以。

如果你还记得Linux 之旅 1:安装中安装Linux时候勾选的那个将账户添加为管理员的选项,其实就是在通过/etc/suders配置文件设置让该账号具有使用sudo命令的权限。

基本用法

使用sudo命令可以很方便地通过其他用户地身份执行某条命令:

[root@xyz tmp]# sudo -u sshd touch /tmp/sudo_test_file
[root@xyz tmp]# ll /tmp/sudo_test_file
-rw-r--r--. 1 sshd sshd 0 821 16:22 /tmp/sudo_test_file

通过-u可以指定执行命令的用户,如果不加则为root用户。

甚至可以执行多条命令:

[root@xyz tmp]# sudo -u sshd sh -c 'mkdir /tmp/sudo_test_dir;cd /tmp/sudo_test_dir;touch sudo_test_file2'
[root@xyz tmp]# ll /tmp/sudo_test_dir
总用量 0
-rw-r--r--. 1 sshd sshd 0 821 16:26 sudo_test_file2

这实际上是借助sh -c来实现的,有点套娃的意思。

事实上sudo命令的调用过程如下:

  1. 读取/etc/sudoers配置文件,并判断当前用户有没有执行sudo命令的权限。
  2. 如果通过上一步检测,则会要求输入当前用户的密码(root不需要输入密码)。
  3. 如果密码也正确,则会执行sudo命令后的Shell命令。

之所以会要求用户输入密码,是考虑到用户有可能临时离开电脑去上厕所或喝咖啡,所以要求身份验证。通过后短期内再次使用sudo不会再重复要求验证。

/etc/sudoers

上面已经说了,用户能不能使用sudo是由/etc/sudoers这个配置文件决定的,如果一个未添加权限的用户使用sudo命令:

[pro1@xyz projecta]$ sudo head -n 5 /etc/shadow

我们信任您已经从系统管理员那里了解了日常注意事项。
总结起来无外乎这三点:

    #1) 尊重别人的隐私。
    #2) 输入前要先考虑(后果和风险)。
    #3) 权力越大,责任越大。

[sudo] pro1 的密码:
pro1 不在 sudoers 文件中。此事将被报告。

如果要给一个用户开放sudo权限,自然需要root来修改这个文件:

[root@xyz tmp]# visudo

这个命令会使用vi打开/etc/sudoers,可以搜索root,然后依葫芦画瓢地设置一个用户可以使用sudo

image-20210821163850745

这里这个字段的含义为:

  1. 账号
  2. 登录者的来源主机名(可以限制远程登录)
  3. 可切换的身份
  4. 可执行的命令

现在使用user1用户执行sudo

[user1@xyz ~]$ sudo head -n 5 /etc/shadow

我们信任您已经从系统管理员那里了解了日常注意事项。
总结起来无外乎这三点:

    #1) 尊重别人的隐私。
    #2) 输入前要先考虑(后果和风险)。
    #3) 权力越大,责任越大。

[sudo] user1 的密码:
root:$6$h5eXZCiKw8ucXyB2$PxxRgKneIDs2TWIpg916ugAfGCfqNf/HJHiXjy0PTPtUmY.pR/e2cUMpjRBqbx5Y0AHNJtjxAf3aOUTek3DpO.::0:99999:7:::
bin:*:18353:0:99999:7:::
daemon:*:18353:0:99999:7:::
adm:*:18353:0:99999:7:::
lp:*:18353:0:99999:7:::

除了直接将用户加入/etc/sudoers外,还可以通过配置用户组来赋予sudo使用权限:

[root@xyz tmp]# cat /etc/sudoers | grep -v '^#.*' | grep -v '^$'
Defaults   !visiblepw
Defaults    always_set_home
Defaults    match_group_by_gid
Defaults    always_query_group_plugin
Defaults    env_reset
Defaults    env_keep =  "COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS"
Defaults    env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"
Defaults    env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES"
Defaults    env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE"
Defaults    env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"
Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin
root    ALL=(ALL)       ALL
user1   ALL=(ALL)       ALL
%wheel  ALL=(ALL)       ALL

看到%wheel ALL=(ALL) ALL没,这行的意思是用户组wheel具有使用sudo的权限,因此我们可以通过将用户添加到wheel用户组的方式赋予sudo权限:

[root@xyz tmp]# usermod -a -G wheel pro1
[root@xyz tmp]# id pro1
uid=1505(pro1) gid=1508(pro1)=1508(pro1),10(wheel),1507(projecta)

之后登录pro1测试的过程不再赘述。

如果想每次使用sudo不再需要输入密码进行验证,可以通过visudo命令修改配置文件中的如下信息:

image-20210821172039765

将上面红框位置内的信息去掉注释,变成如上的内容后保存即可。

这样做了以后,wheel用户组内的用户也可以像root一样在使用sudo的时候不需要输入密码了。

此外,还可以实现一些更复杂的设置,比如说让某些用户只能通过sudo执行特定的命令:

image-20210821172911187

可以修改为上边的设置,现在user1仅能执行passwd这个命令了(需要注意的是这里指定的命令必须是完整路径):

[user1@xyz ~]$ sudo head -n 5 /etc/shadow
[sudo] user1 的密码:
对不起,用户 user1 无权以 root 的身份在 xyz.icexmoon.centos 上执行 /bin/head -n 5 /etc/shadow。
[user1@xyz ~]$ sudo passwd myuser1
[sudo] user1 的密码:
更改用户 myuser1 的密码 。
新的 密码:
无效的密码: 密码少于 8 个字符
重新输入新的 密码:
passwd:所有的身份验证令牌已经成功更新。

但是要知道的是,user1用户拥有的是执行passwd这个命令的全部功能,也就是说也可以通过passwd命令修改root用户的密码,一般来说我们显然不允许这样的操作,如果要进一步限制,不允许user1修改root的密码,可以:

image-20210821174933728

需要注意这里的命令顺序,表示会被阻止的命令形式,如果!/usr/bin/passwd root放在usr/bin/passwd [a-zA-Z]*之前就会出错,原因是先阻止再被允许,显然是不正确的规则,所以最好将阻止规则放在允许规则的后边。

现在看效果:

[user1@xyz ~]$ sudo passwd root
对不起,用户 user1 无权以 root 的身份在 xyz.icexmoon.centos 上执行 /bin/passwd root。
[user1@xyz ~]$ sudo passwd
对不起,用户 user1 无权以 root 的身份在 xyz.icexmoon.centos 上执行 /bin/passwd。
[user1@xyz ~]$ sudo passwd myuser1
更改用户 myuser1 的密码 。
新的 密码:
无效的密码: 密码未通过字典检查 - 它基于字典单词
重新输入新的 密码:
passwd:所有的身份验证令牌已经成功更新。

正是我们希望的。

此外还可以在/etc/sudoers中使用别名:

User_Alias PASSWORD_ADMINS = pro1,pro2,pro3,myuser1,myuser2
Cmnd_Alias PASSWORD_COMMAND = !/usr/bin/passwd,/usr/bin/passwd [a-zA-Z]*,!/usr/bin/passwd root
PASSWORD_ADMINS ALL=(root)      PASSWORD_COMMAND

写入上面的信息后保存后,PASSWORD_ADMINS中关联的用户将可以使用sudo命令修改一般用户的密码。使用别名可以更容易地配置sudo命令的管理权限。

最后,在介绍一种用途:借助sudo命令我们可以实现在不知道root账号密码的情况下切换为root用户,这样可以更好地保护root密码(虽然好像意义并不是特别大,毕竟有sudo权限的用户都可以修改root的密码)。

实现的方法也很简单,只要在/etc/sudoers中添加这样的信息:

pro1            ALL=(root)      /usr/bin/su -

然后使用对应的用户这样:

[pro1@xyz ~]$ sudo su -

如果需要输入密码就输入自己账户的,就可以切换为root了。

事实上《鸟哥的私房菜》这部分章节还有相当一部分内容,但本文的幅度已经很长了,而且我的Typora编辑器已经很卡了,就分为两个章节发吧。

先到这里了,谢谢阅读。

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2021-08-22 13:52:26  更:2021-08-22 13:53:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/28 20:24:10-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计