Linux账号管理与ACL权限设置

文章目录

  • Linux的账户和用户组
    • 用户标识符:UID与GID
    • 用户账号
    • 用户组:有效与初始用户组groups,newgrp
  • 账号管理
    • 新增与删除用户:useradd、相关配置文件、passwd、usermod、userdel
    • 用户功能:id、finger、chfn、chsh
    • 新增与删除用户组:groupadd、groupmod、groupdel、gpasswd
  • 账号管理案例
    • 任务一
    • 任务二
  • Linux详细权限规划:ACL使用
    • 什么是ACL与如何支持启动ACL
    • ACL的设置技巧:getfacl、setfacl
    • 案例
  • Linux 用户身份切换
    • su
    • sudo
    • visudo的设置方法
  • Linux 用户的特殊shell与PAM模块
    • 特殊的shell:/sbin/nologin
    • PAM模块简介
    • PAM模块设置语法
    • 常用模块简介
    • 其他相关文件
  • Linux主机上的用户信息传递
    • 查询用户:w、who、last、lastlog
    • 用户对谈:write、mesg、wall
    • 用户邮箱:mail
    • 给自己的QQ邮箱发送一封邮件
      • ①获取授权码
      • ②使用mailx发送邮件
      • ③测试是否可以发送邮件
  • 账号相关的检查工具:pwck、pwconv、pwunconv、chpasswd

Linux的账户和用户组

管理员的工作中,相当重要的一环就是【管理账户】。因为整个系统都是你管理,并且所有一般用户的账户申请,都必须要通过你的协助才行,所以就必须了解一下如何管理好一个服务器主机中的账号。管理Linux账号之前,我们必须了解Linux到底是如何辨别每一个用户的。

Linux是怎么辨别每一个用户的呢?

Linux是一个多用户系统,可以同时支持多个用户登录,而每个用户都有自己的身份标识,Linux通过用户ID(UID),组ID(GID)来辨别每一个用户

用户标识符:UID与GID

用户ID(UID)是一个数字,通常是从0开始分配的,0是预留的超级用户(root)的UID,1至99是系统保留的UID,100以上的UID通常是由系统管理员分配给普通用户的。每个用户的UID是唯一的,可以用来确定用户的身份

组ID(GID)也是一个数字,通常是从0开始分配的,0是预留的超级用户组(root)的GID,1至99是系统保留的GID,100以上的GID通常由系统管理员分配给用户组。每个用户组的GID是唯一的,可以用来确定用户组的身份

用户账号

Linux系统上面的用户如果需要登录主机以获取shell的环境来工作时,首先它必须要在 计算机前面利用tty1~tty6的终端提供的登录接口,并输入账号与密码才能够登录。

  1. 先查找/etc/passwd 里面是否有你的账号?如果没有则退出,如果有的话则将该账号对应的UID与GID(/etc/group中)读出来,另外,该账号的家目录与shell也一并读出
  2. 再来就是核对密码表,这时Linux会进入/etc/shadow里面找出对应的账号与UID,然后进行核对你刚刚输入的密码与里面的密码是否相符
  3. 如果一切都OK的话,就要进入shell管理的阶段

/etc/passwd文件结构

文件结构:每一行都代表一个账号,有几行就代表有几个账号在你系统里。不过需要特别留意的是,里面有很多账号本来就是系统正常运行所必需的,我们简称系统账号,例如:bin、daemon、adm等,这些账户不要随意删除.

[root@localhost ~]#  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系统都会有的1行,就是root这个系统管理员那一行。你可以明显的看出来,每一行用【:】分隔开,共有7个字段分别表示的是:

字段解释
账户名称该字段代表用户账号的名称,通常由字母、数字和下划线组成。该字段不能包含冒号( : )。
密码该字段代表用户账号的密码,通常是加密后的密码,而不是明文密码。如果该字段为空,则表示该用户没有密码,可以直接登录系统。如果该字段为x,则表示密码存储在/etc/shadow文件中
UID该字段代表用户账号的唯一标识符,通常是一个数字。UID为0的用户是超级用户(root),1~999都是系统账户,其他用户的UID从1000开始分配
GID该字段代表用户所属的主要用户组的唯一标识符,通常是一个数字。用户可以属于多个用户组,但只有一个是主要用户组
用户信息说明栏该字段是一个可选字段,通常包含有关用户的描述信息。
家目录该字段代表用户的家目录,通常用于存储用户的文件和配置信息
shell该字段代表用户的默认Shell程序,用于提供用户与系统交互的界面。

/etc/shadow文件结构

/etc/shadow文件是存储用户账号密码信息的文件。该文件的每一行都代表一个用户账号,由多个字段组成,每个字段用冒号(:)隔开。以下是/etc/shadow文件的结构详解:

[root@localhost ~]# head -n 5 /etc/shadow
root:$6$0x0W5U0lAIGfNePS$fQegjEeiYdvyV7xK7zyhR9jsXzAwkB6XoA6RxpGo0X/uz8uPhblK9frf36sRtpdyNgJY4jZPQplMR1b/Hqgb9/::0:99999:7:::
bin:*:18353:0:99999:7:::
daemon:*:18353:0:99999:7:::
adm:*:18353:0:99999:7:::
lp:*:18353:0:99999:7:::
字段解释
账户名称该字段代表用户账号的名称,与/etc/passwd文件中的用户名字段相同。
密码该字段代表用户账号的密码,通常是加密后的密码。如果用户没有密码,则该字段为空。
最后一次修改密码的日期该字段代表用户最后一次修改密码的日期,通常是从1970年1月1日起的天数。
密码过期时间该字段代表密码的过期时间,通常是从1970年1月1日起的天数。如果该字段为0,则表示密码永不过期。
密码过期前的警告天数该字段代表密码过期前给用户的警告天数。例如,如果该字段为7,则表示在密码过期前7天给用户一个警告提示。
密码过期后的宽限天数该字段代表密码过期后给用户的宽限天数。例如,如果该字段为7,则表示在密码过期后7天内仍然允许用户使用旧密码登录系统。
密码失效日期该字段代表密码失效的日期,通常是从1970年1月1日起的天数。如果该字段为-1,则表示密码已失效。
账号失效日期该字段代表账号失效的日期,通常是从1970年1月1日起的天数。如果该字段为-1,则表示账号已失效。
保留字段该字段是一个保留字段,目前没有使用。

用户组:有效与初始用户组groups,newgrp

/etc/group文件结构

这个文件是在记录GID与组名的对应记录

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

# 其中
# 第一行表示root用户组,GID为0,没有密码,没有成员
# 第二行表示bin用户组,GID为1,密码为x,成员包括root、bin和daemon
字段解释
用户组名用户组的名称,长度不超过32个字符,不能包含冒号和逗号等特殊字符。
用户组密码用户组密码,如果为空则表示没有密码。
GID用户组ID,是一个非负整数,唯一标识一个用户组。
组内成员该用户组包含的用户列表,用逗号分隔。如果该用户组没有成员,则该字段为空。

因为每个用户都可以拥有多个用户组,这就好比在学习读书的时候加入多个社团。不过在这里就很奇怪了,那就是【假如我同时加入多个用户组,那我在写作业的时候,到底是以哪个用户为准呢?】下面我们来介绍有效用户组

/etc/gshadow文件结构

/etc/gshadow文件是Linux系统中的一个重要文件,用于存储用户组的加密密码和其他安全相关信息。该文件只有root用户可以访问和修改,其结构如下:

[root@localhost ~]# head -n 5 /etc/gshadow
root:::
bin:::
daemon:::
sys:::
adm:::
字段解释
组名称与/etc/group文件相同
组密码与/etc/passwd文件中的密码字段相似,但是它是加密的
组管理员列表组管理员列表,由逗号分隔的用户名列表,指定可以管理该组的用户
组成员列表组成员列表,由逗号分隔的用户名列表,指定该组的普通成员

有效用户组与初始用户组

每个用户在它的/etc/passwd里面的第四个字段有个所谓的GID,那个GID就是所谓的【初始用户组】

该命令会列出用户的主用户组名称。用户可以通过修改/etc/passwd文件来改变主用户组,例如:

[root@chenshiren ~]# usermod -a -G  users csq   
[root@chenshiren ~]# grep csq /etc/passwd /etc/group  /etc/gshadow
/etc/passwd:csq:x:1001:1001::/home/csq:/bin/bash

/etc/group:users:x:100:csq
/etc/group:csq:x:1001:

/etc/gshadow:users:::csq
/etc/gshadow:csq:!::

在上述例子中,因为我的zhw账号同时支持zhw和users这两个用户组,因此,在读取,写入执行文件时,针对用户组部分,只要是users与zhw这个两个用户组拥有的功能,zhw这个用户都能够拥有。不过这是针对已存在的文件而言,如果今天要建立一个新的文件或是新的目录,那么新文件的用户组是zhw还users呢?这就要检查以下有效用户组了

groups:有效与支持用户组的观察

如果我以zhw这个用户组的身份登录后,该如何知道我所有支持的用户组?很简单直接输入groups就可以了

注意:group 有加 s

[csq@chenshiren ~]$ groups 
csq users

这个输出信息中,知道了zhw这个用户同时属于zhw和users这三个用户组,而且,第一个输出的用户组即有效用户组。也就是说 ,我此时去touch创建一个文件,那么这个文件拥有者为zhw用户组也是zhw

[csq@chenshiren ~]$ touch csq.txt ; ll csq.txt
-rw-r--r--. 1 csq csq 0  319 13:51 csq.txt

通常有效用户组的作用是新建文件,那么有效用户组是否能够变换?

newgrp:有效用户组的切换

那么如何修改有效用户组呢?newgrp命令用于切换用户的有效用户组,使用户可以使用其他用户组的权限访问文件和目录。在执行newgrp命令时,系统会判断用户是否已经属于该用户组,如果是则直接切换到该用户组,否则需要用户输入该用户组的密码才能切换到该用户组。如果用户没有权限切换到该用户组,则会出现“permission denied”错误。

[csq@chenshiren ~]$ newgrp users 
[csq@chenshiren ~]$ groups  # 此时,csq的有效用户组就是user了
users csq
[csq@chenshiren ~]$ touch users.txt ;ll *.txt    
-rw-r--r--. 1 csq csq   0  319 13:51 csq.txt
-rw-r--r--. 1 csq users 0  319 13:56 users.txt
[csq@chenshiren ~]$ exit  # 注意记得退出newgrp的环境
exit
[csq@chenshiren ~]$ groups
csq users

# 这个命令可以修改目前用户的有效用户组,而且是另外以一个shell来提供这个功能
# 上述例子当中,csq这个用户是以另一个shell登录的,而且新的shell给予csq有效GID为users

image-20240319140844717

账号管理

新增与删除用户:useradd、相关配置文件、passwd、usermod、userdel

useradd

要如何在Linux中新增一个用户呢?非常简单,我们登录系统时会输入(1)账号(2)密码,所以建立一个可用的账号同样的也需要这两个数据,账号可以使用useradd来新建,密码则使用passwd这个命令设置。这两个命令的执行方法如下

[root@chenshiren ~]# useradd [-u UID] [-g 初始用户组] [-G 次要用户组] [-mM] [-c 说明栏]  [-d 家目录绝对路径] [-s shell] 使用者账号名

选项与参数:
-u            # 后面接的是UID,是一组数字,直接指定一个特定的UID给这个账号
-g            # 后面接的是用户组就是上面提到的初始用户组
              # 该用户组的GID会被放到/etc/passwd第四个字段内
-G            # 后面接的用户组则是该账号还可以加入的用户组
              # 这个选项会修改/etc/group内的相关内容
-M            # 强制,不要建立使用者家目录(系统账号默认值)
-m            # 强制,要建立使用者的家目录(一般账号默认值)
-c            # 这个就是/etc/passwd的第五个字段的说明内容,可以随便我们设置
-d            # 指定某个目录成为家目录,而不要使用默认值,务必使用绝对路径
-r            # 建立一个系统账号,这个账号的UID会有限制(参考/etc/login.defs)
-e            # 后面借一个日期,格式为【YYYY-MM-DD】此选项可写入shadow第八个字段
              # 就是设置账号失效日的选项
