用户、组

Linux 安全模型

3A:

认证: Authentication (确认身份, 登录系统的用户名和密码)

授权: Authorization (对于文件和程序的权限)

审计: Accouting|Audition (监控日志)

认证和授权linux本身的软件实现, 审计通过特定的软件实现

用户登录成功时, 系统会自动分配令牌token, token中包含了用户标识和组成员等信息, 用户的每一步操作, 系统都会校验他的token, 验证他的权限。使用`id`可以查看token

用户

linux中每个用户是通过 uid 来唯一标识的 id -u

  • 管理员: root, 0
  • 普通用户
    • 系统用户: 1-499 (centos6及以前), 1-999 (centos7以后), 对守护进行获取资源进行权限分配
    • 登录用户: 500+ (centos6及以前), 1000+ (centos7以后), 给用户进行交互式登录使用

用户组

linux中可以将一个或多个用户加入用户组中, 用户组通过 gid 唯一标识 id -g

  • 管理员组: root, 0
  • 普通组:
    • 系统组
    • 普通组

用户和用户组的关系

  • 用户的主要组: 用户必须属于一个且只有一个主组, 默认创建用户时会自动创建和用户同名的组作为用户的主组, 由于此组中只有一个用户, 又称为私有组
  • 用户的附加组: 一个用户可以属于0个或多个辅助组, 附属组
1
2
[lujinkai@centos7 root]$ id postfix
uid=89(postfix) gid=89(postfix) groups=89(postfix),12(mail)

安全上下文

进程能够访问资源的权限取决于进程的运行者身份, 而非程序本身

用户和组的配置文件

  • /etc/passwd 系统用户配置文件,存储了系统中所有用户的基本信息,并且所有用户都可以对此文件执行读操作
  • /etc/shadow 存储 Linux 系统中用户的密码信息,又称为“影子文件”。
  • /etc/group 用户组配置文件,用户组的所有信息都存放在此文件中
  • /etc/gshadow 存储组用户的密码信息

/etc/passwd 文件格式

1
2
3
4
5
[root@centos7 ~]# whatis passwd
sslpasswd (1ssl) - compute password hashes
passwd (1) - update user's authentication tokens
passwd (5) - password file
[root@centos7 ~]# man 5 passwd
  1. name: 用户登录名
  2. password: 在很早之前, 这里确实存储密码, 后来因为安全问题, 密码就搬迁到/etc/shadow中了, 但是因为兼容性问题, 所以格式不能变, 就留了一个占位符, 用x或*占位
  3. UID: 用户的id
  4. GID: 用户主组的id
  5. GECOS: 存储用户全名和一些注释
  6. directory: 用户家目录
  7. shell: 用户默认使用的shell ( /bin/bash )

/etc/shadow 文件格式

/etc/passwd文件所有用户都可以读, /etc/shadow文件只有root用户才可以读

注意,如果这个文件的权限发生了改变,则需要注意是否是恶意攻击。

Linux /etc/shadow(影子文件)内容解析(超详细)

  1. 用户登录名
  2. 加密过的用户登录密码, 一般用sha512加密
  3. 最后一次修改密码的时间, 如果没有修改过, 则空置
  4. 密码再过几天可以被更改, 0表示随时都可以更改
  5. 密码再过几天必须被更改, 9999是300多年, 可以认为永不过期
  6. 密码过期前几天系统提醒用户, 默认是一周
  7. 密码过期后的宽限时间, 以天为单位, 也就是说密码过期后, 用户如果还没有修改密码, 则在此字段规定的宽限天数内, 用户还是可以登录系统
  8. 账号过期时间, 从1970.1.1开始算, 多少天后账号失效, 在此规定时间之外, 不论密码是否过期, 都无法登录! 该字段通常被使用在具有收费服务的系统中
  9. 保留, 这个字段目前没有使用, 等待新功能的加入

/etc/group 文件格式

