Skip to content

用户的分类

  1. 超级用户:拥有至高无上的权限。root uid=0 gid=0 权限最大。
  2. 普通用户:权限受到限制的用户。1000-65535 做一般权限的系统管理,权限有限。
  3. 程序用户:不登录的用户 系统默认的情况。1=<uid<999 为了提升系统安全性,为了支持所对应服务对系统资源的使用,不能用于登录系统或管理系统。

UID/GID体系说明

UID

  • UID 是系统中用户的唯一数字标识,范围从 0 开始。
  • 系统通过 UID(而非用户名)判断用户权限。
UID 范围用户类型说明
0root 用户超级管理员,拥有系统最高权限(如 /bin/bash 的默认所有者)。
1–999系统用户预留给系统服务(如 mysql, nginx),避免使用 root 运行服务以提高安全性。
1000–60000普通用户由管理员创建的实际用户(默认从 1000 开始)。
≥60000自定义或临时用户部分系统保留更高范围(如某些发行版扩展到 65534)。

相关命令

bash
# 查看当前用户 UID
id -u

# 查看指定用户 UID
id -u username

# 创建用户时指定 UID
sudo useradd -u 1500 newuser

GID(组标识符)

  • GID 是用户组的唯一数字标识,与 UID 类似,但用于组权限管理。
  • 每个用户至少属于一个主组(Primary Group),并可加入多个附加组(Supplementary Groups)。
GID 范围组类型说明
0root 组超级管理员组。
1–999系统组预留给系统服务(如 sys, adm)。
1000–60000普通组用户自定义组(通常与普通用户 UID 范围一致)。

相关命令

bash
# 查看当前用户 GID
id -g

# 查看用户所属的所有组
groups username

# 创建组并指定 GID
sudo groupadd -g 2000 newgroup

用户信息 /etc/passwd详解

/etc/passwd 是 Linux 系统中存储用户账户信息的关键文件,所有用户(包括系统用户)的基本信息都记录在此。该文件为纯文本格式,全局可读但只有 root 用户可写。

字段结1构(共7个字段,用冒号分隔)

序号字段名说明
1用户名用户登录名(如 root, ftp 等)
2密码占位符历史遗留字段,现代系统用 x 表示密码存储在 /etc/shadow
3UID用户ID: - 0 = root - 1-999 = 系统用户 - 1000+ = 普通用户
4GID主组ID,对应 /etc/group 中的组
5GECOS注释字段,通常包含用户全名、联系方式等信息
6家目录用户登录后的初始工作目录
7登录Shell用户默认shell(如 /bin/bash), /sbin/nologin 表示禁止登录

用户密码数据库文件 /etc/shadow详解

/etc/shadow 是 Linux 系统的密码数据库文件,存储所有用户的加密密码及安全策略信息。相比 /etc/passwd,该文件具有以下特性:

  • 仅 root 用户可读写
  • 采用更安全的存储机制
  • 包含密码时效控制参数

字段结构(9个字段,冒号分隔)

序号字段名格式说明特殊值含义
1用户名/etc/passwd对应-
2加密密码格式:$id$salt$hash (id=1-MD5, 5-SHA256, 6-SHA512)!=锁定账户 *=服务账户
3最后修改日期从1970-1-1起的天数0=下次登录必须修改密码
4最小修改间隔从第 3 字段起,多长时间之内不能修改密码0=无限制
5密码有效期距离第 3 字段多长时间内需要再次变更密码99999=永不过期
6密码过期前告警距离密码有效期的前 n 天告警默认7
7密码过期后宽限期密码过期后仍允许登录的天数空=立即禁用 0=过期后禁用
8账户过期日期从1970-1-1起的天数空=永不过期
9保留字段未使用-

字段详解

bash
[root@localhost ~]#head -1 /etc/shadow
root:$6$9w5Td6lg$bgpsy3olsq9WwWvS5Sst2W3ZiJpuCGDY.4w4MRk3ob/i85fl38RH15wzVoomff9isV1PzdcXmixzhnMVhMxbvO:15775:0:99999:7:::