-f            # 后面接shadow的第七字段位选项,指定密码是否会失效,0为立刻失效
              # -1为永不失效(密码只会过期后强制于登录时重新设置而已)

其实系统已经帮我们规定好了非常多的默认值了,所以我们可以简单地使用【useradd 账号】来建立账户。centos默认值如下

  • 在/etc/passwd里面建立一行与账户相关的数据,包括建立UID/GID/家目录等
  • 在/etc/shadow里面将此账号的密码相关参数写入,但是尚未有密码
  • 在/etc/group 里面加入一个与账号名称一模一样的组名
  • 在/home下面建立一个与账号同名的目录作为用户家目录,且权限为700

完全参考默认值建立一个使用者,名称为csr

[root@chenshiren ~]# useradd csr
[root@chenshiren ~]# ll /home/csr/ -d
drwx------. 3 csr csr 78  319 15:55 /home/csr/
# 默认会建立使用者的家目录,且权限为700,这个是重点

[root@chenshiren ~]# grep csr /etc/passwd /etc/shadow /etc/group
/etc/passwd:csr:x:1003:1003::/home/csr:/bin/bash
/etc/shadow:csr:!!:19801:0:99999:7:::
/etc/group:csr:x:1003:         <== 默认会建立一个与账号一模一样的用户组名

假设我们已经知道我的系统中有个用户组名称为users,且UID1500并不存在,请用users为初始用户组,以及uid为1500来建立一个名为csr2的账号

[root@chenshiren ~]# useradd -u 1500 -g users csr2
[root@chenshiren ~]# ll -d /home/csr2/
drwx------. 3 csr2 users 78  319 15:59 /home/csr2/
[root@chenshiren ~]# grep csr2 /etc/passwd /etc/shadow /etc/group
/etc/passwd:csr2:x:1500:100::/home/csr2:/bin/bash
/etc/shadow:csr2:!!:19801:0:99999:7:::
# UID与初始用户组确实修改成我们需要的了

建立一个系统账号,名称为csr3

[root@chenshiren ~]# useradd -r csr3
[root@chenshiren ~]# ll -d /home/csr3
ls: 无法访问 '/home/csr3': 没有那个文件或目录
[root@chenshiren ~]# grep csr3 /etc/passwd /etc/shadow /etc/group
/etc/passwd:csr3:x:978:977::/home/csr3:/bin/bash
/etc/shadow:csr3:!!:19801::::::
/etc/group:csr3:x:977:

# 一般账号UID应该是1000以后了,系统UID则一般小于1000
# 然后就会有些人问啊为什么没有家目录呢?
# 这个是由于系统账号主要是用来执行系统所需服务的权限设置,所以系统账号默认都不会主动创建家目录

useradd参考文件

/etc/default/useradd配置文件详解

你想过这样一个问题没有为什么 【usradd csr1】 会主动在/home/csr1建立起家目录?家目录内容有什么数据且来自哪里?为何默认使用的是/bin/bash这个shell呢?为什么密码字段已经都规范好了呢(0:99999:7那一串)?这里我们就要介绍以下useradd所使用的配置文件

[root@localhost ~]# useradd -D
GROUP=100               <== 默认的用户组
HOME=/home              <== 默认的家目录所在目录
INACTIVE=-1             <== 密码失效日,在shadow内的第7字段
EXPIRE=                 <== 账户失效日,在shadow内的第8字段
SHELL=/bin/bash         <== 默认的shell
SKEL=/etc/skel          <== 使用者家目录的内容数据参考目录
CREATE_MAIL_SPOOL=yes   <== 是否主动帮助使用者建立邮箱(mailbox)

这些数据其实是由/etc/default/useradd 调用出来的,i可以自行用vim去查看该文件的内容。

下面是该文件的配置及其含义:

  1. GROUP:新建账户的初始用户使用GID为100
  2. HOME:新建用户的主目录,默认值为/home。
  3. INACTIVE:新建用户账户不活动的天数,默认值为-1,表示永不失效。
  4. EXPIRE:新建用户账户的过期时间,默认值为空,表示永不过期。
  5. SHELL:新建用户的默认Shell,默认值为/bin/bash。
  6. SKEL:指定一个目录,将该目录中的文件和目录作为新建用户的模板。
  7. CREATE_MAIL_SPOOL:设置为yes时,新建用户同时创建邮件存储目录(/var/spool/mail/用户名称)

/etc/login.defs配置文件详解

除了这些基本的账号设置值之外,UID/GID的密码参数有时在哪里参考呢?那就要看看/etc/login.defs,这个文件了

[root@chenshiren ~]# cat /etc/login.defs  | sed  -e  '/^$/d'  -e '/^#/d'   
...
MAIL_DIR        /var/spool/mail    
PASS_MAX_DAYS   99999              # /etc/shadow内的第五个字段,单位为天。如果超过该期限,用户将被要求更改密码。默认值为 99999,表示永不过期。
PASS_MIN_DAYS   0                  #  /etc/shadow内的第4个字段,该选项用于设置用户更改密码的最短间隔时间,即用户必须在该时间间隔后才能再次更改密码。默认值为 0,表示可以立即更改密码
PASS_WARN_AGE   7   # /etc/shadow内的第6个字段,该选项用于设置用户密码过期前的警告时间,单位为天。                     # 如果设置为 7,则表示用户密码将在过期前 7 天收到警告通知。默认值为 7
UID_MIN                  1000      # 使用者最小的UID,意思就是小于1000的UID为系统保留
UID_MAX                 60000      # 使用者能够用的最大UID
SYS_UID_MIN               201      # 保留给使用者自行设置的系统账号最小值UID
SYS_UID_MAX               999      # 保留给使用者自行设置的系统账号最大值UID
GID_MIN                  1000      # 使用者自定义用户组的最小GID,小于1000为系统保留
GID_MAX                 60000      # 使用者自定义用户组的最大GID
SYS_GID_MIN               201      # 保留给使用者自行设置的系统账号最小值GID
SYS_GID_MAX               999      # 保留给使用者自行设置的系统账号最大值GID
CREATE_HOME     yes                # 在不加-M及-m时,是否主动建立使用者家目录?
UMASK           077                # 使用者家目录建立的umask,因此权限会是700
USERGROUPS_ENAB yes                # 使用userdel删除时,是否会删除初始用户组
ENCRYPT_METHOD SHA512              # 密码加密的机制使用的是SHA-512

