shadow文件解析
shadow文件以:作为分隔符,一共有九个字段.
# root:$y$jMHLcY0:19777:0:99999:7:::
- 账号名称:与/etc/passwd相同
- 加强后的密码:这个字段内是经过加密过的密码
- 上次更改密码的日期:上一次修改密码的天数(从1970年1月1日开始累计)
- 密码不可被修改天数:例如值为20,当设置完密码后,20天内都无法修改密码
- 密码最大有效期:最近一次修改密码后再多少天内需要再次修改密码才行,超出时间会变为过期特性(登录强制修改密码)
- 密码到期提醒天数:快要到期前的N天就会提醒修改密码
- 密码过期后的宽限期:在密码过期几天后,如果用户还是没有修改密码,这个账号就会失效,无法使用密码登录
- 账户过期日期:一旦账户超过了这个日期,用户将无法登录,即使密码有效
- 保留字段
例子:
exampleuser:$6$random_salt$hashed_password:19300:0:90:7:30:19450:
- 这个就是代表用户在第
19300
天更改了密码 - 根据第5个字段的设置,密码将在第
19300 + 90 = 19390
天过期 - 从
19383
天开始(即到期前7天),系统会提醒用户密码即将过期 - 密码在第
19390
天正式过期。如果用户在这之前没有更改密码,他们仍然可以登录系统,但只能在第19390
天之后的30天内进行登录,即到第19390 + 30 = 19420
天。 - 这30天内,用户必须在登录后立即更改密码.否则,他们将无法执行其他操作.
- 如果用户在第
19420
天前没有登录并更改密码,那么在第19420
天之后,用户将无法再使用旧密码登录系统.账户有效,但密码已过期,系统将拒绝用户的登录尝试 - 在
19450
天会直接让账户失效
有效与初始组,groups,newgr
每一个用户都可以拥有多个支持的用户组,假如说我同时加入多个用户组,在当前进程下使用的是哪个用户组呢?接下来我们就详细探讨一下.
初始组
/etc/passwd文件:
# ubuntu-dzd:x:1000:1000:Ubuntu-dzd,,,:/home/ubuntu-dzd:/usr/bin/zsh
这里ubuntu-dzd的主组的GID是1000,这个就是ubuntu-dzd这个用户的主组(创建用户时,在默认情况下会创建一个与用户同名同ID的组).
/etc/group文件:
# ubuntu-dzd:x:1000:
ubuntu-dzd组的GID为1000,第四个字段为空,表示ubuntu-dzd这个组没有附加组的用户.ubuntu-dzd作为ubuntu-dzd的初始成员,不需要再这里列出(第四字段意思是:如果 abc用户将 ubuntu-dzd 作为附加组加入,那么 abc 会在第四个字段中列出).
有效组
如果 ubuntu-dzd 账号同时属于 whe
、roo
、dg
这三个用户组,那么 ubuntu-dzd 账号将继承这三个组的权限,可以访问和使用这些组所支持的资源.如果你要新建一个组,那所属组应该是谁呢?(默认情况下,是与你同名的主组)这个时候就需要用groups这个命令查询当时支持的有效组了.
groups
(有效与支持用户组的观察)
我以ubuntu-dzd这个用户身份登录后,输入groups就可以输出我所支持的用户组了.
➜ ~ groups
ubuntu-dzd adm cdrom sudo dip plugdev kvm lpadmin lxd sambashare wireshark libvirt docker
# 在这个输出中排名第一的是有效用户组,也就是在当前进程创建一个文件或目录它的所属组是ubuntu-dzd(在没有使用newgrp的情况下)
newgrp
(有效用户组切换)
那么如何修改有效用户组呢?就要使用newgrp了.groups可以检查你所能切换的有效组.
➜ ~ groups
ubuntu-dzd adm cdrom sudo dip plugdev kvm lpadmin lxd sambashare wireshark libvirt docker
➜ ~ newgrp lxd
➜ ~ groups
lxd adm cdrom sudo dip plugdev kvm lpadmin sambashare wireshark libvirt docker ubuntu-dzd
➜ ~ exit #退出这个shell进程
# 对于newgrp这个指令来说,实际上是启用了一个新的shell进程,而且新的shell给予了ubuntu-dzd这个用户有效的GID为lxd.所以你要想回到原本的环境可以使用exit退出这个进程
账号管理
新增与删除用户
useradd
➜ ~ useradd [-u UID] [-g 初始用户组] [-G 附属组] 以此类推 使用者账户名
# 选项
-u:指定UID
-g:指定初始组
-a:追加附属组
-G:指定附属组(如果没有-a参数就会清空附属组)
-M:强制,不要建立使用者家目录(系统账号默认)
-m:强制,要建立使用者家目录(一般账号默认)
-c:passwd文件第五的字段的说明字段,随意设置
-d:指定家目录,不使用默认值,指定的家目录一定要是绝对路径
-r:建立一个系统账号,这个账号的UID会限制(小于1000)
-s:指定shell
-e:写入shadow第八个字段,账号失效日期
-f:指定密码是否会失效,0为立即失效,1为永远不失效
对于useradd的默认配置文件通常在/etc/default/useradd这个文件中.
# useradd defaults file
GROUP=100 #默认组
HOME=/home #默认家目录
INACTIVE=-1 #密码过期的宽限天数,-1不限期
EXPIRE= #账户过期时间,为空是永不过期
SHELL=/bin/bash #默认登录shell
SKEL=/etc/skel #新用户的家目录将从这个目录复制初始内容.里边包含家目录的默认配置文件
CREATE_MAIL_SPOOL=yes #是否创建邮箱
# 私有用户组机制
系统会建立一个与账号一样的用户组给用户作为初始组.家目录默认权限700
# 公共用户组机制
以GROUP=100这个设置值为新建账户的初始用户组,以此每一个账号都属于users这个用户组.
# 一般来说我遇到的系统都是私有用户组机制
对于UID/GID的密码参数在/etc/login.defs,在这里不在过多阐述.
passwd
➜ ~ passwd [--stdin] root
➜ ~ passwd [-l] [-u] [--stdin] [-S] [-n] 以此类推 账号
# 参数
--stdin:会通过前一个管道符数据,作为密码输入.例如echo "root" | passwd --stdin root
-l:是lock的意思,会将/etc/shadow第二个参数加上!使密码失效
-u:是unlock的意思,除去!让密码生效
-S:列出密码相关参数
-n:接天数,第四个参数,密码不可修改天数
-x:接天数,第五个参数,密码最大有效期
-w:接天数,第六个参数,密码过期警告
-i:接天数,第七个参数,密码最后的宽限日期
chage
➜ ~ chage [options] 账号名
# 选项
-l:累出账号的详细密码参数
-d:后边接日期,修改第三个参数(最近修改密码日期),格式YYYY-MM-DD
-E:后边接日期,修改第八个参数(账号失效日期),格式YYYY-MM-DD
-I:后边接天数,修改第七个参数
-m:后边接天数,修改第四个参数
-M:后边接天数,修改第五个参数
-W:后边接天数,修改第六个参数
# 可以让用户登录就修改密码
chage -d 0 用户 #直接让用户过期
usermod
➜ ~ usermod [options] 账号
# 选项
-c:账号说明
-d:账号的家目录
-e:shadow文件第八个参数,格式YYYY-MM-DD
-f:接天数,shadow的第七个参数
-g:修改初始组
-G:用于指定用户的附属组,会替换用户当前的所有附属组
-a:与G组合,追加附属组
-l:修改账号名称
-s:修改默认shell
-u:修改UID
-L:使密码冻结
-U:解冻密码
userdel
➜ ~ userdel -r 账号
# 选项
-r:用于删除使用者的家目录
新增与删除用户组
groupadd
➜ ~ groupadd [options] 用户组名称
# 选项
-g:GID
-r:建立系统用户组
groupmod
➜ ~ groupmod [options] 用户组名称
# 选项
-g:修改GID
-n:修改用户组名称
groupdel
➜ ~ groupdel groupname