1.用户名 同 /etc/passwd 文件的用户名有相同的含义。

2.加密密码 这里保存的是真正加密的密码。目前 Linux 的密码采用的是 SHA512 散列加密算法,原来采用的是 MD5 或 DES 加密算法。SHA512 散列加密算法的加密等级更高,也更加安全。 注意,这串密码产生的乱码不能手工修改,如果手工修改,系统将无法识别密码,导致密码失效。很多软件透过这个功能,在密码串前加上 "!"、"" 或 "x" 使密码暂时失效。 所有伪用户的密码都是 "!!" 或 "",代表没有密码是不能登录的。当然,新创建的用户如果不设定密码,那么它的密码项也是 "!!",代表这个用户没有密码,不能登录。

3.最后一次修改时间 此字段表示最后一次修改密码的时间,可是,为什么 root 用户显示的是 15775 呢? 这是因为,Linux 计算日期的时间是以 1970 年 1 月 1 日作为 1 不断累加得到的时间,到 1971 年 1 月 1 日,则为 366 天。这里显示 15775 天,也就是说,此 root 账号在 1970 年 1 月 1 日之后的第 15775 天修改的 root 用户密码。 那么,到底 15775 代表的是哪一天呢?可以使用如下命令进行换算:

bash
[root@localhost ~]# date -d "1970-01-01 15775 days"
2013年03月11日 星期一 00:00:00 CST

4.最小修改时间间隔 最小修改间隔时间,也就是说,该字段规定了从第 3 字段(最后一次修改密码的日期)起,多长时间之内不能修改密码。如果是 0,则密码可以随时修改;如果是 10,则代表密码修改后 10 天之内不能再次修改密码。 此字段是为了针对某些人频繁更改账户密码而设计的。

5.密码有效期 经常变更密码是个好习惯,为了强制要求用户变更密码,这个字段可以指定距离第 3 字段(最后一次更改密码)多长时间内需要再次变更密码,否则该账户密码进行过期阶段。 该字段的默认值为 99999,也就是 273 年,可认为是永久生效。如果改为 90,则表示密码被修改 90 天之后必须再次修改,否则该用户即将过期。管理服务器时,通过这个字段强制用户定期修改密码。

6.密码需要变更前的警告天数 与第 5 字段相比较,当账户密码有效期快到时,系统会发出警告信息给此账户,提醒用户 "再过 n 天你的密码就要过期了,请尽快重新设置你的密码!"。 该字段的默认值是 7,也就是说,距离密码有效期的第 7 天开始,每次登录系统都会向该账户发出 "修改密码" 的警告信息。

7.密码过期后的宽限天数 也称为“口令失效日”,简单理解就是,在密码过期后,用户如果还是没有修改密码,则在此字段规定的宽限天数内,用户还是可以登录系统的;如果过了宽限天数,系统将不再让此账户登陆,也不会提示账户过期,是完全禁用。 比如说,此字段规定的宽限天数是 10,则代表密码过期 10 天后失效;如果是 0,则代表密码过期后立即失效;如果是 -1,则代表密码永远不会失效。

8.账号失效时间 同第 3 个字段一样,使用自 1970 年 1 月 1 日以来的总天数作为账户的失效时间。该字段表示,账号在此字段规定的时间之外,不论你的密码是否过期,都将无法使用! 该字段通常被使用在具有收费服务的系统中。

9.保留 这个字段目前没有使用,等待新功能的加入。

添加用户账号

useradd

useradd 是 Linux 系统中用于创建新用户账户的核心工具,会同时更新以下文件:

  • /etc/passwd
  • /etc/shadow
  • /etc/group
  • /etc/gshadow
  • 用户家目录(可选)

基本语法

bash
useradd [选项] 用户名

选项