1
2
3
4
root:x:0:
mail:x:12:postfix
lujinkai:x:1000:
# 组名:密码:GID:以当前组为附加组的用户列表(分割符为逗号)

/etc/gshadow 文件格式

1
2
3
4
root:::
mail:::postfix
lujinkai:!::
# 组名:组密码:组管理员
  • 组密码

    通常不设置组密码, 为空或者 ! 都表示该群组没有组密码

  • 组管理员列表

    可以更改组密码和添加用户到群组中, 组管理员列表用逗号分隔。这个功能现在不常用了。

  • 组管理员

    该字段显示这个用户组中有哪些附加用户,和 /etc/group 文件中附加组显示内容相同,多个用户也是用逗号分隔

相关命令

getent

用来察看系统的数据库中的相关记录,系统数据库包括:ahosts、ahostsv4、ahostsv6、aliases、ethers、group、gshadow、hosts、initgroups、netgroup、networks、passwd、protocols、rpc、services、shadow

1
2
# getent database [key ...]
# getent会通过key查询整条数据, 当然, 一条数据并非只能对应一个key, 例如passwd, 一条数据的key可以是用户名, 也可以是UID
1
2
3
4
5
6
7
8
# 查询passwd
[root@centos7 ~]# getent passwd lujinkai
lujinkai:x:1000:1000:lujinkai:/home/lujinkai:/bin/bash
[root@centos7 ~]# getent passwd 1000
lujinkai:x:1000:1000:lujinkai:/home/lujinkai:/bin/bash
# 查询shadow
[root@centos7 ~]# getent shadow lujinkai
lujinkai:$6$Kmenu.bK$sIXTEMYHCL9QJ9ZLEmkeybfF6NV3p6l2m3G1SLFSgomaDOPArKcbZuUHgIunOXjMqfJ48KYbW76YvEgg1hcXs0:18475:0:99999:7:::

文件操作 vipw、vigr、pwck、grpck

尽量不要直接修改/etc/passwd、/etc/group、/etc/shadow、/etc/gshadow这四个文件。

vipw可以用来编辑/etc/passwd,vigr可以用来编辑/etc/group,它俩都有语法检查功能。

pwck用来验证/etc/passwd和/etc/shadow的内容和格式的完整性,grpck用于验证组文件的完整性。

虽然用这四个命令会比直接使用vim修改这四个文件更安全,但是也不推荐使用,了解即可。

推荐使用:useradd、groupadd、chage等命令,当然本质还是修改这四个文件。

用户创建 useradd

注: adduser 等于 useradd

1
useradd [options] LOGIN
  • -u, –uid UID

    指定uid, 不过不加-o参数, 指定的uid必须是唯一非负整数

  • -o, –non-unique

    配合-u选项, 不检查UID的唯一性

  • -g, –gid GROUP

    指定用户所属基本组, 可以是组名, 也可以是GID

  • -c, –comment COMMENT

    用户的的注释, 要简短一些

  • -d, –home-dir HOME_DIR

    指定用户的家目录

  • -s, –shell SHELL

    指定用户的默认shell, 可从/etc/shells中选择, 如果是给服务用, 指定/sbin/nologin

  • -G, –groups GROUP1[,GROUP2,…[,GROUPN]]]

    指定用户的附加组, 组须是已存在的

  • -N, –no-user-group

    不创建私用组作为主组, 使用users组做主组

  • -r, –system

    创建系统用户 centos6之前: UID < 500, centos7之后: UID < 1000
    使用这个参数, 不会自动创建家目录和邮件目录

  • -m, –create-home

    创建家目录, 用于系统用户

  • -M, –no-create-home

    不创建家目录, 用于非系统用户

  • -p, –password PASSWORD

    指定密码, 必须是加密过后的

创建用户相关文件

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

useradd命令默认值设置在 /etc/default/useradd