现在你知道,使用useradd这个程序在建立Linux上的账号时,至少会参考:

  • /etc/default/useradd
  • /etc/login.defs
  • /etc/skel/*

不过最重要的其实是建立/etc/passwd、/etc/shadow、/etc/group、/etc/gshadow 还有用户家目录。了解了这些文件我们接下来就可以处理一下用户的密码了

passwd修改用户密码

刚刚我们讲到了,使用useradd建立了账号后,在默认情况下,该账号是暂时被锁定的,也就是说,该账号无法登录的!!!,我们可以使用passwd命令给他设置新密码就好了

passwd [选项] [账号名称]
> [-n 日数][-x 人数][-w 日数][-i 日期] 这些参数只有root能设置

选项参数
--stdin   可以通过来自前一个管道的数据,作为密码输入,对shell脚本有帮助
-l        是lock的意思,会将/etc/shadow 第二个字段前面加上!使密码失效
-u        与-l相对,是Unlock的意思
-S(大写)  列出密码相关参数,即shadow文件内地大部分信息    
-n        后面接天数,shadow的第4字段,多久不可修改密码天数
-x        后面接天数,shadow的第5字段,多久内必须要修改密码
-w        后面接天数,shadow的第6字段,密码过期前的警告天数
-i        后面接日期,shadow的第7字段,密码失效日期

请root设置csr的密码

[root@chenshiren ~]# passwd csr
更改用户 csr 的密码 。
新的 密码:                   <== 这里直接输入新密码,屏幕不会有任何反应
无效的密码: 密码是一个回文     <== 密码太简单重新输入
重新输入新的 密码:            <== 再输入一次同样的密码
passwd:所有的身份验证令牌已经成功更新。  <== 竟然修改成功了

当我要设置短密码的时候,可以使用root设置,那如果是用户自己要该密码呢?

[csr@localhost ~]$ passwd          <== 后面不加账号就是改自己的密码
更改用户 csr 的密码 。
为 csr 更改 STRESS 密码。
(当前)UNIX 密码:                  <== 输入旧密码
新的 密码:                         <== 输入新密码
无效的密码: 密码是一个回文           <== 提示密码太短
新的 密码:                         <== 重新输入
无效的密码: 密码是一个回文           <== 还是不行
新的 密码:                         <==输入难一点的密码
重新输入新的 密码:                  <==重新输入
passwd:所有的身份验证令牌已经成功更新。 <== 设置成功了!

你的密码最好符号如下要求:

  • 密码不能与账号相同
  • 密码尽量不要选用字段里面会出现的字符串
  • 密码需要超过8个字符
  • 密码不要使用简单的关系式,如1+1=2,iloveyou等等
  • 密码尽量使用大小写字符、数字、特殊字符($、-、_等)的组合

使用–stdin建立用户的密码

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

让csr每60天需要修改密码,密码过期后10天未使用就声明账号失效

[root@localhost ~]# passwd -S csr
csr PS 2023-04-10 0 99999 7 -1 (密码已设置,使用 SHA512 算法。)
[root@localhost ~]# passwd -x 60 -i 10 csr
调整用户密码老化数据csr。
passwd: 操作成功
[root@localhost ~]# passwd -S csr
csr PS 2023-04-10 0 60 7 10 (密码已设置,使用 SHA512 算法。)

让csr账户失效,查看完毕后再让他失效

[root@localhost ~]# passwd -l csr
锁定用户 csr 的密码 。
passwd: 操作成功
[root@localhost ~]# passwd -S csr
csr LK 2023-04-10 0 60 7 10 (密码已被锁定。)
[root@localhost ~]# grep csr /etc/shadow
csr:!!$6$aUlf83nj$Oen9IE2eFsjOhMLyRa011SjfvJhntvgypiSra1BMyyu9vUqtlB7.4gOU6pG8qpm/h38XvcPu31lDRNM9OtlOd0:19457:0:60:7:10::
csr2:!!:19457:0:99999:7:::
csr3:!!:19457::::::                 
[root@localhost ~]# passwd -u csr
解锁用户 csr 的密码。
passwd: 操作成功
[root@localhost ~]# grep csr /etc/shadow
csr:$6$aUlf83nj$Oen9IE2eFsjOhMLyRa011SjfvJhntvgypiSra1BMyyu9vUqtlB7.4gOU6pG8qpm/h38XvcPu31lDRNM9OtlOd0:19457:0:60:7:10::
csr2:!!:19457:0:99999:7:::
csr3:!!:19457::::::

chage

除了使用passwd -S之外,有没有更详细的密码参数显示功能呢?有就是chage了,用法如下

chage [options] username

选项参数:
-l        列出该账号的详细密码参数
-d        后面接日期,修改shadow 第三个字段(最近一次修改密码的日期)格式为YYYY-MM-DD
-m        后面接日期,修改shadow 第四个字段(密码最短保留天数)
-M        后面接日期,修改shadow 第五个字段(密码多久需要进行修改)
-W        后面接日期,修改shadow 第六个字段(密码过期前警告日期)
-I        后面接日期,修改shadow 第七个字段(密码失效日期)
-E        后面接日期,修改shadow 第八个字段(账户失效日)格式为YYYY-MM-DD

列出csr的详细密码参数

[root@localhost ~]# chage -l csr
最近一次密码修改时间                                    :4月 10, 2023
密码过期时间                                    :4月 11, 2023
密码失效时间                                    :4月 21, 2023
帐户过期时间                                            :从不
两次改变密码之间相距的最小天数          :1
两次改变密码之间相距的最大天数          :1
在密码过期之前警告的天数        :7

建立一个名为agetest的账号,该账号第一次登录后使用默认密码,但必须要修改过密码,使用新密码才能登录系统使用bash环境

[root@localhost ~]# useradd agetest
[root@localhost ~]# echo "agetestABC123"| passwd --stdin agetest
更改用户 agetest 的密码 。
passwd:所有的身份验证令牌已经成功更新。
[root@localhost ~]# chage -d 0 agetest
[root@localhost ~]# chage -l agetest |head -n 3
最近一次密码修改时间                                    :密码必须更改
密码过期时间                                    :密码必须更改
密码失效时间                                    :密码必须更改
# 此时账号的密码建立时间会被改为1970/1/1,所以会有问题

尝试登录agetest

连接成功
You are required to change your password immediately (root enforced)
WARNING: Your password has expired.
You must change your password now and login again!
更改用户 agetest 的密码 。
为 agetest 更改 STRESS 密码。
(当前)UNIX 密码:    <<== 这个账号被强制性要求改密码

usermod

usermod是Linux系统中用来修改用户账号信息的命令,可以用来修改用户的用户名、用户ID、所属组、家目录、登录Shell等信息。其语法如下:

usermod [选项] [username]
选项参数:
-c    后面接账号的说明,即/etc/passwd第五字段,可以加入一些账号的说明
-d    后面接账号的家目录,即修改/etc/passwd的第六字段
-e    后面接日期,格式是YYYY-MM-DD 也就是在/etc/shadow被的第八个字段内容
-f    后面接天数,为shadow第七个字段
-g    后面接初始用户组,修改/etc/passwd的第四个字段,就是修改GID
-aG   用于将用户添加到一个或多个附加组中。该选项后面需要指定一个或多个组名,用逗号分隔。这将使用户成为这些组的成员,并且可以在这些组中具有相应的权限。
-l    后面接账号名称,就是修改账户的名称,/etc/passwd的第一个字段
-u    后面接UID数字,即/etc/passwd第三字段的数据
-s    后面接shell的实际文件,例如/bin/bash或/bin/csh等
-L    暂时将使用者的密码冻结,让他无法登录,其实仅改/etc/shadow的密码字段
-U    将/etc/shadow密码字段的感叹号()拿掉,解锁。
-p    用于设置用户的密码,选项后面需要跟着加密后的密码。

修改使用者csr的说明字段,加上【i am csr】的说明

[root@localhost ~]# usermod -c "i am csr" csr
[root@localhost ~]# grep csr /etc/passwd
csr:x:1002:1002:i am csr:/home/csr:/bin/bash
...

使用者csr这个账号在2023年4月10日失效

[root@localhost ~]# usermod -e "2023-04-10" csr
[root@localhost ~]# chage -l csr |head -n 4
最近一次密码修改时间                                    :4月 10, 2023
密码过期时间                                    :4月 11, 2023
密码失效时间                                    :4月 21, 2023
帐户过期时间                                            :4月 10, 2023

建立zhw3这个系统账号时没有设置家目录,请建立它的家目录

[root@localhost home]# mkdir zhw3
[root@localhost home]# ll -d zhw3
drwxr-xr-x. 2 root root 6 410 20:40 zhw3
[root@localhost home]# chown zhw3:zhw3 zhw3
[root@localhost home]# ll -d zhw3
drwxr-xr-x. 2 zhw3 zhw3 6 410 20:40 zhw3
[root@localhost home]# chmod 700 zhw3
[root@localhost home]# ll -d zhw3
drwx------. 2 zhw3 zhw3 6 410 20:40 zhw3
[root@localhost home]# usermod -d /home/zhw3 zhw3
[root@localhost home]# grep zhw3 /etc/passwd
zhw3:x:1502:1502::/home/zhw3:/bin/bash

userdel

这个功能就很简单了,目的就是删除用户的相关数据,而用户的数据有:

  • 用户账号/密码相关参数:/etc/passwd、/etc/shadow
  • 用户组相关参数:/etc/group、 /etc/gshadow
  • 用户个人文件数据:/home/username、/var/spool/mail/username

整个命令的语法很简单:

userdel [选项] [username]

选项参数:
-r    连同使用者的家目录一起删除

删除csr,连同家目录一起删了

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

用户功能:id、finger、chfn、chsh

useradd、usermod、userdel都是系统管理员能够使用的命令,如果我是一般用户呢?那么我除了密码之外就无法修改其他数据?当然不是,这里我们介绍一下一般用户常用的账户数据修改与查询命令

id

id [usrename]

查看root自己的相关ID信息

[root@localhost home]# id
uid=0(root) gid=0(root)=0(root) 环境=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
# 这行信息显示了UID/GID以及支持的所以用户组

查看一下zhw3

[root@localhost home]# id zhw3
uid=1502(zhw3) gid=1502(zhw3)=1502(zhw3)
# 这条命令也可以用做查系统的账号
[root@localhost home]# id car
id: car: no such user
 # 表示系统没有这个账号

finger

finger命令用于显示用户的登录信息和详细信息,包括用户的登录名、全名、登录Shell等

centos7默认是没有finger这个命令,需要咋们手动安装

yum install -y finger

使用方法如下

finger [选项] [username]

选项:
-s    只显示用户的登录状态信息,不显示详细信息。
-m    列出与后面接的账号相同者,而不是利用部分比对(包括全面部分)

查看zhw3的使用者相关账号属性

[root@localhost home]# finger zhw3
Login: zhw3                             Name: 
Directory: /home/zhw3                   Shell: /bin/bash
Never logged in.
No mail.
No Plan.

其实finger列出来的几乎都是/etc/passwd文件里面的东西,列出的信息说明如下

  • Login:为用户账号,即/etc/passwd内的第一字段
  • Name:为全名,即/etc/passwd内的第五字段(或称为注释)
  • Directory:就是家目录
  • Shell:就是使用的Shell文件所在
  • Never logged in:finger还会调查用户登录主机的情况
  • No mail:调查/var/spool/mail 当中的邮箱数据
  • No Plan:表示该用户没有设置计划表,这也可以作为一种提示,告诉其他用户该用户没有特别的安排或计划

利用zhw建立自己的计划文件

[zhw@localhost ~]$ echo "i love you you love i i bu zhi dao" > ~/.plan
[zhw@localhost ~]$ finger zhw
Login: zhw                              Name: 
Directory: /home/zhw                    Shell: /bin/bash
Last login 一 410 21:14 (CST) on pts/0
No mail.
Plan:
i love you you love i i bu zhi dao

找出目前在系统上面登录的使用者与登录时间

[zhw@localhost ~]$ finger
Login     Name       Tty      Idle  Login Time   Office     Office Phone   Host
root      root       pts/0          Apr 10 19:49                           (192.168.100.1)
root      root       pts/1    1:26  Apr 10 19:49                           (192.168.100.1)

在上述实例中,我们发现输出的信息有office、office Phone等,那么这些信息要如何记录呢?下面我们来介绍chfn这个命令,来看看如何修改用户的finger数据

chfn

chfn [选项] [username]

选项参数:
-f    后面接完整的大名
-o    您办公室的房间号码
-p    办公室的电话号码
-h    家里的电话号码

zhw自己修改一下自己的相关信息

[zhw@localhost ~]$ chfn
Changing finger information for zhw.
名称 []: zhw         # 输入想呈现的全名
办公 []: 137         # 办公室号码
办公电话 []: 137      # 办公室电话
住宅电话 []: 520      # 家里的电话

密码:                # 确认身份,输入自己的密码
Finger information changed.

[zhw@localhost ~]$ grep zhw /etc/passwd
zhw:x:1001:1001:zhw,137,137,520:/home/zhw:/bin/bash
zhw3:x:1502:1502::/home/zhw3:/bin/bash
[zhw@localhost ~]$ finger zhw
Login: zhw                              Name: zhw
Directory: /home/zhw                    Shell: /bin/bash
Office: 137, 137                        Home Phone: 520
Last login 一 410 21:22 (CST) on pts/0
No mail.
Plan:
i love you you love i i bu zhi dao

这个命令说实在的,除非是你的主机有很多用户,否则真用不到这个程序,不过玩玩也是可以的

chsh

chsh [选项]

选项参数:
-l    列出目前系统上面可用的shell,其实就是/etc/shells的内容
-s    设置修改自己的shell

用zhw的身份列出系统上所以合法的shell,并且指定csh为自己的shell

[zhw@localhost ~]$ chsh -l
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
[zhw@localhost ~]$ chsh -s /bin/sh
Changing shell for zhw.
密码:
Shell changed.
[zhw@localhost ~]$ grep zhw /etc/passwd
zhw:x:1001:1001:zhw,137,137,520:/home/zhw:/bin/sh
zhw3:x:1502:1502::/home/zhw3:/bin/bash
[zhw@localhost ~]$ chsh -s /bin/bash
Changing shell for zhw.
密码:
Shell changed.
[zhw@localhost ~]$ grep zhw /etc/passwd
zhw:x:1001:1001:zhw,137,137,520:/home/zhw:/bin/bash
zhw3:x:1502:1502::/home/zhw3:/bin/bash

不论是chfn与chsh,都能够让一般用户修改/etc/passwd这个系统文件。所以这两个文件是什么权限?显而易见是SUID的权限

新增与删除用户组:groupadd、groupmod、groupdel、gpasswd

已经了解了新增、删除、修改、查询后,再来了解以下用户组的相关内容,基本上,用户组的内容都与这两个文件有关/etc/group,/etc/gshadow,用户组的内容其实很简单,都是上面两个文件的新增,修改与删除而已

groupadd

groupadd [选项] [用户组名称]

选项参数:
-g    后面接某个特定的GID,用来直接设置某个GID
-r    建立系统用户组、与/etc/login.defs 内的GID_MIN有关

新建一个用户组,名称为group1

[root@localhost home]# groupadd group1
[root@localhost home]# grep group1 /etc/group /etc/gshadow
/etc/group:group1:x:1503:
/etc/gshadow:group1:!::

# 的GID也是会由1000以上最大GID + 1来决定

groupmod

groupmod [选项] [用户组名]

选项:
-g   修改既有GID的数字
-n   修改既有的用户组的名称

将刚刚上面的命令创建的group1名称改为mygroup,GID为201

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

groupdel

groupdel [用户组名]

将刚刚的mygroup删除

[root@localhost home]# groupdel  mygroup

若要删除zhw这个用户组的话?

[root@localhost ~]# groupdel zhw
groupdel:不能移除用户“zhw”的主组

为什么不能删除zhw这个用户组呢?这是因为在你尝试删除名为“zhw”的用户组时,该组被分配为用户“zgw”的主组。在删除组之前,你需要将该组从该用户的主组中删除,或者将该用户分配到另一个主组中。

gpasswd:用户组管理员功能

如果系统管理员太忙碌了,导致某些账号想要加入某个选项时找不到人帮忙,这个时候可以建立【用户组管理员】,什么是用户组管理员呢?就是让用户具有一个管理员的权限管理某些账号。那如何【建立一个用户组管理员呢】?就得要通过gpasswd。

gpasswd [选项] groupname

选项:
   若没有设置参数,就表示设置groupname密码(/etc/gshadow)
-a:添加用户到组中;
-d:从组中删除用户;
-M:将一个成员列表分配给组;
-r:删除组密码;
-R:设置组的密码检查间隔;
-A:指定允许管理组的用户列表。

建立一个新用户组,名称为testgroup且用户组交由zhw管理

[root@localhost ~]# groupadd testgroup        # 创建用户组testgroup
[root@localhost ~]# gpasswd testgroup         # 设置testgroup的密码
正在修改 testgroup 组的密码
新密码:
请重新输入新密码:           
[root@localhost ~]# gpasswd -A zhw testgroup   # 加入用户组管理员为zhw
[root@localhost ~]# grep testgroup /etc/group /etc/gshadow   
/etc/group:testgroup:x:1503:
/etc/gshadow:testgroup:$6$WgdumCsI582$vkOO8AH5BxyN8nNsZOpsH96ghbyBjzNGpiJBmzxlIbWBXsyiu5FXF.JSqXTUd/B7D7ohhFFIgWzga6krJ6NOR.:zhw:    #此时zhw则拥有testgroup的控制权

以zhw登录系统,并且让它加入csq,csr2成为testgroup的成员

[zhw@localhost ~]$ gpasswd  -a csq testgroup
正在将用户“csq”加入到“testgroup”组中
[zhw@localhost ~]$ gpasswd -a zhw3 testgroup
正在将用户“zhw3”加入到“testgroup”组中
[zhw@localhost ~]$ grep testgroup /etc/group 
testgroup:x:1503:csq,zhw3

上述实验是让testgroup成为一个可以公开的用户组,然后建立起用户组管理员,用户组管理员可以有多个。上述案例我将zhw设置为testgroup的用户组管理员,所以zhw可以自行增加用户组成员。然后该用户组成员就能够使用newgrp

账号管理案例

任务一

账号管理不是随意创建几个账号就好了,有时候我们需要考虑到一台主机上面可能有多个账号在协同工作。比如说,在某学校的实习生要分组,这些同一组的同学间必须要能够互相修改对方的数据文件,但是同时这些同学又需要保留自己的私密数据,因此直接公开家目录是不适宜的。那该如何是好呢?

任务一:单纯完成上面交代的任务,假设我们需要的账号数据如下,你该怎么做?

账号名称账号全名支持次要用户组是否可以登录主机密码
myuser1no.1 usermygroup1可以password
myuser2no.2 usermygroup2可以password
myuser3no.3 user无额外支持不可以password

处理方法如下

# 先处理账号相关的属性数据
[root@localhost ~]# groupadd mygroup1
[root@localhost ~]# useradd -G mygroup1 -c "no.1 user" myuser1
[root@localhost ~]# useradd -G mygroup1 -c "no.2 user" myuser2
[root@localhost ~]# useradd -c "no.3 user" -s /sbin/nologin myuser3
# 在处理账号的密码相关属性的数据
[root@localhost ~]# echo "password" |passwd --stdin myuser1
更改用户 myuser1 的密码 。
passwd:所有的身份验证令牌已经成功更新。
[root@localhost ~]# echo "password" |passwd --stdin myuser2
更改用户 myuser2 的密码 。
passwd:所有的身份验证令牌已经成功更新。
[root@localhost ~]# echo "password" |passwd --stdin myuser3
更改用户 myuser3 的密码 。
passwd:所有的身份验证令牌已经成功更新。

任务二

我的用户pro1、pro2、pro3是同一个项目计划的开发人员,我想要让这三个用户在同一个目录下面工作,但这三个用户还是拥有自己的家目录与基本的私有用户组。假设我要让这个项目计划在/srv/projecta目录下面开发,可以如何进行?

# 假设三个账号都为建立,可先建立名为projecta的用户组,再让三个用户加入到次要用户组中
[root@localhost ~]# groupadd projecta
[root@localhost ~]# useradd -G projecta -c "projecta user" pro1
[root@localhost ~]# useradd -G projecta -c "projecta user" pro2
[root@localhost ~]# useradd -G projecta -c "projecta user" pro3
[root@localhost ~]# echo "password" | passwd --stdin pro1
更改用户 pro1 的密码 。
passwd:所有的身份验证令牌已经成功更新。
[root@localhost ~]# echo "password" | passwd --stdin pro2
更改用户 pro2 的密码 。
passwd:所有的身份验证令牌已经成功更新。
[root@localhost ~]# echo "password" | passwd --stdin pro3
更改用户 pro3 的密码 。
passwd:所有的身份验证令牌已经成功更新。
# 开始建立此项目的开发目录
[root@localhost ~]# mkdir /srv/projecta
[root@localhost ~]# chgrp projecta /srv/projecta/
[root@localhost ~]# chmod 2770 /srv/projecta/
[root@localhost ~]# ll -d /srv/projecta/
drwxrws---. 2 root projecta 6 411 09:02 /srv/projecta/

Linux详细权限规划:ACL使用

Linux的权限概念是非常重要的。但是传统的权限仅有三种(owner、group、others)身份搭配三种权限(r、w、x)而已,并没有办法单纯针对某一个用户或某一个用户组来设置特定的权限需求。

什么是ACL与如何支持启动ACL

ACL是Access Control List 的英文缩写,中文译为访问控制列表,主要目的是提供传统的属主,所属群组、其他人的读、写、执行权限之外的详细权限设置。ACL可以针对单一用户、单一文件或目录进行(r、w、x)的权限设置,对于需要特殊权限的使用状况非常有帮助。

那ACL主要可以针对哪些方面来控制权限?它主要可以针对几个选项:

  • 用户:可以针对用户来设置权限
  • 用户组:针对用户组为对象来设置权限
  • 默认属性:还可以针对在该目录下建立新文件/目录时,规范新数据的默认权限

也就是说,如果你有一个目录,需要给一堆人使用,每个人或每个用户组所需要的权限并不相同时,在过去,传统的Linux三种身份的三种权限是无法达到的,因为基本上传统的Linux权限只能针对一个用户、一个用户组及非此用户组的其他人设置权限而已,无法针对单一用户来设计权限,而ACL就是为了要解决这个问题。

如何启动ACL

你不确定系统是否针对支持ACL的话,那么就来检查以下内核挂载时显示的信息吧

[root@chenshiren ~]# dmesg |grep -i acl
[    1.355501] systemd[1]: systemd 252-13.el9_2 running in system mode (+PAM +AUDIT +SELINUX -APPARMOR +IMA +SMACK +SECCOMP +GCRYPT +GNUTLS +OPENSSL +ACL +BLKID +CURL +ELFUTILS -FIDO2 +IDN2 -IDN -IPTC +KMOD +LIBCRYPTSETUP +LIBFDISK +PCRE2 -PWQUALITY +P11KIT -QRENCODE +TPM2 +BZIP2 +LZ4 +XZ +ZLIB +ZSTD -BPF_FRAMEWORK +XKBCOMMON +UTMP +SYSVINIT default-hierarchy=unified)
[    2.660297] SGI XFS with ACLs, security attributes, scrub, quota, no debug enabled
[    2.993959] systemd[1]: systemd 252-13.el9_2 running in system mode (+PAM +AUDIT +SELINUX -APPARMOR +IMA +SMACK +SECCOMP +GCRYPT +GNUTLS +OPENSSL +ACL +BLKID +CURL +ELFUTILS -FIDO2 +IDN2 -IDN -IPTC +KMOD +LIBCRYPTSETUP +LIBFDISK +PCRE2 -PWQUALITY +P11KIT -QRENCODE +TPM2 +BZIP2 +LZ4 +XZ +ZLIB +ZSTD -BPF_FRAMEWORK +XKBCOMMON +UTMP +SYSVINIT default-hierarchy=unified)

ACL的设置技巧:getfacl、setfacl

既然知道了文件系统支持ACL后,接下来应该如何设置与查看ACL呢?很简单利用以下两个命令就好了

  • getfacl:获取某个文件/目录的ACL设置选项
  • setfacl:设置某个文件/目录的ACL规范

setfacl

setfacl是一个用于设置文件或目录访问控制列表(ACL)的工具。通过setfacl命令,可以为特定用户或组添加或删除权限,或者清除ACL条目

setfacl命令语法:

setfacl [-bkRd] [{-m|-x} acl参数] 目标文件名
选项解释
-m添加ACL条目
-x删除ACL条目
-b删除所有ACL条目
-k删除默认ACL条目
-d设置【默认ACL参数】的意思,只对目录有效,在该目录新建的数据会引用此默认值
-R递归设置ACL,即包括子目录都会被设置

设置ACL特殊权限,针对单一用户的设置方式:

针对特定使用者的方式:设置规范:【u : [使用者的账号] : [rwx] 】

# 1.针对特定使用者的方式:设置规范:【u : [使用者的账号] : [rwx] 】

[root@chenshiren ~]# touch acl_test1
[root@chenshiren ~]# ll acl_test1 
-rw-r--r--. 1 root root 0  319 16:53 acl_test1
[root@chenshiren ~]# setfacl -m u:csq:rx acl_test1 
[root@chenshiren ~]# ll acl_test1 
-rw-r-xr--+ 1 root root 0  319 16:53 acl_test1  # 权限部分多了个+
[root@chenshiren ~]# setfacl -m u::rwx acl_test1 
[root@chenshiren ~]# ll acl_test1 
-rwxr-xr--+ 1 root root 0  319 16:53 acl_test1
# u后面无使用者列表,代表设置该文件拥有者,所以上面显示root的权限成为了rwx

getfacl

getfacl是一个用于获取文件或目录访问控制列表(ACL)的工具。通过getfacl命令,可以查看文件或目录的ACL信息。下面是getfacl命令的语法及使用案例详解:

getfacl命令语法

getfacl [选项] 目标文件名
选项解释
-R递归获取ACL信息
-r递归获取ACL信息,并以相对路径形式输出

获取文件的ACL信息:

[root@chenshiren ~]#  getfacl  /acl_test1 
getfacl: Removing leading '/' from absolute path names
# file: acl_test1    <== 说明文件名
# owner: root        <== 说明此文件的拥有者
# group: root        <== 此文件的所属用户组
user::rwx            <== 没写使用者,代表文件的拥有者权限
user:csq:r-x         <== 针对csq用户权限的设置 为 rx
group::r--           <== 针对文件用户组的设置 为 r
mask::r-x            <== 此文件的默认有效权限: rx
other::r--           <== 其他人拥有的权限              

特定的单一用户组的权限设置:【g:用户组名:权限】

# 2.特定的单一用户组的权限设置:【g:用户组名:权限】
[root@chenshiren ~]# setfacl -m g:mygroup1:rx /acl_test1 
[root@chenshiren ~]# getfacl /acl_test1 
getfacl: Removing leading '/' from absolute path names
# file: acl_test1
# owner: root
# group: root
user::rwx
user:csq:r-x
group::r--
group:mygroup1:r-x  # 这里就是新增的部分,多了这个用户组的权限设置
mask::r-x
other::r--

针对有效权限mask的设置方式:设置规范【m:[rwx]】

mask的意义是:用户或用户组所设置的权限必须要存在于mask的权限设置范围内才会生效,此即【有效权限】

# 3.针对有效权限mask的设置方式:设置规范【m:[rwx]】

[root@chenshiren ~]# setfacl -m m:r /acl_test1 
[root@chenshiren ~]# getfacl /acl_test1 
getfacl: Removing leading '/' from absolute path names
# file: acl_test1
# owner: root
# group: root
user::rwx
user:csq:r-x                    #effective:r--   # 仅r而已,x不会生效
group::r--
group:mygroup1:r-x              #effective:r--
mask::r--
other::r--
[root@chenshiren ~]# ll /acl_test1 
-rwxr--r--+ 1 root root 0  319 16:53 /acl_test1
# 可以通过mask来规范最大允许的权限

案例

上述案例当中 acl_test 给予了csq【rx】的权限,再创建一个用户zhw,限制zhw用户对acl_test的读写执行权限

[root@chenshiren ~]# useradd zhw
[root@chenshiren ~]# setfacl -m u:zhw:--- /acl_test1 
[root@chenshiren ~]# getfacl /acl_test1 
getfacl: Removing leading '/' from absolute path names
# file: acl_test1
# owner: root
# group: root
user::rwx
user:zhw:---
user:csq:r-x
group::r--
group:mygroup1:r-x
mask::r-x
other::r--
[root@chenshiren ~]# echo "000000" | passwd --stdin zhw      
更改用户 zhw 的密码 。
passwd:所有的身份验证令牌已经成功更新
[zhw@chenshiren ~]$ cat /acl_test1 
cat: /acl_test1: 权限不够
[zhw@chenshiren ~]$ echo "aadad" > /acl_test1 
-bash: /acl_test1: 权限不够
[zhw@chenshiren ~]$ sh /acl_test1
sh: /acl_test1: 权限不够

创建一个目录,给csq用户ACL[rwx]权限

[root@chenshiren ~]# mkdir /tmp/acl_dir
[root@chenshiren ~]# setfacl -m u:csq:rwx /tmp/acl_dir/
[root@chenshiren ~]# getfacl /tmp/acl_dir/
getfacl: Removing leading '/' from absolute path names
# file: tmp/acl_dir/
# owner: root
# group: root
user::rwx
user:csq:r-x
group::r-x
mask::r-x
other::r-x

在目录下创建几个文件看看ACL的权限设置能否被父继承

[root@chenshiren ~]# touch /tmp/acl_dir/{csq.txt,zhw.txt,ccc.txt}
[root@chenshiren ~]# ls -l /tmp/acl_dir/
-rw-r--r--. 1 root root 0  319 17:48 ccc.txt
-rw-r--r--. 1 root root 0  319 17:48 csq.txt
-rw-r--r--. 1 root root 0  319 17:48 zhw.txt
# 可以看到没有+号 是没有被继承的

修改目录ACL权限,使目录未来文件的ACL权限继承

[root@chenshiren ~]# setfacl -m d:u:csq:rwx /tmp/acl_dir/
[root@chenshiren ~]# getfacl /tmp/acl_dir/
getfacl: Removing leading '/' from absolute path names
# file: tmp/acl_dir/
# owner: root
# group: root
user::rwx
user:csq:rwx
group::r-x
mask::rwx
other::r-x
default:user::rwx
default:user:csq:rwx
default:group::r-x
default:mask::rwx
default:other::r-x
[root@chenshiren ~]# touch /tmp/acl_dir/{newcsq.txt,newzhw.txt}
[root@chenshiren ~]# ll /tmp/acl_dir/{newcsq.txt,newzhw.txt}
-rw-r--r--+ 1 root root 0  319 17:45 /tmp/acl_dir/newcsq.txt
-rw-r--r--+ 1 root root 0  319 17:45 /tmp/acl_dir/newzhw.txt
# 有+号继承了
[csq@chenshiren acl_dir]$ echo "abcd" > newcsq.txt 
[csq@chenshiren acl_dir]$ cat newcsq.txt 
abcd

不让其他人使用这个目录

[root@chenshiren ~]# setfacl -m o::---  /tmp/acl_dir/
[root@chenshiren ~]# setfacl -m d:o::---  /tmp/acl_dir/
[root@chenshiren ~]# getfacl /tmp/acl_dir/             
getfacl: Removing leading '/' from absolute path names
# file: tmp/acl_dir/
# owner: root
# group: root
user::rwx
user:csq:rwx
group::r-x
mask::rwx
other::---
default:user::rwx
default:user:csq:rwx
default:group::r-x
default:mask::rwx
default:other::---

[zhw@chenshiren ~]$ cd /tmp/acl_dir/
-bash: cd: /tmp/acl_dir/: 权限不够

Linux 用户身份切换

那么如何让一般用户变身份成为root呢?主要有两种方式

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

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

su

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

su [选项] [用户名]
选项解释
-表示切换到目标用户的环境变量,即切换到目标用户的家目录
-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 -
密码:
上一次登录:二 411 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 -
密码:
上一次登录:二 411 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 二 411 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 411 15:47 /tmp/mysshd
# 留意以下,这个文件的权限是由sshd所建立的

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

sudo命令的执行流程如下:

  1. 用户输入sudo命令,并指定要执行的命令。
  2. 系统检查用户是否在sudoers文件中有相应的权限,如果没有,则提示用户无权执行该命令。
  3. 如果用户有权限执行该命令,则要求用户输入自己的密码,而不是目标用户的密码。
  4. 系统检查密码是否正确,如果正确,则将用户切换为目标用户身份,并执行命令。
  5. 执行完命令后,返回原用户身份。

所以说,sudo的执行的重点是【能否使用sudo,必须要看/etc/sudoers的设置值】由于能否使用与/etc/sudoers有关,所以我们当然要去编辑sudoers文件,不过该文件的内容有一定的规范,所以直接使用vi去编辑是不好的,此时,我们要通过visudo去修改这个文件

visudo与/etc/sudoers

除了root之外的其外账号,若想要使用sudo执行属于root的权限命令,则root需要先使用visudo去修改/etc/sudoers,让账号能够使用全部或部分的root命令功能

visudo的设置方法

一、单一用户可使用root所有命令,与sudoers文件语法

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

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

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

  1. 第一个组件:表示授权的用户或用户组,这里是root用户。
  2. 第二个组件:表示用户或用户组执行命令的主机,这里是ALL,表示可以在任何主机上执行命令。
  3. 第三个组件:表示用户或用户组可以切换到的目标用户,这里是ALL,表示可以切换到任何用户的身份。
  4. 第四个组件:表示用户或用户组可以执行的命令,这里是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

创建用户a1,a2,a3,能否通过用户组的功能让这三个人可以管理系?可以很简单,如下案例

[root@chenshiren ~]# useradd a1
[root@chenshiren ~]# useradd a2
[root@chenshiren ~]# useradd a3
[root@chenshiren ~]# echo "000000" |passwd --stdin a1
更改用户 a1 的密码 。
passwd:所有的身份验证令牌已经成功更新。
[root@chenshiren ~]# echo "000000" |passwd --stdin a2
更改用户 a2 的密码 。
passwd:所有的身份验证令牌已经成功更新。
[root@chenshiren ~]# echo "000000" |passwd --stdin a3
更改用户 a3 的密码 。
passwd:所有的身份验证令牌已经成功更新。
[root@root zhw]# visudo
...(前面省略)...
%wheel  ALL=(ALL)       ALL   # 把这行的#拿掉
# 在最左边加上%,代表后面接的是一个【用户组】,改完保存退出
...(后面省略)...
[root@chenshiren ~]# usermod -aG wheel a1  # 将a1加入wheel的支持

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

[a1@chenshiren ~]$ sudo head -n 3 /etc/passwd   # 这里身份是a1

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

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

[sudo] a1 的密码:    # 输入用户a1的密码
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin

[a2@chenshiren ~]$ sudo head -n 3 /etc/passwd   # 这里身份是a2

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

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

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

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

不过,既然我们都信任这些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用户身份执行。

五、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 的密码:
上一次登录:三 412 17:36:49 CST 2023pts/2 上
[root@localhost ~]# 

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

Linux 用户的特殊shell与PAM模块

你想过吗?如果我今天想要建立一个【仅能使用邮件服务的相关账号,而该账号并不能登录Linux主机】,如果不能给予该账号一个密码,那么该账号就无法使用系统的各项资源,当然也包括mail资源。如果给予一个密码,那么该账号就可能能登录Linux主机。

在之前用户管理的时候我们谈到了etc/login.defs文件中,默认密码是5个字符长度,该值是已经被PAM模块所替换,那么什么是PAM?为什么可以影响用户登录呢?

特殊的shell:/sbin/nologin

之前在用户管理里面passwd文件结构里面我们就谈过系统账号,他的shell就是使用/sbin/nologin,重点在于系统账号是不需要登录的。所以我们就给他这个无法登录的合法shell,使用了这个shell的用户即使有了密码也无法登录,因为会出现如下的信息:

连接成功
Last login: Wed Apr 12 17:36:01 2023 from 192.168.100.1
This account is currently not available.

我们所谓的【无法登录】指的是:【这个用户无法使用bash或其他shell来登录系统】而已,并不是说这个账号就无法使用其他的系统资源。举例来说,各个系统账号,打印作业由IP这个账号在管理,WWW服务由apache这个账号在管理,他们都可以进行系统程序的工作,但是【就是无法登录主机获取交互的shell】而已。

就像我们上面谈到的邮件服务问题,我们就可以用/sbin/nologin作为他们的shell。

另外,如果我想要让某个具有/sbin/nologin的用户知道,它们不能登录主机时,其实我们可以建立【/etc/nologin.txt】这个文件,并且在这个文件内说明不能登录的原因,那么下次当这个用户想要登录的时候,屏幕上就会出现的是/etc/nologin.txt文件里面的内容,而不是默认内容

那么我们尝试创建一个不可以登录的账号,然后创建一个nologin.txt的文件写入不可登录的原因,然后登录测试

[root@chenshiren ~]# useradd -s /sbin/nologin myuser4 
[root@chenshiren ~]# vim /etc/nologin.txt # 修改如下信息
此帐户系统帐户或邮件帐户
请不要使用此帐户登录我的Linux服务器
[root@chenshiren ~]# su - myuser4   # 登录
此帐户系统帐户或邮件帐户
请不要使用此帐户登录我的Linux服务器
# 结果发现与原本的默认信息不一样

PAM模块简介

下图来自百度百科PAM

image-20240320021541004

PAM(Pluggable Authentication Modules)可以说是一套应用程序编程接口,它提供了一连串的验证机制,只要用户将验证阶段的需求告知PAM后,PAM就能够返回用户验证的结果(成功或失败)。

由于PAM仅是一套验证的机制,又可以提供给其他程序所调用引用,因此不论你使用什么程序,都可以使用PAM来进行验证,如此一来,就能够让账号密码或是其他方式的验证具有一致的结果

image-20240320022935940

PAM以一个独立的API存在,任何程序有需求时,可以向PAM发出验证需求的通知,PAM经过一连串的验证后,将验证的结果返回给该程序,然后改程序就能够利用验证的结果允许登录或显示其他无法使用的信息。

PAM模块设置语法

PAM工作过程如下:

  1. 当用户尝试登录或进行身份验证时,应用程序调用PAM库(/usr/lib64/security/)
  2. PAM库通过读取配置文件/etc/pam.d/中与应用程序相关的配置信息,确定需要调用哪些PAM模块。
  3. 根据配置信息,PAM框架依次调用每个配置的模块进行身份验证、授权、账户管理和会话管理等操作。
  4. 每个模块根据其功能完成相应的任务,例如验证密码、检查账户状态、设置环境变量等。
  5. 如果所有模块成功通过,用户将被授权访问系统资源。如果有任何一个模块失败,用户将被拒绝访问并收到相应的错误消息。

查看登录所需要的PAM流程是什么

[root@chenshiren ~]# cat /etc/pam.d/login 
#%PAM-1.0
auth       substack     system-auth
auth       include      postlogin
account    required     pam_nologin.so
account    include      system-auth
password   include      system-auth
# pam_selinux.so close should be the first session rule
session    required     pam_selinux.so close
session    required     pam_loginuid.so
# pam_selinux.so open should only be followed by sessions to be executed in the user context
session    required     pam_selinux.so open
session    required     pam_namespace.so
session    optional     pam_keyinit.so force revoke
session    include      system-auth
session    include      postlogin
-session   optional     pam_ck_connector.so
# 验证类别  控制标准      PAM模块与该模块的参数

第一个字段,验证类型

  • 认证模块(auth):用于验证用户身份,确认用户是否合法。常见的认证模块包括pam_unix.so(使用系统本地账户进行验证)
  • 授权模块(account):用于检查用户是否允许访问系统资源。授权模块可以处理账户是否过期、是否在访问时间范围内等情况。
  • 账户管理模块(password):用于管理用户账户相关事务,如密码更改、密码策略检查等。常见的账户管理模块包括pam_pwquality.so(密码质量检查)等
  • 会话管理模块(session):用于管理用户登录与注销时的信息,例如设置环境变量、记录日志等。

第二个字段,验证的控制标识

  • required:此验证若成功则带有success(成功)的标志,若失败则带有failure的标志,但不论成功或失败都会继续后续的验证流程。由于后续验证流程可以继续进行,因此相当有利于数据的记录(log),这也是PAM最常使用required的原因
  • requisite:若验证失败则立刻返回原程序 failure 的标志,并终止后续的验证流程。若验证成功则带有success 的标志并继续后续的验证流程。这个选项与required 最大的差异,就在于失败的时候还要不要继续验证下去?由于 requisite 是失败就终止,因此失败时所产生的 PAM 信息就无法通过后续的模块来记录。
  • sufficient:若验证成功则立刻返回 success 给原程序,并终止后续的验证流程。若验证失败则带有 faiure 标志并继续后续的验证流程。这个标识与requisits 刚好相反
  • optional:这个模块控件大多是在显示信息而已,并不用在验证方面

第二个字段,pam所支持的动作列表

标记说明
ignore忽略这个状态,不会对验证结果产生影响
bad表示这个返回状态代表验证失败、余下的模块调用也永远失败
die与bad相同,但是应该立即返回到应用,不在继续调用余下模块
ok标识这个返回状态应该被看作是验证成功,继续调用余下模块
done与ok相同,但是应该立即返回到应用,不在继续调用余下模块
N与ok相同,但是要跳过N个模块才能继续
reset清楚所有的返回状态、继续调用余下模块

第二个字段,pam常见的返回状态

状态说明
success认证成功
auth_err认证失败
new_authtok_reqd需要新的认证令牌。有三种情况会返回这个状态:1. 根据安全策略需要更密码,2. 是密码为空;3. 是密码已经过期
ignore忽略底层account类型模块的返回状态,而且无论是否被required、sufficient和optional修饰。处于安全考虑,这个返回状态通常需要被忽略掉,这样其他模块的返回状态会被参考
user_unknown未知用户
try_again已经通过了密码服务的初步检测
default所有没有注明的返回状态

上述表格来自此篇博客

image-20240320034900938

程序运行中遇到验证时才会去调用PAM,而PAM验证又分很多类型与标识,不同的验证标识所返回的信息并不相同。

常用模块简介

[root@chenshiren ~]# cat /etc/pam.d/login 
#%PAM-1.0
auth       substack     system-auth
auth       include      postlogin
account    required     pam_nologin.so
account    include      system-auth
password   include      system-auth
# pam_selinux.so close should be the first session rule
session    required     pam_selinux.so close
session    required     pam_loginuid.so
# pam_selinux.so open should only be followed by sessions to be executed in the user context
session    required     pam_selinux.so open
session    required     pam_namespace.so
session    optional     pam_keyinit.so force revoke
session    include      system-auth
session    include      postlogin
-session   optional     pam_ck_connector.so
# 验证类别  控制标准      PAM模块与该模块的参数

# auth substack system-auth:调用system-auth文件中定义的认证规则
# include: 表示引用其他的配置文件或模块来执行认证。

[root@chenshiren ~]# cat /etc/pam.d/system-auth
# Generated by authselect on Sat Feb 24 08:00:30 2024
# Do not modify this file manually.

auth        required                                     pam_env.so
auth        required                                     pam_faildelay.so delay=2000000
auth        sufficient                                   pam_fprintd.so
auth        [default=1 ignore=ignore success=ok]         pam_usertype.so isregular
auth        [default=1 ignore=ignore success=ok]         pam_localuser.so
auth        sufficient                                   pam_unix.so nullok
auth        [default=1 ignore=ignore success=ok]         pam_usertype.so isregular
auth        sufficient                                   pam_sss.so forward_pass
auth        required                                     pam_deny.so

account     required                                     pam_unix.so
account     sufficient                                   pam_localuser.so
account     sufficient                                   pam_usertype.so issystem
account     [default=bad success=ok user_unknown=ignore] pam_sss.so
account     required                                     pam_permit.so

password    requisite                                    pam_pwquality.so local_users_only
password    sufficient                                   pam_unix.so sha512 shadow nullok use_authtok
password    sufficient                                   pam_sss.so use_authtok
password    required                                     pam_deny.so

session     optional                                     pam_keyinit.so revoke
session     required                                     pam_limits.so
-session    optional                                     pam_systemd.so
session     [success=1 default=ignore]                   pam_succeed_if.so service in crond quiet use_uid
session     required                                     pam_unix.so
session     optional                                     pam_sss.so
[root@chenshiren ~]# cat /etc/pam.d/postlogin 
# Generated by authselect on Sat Feb 24 08:00:30 2024
# Do not modify this file manually.

session     optional                   pam_umask.so silent
session     [success=1 default=ignore] pam_succeed_if.so service !~ gdm* service !~ su* quiet
session     [default=1]                pam_lastlog.so nowtmp silent
session     optional                   pam_lastlog.so silent noupdate showfailed

常用模块

  • pam_securetty.so

限制系统管理员(root),只能够从安全的(secure)终端登录。那什么是终端?例如tty1,tty2,tty3等传统的终端设备名称。安全的终端设置就在/etc/securetty这个文件中。/etc/securetty是一个文本文件,用于指定哪些终端设备可以用于root用户登录。当root用户登录时,系统会检查当前登录的终端设备是否在/etc/securetty中指定的列表中,如果不在列表中,则无法登录。、

RHEL8以后默认禁用securetty,默认情况下,securetty PAM 模块已被禁用,RHEL 中不再包含 /etc/securetty 配置文件。由于 /etc/securetty 列出了许多可能的设备,因此在大多数情形下实际效果是默认允许的,因此这种更改仅有轻微的影响。然而,如果使用更严格的配置,需要添加一行,在 /etc/pam.d 目录的适当文件里启用 pam_securetty.so 模块,并创建一个新的 /etc/securetty 文件。

  • pam_nologin.so

这个模块可以限制一般用户是否能够登录主机。当/etc/nologin这个文件存在时,则所有一般用户均无法再登录系统了,若/etc/nologin存在,则一般用户在登录时,在他们的终端上会将该文件的内容显示出来,所以,正常情况下,这个文件应该是不能存在于系统中的,但这个模块对root以及已经登录系统中的一般账号没有影响(注意:这与/etc/nologin.txt并不相同)

  • pam_seLinux.so

SELinux是一个针对程序来进行详细管理权限的功能,由于SELinux会影响到用户执行程序的权限,因此我们利用PAM模块,将SELinux暂时关闭,等到验证通过后,在给予启动。

  • pam_console.so

当系统出现某些问题,或是某些时刻你需要使用特殊的终端接口(例如 RS232之类的终端设备)登录主机时,这个模块可以帮助处理一些文件权限的问题,让用户可以通过特殊终端接口(console)顺利地登录系统。

  • pam_loginuid.so

我们知道系统账号与一般账号的UID是不同的,一般账号的UID均大于1000才合理,因此为了验证用户的UID真的是我们所需要的数值,可以使用这个模块来进行规范

  • pam_env.so

用来设置环境变量的一个模块,如果你需要额外设置环境变量,可以参考/etc/security/pam_env.conf 这个文件的详细说明

  • pam_unix.so

这个是个很复杂且重要的模块,这个模块可以用在验证阶段的认证功能、授权阶段的账号许可证管理、会话阶段的日志文件记录等,甚至还可以用在密码更新阶段的检验。

  • pam_pwquality.so

可以用来检验密码的强度,包括密码是否在字段中、密码输入几次都失败就断掉此次连接等功能,都是这个模块提供的。

  • pam_limits.so

pam.limits.so用于设置用户的资源限制,例如CPU使用时间、内存限制、文件打开数等。可以通过修改/etc/security/limits.conf文件来设置用户的资源限制,而pam.limits.so模块可以根据这些限制配置进行验证和应用

Linux-PAM 中文文档

login的PAM验证机制流程

  • 验证阶段(auth)

    (1)pam_env.so设置用户环境变量

    (2)pam_faildelay.so delay=2000000:在认证失败延迟一段时间再尝试,延迟两秒以防暴力破解

    (3)pam_fprintd.so:身份认证

    (4)pam_usertype.so isregular:基于用户类型进行认证,普通用户(isregular)

    (5)pam_localuser.so: 在不在 /etc/passwd 中

    (6)pam_unix.so nullok:如果用户名存在且密码正确,则认证通过;nullok表示允许空密码登录。

    (7)pam_usertype.so isregular:再次基于用户类型进行认证

    (8)pam_sss.so forward_pass:如果SSSD(System Security Services Daemon)认证成功,则认证通过

    (9)pam_deny.so:如果前面的认证规则都失败,则拒绝认证

    (10)pam_umask.so silent:以静默模式(silent)运行。该模块用于设置用户会话期间的文件创建默认权限(umask)

    (11)pam_succeed_if.so service !~ gdm* service !~ su* quiet:检查当前服务名称是否不以 gdmsu 开头

    (12)pam_lastlog.so nowtmp silent:在当前的会话期间更新用户的最后登录信息,nowtmp 不更新 wtmp 条目,silent:不通知用户任何先前的登录信息,只需更新/var/log/lastlog文件即可

    (13)pam_lastlog.so silent noupdate showfailed:用于在会话期间记录用户的登陆信息,noupdate:不要更新任何文件,showfailed:显示失败的登录尝试次数和上次 btmp 尝试失败的日期。

  • 授权阶段(account)

    (1)pam_nologin.so:判断nologin是否存在,若存在则不允许一般用户登录

    (2)pam_unix.sopam_localuser.so进行账号管理

    (3)pam_usertype.so issystem:基于用户类型进行认证,普通用户(isregular)

    (4)pam_sss.so:基于SSSD(System Security Services Daemon)的身份认证服务

    (5)pam_permit.so允许该账号登录

  • 密码阶段(passwd):

    (1)pam_pwquality.so 模块用于对密码进行质量检查,强制要求本地用户(local_users_only)设置符合指定规则的密码。如果密码不符合要求,则拒绝该密码

    (2)pam_unix.so 通过sha521、shadow等功能进行密码检验,若通过则返回login程序,若不通过则终止检验

    (3)pam_sss.so :模块与 SSSD 集成,用于处理密码认证,use_authtok 表示将验证成功的密码传递给后续模块进行处理。如果 SSSD 认证成功,则通过该模块。

    (4)pam_deny.so:拒绝登录

  • 会话阶段(session):

    (1)pam_selinux.so close :暂时关闭SELinux

    (2)pam_limits.so设置好用户能够操作的系统资源

    (3)登录成功后开始记录相关信息再日志文件中

    (4)以pam_loginuid.so 规范不同的UID权限

    (5)开启pam_selinux.so的功能。

其他相关文件

limits.conf

/etc/security/limit.conf是Linux系统中与进程资源限制有关的配置文件。它可以用来限制单个用户或整个系统中的进程使用某些资源

zhw这个用户只能建立100MB的文件,且大于90MB会警告⚠

[root@localhost ~]# vim /etc/security/limits.conf 
....
..
zhw     soft       fsize    90000
zhw     hard       fsize    100000
#账号   #限制根据   #限制选项  #限制值
 
# 第一列位账号,或是用户组,若为用户组则前面加上@,例如@projecta
# 第二列位限制的数据,是严格(hard),还是仅为警告(soft)
# 第三列位相关限制,此例中限制文件容量
# 第四列位限制的值,在此例中单位位KB
# 若zhw用户登录后,进行如下的操作则会有相关的限制

[zhw@localhost ~]$ ulimit -a   # 注意这里是zhw用户
....
..
file size               (blocks, -f) 90000
...
....
[zhw@localhost ~]$ dd if=/dev/zero of=test bs=1M count=110
文件大小超出限制
[zhw@localhost ~]$ ll --block-size=K test 
-rw-rw-r--. 1 zhw zhw 90000K 414 20:22 test

限制pro1这个用户组,每次仅能有一个使用者登录系统(maxlogins)

[root@localhost ~]# vi /etc/security/limits.conf
....
@pro1 hard maxlogins

# 如果要使用用户组功能的话,这个功能似乎对初始用户组才有效。而如果你尝试多个pro1的登录时,
# 第二个以后就无法登录了,而且在/var/log/secure 文件中还会出现如下信息
Apr 14 20:28:59 localhost sshd[20712]: Accepted password for pro1 from 192.168.100.1 port 51958 ssh2
Apr 14 20:28:59 localhost sshd[20712]: pam_limits(sshd:session): Too many logins (max 1) for pro1
Apr 14 20:28:59 localhost sshd[20712]: pam_unix(sshd:session): session opened for user pro1 by (uid=0)
Apr 14 20:28:59 localhost sshd[20712]: error: PAM: pam_open_session(): Permission denied

这个文件设置完成立马生效,你不用重启任何服务。但是PAM有个特殊的地方,由于它是在程序调用的时才给予设置的,因此你修改完成的数据,对于已经登录系统中的用户来说是没有效果的,要等他再次登录时才会生效。

/var/log/secure、/var/log/messages

/var/log/secure文件记录与系统认证和授权相关的信息,包括用户登录和注销、系统重启以及其他与安全相关的事件。这个文件通常被系统管理员用来监视系统活动并跟踪安全相关问题。

/var/log/messages文件是一个通用的系统日志文件,记录有关系统事件和进程的信息。它包括有关硬件和软件错误、系统警告和其他系统消息的信息。这个文件对于需要在系统上解决问题的系统管理员和开发人员来说是一个有用的信息源

如果你无法登录或是参数一些你无法预期的错误时,由于PAM模块都会将数据记录在/var/logsecure当中,所以发生问题请务必到该文件内去查询一个问题点。举例来说,我们上述例二,就谈到了多重登录的错误可以到/var/log/secure中查看

Linux主机上的用户信息传递

如过你在LInux上面操作时,刚好有其他用户也登录主机,你想要跟他交谈,该如何是好呢?你想要知道某个账号的相关信息,该如何查看呢?

查询用户:w、who、last、lastlog

现在如何知道目前已经登录在系统上面的用户有几个呢?可以通过w或who来查询

[root@localhost ~]# w
 20:56:23 up 43 min,  4 users,  load average: 0.12, 0.10, 0.06
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    192.168.100.1    20:12    7.00s  0.05s  0.00s w
root     pts/1    192.168.100.1    20:12   43:27   4.77s  4.76s top
pro1     pts/2    192.168.100.1    20:26   30:20   0.01s  0.01s -bash
pro1     pts/3    192.168.100.1    20:26   30:20   3.37s  3.37s top

# 第一列:用户名:显示当前登录用户的用户名,通常是登录系统时所使用的用户名。
# 第二列:终端号:显示登录用户所使用的终端设备号,通常是tty或pts。
# 第三列:远程IP地址:如果是远程登录,则显示远程IP地址;如果是本地登录,则显示“:0”。
# 第四列:登录时间:显示登录时间,包括日期和具体时间。
# 第五列:IDLE:表示CPU空闲时间,即CPU没有在执行任何任务的时间。
# 第六列:JCPU:表示任务在CPU上运行的总时间,包括用户态和内核态。
# 第七列:PCPU:表示任务在CPU上使用的时间百分比,包括用户态和内核态。
# 第八列:运行的命令:如果登录用户正在运行命令,则会显示该命令的名称和参数。

这个例子中

第一行:当前时间是20.:56:23,系统已经运行了43分钟,目前有4个用户(user)登录到系统中,系统负载情况位0.12,0.10,0.06

第二行:各个选项的说明

第三行:用户root,终端pts/0,远程IP地址为192.168.100.1 ,登录时间为20:12,CPU空闲时间为7秒,任务在CPU上运行的总时间为0.05秒,任务在CPU上使用的时间百分比0.00秒,当前未运行任何命令。(后面的-bash,代表当前在运行一个bash shell进程。)

第四行:同第三行意思相同,自行带入数据

[root@localhost ~]# who
root     pts/0        2023-04-14 20:12 (192.168.100.1)
root     pts/1        2023-04-14 20:12 (192.168.100.1)
pro1     pts/2        2023-04-14 21:05 (192.168.100.1)
pro1     pts/3        2023-04-14 21:05 (192.168.100.1)

# 第一列:登录用户名:显示当前登录到系统中的用户名。
# 第二列:终端设备:显示当前用户登录所使用的终端设备,如tty1、pts/0等。
# 第三列:登录时间:显示当前用户登录系统的时间,格式为月日(mm-dd)和时分(hh:mm)。
# 第四列:远程IP地址:如果当前用户是通过网络登录到系统中的,who命令会显示远程IP地址。

另外,如果你想要知道每个账号最近登录的时间,则可以使用lastlog这个命令,lastlog会去读取/var/log/lastlog文件,并将数据输出如下

[root@localhost ~]# lastlog
用户名           端口     来自             最后登陆时间
root             pts/1    192.168.100.1    五 414 20:12:56 +0800 2023
bin                                        **从未登录过**
daemon                                     **从未登录过**
adm                                        **从未登录过**
lp                                         **从未登录过**
sync                                       **从未登录过**
shutdown                                   **从未登录过**
halt                                       **从未登录过**
mail                                       **从未登录过**
operator                                   **从未登录过**
games                                      **从未登录过**
ftp                                        **从未登录过**
nobody                                     **从未登录过**
systemd-network                            **从未登录过**
dbus                                       **从未登录过**
polkitd                                    **从未登录过**
sshd                                       **从未登录过**
postfix                                    **从未登录过**
chrony                                     **从未登录过**
zhw              pts/0                     五 414 20:21:16 +0800 2023
csq                                        **从未登录过**
pro1             pts/3    192.168.100.1    五 414 21:05:26 +0800 2023
pro2             pts/1    192.168.100.1    三 412 17:37:18 +0800 2023
pro3                                       **从未登录过**
myuser1          pts/0                     三 412 14:28:54 +0800 2023
myuser2                                    **从未登录过**
myuser3                                    **从未登录过**
myuser4          pts/0                     三 412 20:40:49 +0800 2023

这样就能够知道每个账号最近登录时间

用户对谈:write、mesg、wall

那么我是否能够和系统上面的用户聊天呢?可以的,利用write这个命令,可以直接将信息传给接收者。

例如可以这样做,加入目前root和pro1俩人在线,我们使用root跟zhw讲话可以这样做:

write <使用者账号>  [使用者所在终端界面]
[root@localhost ~]# who
root     pts/0        2023-04-15 18:00 (192.168.100.1)
zhw      pts/2        2023-04-15 18:02 (192.168.100.1)
[root@localhost ~]# write zhw pts/2
zhw
nihao           <== 这两行是root写的信息
# 结束时,请按下ctrl + D 结束输入,此时在zhw用户的终端中就会显示
[zhw@localhost ~]$ 
Message from root@localhost.localdomain on pts/0 at 18:08 ...
zhw
nihao
EOF

立刻会有信息发给zhw,不过当时zhw正在编写文件或者查数据。你发消息就会立刻中断zhw原本的任务。所以,如果zhw这个用户不想要接受任何消息,直接执行这个操作

[zhw@localhost ~]$ mesg n
[zhw@localhost ~]$ mesg
is n

不过,这个mesg的功能对root传送来的信息没有阻止能力,所以如果是root传送信息,zhw还是得要收下。但是如果root的mesg是n的,那么zhw写给root的信息就会变成这样

[zhw@localhost ~]$ write root     # 这里是zhw用户
write: you have write permission turned off

如果想要启用的话,再次执行【mesg y】就好。想要知道目前mesg状态,直接执行【mesg】即可。相对于write是仅针对一个用户来发送【短信】,我们还可以【对所有系统上面的用户发送短信(广播)】,使用wall即可,它的语法也是很简单的。

[root@localhost ~]# wall "i am root , hi everyone"

然后你就会发现所有人都会收到这个短信,连自己都能看到

用户邮箱:mail

使用wall、write毕竟要等到用户在线才能够进行,有没有其他方式来联络呢?我们可以用mailbox来给用户发送邮件,每个用户上面都有个mailbox,可以寄、收maillbox内的邮件。一般来说,mailbox都会放置在/var/spool/mail里面,一个账号一个mailbox(文件),举例来说,我的zhw用户就具有/var/spool/mail/zhw这个mailbox。

那么如何寄邮件呢?直接使用mail这个命令就行了。这个命令的用法很简单,直接执行【mail -s “邮件标题” username@localhost】即可。一般来说,如果寄给本机上面的用户,基本连【@localhost】都不用写。举例来说,我以root寄信给csq用户,邮件标题是【hello,zhw nice to meet you】则:

# 如果没有mail这条命令就需要安装
# RHEL 9 将mailx软件包替换为了 s-nail
[root@chenshiren ~]#  yum install -y s-nail postfix

[root@chenshiren ~]# mail -s "hello,zhw nice to meet you" csq
To: csq
Subject: hello,zhw nice to meet you

ni hao csq   # 信息内容
^D  
-------
(Preliminary) Envelope contains:
To: csq
Subject: hello,zhw nice to meet you
Send this message [yes/no, empty: recompose]? yes  # 是否要发送信息 yes
[root@localhost ~]#     # 退出到了命令行界面了

这样就已经寄出一封信给csq这个用户了。或许你会觉得mail这个程序不好用,因为在邮件编写的过程中,如果写错字而按回车进入了下一行,前一行的数据很难删除,就很难办了。其实我们可以使用数据流重定向,利用 【<】就可以达到替换键盘输入的要求了,也就是是说可以先把信中的内容编好,如何再以mail -s “hello,zhw nice to meet you” csq < filename 来传输文件内容即可

[root@chenshiren ~]# echo "hello,csq nice to meet you"  > givecsqmail.txt   
[root@localhost ~]# mail -s "hello,zhw nice to meet you" csq < givezhwmail.txt 

将你的家目录下的环境变量文件(~/.bashrc)寄给自己

[csq@chenshiren ~]$ mail -s ".bashrc file give root" root < ~/.bashrc

通过管道符命令直接将ls -al ~ 的内容传给root

[zhw@localhost ~]$ ls -al ~ | mail -s "my homefile give root" root

上面说到如何【发送邮件】,那么如何接收邮件呢?同样使用mail。假设我以zhw的身份登录主机,输入mail后会,会显示什么内容呢?

[zhw@localhost ~]$ mail
Heirloom Mail version 12.5 7/5/10.  Type ? for help.
"/var/spool/mail/zhw": 4 messages 4 new
>N  1 root                  Sat Apr 15 19:30  19/646   "hello,zhw nice to meet you"
&       <==这里可以输入很多命令,如果要查看,输入?即可

输入mail之后,我们可以看到我有一封邮件,这封邮件的前面那个 > 代表目前处理的邮件,而在大与附后的右边那个N 代表该封哟见尚未度过。如果我想知道mail内部的命令有哪些,可以在 & 后面输入【?】就可以看到如下画面

& ?
               mail commands
type <message list>             type messages
next                            goto and type next message
from <message list>             give head lines of messages
headers                         print out active message headers
delete <message list>           delete messages
undelete <message list>         undelete messages
save <message list> folder      append messages to folder and mark as saved
copy <message list> folder      append messages to folder without marking them
write <message list> file       append message texts to file, save attachments
preserve <message list>         keep incoming messages in mailbox even if saved
Reply <message list>            reply to message senders
reply <message list>            reply to message senders and all recipients
mail addresses                  mail to specific recipients
file folder                     change to another folder
quit                            quit and apply changes to folder
xit                             quit and discard changes made to folder
!                               shell escape
cd <directory>                  chdir to directory or home if none given
list                            list names of all available commands

指的是每封邮件的左边那个数字,而几个比较常见的命令是:

命令意义
h列出邮件标头,如果要查看40封邮件左右的邮件标头,可以输入【h 40】
d删除后续接的邮件号码,删除单封是【d10】,删除20~40封则【d20-40】。不过操作要生效的话,需要配合q命令才行(下面会说明)
s将邮件储存为文件。例如我要将第一封邮件的内容存储为文件可以这样做:【s 1 ~/mail.file】
x输入x或者输入exit都可以,这个是【不做任何操作退出mail程序】的意思。不论你刚刚删除了什么邮件或读过什么,使用exit会直接退出mail,所以你做出的删除或者阅读工作都会无效。
q相对于exit是不操作退出,q则会实际进行你刚刚所执行的任何操作(尤其是删除)

用户对谈可以方便用户之间的交流和协作,也可以被用来发送系统通知或警告。但需要注意保护隐私和安全,避免向其他用户泄露敏感信息

给自己的QQ邮箱发送一封邮件

①获取授权码

进入QQ邮箱点击设置

image-20230415205821885

点击账户

image-20230415205918003

往下滑找到 POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务

开启服务

image-20230415210442458

可能会弹出一个绑定手机号的先绑定手机号

image-20230415210527719

绑定成功后会出现授权码

image-20230415210927897

保存完毕关闭页面

②使用mailx发送邮件

  1. 安装s-nails-nail
yum install -y s-nail postfix
  1. 编辑mailx配置文件
[root@chenshiren ~]# vim /etc/s-nail.rc 

在文件末尾添加以下配置项:

set from=123@qq.com
set smtp=smtp.qq.com
set smtp-auth-user=123@qq.com
set smtp-auth-password=[这里填授权码]
set smtp-auth=login

解释

  1. set from=123@qq.com:
    set from是用于设置邮件的发件人地址。在这里,123@qq.com是邮件的发件人地址

  2. set smtp=smtp.qq.com:
    set smtp是用于设置SMTP服务器的地址。在这里,smtp.qq.com是QQ邮箱的SMTP服务器地址

  3. set smtp-auth-user=123@qq.com:
    set smtp-auth-user是用于设置SMTP服务器需要验证的用户名。在这里,123@qq.com是QQ邮箱的用户名

  4. set smtp-auth-password=[这里填的是授权码]
    set smtp-auth-password是用于设置SMTP服务器需要验证的密码。

  5. set smtp-auth=login:
    set smtp-auth是用于设置SMTP服务器使用的身份验证方式。在这里,使用登录认证的方式进行身份验证,即Auth Login。SMTP服务器会要求客户端提供用户名和密码,然后验证这些凭据是否正确。如果验证成功,就允许客户端发送邮件;否则,就拒绝客户端的请求。使用登录认证的方式进行身份验证,可以使SMTP服务器在传输过程中对身份信息进行加密,提高了安全性。

③测试是否可以发送邮件

给123@qq.com(自己可以换一个可以收到邮箱的账号自行测试)发送一封邮件

# -v 是显示发送过程,发送过程中出错可以看到
[root@chenshiren ~]# echo "你好CSQ我是Linux端发出的信息" > mailfile.txt 
[root@chenshiren ~]# mail -v -s "邮件主题1" xxxx@qq.com < mailfile.txt
s-nail: Warning: variable superseded or obsoleted: smtp
s-nail: Warning: variable superseded or obsoleted: smtp-auth-user
s-nail: Warning: variable superseded or obsoleted: smtp-auth-password
s-nail: No such file to load: /root/.mailrc
s-nail: Warning -- v15-compat=yes will be default in v14.10.0!
s-nail: P(seudo)R(andom)N(umber)G(enerator): *TLS RAND_*
s-nail: Obsoletion warning: please do not use *smtp*, instead assign a smtp:// URL to *mta*!
s-nail: Obsoletion warning: Use of old-style credentials, which will vanish in v15!
s-nail:   Please read the manual section "On URL syntax and credential lookup"
s-nail: Resolving host smtp.qq.com:smtp ... done
s-nail: Connecting to 120.232.69.34:smtp ... connected.

发送成功了!

image-20240320185247180

账号相关的检查工具:pwck、pwconv、pwunconv、chpasswd

pwck

pwck 这个命令会检查/etc/passwd这个账号配置文件内的信息,检查实际的家目录是否存在等信息,还可以比对/etc/passwd与/etc/shadow的信息是否一致。如果/etc/passwd中的数据字段有误时,会提示用户修正

pwconv

这个命令主要的目的是在【将 /etc/passwd 内的账号与密码,移动到/etc/shadow 当中】早期的Linux 系统当中并没有/etc/shadow,所以,用户的登录密码早期是在/etc/passwd 的第二栏。后来为了系统安全,才将密码数据移动到 /etc/shadow内,使用pwconv后,可以:

  • 比对/etc/passwd 及/etc/shadow,若/etc/passwd 内的账号并没有对应的/etc/shadow 密码时则 pwconv 会去/etc/login.defs 读取相关的密码数据,并建立该账号的/etc/shadow 数据。

  • 若/etc/passwd 中存在加密后的密码数据时,则pwconv 会将该密码栏移动到 /etc/shadow中,并将原本的 /etc/passwd 中相对应的密码栏变成x。

pwunconv

相对于 pwconv,pwunconv 则是【将 /etc/shadow 内的密码栏数据写回 /etclpasswd 当中,并月删除/etc/shadow 文件】

chpasswd

chpasswd ,它可以【读入未加密前的密码,并且经过加密后,将加密后的密码写入/etc/shadow 当中】,这个命令在大量创建账号时经常被使用。它可以由标准输入读入数据,每条数据的格式是【username:password】。

# 假如要修改csq账号的密码
[root@chenshiren ~]# echo "csq:123456" | chpasswd 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/473608.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【文件操作和IO】

文件操作和IO 1.文件2. 硬盘上文件的目录结构3. 文件路径4. 文件重要分类&#xff1a;5. Java中操作文件5.1 Java对于文件操作的API5.2 Java中使用File类来进行文件操作5.3 File类属性5.4 构造方法5.5 方法&#xff1a; 6. 文件内容的读写 -- 文件流&#xff08;数据流&#xf…

C++ List底层实现

文章目录 前言成员变量成员函数迭代器self& operator()前置self operator(int)后置self operator--()前置--self operator--(int)后置--bool operator!(const self & tmp)判断是否相等T* operator*() 解引用操作 list()初始化iterator begin()iterator end()const_iter…

视频无水印批量下载软件|抖音视频提取工具

视频无水印批量下载软件 在当今社交媒体充斥着大量优质视频内容的时代&#xff0c;很多用户都希望能够轻松下载自己喜爱的视频进行收藏或分享。为了满足用户的需求&#xff0c;我们特别推出了一款专业的视频无水印批量下载软件&#xff0c;让您可以方便快捷地获取喜爱的视频内容…

鸿蒙Harmony应用开发—ArkTS-转场动画(共享元素转场)

当路由进行切换时&#xff0c;可以通过设置组件的 sharedTransition 属性将该元素标记为共享元素并设置对应的共享元素转场动效。 说明&#xff1a; 从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 属性 名称参数参数描述…

springboot企业级抽奖项目业务二(用户模块)

书接上回&#xff0c;梅开二度 开发流程 该业务基于rouyi生成好了mapper和service的代码&#xff0c;现在需要在controller层写接口 实际操作流程&#xff1a; 看接口文档一>controller里定义函数一>看给出的工具类一>补全controller里的函数一>运行测试 接口…

练习 9 Web [SUCTF 2019]CheckIn (未拿到flag)

上传图片格式的木马文件&#xff1a; 返回 <? in contents!,存在PHP代码检测 上传非图片格式文件&#xff1a; 返回 不允许非image 修改木马PHP代码规避检测 <? ?> 改为 < script language“php”>< /script ><?php eval($_POST[shell]);?>…

鸿蒙实战开发:【相机和媒体库】

介绍 在ArkTS中调用相机拍照和录像&#xff0c;以及如何使用媒体库接口进行媒体文件的增、删、改、查操作。本示例用到了 权限管理能力相机模块能力接口图片处理接口音视频相关媒体业务能力接口媒体库管理接口设备信息能力接口文件存储管理能力接口弹窗能力接口 效果预览 首…

virtualBox镜像复制

镜像复制 有一个镜像后&#xff0c;图方便&#xff0c;想直接使用这个vdi文件&#xff0c;但vdi有个uuid值&#xff0c;同一个虚拟机中不能同时存在两个同样的uuid的介质的&#xff0c;普通的复制文件所得到的uuid是一样的 &#xff0c;所以需要用到自带的方法复制vdi文件&…

SpringCloud中的@EnableDiscoceryClient和@EnableFeignClients注解的作用解析、RPC远程过程调用

目录 EnableDiscoveryClient 服务发现的核心概念 服务注册中心 EnableDiscoveryClient注解的作用 服务心跳健康检查 使用示例 EnableFeignClients Feign简介 EnableFeignClients注解的作用 RPC&#xff08;Remote Procedure Call&#xff09; 参考链接 Spring Cloud…

Cache缓存:HTTP缓存策略解析

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

【Kotlin】扩展属性、扩展函数

1 类的扩展 Kotlin 提供了扩展类或接口的操作&#xff0c;而无需通过类继承或使用装饰器等设计模式&#xff0c;来为某个类添加一些额外的属性或函数&#xff0c;我们只需要通过一个被称为扩展的特殊声明来完成。通过这种机制&#xff0c;我们可以将那些第三方类不具备的功能强…

Gateway新一代网关

Gateway新一代网关 1、概述 ​ Cloud全家桶中有个很重要的组件就是网关&#xff0c;在1.x版本中都是采用的Zuul网关&#xff1b; ​ 但在2.x版本中&#xff0c;zuul的升级一直跳票&#xff0c;SpringCloud最后自己研发了一个网关SpringCloud Gateway替代Zuul。 ​ 官网&…

HarmonyOS/OpenHarmony应用开发-HDC环境变量设置

hdc&#xff08;HarmonyOS Device Connector&#xff09;是 HarmonyOS 为开发人员提供的用于调试的命令行工具&#xff0c;通过该工具可以在 windows/linux/mac 系统上与真实设备或者模拟器进行交互。 hdc 工具通过 HarmonyOS SDK 获取&#xff0c;存放于 /Huawei/Sdk/openhar…

责任链模式(处理逻辑解耦)

前言 使用设计模式的主要目的之一就是解耦&#xff0c;让程序易于维护和更好扩展。 责任链则是将处理逻辑进行解耦&#xff0c;将独立的处理逻辑抽取到不同的处理者中&#xff0c;每个处理者都能够单独修改而不影响其他处理者。 使用时&#xff0c;依次调用链上的处理者处理…

RK3399 android10 移植SiS-USB触摸驱动

一&#xff0c;SiS USB触摸简介 SiS USB 触摸屏通常是一种外接式触摸屏设备&#xff0c;通过 USB 接口连接到计算机或其他设备上。这种触摸屏设备可以提供触摸输入功能&#xff0c;用户可以通过手指或触控笔在屏幕上进行操作&#xff0c;实现点击、拖动、缩放等操作。 SiS USB…

双向链表增删改查、遍历、倒置、销毁等——数据结构——day3

首先&#xff0c;我先把我的头节点写出来&#xff0c;里面有整理好的结构体 #ifndef __DOULINK_H__ #define __DOULINK_H__#include<stdio.h> #include<stdlib.h> #include<string.h>typedef struct student {int id;char name[50];int score; }DATA_TYPE; …

【数据可视化】Echarts中的其它图表

个人主页 &#xff1a; zxctscl 如有转载请先通知 文章目录 1. 前言2. 绘制散点图2.1 绘制基本散点图2.2 绘制两个序列的散点图2.3 绘制带涟漪特效的散点图 3. 绘制气泡图3.1 绘制标准气泡图3.2 绘制各国人均寿命与GDP气泡图3.3 绘制城市A、城市B、城市C三个城市空气污染指数气…

负数,小数转换二进制

负数转换二进制 例&#xff1a;在带符号整数signed char的情况下&#xff0c;-57如何被表示成负数呢&#xff1f;在计算机中又是如何计算66-57呢&#xff1f; 解析 考虑int占有32位太长&#xff0c;因此使用只占8位的signed char类型来举例。57用二进制表示位00111001&#…

28-5 文件上传漏洞 - 图片马

一、文件内容检测 解析漏洞定义 控制文件是否被当做后端脚本处理 二、图片马绕过 图片马;在图片中包含一句话木马。利用解析漏洞如.htaccess 或文件包含漏洞,对图片马进行解析,执行其中的恶意代码。优势在于可以绕过多种防护机制。 三、图片马制作方法: # 一句话马示例…

nRF Sniffer在wireshark下的环境搭建

一、准备 nRF Sinffer 安装包&#xff1a; 直接下载&#xff1a;https://nsscprodmedia.blob.core.windows.net/prod/software-and-other-downloads/desktop-software/nrf-sniffer/sw/nrf_sniffer_for_bluetooth_le_4.1.1.zip 官网下载&#xff1a; nRF Sniffer for Bluetooth…
最新文章