选项作用描述
-c "备注"设置用户备注信息(通常为全名)
-d 目录指定家目录路径(默认 /home/用户名
-e 日期设置账户过期日期(格式:YYYY-MM-DD)
-f 天数密码过期后宽限天数(0=立即禁用,-1=禁用此功能)
-g 主组指定主用户组(GID或组名)
-G 附加组指定附加用户组(逗号分隔)
-m自动创建家目录(配合 -k 可指定模板目录)
-M不创建家目录(适用于服务账户)
-N不创建与用户同名的用户组
-p 密码设置加密后的密码(建议用 passwd 命令替代)
-r创建系统账户(UID范围 1-999)
-s shell指定登录shell(如 /bin/bash/sbin/nologin 禁止登录)
-u UID手动指定用户ID

配置文件

/etc/default/useradd 定义默认参数:

ini
GROUP=100        # 默认起始GID
HOME=/home       # 家目录位置
INACTIVE=-1      # 密码过期宽限期。-1表示永久有效,0表示失效
EXPIRE=          # 默认过期日期
SHELL=/bin/bash  # 默认shell
SKEL=/etc/skel   # 家目录模板

注意事项

  1. 创建用户后必须用 passwd 设置密码
  2. 使用 -p 选项时需提供 已加密 的密码(可通过 openssl passwd 生成)
  3. 生产环境中建议使用 -e 设置服务账户过期时间
  4. 删除用户时如需移除家目录,应使用 userdel -r

用户家目录配置模板

文件来源

新建用户账号时,从/etc/skel/目录中复制而来

主要的用户初始配置文件:

  • ~/.bash_profile:每次登录时执行
  • ~/.bashrc:每次进入新 bash 环境时执行
  • ~/.bash_logout:每次退出登录时执行

组账号管理

组账号概述

类型作用配置文件关键命令
用户系统使用者身份标识/etc/passwduseradd, usermod, userdel
用户集合,用于共享权限管理/etc/groupgroupadd, groupmod, groupdel
密码认证凭据(加密存储)/etc/shadowpasswd, chage
SELinux增强安全策略(可选)/etc/selinux/configsemanage, chcon

组类型

  • 主组(Primary Group):用户创建文件时默认所属组
  • 附加组(Supplementary Group):用于额外权限分配(如 sudo, docker

组账号文件

  1. /etc/group:保存组账号基本信息
  2. /etc/gshadow:保存组账号的密码信息(较少使用)

权限基础概念

三位一体权限系统:

  • 用户权限 (u):文件所有者
  • 组权限 (g):文件所属组
  • 其他用户权限 (o):除拥有着和属组之外的用户权限(最低的)

权限类型

符号数字文件权限目录权限
r4读取文件内容列出目录内容
w2修改文件内容创建/删除目录内文件
x1执行文件进入目录
-0无权限无权限

目录权限

查看目录的权限需要读(r)权限,进入目录创建文件需要执行(x)权限,在该目录中创建文件或文件夹和删除需要写(w)权限

NOTE

对文件写入内容需要文件的权限。对文件创建和删除需要上级目录的权限

特殊权限

suid(Set - User - ID)

概念

  • 当一个可执行文件设置了 suid 位后,用户在执行该文件时,会临时拥有该文件所有者的权限。换句话说,就是进程在执行过程中会以文件所有者的用户身份来运行。这对于一些需要特定权限才能完成任务的程序非常有用。例如,/usr/bin/passwd 这个用于更改用户密码的程序就设置了 suid 位。因为只有超级用户(root)才有权限修改密码文件(/etc/shadow),通过设置 suid,普通用户在运行 passwd 命令时,就可以临时获得 root 权限来修改密码。

设置和查看方法

  • 设置:使用 chmod 命令,格式为 chmod u+s 文件名。例如,要给一个名为 test 的可执行文件设置 suid,可以执行 chmod u+s test。
  • 查看:在 ls -l 命令的输出中,文件权限的第 4 位(原本是用户权限位)如果显示为 s(对于可执行文件)或者 S(对于不可执行文件),则表示设置了 suid。例如,-rwsr - xr - x 表示文件设置了 suid,其中 s 的出现位置表示它替代了原来的用户可执行权限位。

应用场景和注意事项

  • 应用场景主要是用于系统管理工具。像前面提到的 passwd、mount、umount 等命令,它们需要以 root 权限来操作系统的敏感文件(如密码文件、挂载点等),通过设置 suid,可以让普通用户在使用这些命令时获得必要的权限。
  • 然而,suid 也存在安全风险。如果一个具有 suid 权限的可执行文件存在漏洞,恶意用户可能利用这个漏洞以较高的权限执行恶意操作。因此,系统管理员应该谨慎使用 suid,只在必要的程序上设置,并且定期检查这些程序的完整性。

sgid(Set - Group - ID)

概念

  • 对于目录来说,设置 sgid 位后,该目录下的所有新创建的文件和子目录都会继承该目录的所属组。这样可以保证在一个共享目录中,所有文件的所属组保持一致,方便组内成员对该目录下的文件进行操作。
  • 对于文件,如果设置了 sgid 位,当文件被执行时,进程会以文件所属组的权限来运行。不过这种情况相对较少使用。

设置和查看方法

  • 设置:使用 chmod 命令,格式为 chmod g+s 目录名(对于目录)或 chmod g+s 文件名(对于文件)。例如,要给一个名为 shared_dir 的目录设置 sgid,可以执行 chmod g+s shared_dir。
  • 查看:在 ls -l 命令的输出中,文件权限的第 5 位(原本是组权限位)如果显示为 s(对于可执行文件或目录)或者 S(对于不可执行文件),则表示设置了 sgid。例如,drwxrwsr - x 表示目录设置了 sgid,其中 s 出现在组权限位。

应用场景和注意事项

  • 主要应用场景是共享目录。例如,在一个开发团队中,有一个共享的代码目录,通过设置 sgid,团队成员在这个目录下创建的文件都会属于团队组,这样组内的其他成员可以更容易地进行代码协作。
  • 对于 sgid 在文件上的应用,由于使用场景较少,而且同样存在潜在的安全风险,需要谨慎使用。如果一个具有 sgid 权限的文件被恶意利用,可能会导致组权限的滥用。

sbits(Sticky Bit)

概念

  • 主要用于目录。当一个目录设置了 sticky bit 位后,只有文件的所有者或者超级用户才有权限删除或重命名该目录下的文件。这可以防止用户删除其他用户在共享目录中的文件。例如,在 /tmp 目录下,许多用户都会存储临时文件,设置了 sticky bit 后,用户不能随意删除其他用户的文件,只能删除自己创建的文件。

设置和查看方法

  • 设置:使用 chmod 命令,格式为 chmod o+t 目录名。例如,要给一个名为 common_dir 的目录设置 sticky bit,可以执行 chmod o+t common_dir。
  • 查看:在 ls -l 命令的输出中,文件权限的最后一位(其他用户权限位)如果显示为 t,则表示设置了 sticky bit。例如,drwxrwxr - t 表示目录设置了 sticky bit。

应用场景和注意事项

  • 典型应用场景就是类似 /tmp 这样的共享目录。它有效地保护了用户在共享目录下的文件不被其他用户随意删除。
  • 但对于非共享目录,一般不需要设置 sticky bit。在设置时,要确保目录的权限设置合理,因为如果目录权限过于宽松,即使设置了 sticky bit,可能还会存在其他安全风险,例如其他用户可能对文件有写权限等情况。

权限和归属

mermaid
graph TD
    A[ls -l install.log] --> B["-rw-r--r--"]
    A --> C["1"]
    A --> D["root"]
    A --> E["root"]
    A --> F["34298"]
    A --> G["04-02"]
    A --> H["00:23"]
    A --> I["install.log"]

    subgraph 注释
        B -->|文件类型、权限| J["-rw-r--r--"]
        J -->|文件类型| K["-:普通文件"]
        J -->|属主权限| L["r-w-:读写权限"]
        J -->|属组权限| M["r--:只读权限"]
        J -->|其他用户权限| N["r--:只读权限"]

        C -->|硬链接计数| O["1:硬链接数量"]

        D -->|属主| P["root:文件所有者"]

        E -->|属组| Q["root:文件所属组"]

        F -->|文件大小| R["34298:文件大小(字节)"]

        G -->|最后修改日期| S["04-02:4月2日"]

        H -->|最后修改时间| T["00:23:0点23分"]

        I -->|文件名| U["install.log:文件名称"]
    end

第一列 文件类型、权限

第1位表示文件类型

  • -:表示普通文件
  • d:表示目录
  • l:表示软链接
  • p:表示 PIPE 管道文件
  • s:表示 socket 通信套接字文件
  • c:表示字符设备文件
  • b:表示块设备文件

第2、3、4位归属主

rw- 表示文件归属主权限。

  • r:可读,数字4表示,
  • w:可写,数字2表示
  • x:可执行,数字1表示
  • -:无权限

第5、6、7位归属组

r--表示的文件归属附属组的权限。

  • r:可读,数字4表示,
  • w:可写,数字2表示
  • x:可执行,数字1表示
  • -:无权限

第二列硬链接数

1:硬链接计数,表示该文件有多少个硬链接指向它。

第三列归属主

root表示归属主。

第四列归属组

root表示归属的附属组。

第五列文件大小

1表示的文件大小,以字节为单位。

第六列修改日期

04-02文件的最后修改日期。

第七列修改时间

00:23文件的最后修改时间

第八列文件名

install.log:文件名。

权限掩码 umask

umask(user file-creation mask)是Linux系统中用于控制新建文件/目录默认权限的掩码值。它通过屏蔽(取消)特定权限位来设置安全基线。

语法格式

bash
umask [-p] [-S] [mode]
  • 无参数:显示当前umask值
  • -S:符号模式显示(rwx形式)
  • -p:可重用输出格式
  • mode:设置新umask值(八进制或符号格式)

权限计算原理

  • 文件默认权限:666 - umask

  • 目录默认权限:777 - umask

  • 实际权限 = 默认权限 & (~umask)

    选项说明
    0022典型安全设置(文件644,目录755)
    0002组可写(文件664,目录775)
    0077严格模式(文件600,目录700)

注意事项

  1. umask是进程属性,只在当前shell会话有效

  2. 系统服务可能有自己的umask设置(如/etc/init.d/脚本)

  3. 新建文件的执行权限需单独赋予(chmod +x)

  4. 安全模式修改,在文件/etc/profile末尾追加如下

    bash
    # 判断当uid大于199并且uid=gid时umask设置027,创建目录权限就变成750,文件权限为640
    # umask 安全
    if [ $UID -gt 199 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`" ]; then
            umask 027
        else
            umask 022
    fi
    
    # 使配置文件生效 
    source ~/.bashrc

权限对照表

umask文件权限目录权限
022644755
027640750
077600700

NOTE

使用umask -p输出的命令可直接在脚本中重用

案例

bash
# 查看当前umask(八进制)
umask
# 输出示例:0022

# 查看符号表示
umask -S
# 输出:u=rwx,g=rx,o=rx

# 临时修改umask
umask 027  # 文件默认640,目录默认750

# 永久生效(添加到~/.bashrc或/etc/profile)
echo "umask 022" >> ~/.bashrc
# 使配置文件生效 
source ~/.bashrc

权限验证流程

当用户访问文件时,系统按以下顺序检查权限:

  1. 是否为所有者 → 检查用户权限(u)
  2. 是否属于文件组 → 检查组权限(g)
  3. 其他情况 → 检查其他用户权限(o)
  4. ACL规则(如果存在)→ 覆盖传统权限