1
2
3
4
5
6
7
8
# useradd defaults file
GROUP=100 # 如果useradd没有指定组,并且/etc/login.defs中的USERGROUPS_ENAB为no或者useradd使用了-N选项时,此时该参数生效。
HOME=/home # 家目录放在此目录下
INACTIVE=-1 # 对应/etc/shadow文件第7列, 即用户密码过期的宽限期, -1表示不过期
EXPIRE= # 对应/etc/shadow文件第8列,即用户账号的有效期, 不设置表示不启用
SHELL=/bin/bash
SKEL=/etc/skel
CREATE_MAIL_SPOOL=yes

/etc/skel/ 是模板目录,骨架目录。每新建一个用户的家目录,就会把/etc/skel/下的文件拷贝一份到家目录下。

1
2
3
4
5
6
7
[root@centos7 skel]# ls -lia /etc/skel/
total 24
134321114 drwxr-xr-x. 2 root root 62 Jul 29 17:08 .
134320193 drwxr-xr-x. 73 root root 8192 Aug 1 17:49 ..
134360296 -rw-r--r--. 1 root root 18 Apr 1 10:17 .bash_logout
134360297 -rw-r--r--. 1 root root 193 Apr 1 10:17 .bash_profile
134360298 -rw-r--r--. 1 root root 231 Apr 1 10:17 .bashrc

/etc/login.defs

配合/etc/passwd和/etc/shadow来对用户进行一些限制 但是优先级低于/etc/passwd和/etc/shadow.

如果有冲突的地方,系统会以/etc/passwd和/etc/shadow为准.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@centos7 skel]# egrep -v '^[ ]*$|^#' /etc/login.defs
MAIL_DIR /var/spool/mail
PASS_MAX_DAYS 99999
PASS_MIN_DAYS 0
PASS_MIN_LEN 5
PASS_WARN_AGE 7
UID_MIN 1000
UID_MAX 60000
SYS_UID_MIN 201
SYS_UID_MAX 999
GID_MIN 1000
GID_MAX 60000
SYS_GID_MIN 201
SYS_GID_MAX 999
CREATE_HOME yes
UMASK 077
USERGROUPS_ENAB yes
ENCRYPT_METHOD SHA512

批量创建用户

1
newusers passwd 用户文件

用户文件:指定包含用户信息的文本文件,文件格式要与/etc/passwd相同

批量修改用户密码 chpasswd

1
echo username:passwd | chpasswd

生成密码:

  • CentOS 6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# grub-crypt 是centos6中的命令, 可以对口令进行加密, 默认加密方式是 sha-512
[root@centos6 ~]# grub-crypt --help
Usage: grub-crypt [OPTION]...
Encrypt a password.

-h, --help Print this message and exit
-v, --version Print the version information and exit
--md5 Use MD5 to encrypt the password
--sha-256 Use SHA-256 to encrypt the password
--sha-512 Use SHA-512 to encrypt the password (default)

Report bugs to <bug-grub@gnu.org>.
EOF
[root@centos6 ~]# grub-crypt
Password:
Retype password:
$6$O4ufCj1vTKW/7Ko7$p9rV3m0dsEsr0ebCyOVN.togh1fVhQCCDBsoc.RkelfWnRrIm3W5vVPuB86oOKo1Yei0QKxO2MRMoX2qzHV7M1
[root@centos6 ~]# useradd -p '$6$O4ufCj1vTKW/7Ko7$p9rV3m0dsEsr0ebCyOVN.togh1fVhQCCDBsoc.RkelfWnRrIm3W5vVPuB86oOKo1Yei0QKxO2MRMoX2qzHV7M1' test
[root@centos6 ~]# getent shadow test
test:$6$O4ufCj1vTKW/7Ko7$p9rV3m0dsEsr0ebCyOVN.togh1fVhQCCDBsoc.RkelfWnRrIm3W5vVPuB86oOKo1Yei0QKxO2MRMoX2qzHV7M1:18475:0:99999:7:::

  • CentOS 7
