在linux中,对用户策略进行设置,分别有usermod passwd chage 这三个命令,每个命令都有一堆的选项,难于记忆,且容易混淆。但本质上,这三个命令都是通过操作/etc/shadow文件来进行相关设置的,所以,从shadow文件各字段的角度,对上述三个命令的用法进行梳理,可以帮助深刻理解shadow文件各字段的意义,也便于牢固记忆这三个命令的相关用法

shadow文件的总体认识

shadow文件与passwd文件类似,都是一行代表一个用户的密码信息,每行中使用8个冒号分隔出9个字段。要查看该文件,可以使用getent shadow 命令。如果想查看某个用户的密码信息,可以用getent shadow username 命令。比如,要查看python用户的密码信息:

1
2
[root@centos8 ~]#getent shadow python
python:$6$WScgAOrAEnpc.cyX$wNrlFUl/DPntPEEdv5/fJC1DS3ocmRNcgzqzQl8aW6ThBz0Iy9u8FP4.zP2kXYu6n8tgIUW7Dfkk84YCJefi70:18436:0:99999:7:::

编辑该文件,就可以对用户策略进行设置。理论上,当然可以用任何文本编辑工具编辑这一文件,但linux不推荐这样做,因为这既不方便,又容易造成错误,一旦不小心修改错了,会造成系统无法启动。所以linux提供了诸如usermod passwd chage 等命令来操作这一文件。但如果你一定要手工编辑这一文件,linux也提供了一个较为安全的命令,就是vipw -s (不加选项用vipw 是手工编辑/etc/passwd文件),好处是具有文件格式的检查功能,出现错误会有提示信息。
对于查看用户的密码信息,可以用passwd -S username 进行,该命令与上面所说的getent shadow username 命令不同之处在于:
getent shadow是原汁原味地将shadow文件中的用户密码信息呈现出来, 和你cat /etc/shadow是一样的,对于日期,是以数值的表示方式,代表从1970年1月1日(大名鼎鼎的UNIX纪元)到某一天的天数。比如第三字段,就代表最近一次修改密码的那天到1970年1月1日的天数,因为是一串数字,所以不直观。
passwd -S 对日期的显示更为直观,采用yyyy-mm-dd这样的格式,看起来友好多了:

1
2
[root@centos8 ~]#passwd -S python
python PS 2020-06-23 0 99999 7 -1 (Password set, SHA512 crypt.)

对于shadow文件有了直观的认识后,下面来详解每个字段的具体含义和编辑该字段用到的命令:

第一字段

用户名,与/etc/passwd文件中的用户相对应。
操作这一字段的命令:

1.usermod -l

用于修改用户名。使用该命令,可以将/etc/passwd和/etc/shadow两个文件中的相应用户名同时进行修改,比如:

1
2
3
4
5
6
7
[ root@centos8 ~]#useradd test   #添加test用户
[ root@centos8 ~]#getent shadow test #查看test用户密码信息
test:!!:18442:0:99999:7:::
[root@centos8 ~]#usermod -l test2 test #将test用户的用户名改为test2
[ root@centos8 ~]#getent shadow test #再查看test用户,已经没有了
[root@centos8 ~]#getent shadow test2 #此时用户名已改为test2
test2:!!:18442:0:99999:7:::

第二字段

用户密码,该段又被三个$分成三段,第一字段代表加密使用的单向加密算法,使用数字表示,1表示MD5,6代表SHA512算法;第二个字段代表加密算法使用的随机因子,也就是salt;第三个字段代表加密后的最终结果。该字段以!开头时,代表该用户被锁定
操作这一字段的命令:

1.passwd

用于添加及修改密码,比如:

1
2
3
4
5
6
[ root@centos8 ~]#passwd test  #为test用户设置密码
Changing password for user test.
New password: #手动输入想为test用户设置的密码
BAD PASSWORD: The password is shorter than 8 characters
Retype new password: #再次输入密码确认
passwd: all authentication tokens updated successfully.

--stdin 使用管道传入密码,常用于脚本,比如:

1
2
3
[root@centos8 ~]#echo centos | passwd --stdin test #为test用户设置密码为centos
Changing password for user test.
passwd: all authentication tokens updated successfully.

2.passwd -l

用于锁定用户,lock,l就是lock的首字母,其实质就是给该字段前面加上感叹号,比如:

1
2
3
4
5
[ root@centos8 ~]#passwd -l test #锁定test用户
Locking password for user test.
passwd: Success
[root@centos8 ~]#getent shadow test #查看shadow文件,已给第二字段加上感叹号
test:!!$6$BtpgEHVJIxMBjTF9$au3lBPtv9pQrKmgXoGIgfQ2UgeuX013WT1LyCFsXwHMIDsYh5pRChdpm8LvTl86GrZoBrrUHRBWnPJ0gKUtNB1:18442:0:99999:7:::

3.passwd -u

用于解锁用户,unlock,u就是unlock的首字母,其实质就是去掉该字段前面的感叹号,比如:

1
2
3
4
5
[root@centos8 ~]#passwd -u test #解锁test用户
Unlocking password for user test.
passwd: Success
[root@centos8 ~]#getent shadow test #查看shadow文件,第二字段的感叹号已没有
test:$6$BtpgEHVJIxMBjTF9$au3lBPtv9pQrKmgXoGIgfQ2UgeuX013WT1LyCFsXwHMIDsYh5pRChdpm8LvTl86GrZoBrrUHRBWnPJ0gKUtNB1:18442:0:99999:7:::

4.usermod -L

用于锁定用户,功能与passwd -l 完全一样,只是注意选项是大写的L

5.usermod -U

用于解锁用户,功能与passwd -u 完全一样,只是注意选项是大写的U

第三字段

最近一次修改密码的时间,具体的数值代表1970年1月1日到修改密码那天的天数,当使用passwd命令修改用户密码时,该字段就会立即设为当前的日期距离1970年1月1日的天数
操作这一字段的命令:

1.passwd -e

该命令将会把该字段置0,要求用户登录时需要立即修改密码,比如:

1
2
3
4
5
[root@centos8 ~]#passwd -e test
Expiring password for user test.
passwd: Success
[root@centos8 ~]#getent shadow test #查看第三字段,已变成0
test:$6$BtpgEHVJIxMBjTF9$au3lBPtv9pQrKmgXoGIgfQ2UgeuX013WT1LyCFsXwHMIDsYh5pRChdpm8LvTl86GrZoBrrUHRBWnPJ0gKUtNB1:0:0:99999:7:::

2.chage -d yyyy-mm-dd

该命令可以手动设定这一字段所表示的日期,比如:

1
2
3
4
5
[root@centos8 ~]#chage -d 2020-6-29 test #将test用户的最近一次密码修改时间设为2020年6月29日
[root@centos8 ~]#getent shadow test #查看test用户的第三字段,已是18442,代表2020年6月29日距1970年1月1日的天数
test:$6$BtpgEHVJIxMBjTF9$au3lBPtv9pQrKmgXoGIgfQ2UgeuX013WT1LyCFsXwHMIDsYh5pRChdpm8LvTl86GrZoBrrUHRBWnPJ0gKUtNB1:18442:0:99999:7:::
[ root@centos8 ~]#passwd -S test #使用passwd -S命令看得更直观
test PS 2020-06-29 0 99999 7 -1 (Password set, SHA512 crypt.)

第四字段

本次修改密码后,最少经过多少天才能再次修改密码,该段默认为0,表示可以随时修改密码。
操作这一字段的命令:

1.passwd -n

该命令可以设置能够再次设置密码的间隔时间,比如:

1
2
3
4
5
6
7
[root@centos8 ~]#passwd -n 3 test #设置test用户在最近一次设置完密码后,必须3天后才能再次设置密码
Adjusting aging data for user test.
passwd: Success
[ root@centos8 ~]#getent shadow test #查看第三字段,已改为3
test:$6$BtpgEHVJIxMBjTF9$au3lBPtv9pQrKmgXoGIgfQ2UgeuX013WT1LyCFsXwHMIDsYh5pRChdpm8LvTl86GrZoBrrUHRBWnPJ0gKUtNB1:18442:3:99999:7:::
[root@centos8 ~]#passwd -S test
test PS 2020-06-29 3 99999 7 -1 (Password set, SHA512 crypt.)

2.chage -m

功能与passwd -n 完全一样。

第五字段

密码过期时间,即本次修改密码后,再过多少天密码过期,默认值为99999
操作这一字段的命令:

1.passwd -x

该命令可以设置密码过期时间,比如:

1
2
3
4
5
6
7
[ root@centos8 ~]#passwd -x 7 test #设置test用户的密码过期时间为7天
Adjusting aging data for user test.
passwd: Success
[root@centos8 ~]#getent shadow test #第五字段已设置为7
test:$6$BtpgEHVJIxMBjTF9$au3lBPtv9pQrKmgXoGIgfQ2UgeuX013WT1LyCFsXwHMIDsYh5pRChdpm8LvTl86GrZoBrrUHRBWnPJ0gKUtNB1:18442:3:7:7:::
[root@centos8 ~]#passwd -S test
test PS 2020-06-29 3 7 7 -1 (Password set, SHA512 crypt.)

2.chage -M

该命令功能同passwd -x完全相同

第六字段

密码过期前发出提示消息的时间,默认为7,代表在密码过期前7天开始,给用户发提示消息
操作这一字段的命令:

1.passwd -w

该命令可以设置在密码过期前多少天给用户发提示信息,比如:

1
2
3
4
5
6
7
[root@centos8 ~]#passwd -w 8 test #设置test在密码过期前8天,就收到系统的提示信息
Adjusting aging data for user test.
passwd: Success
[root@centos8 ~]#getent shadow test
test:$6$BtpgEHVJIxMBjTF9$au3lBPtv9pQrKmgXoGIgfQ2UgeuX013WT1LyCFsXwHMIDsYh5pRChdpm8LvTl86GrZoBrrUHRBWnPJ0gKUtNB1:18442:3:7:8:::
[root@centos8 ~]#passwd -S test
test PS 2020-06-29 3 7 8 -1 (Password set, SHA512 crypt.)

此时用test用户登录,可以看到:

1
2
3
Connecting to 10.0.0.101:22...
Connection established.
Warning: your password will expire in 7 days #系统的提示信息

2.chage -W

该命令的功能同passwd -w 完全相同,只是要注意chage用的是大写的W,而passwd用的是小写的w

第七字段

密码过期后还可以继续使用的天数,超过此时间,用户将不可登录,即inactive状态的时间,默认为空。可以理解为,到了密码的过期时间,如果还没有更改密码,系统仍会宽限一段时间,允许你继续登录。但如果过了这段时间你还不改密码,系统就会把你的账户禁用。
操作这一字段的命令:

1.passwd -i

该命令可以设置在密码过期后还可以继续使用的天数,比如:

1
2
3
4
5
6
7
[root@centos8 ~]#passwd -i 3 test #设置test用户的宽限时间是3天
Adjusting aging data for user test.
passwd: Success
[root@centos8 ~]#getent shadow test #该字段已改为3
test:$6$BtpgEHVJIxMBjTF9$au3lBPtv9pQrKmgXoGIgfQ2UgeuX013WT1LyCFsXwHMIDsYh5pRChdpm8LvTl86GrZoBrrUHRBWnPJ0gKUtNB1:18442:3:7:8:3::
[root@centos8 ~]#passwd -S test
test PS 2020-06-29 3 7 8 3 (Password set, SHA512 crypt.)

2.chage -I

该命令同passwd -i 的功能完全相同,只是注意passwd用的是小写的i,而chage用的是大写的I

3.usermod -f

该命令同passwd -i 的功能完全相同。

第八字段

账号的有效期,同样是用数值表示,代表从1970年1月1日到用户被禁的那天的天数,默认为空
操作这一字段的命令

1.chage -E yyyy-mm-dd

该命令可以手动设置账号的有效期,比如:

1
2
3
[root@centos8 ~]#chage -E 2020-7-2 test #设置test用户的有效期是2020年7月2日
[root@centos8 ~]#getent shadow test #该字段的数值已被设置为2020年7月2日至1970年1月1日的天数
test:$6$BtpgEHVJIxMBjTF9$au3lBPtv9pQrKmgXoGIgfQ2UgeuX013WT1LyCFsXwHMIDsYh5pRChdpm8LvTl86GrZoBrrUHRBWnPJ0gKUtNB1:18442:3:7:8:3:18445:

2. usermod -e yyyy-mm-dd

该命令的功能与 chage -E完全相同,只是要注意chage用的是大写的E,而usermod用的是小写的e

第九字段

这个字段是保留字段,为以后新增的功能预留的位置,暂无命令可以操作该字段