2.1 用户名和密码

和用户账号相关的两个重要文件

当我们登录 Linux 系统时,需要输入用户名和密码。虽然我们输入的是用户名,但其实 Linux 主机并不直接认识我们的用户名,它只认识 ID,用户名只是为了让人们更容易记住而已。

UID,User ID,用户 ID GID,Group ID,用户组 ID

今天,我们就来了解下 Linux 是如何辨认每个用户的。

1. 流程

当我们通过 ssh 命令输入用户名和密码的时候,Linux 系统会做以下工作:

  1. 先查找 /etc/passwd 里是否有输入的用户名

    • 如果没有,则退出

    • 如果有,那就将该用户名对应的 UID 和 GID(在 /etc/group 中)取出来,同时也会取出该用户的 home 目录和 shell 设置

  2. 核对密码表 /etc/shadow

    • Linux 会根据用户名,从 /etc/shadow 里找出对应的密码进行校验

    • 如果校验成功,则会进入 shell 管理的阶段

上面提到了两个和用户账号相关的重要文件:

  • /etc/passwd:管理着用户名、UID 和 GID

  • /etc/shadow:专门管理着密码

2. /etc/passwd

2.1 文件内容

比如,在阿里云上,运行命令 cat /etc/passwd,会显示如下内容:

## UID = 0, 系统管理员
root:x:0:0:root:/root:/bin/bash

## UID ∈ [1,999], 系统账号
##   由于在系统上启动的网络服务或后台服务,希望使用较小的权限去运行
##      所以,不希望使用 root 的身份来执行这些服务
##      因此,就为运行中的程序提供了这些系统账号
##   这些系统账号通常是不可登录的(即没法使用 bash 或其它 shell 来登录系统)
##      所以才会有 /sbin/nologin 这个特殊的 shell 存在
# 1~200 由 Linux 自行建立的系统账号
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
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/false
nscd:x:28:28:NSCD Daemon:/:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
# 201~999 若用户有系统账号的需求时,可以使用的账号 UID
dockerroot:x:996:993:Docker User:/var/lib/docker:/sbin/nologin
nginx:x:997:995:Nginx web server:/var/lib/nginx:/sbin/nologin
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
polkitd:x:999:997:User for polkitd:/:/sbin/nologin

## UID >= 1000, 一般用户
shareread:x:1000:1000::/home/shareread:/bin/bash

2.2 文件格式

文件 /etc/passwd 里的每一行就代表一个账号,有几行就代表系统中有几个账号。

每行以冒号:为分隔符,分为 7 列,如下:

含义
说明

1

账号名称

2

密码

值都为 x

3

UID

0 是系统管理员 1~999 是系统账号,通常是不可登录的 1000+ 是可登录的账号,给一般用户用的

4

GID

/etc/group 有关,用来规范组名的

5

用户信息说明

一般没啥用 但是如果提供了 figure 功能,这个字段可以提供很多信息

6

home 目录

当用户登录成功之后,就会自动进入到 home 目录里

7

shell

当用户登录系统之后,就会获取一个 shell 来和 系统的内核进行沟通,以完成用户的操作任务。 eg. - /bin/sync - /sbin/shutdown - /sbin/halt - /bin/false - /sbin/nologin 为不可登录的系统账号准备的 - /bin/bash 可正常登录的用户

如果将一般用户的 UID 改成 0,那他也就具有 root 的权限了。不过,非常不建议这么做。

2.3 文件权限

很多程序的运行都和权限有关,而权限又和 UID 和 GID 相关,所以各个程序都要读取 /etc/passwd 来了解不同账号的权限,所以它的权限需要设置成 -rw -r--r--

# ls -l /etc/passwd
-rw-r--r-- 1 root root 1236 Dec 18  2018 /etc/passwd

早期的 Unix 系统,密码是存在 /etc/passwd 文件里的,虽然也有加密,但因为这个文件的特性是所有的程序都能读取,这就导致密码容易被窃取进而被暴力破解出来,所以后来就将密码移到了 /etc/shadow 文件里,该文件的权限是 -rw------- 或者 ----------,即只有 root 才能读写。

# ls -l /etc/shadow
---------- 1 root root 862 Dec 18  2018 /etc/shadow

3. /etc/shadow

3.1 文件内容

比如,在阿里云上,运行命令 cat /etc/shadow,会显示如下内容:

# 系统账号的
bin:*:17110:0:99999:7:::
daemon:*:17110:0:99999:7:::
adm:*:17110:0:99999:7:::
lp:*:17110:0:99999:7:::
sync:*:17110:0:99999:7:::
shutdown:*:17110:0:99999:7:::
halt:*:17110:0:99999:7:::
mail:*:17110:0:99999:7:::
operator:*:17110:0:99999:7:::
games:*:17110:0:99999:7:::
ftp:*:17110:0:99999:7:::
mysql:!!:17624::::::
nscd:!!:17454::::::
ntp:!!:17454::::::
apache:!!:17883::::::
tcpdump:!!:17454::::::
sshd:!!:17454::::::
dbus:!!:17454::::::
postfix:!!:17454::::::
nobody:*:17110:0:99999:7:::
systemd-network:!!:17454::::::

dockerroot:!!:17883::::::
nginx:!!:17624::::::
chrony:!!:17454::::::
polkitd:!!:17454::::::

# root 用户的
root:$6$.PENTCpQ$L55HQMW5tf4Yj4x5Fvls95MyeWI1J5Rp1xbtbsXw0EQhW/X0QBuO1vwGLQ3OqJxdm6py40IJvvPG8yYZQx0Pw0:17623:0:99999:7:::

# 一般用户的
shareread:$6$RqqEr.T/$Ld84B.mtqKmrXdL3KUgLKiujpo.udClGH1JlKr4Nps5R6ZQa/X5a2voE65Qorqmcbm6rl9tkaYo1c3wyEH3rk/:17686:0:99999:7:::

3.2 文件格式

每行以冒号:为分隔符,分为 9 列,如下:

含义
说明

1

账号名称

2

密码

是经过编码的密码(摘要)

3

最近修改密码的日期

整数,是以1970年1月1日作为1而累加的

4

密码不可被修改的天数

相对于第3个字段 若是0则表示密码可以随时修改

5

密码需要重新修改的天数

相对于第3个字段 如果是99999(即273年)则表示不强制

6

密码需要修改期限前的警告天数

相对于第5个字段

7

密码过期后的账号宽限时间

相对于第5个字段 虽然密码过期但是该账号还是能执行其它任务的 不过如果密码过期了,当我们登录系统时, 系统会强制要求必须要重新设置密码之后 才能继续使用,这就是密码过期特性 如果在密码过去的n天后,用户还是没有登录 更改密码,那么这个账号的密码就会失效

8

账号失效日期

账号在此日期之后,将无法再使用

9

保留字段

要想知道 shadow 使用的加密机制,可以使用 authconfig 命令查询。如下:

# authconfig --test | grep hashing
password hashing algorithm is sha512

3.3 密码忘了,怎么办?

如果是一般用户,可以让系统管理员帮忙。他可以直接重置我们的密码而不需要知道旧密码,即以 root 的身份使用 passwd 命令。

如果是 root 用户,那可以使用各种可行的方法进入 Linux 后再去修改。比如重新启动系统之后进入单人维护模式,系统会主动给予 root 权限的 bash 接口,此时再以 passwd 命令修改密码即可。或者以 Live CD 启动后挂载根目录去修改 /etc/shadow,将里面 root 的密码字段清空,再重新启动之后,root 不用密码即可登录,登录后再用 passwd 命令设置 root 的密码即可。

Last updated