1
2
3
4
5
# CentOS 7中没有直接命令能加密sha-512口令, 可以使用python
[root@centos7 ~]#python -c 'import
crypt,getpass;pw="magedu";print(crypt.crypt(pw))'
$6$pt0SFMf6YqKea3mh$.7Hkslg17uI.Wu7BcMJStVVtkzrwktXrOC8DxcMFC4JO1igrqR7VAi87H5PH
OuLTUEjl7eJqKUhMT1e9ixojn1
  • CentOS 8
1
2
3
4
5
6
7
8
# -6 表示sha-512加密方式, CentOS7中只有-1(md5)加密方式
[root@centos8 ~]# whatis passwd
openssl-passwd (1ssl) - compute password hashes
passwd (1) - update user's authentication tokens
passwd (5) - password file
[root@centos8 ~]# man openssl-passwd
[root@centos8 ~]# openssl passwd -6 123456
$6$vQQo/2Ie/NqmeTqp$o6kCsDtZwNtW7rLh/LEk8yA26sYW4Kmja7uk/pLp..cNe77btZf3tRxeqtSwgoGKzc5GgXJT9NIpXNShQ9L7r0
  • Ubuntu
1
2
3
4
5
6
7
8
9
10
[root@ubuntu1804 ~]#echo wang:centos |chpasswd
[root@ubuntu1804 ~]#passwd wang <<EOF
> centos
> centos
> EOF
Enter new UNIX password: Retype new UNIX password: passwd: password updated
successfully
[root@ubuntu1804 ~]#echo -e 'magedu\nmagedu' | passwd wang
Enter new UNIX password: Retype new UNIX password: passwd: password updated
successfully

修改用户 usermod

修改用户属性, 不过用户一旦创建完了, 很少会再修改, 所以usermod几乎不用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 格式
usermod [OPTION] login
# 常见选项
-u UID: 新UID
-g GID: 新主组
-G GROUP1[,GROUP2,...[,GROUPN]]]:新附加组,原来的附加组将会被覆盖;若保留原有,则要同时使用-a选项
-s SHELL:新的默认SHELL
-c 'COMMENT':新的注释信息
-d HOME: 新家目录不会自动创建;若要创建新家目录并移动原家数据,同时使用-m选项
-l login_name: 新的名字
-L: lock指定用户,在/etc/shadow 密码栏的增加 !
-U: unlock指定用户,将 /etc/shadow 密码栏的 ! 拿掉
-e YYYY-MM-DD: 指明用户账号过期日期
-f INACTIVE: 设定非活动期限,即宽限期

删除用户 userdel

1
2
3
4
5
# 格式
userdel [OPTIONS]... Login
# 常见选项
-f --force 强制
-r --remove 删除用户家目录和邮箱

查看用户相关ID信息

1
2
3
4
5
6
7
8
# id [OPTION]... [USER]
# -u
# -g
# -G
[root@centos8 ~]# id -u
0
[root@centos8 ~]# id -u lujinkai
1000

切换用户 su

su 即 switch user

两种切换的方式:

  • su UserName: 非登录式切换, 即不会读取目标用户的配置文件,不改变当前工作目录,即不完全切换
  • su - UserName: 登录式切换, 会读取目标用户的配置文件,切换至自已的家目录,即完全切换

注意:su 切换新用户后,使用 exit 退回至旧的用户,而不要再用 su 切换至旧用户,否则会生成很多的bash子进程,环境可能会混乱。

修改用户密码 passwd

1
passwd [OPTIONS] UserName
1
2
3
4
5
6
7
8
9
10
-d:删除指定用户密码
-l:锁定指定用户
-u:解锁指定用户
-e:强制用户下次登录修改密码
-f:强制操作
-n mindays:指定最短使用期限
-x maxdays:最大使用期限
-w warndays:提前多少天开始警告
-i inactivedays:非活动期限
--stdin:从标准输入接收用户密码,Ubuntu无此选项

修改用户密码策略 chage

1
chage [OPTION]... LOGIN
1
2
3
4
5
6
7
-d LAST_DAY #更改密码的时间
-m --mindays MIN_DAYS
-M --maxdays MAX_DAYS
-W --warndays WARN_DAYS
-I --inactive INACTIVE #密码过期后的宽限期
-E --expiredate EXPIRE_DATE #用户的有效期
-l 显示密码策略

用户相关的其他命令

  • chfn 指定个人信息, 这个命令修改的是/etc/passwd的第5个字段
  • chsh 指定shell, 相当于usermod -s
  • flnger 可以查看用户个人信息

这几个命令用的不多, 了解即可, flnger命令在CentOS8中已经没有了

创建组

1
groupadd [OPTIONS]... group_name
  • -g GID : 指明GID
  • -r : 创建系统组, CentOS 6之前: ID<500,CentOS 7以后: ID<1000

范例: groupadd -g 48 -r apache

修改组

groupmod 修改组的属性, 用的不多

1
groupmod [OPTIONS]... group
  • -n group_name : 新名字
  • -g GID : 新GID

删除组 groupdel

1
groupdel [options] GROUP

只有当组下没有用户后, 才能删除成功

更改组密码 和 添加删除附加组成员

gpasswd 命令, 可以更改密码, 也可以修改附加组的成员关系。

1
gpasswd [OPTIONS] GROUP
  • -a user : 将user添加到指定组中

  • -d user : 从指定附加组中移除用户user

  • -M user1,user2,user3… : 设置组成员列表, 会覆盖已有的组成员列表

  • -A user1, user2, user3 … : 设置有组管理员列表

    设置管理员的之前, 这些用户必须已经在组内了, 管理员有权限往组内添加用户

临时切换主组

newgrp 把用户的主组临时切换到附加组

这个命令用的不多, 了解一下就行

更改和查看组成员

  • groupmems 可以管理附加组的成员关系 (只有root用户可以执行这个命令)
1
2
3
4
5
6
7
8
# 格式
groupmems [options] [action]
# 常见选项
-g, --group groupname #更改为指定组 (只有root)
-a, --add username #指定用户加入组
-d, --delete username #从组中删除用户
-p, --purge #从组中清除所有成员
-l, --list #显示组成员列表

范例:

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@centos7 ~]# getent group lujinkai
lujinkai:x:1000:lujinkai
[root@centos7 ~]# groupmems -g lujinkai -a test
[root@centos7 ~]# getent group lujinkai
lujinkai:x:1000:lujinkai,test
[root@centos7 ~]# groupmems -g lujinkai -l
lujinkai test
[root@centos7 ~]# groupmems -g lujinkai -d test
[root@centos7 ~]# getent group lujinkai
lujinkai:x:1000:lujinkai
[root@centos7 ~]# groupmems -g lujinkai -p
[root@centos7 ~]# getent group lujinkai
lujinkai:x:1000:
  • groups 可以查看用户所属组的列表
1
2
3
# test用户所属的组有两个 test 和 lujinkai, test是主组 lujinkai是附加组
[root@centos7 ~]# groups test
test : test lujinkai

练习

1.创建用户gentoo,附加组为bin和root,默认shell为/bin/csh,注释信息为”Gentoo Distribution”

1
2
3
4
5
[root@centos7 ~]# useradd gentoo -G bin,root -s /bin/csh -c "Gentoo Distribution"
[root@centos7 ~]# getent passwd gentoo
gentoo:x:1003:1003:Gentoo Distribution:/home/gentoo:/bin/csh
[root@centos7 ~]# groups gentoo
gentoo : gentoo root bin

2.创建下面的用户、组和组成员关系:
名字为webs 的组
用户nginx,使用webs 作为附加组
用户varnish,使用webs 作为附加组
用户mysql,不可交互登录系统,且不是webs 的成员,nginx,varnish,mysql密码都是magedu