了解如何利用 Linux 文件安全系统和共享数据
更多精彩
- 更多技术博客,请移步 IT人才终生实训与职业进阶平台 - 实训在线
7.1 Linux 的安全性
- Linux 安全系统的核心是用户账户
7.1.1 /etc/passwd 文件
-
/etc/passwd
是 Linux 中用于存放用户登录信息的文件,如下图- 在该文件中将用户的登录名与对应的 UID 进行匹配
- 在该文件中通常会存在很多账户,但有些账户并不是真的用户,例如 mail
- 这类账户是 Linux 为各种功能创建的用户账户,叫做 系统账户
- 这类账户用于运行对应服务进程,及访问对应服务资源
- 所有运行在后台的服务都需要使用这样的 系统账户 进行访问
- 使用 系统账户 操作对应后台服务的原因是为了防止服务被攻陷时,被非法拿到过多的系统控制权
- 系统账户 的 UID 一般都是在 500 以内,这是 Linux 为 系统账户 预留的范围
-
每个用户信息的各种内容使用冒号分隔,每个冒号之间内容的具体含义如下
-
/etc/passwd
是一个标准的文本文件,所以其实可以手动在文件内部对用户进行增加或删除- 但及其不推荐这样做,因为如果因为操作错误导致文件损坏,会直接影响到这个系统的用户管理,甚至 root 用户都无法登录
7.1.2 /etc/shadow 文件
- 在
/etc/passwd
中看到的用户密码都是一个符号x
,这是因为该文件是所有登录用户都有权访问的文件,处于安全考虑,将真正的密码存放在了只有 root 用户才能访问的/etc/shadow
中 -
文件的完整内容如下图
-
每个用户密码的各种内容使用冒号分隔,每个冒号之间的内容具体含义如下
7.1.3 useradd 命令添加新用户
-
useradd
命令可以一次性创建新用户账户,以及设置用户 HOME 目录结构- 如果在执行命令时不添加任务指令,就会直接调用系统默认值对新用户进行配置
- 系统默认值被存放在
/etc/default/useradd
文件中,如下图- 使用
useradd -D
也可以查看系统默认值
- 使用
-
对于上述这些默认值的解释,如下图
- 关于上图中的第 6 条,
/etc/skel
目录下有哪些文件,如下图- 可以看到,这些就是在第 6 章中介绍过的 用户启动文件
- 所以这个操作是为了将系统默认的 用户启动文件 直接给予新用户
7.1.3.1 useradd 命令直接创建用户
- 使用
useradd username
直接创建用户,如下图- 书中提到说如果直接创建用户,系统不会为用户创建 HOME 目录,需要使用
useradd -m username
才会创建 HOME 目录 - 但实测发现即时不加
-m
指令,新用户的 HOME 目录也被创建了,并且目录下被复制了/etc/skel
中的文件
- 书中提到说如果直接创建用户,系统不会为用户创建 HOME 目录,需要使用
- 需要注意的是,这样创建的用户默认没有配置密码,所以也无法直接登录,目前只能先用 root 账户登录,再通过
su username
切换到该用户,后续会介绍如何在创建用户后,为新用户指定密码
7.1.3.2 useradd -D 命令查看并修改新建用户默认值
- 使用
useradd -D
命令可以查看新建用户的默认值,这一点在上文中已经演示过 - 如果在
useradd -D
命令后再添加指令,则可以实现对这些默认值的修改,如下图- 通过
-s
指令,将新建用户的默认 shell 改成了 dash shell
- 通过
-
useradd -D
命令可使用的指令列表如下图
7.1.4 userdel 命令删除用户
- 使用
userdel username
命令可以直接删除用户,但只会删除/etc/passwd
中的用户信息,该用户对应的 HOME 目录以及其他相关的文件,都不会删除 - 使用
userdel -r username
命令则可以再删除用户的时候,将该用户对应的 HOME 目录以及邮件都删除- 但除了这两个目录之外的其他和这个用户相关的文件、目录依旧不会被删除
- 例如由这个用户创建的文件、目录,依旧会存在于系统中
- 如下图,就是使用
userdel asing1elife
命令来删除刚刚创建的用户- 直接使用
userdel asing1elife
命令删除用户后,依旧可以查询到该用户的 HOME 目录 - 但再次使用
userdel -r asing1elife
命令删除用户时,提示用户不存在,说明用户在/etc/passwd
中的信息确实被删除了 - 之后再次创建用户,直接使用
userdel -r asing1elife
命令删除用户,并再次查询用户的 HOME 目录,则找不到该目录
- 直接使用
7.1.5 修改用户
7.1.5.1 usermod 命令修改用户信息
- 使用
usermod
命令可以修改用户在/etc/passwd
中的大部分信息,如下图
- 使用
usermod -c comment username
命令就可以修改用户的备注信息,如下图
- 使用
usermod -p password username
命令更改用户密码,但实际不行,如下图- 使用
passwd asing1elife
命令可以对用户密码进行更改,之后查看/etc/shadow
可以看到该用户加密后的密码信息 - 使用
usermod -p teamnote asing1elife
命令再次对用户密码进行更改,之后查看/etc/shadow
可以看到该用户的密码信息变成了明文的 teamnote - 这是因为
usermod -p
命令需要指定的是加密后的用户密码,所以这非常不实用,一般修改密码还是会用passwd
命令
- 使用
- 使用
usermod -L username
命令可以锁定指定用户,禁止用户登录,使用usermod -U username
命令则可以解锁指定用户,允许用户登录,如下图- 可以看到,左侧通过 root 用户使用
usermod -L asing1elife
命令锁定了该用户,右侧该用户尝试登录时就算密码输入正确,依旧提示 Permission denied ,表示无法登录 - 之后左侧通过 root 用户使用
usermod -U asing1elife
命令解锁勒该用户,右侧该用户再次尝试登录就可以顺利登录成功
- 可以看到,左侧通过 root 用户使用
-
usermod -g
命令和usermod -G
命令在使用上存在本质区别,如下图-
usermod -g
命令用于修改用户的默认组 -
usermod -G
命令用于为用户添加新组 - 使用
useradd asing1elife
命令创建新用户后,可以查看该用户的 主要用户组 是随用户一起创建的 GID 是 1001 的 asing1elife 组 - 使用
usermod -g shared asing1elife
命令将用户的 主要用户组 修改为 GID 是 1000 的 shared 组 - 使用
usermod -G asing1elife asing1elife
命令将 asing1elife 用户组重新赋予该用户,查看/etc/group
可以看到 asing1elife 组中有一个组成员是 asing1elife 用户 - 至于为什么在
/etc/group
中,shared 组最后没有显示组成员信息,而 asing1elife 组显示了组成员信息,在后续 7.2.1 /etc/group 文件 章节中会有详细解析
-
7.1.5.2 passwd 修改用户密码
- 每个用户都可以修改自己的密码,但只有 root 用户可以修改其他用户的密码
- 使用
passwd username
命令可以直接修改指定用户的密码,如下图- 可以看到,在修改密码时会给予非常友好的操作步骤和提示
- 密码必须大于等于 8 个字符
- 密码不能太简单,比如 12345678 就无法通过验证
- 密码不能和用户名一样
-
一次修改最多尝试三次就会被中止
- 使用
passwd -e username
命令可以强行终止用户的密码使用期限,具体表现为用户下次登录时系统会提示必须修改密码,如下图- 左侧通过 root 用户使用
passwdw -e asing1elife
命令终止了该用户的密码使用期限 - 右侧当该用户尝试使用当前密码进行登录时,虽然登录成功,但系统强制弹出了修改密码的操作
- 首先需要输入一遍当前的密码,验证正确后,再输入新密码
- 并且新密码会有基本验证,不能和之前的密码太相似,也不能和之前的密码一样
-
新密码修改成功后,用户的当前连接会被终止,需要使用新密码再次登录
- 左侧通过 root 用户使用
7.1.5.3 chpasswd 批量修改用户密码
- 使用
chpasswd < fileName
命令,可以从指定文件中批量读取用户的username:password
键值对,然后修改这些用户的密码,如下图- 左侧通过 root 用户创建了 userpwd 文件,并写入了两个
username:password
键值对 - 之后使用
chpasswd < userpwd
命令执行了该文件,相当于同时修改了这两个用户的密码 -
右侧这两个用户通过新密码顺利登录成功
- 左侧通过 root 用户创建了 userpwd 文件,并写入了两个
7.1.5.4 chsh 命令修改用户的默认 shell
- 使用
chsh -s absolutePathShell username
命令可以修改用户的默认 shell ,如下图- absolutePathShell 表示指定的 shell 必须是完整路径,例如
/bin/zsh
,不能只是 shell 的名称,例如 zsh - 可以看到,一开始在
/etc/passwd
中,用户 asing1elife 的默认 shell 是/bin/bash
- 之后在
/etc/shells
中查看了当前系统可用的 shell 类型,找到了/bin/zsh
- 使用
chsh -s /bin/zsh asing1elife
将用户的 shell 类型修改为 zsh - 提示修改成功后再次查看
/etc/passwd
可以看到用户的默认 shell 确实是/bin/zsh
- absolutePathShell 表示指定的 shell 必须是完整路径,例如
7.1.5.5 chfn 命令修改用户备注信息
- 使用
chfn asing1elife
命令可以修改用户备注信息,你可能会问这和usermod -c comment asing1elife
命令有什么区别? - 区别在于
chfn
命令可以会详细的询问该用户的信息,如下图,而usermod -c
命令只接受填入一个字符串- 在修改成功后,系统提示 Finger information changed ,这是因为
chfn
命令其实是将用于 Unix 的finger
命令的信息存入了备注字段 - 之后尝试使用
finger asing1elife
命令查看对应信息,被告知该命令不存在,因为大部分 Linux 系统默认都没有安装该命令
- 在修改成功后,系统提示 Finger information changed ,这是因为
- 可以使用
yum intall -y finger
命令在线安装该命令到当前系统中,之后再使用finger asing1elife
命令就可以看到上述通过chfn
命令输入的用户备注信息了,如下图- 这里输入
yum intall -y finger
命令后提示已安装,是因为我刚才装的,本身下图中的 Linux 系统是没有安装该命令的
- 这里输入
7.1.5.6 chage 命令管理用户有效期
- 使用
chage
命令可以通过各种指令改变用户在/etc/shadow
中的各种信息,如下图
- 使用
chage -d 20 asing1elife
命令可以将用户上次修改密码的天数改为 20 天,如下图- 同时,使用
chage -d 2019-12-01 asing1elife
命令可以将用户上次修改密码的天数改为自 1970-01-01 到 2019-12-01 - 可以看到第三个字段一直在变化,这个字段就是用来记录用户自上次修改密码后经过的天数,默认是从 1970-01-01 开始计算
-
chage
命令的日期值可以使用天数( 需要从 1970-01-01 开始计算才有意义,但不是强制的 )或者 YYYY-MM-DD 格式的日期值
- 同时,使用
- 使用
chage -E 2019-12-01 asing1elife
命令可以设置用户密码过期的日期,也就是账户被禁用的日期,如下图- 可以看到
/etc/shadow
中用户信息的倒数第二个字段发生了变化,和正数第三个字段之间只差一天,说明这个用户明天就过期了
- 可以看到
- 使用
chage -E
命令可以实现为系统创建临时用户的效果,如下图- 左侧 root 用户使用
chage -E 2019-11-30 asing1elife
命令为该用户设置了一个在今天之前的日期,表示该用户已经过期了 -
右侧该用户尝试登录时系统就会告知账户已经过期,请联系系统管理员,并自动关闭连接
- 左侧 root 用户使用
- 使用
chage -I 3 asing1elife
命令可以设置用户密码过期多少天后禁止用户登录,如下图- 可以看到倒数第三个字段发生了变化,变成了命令设置的数字
- 我本来认为这个字段控制的日期应该为影响到通过
-E
指令指定的过期日期 - 比如通过
-E
指令指定 2019-11-30 日过期,之后再通过-I
指令指定密码过期 3 天后禁止登录,那么实际的禁止用户登录的日期应该是 2019-12-03 -
但实测发现不是,用户依旧无法登录
- 使用
chage -m 10 asing1elife
命令可以设置用户自上次修改密码后,至少需要经过 10 天才能再次更改密码,如下图- 左侧 root 用户使用
chage -m 10 asing1elife
命令设置用户 10 天后才能更改密码 -
右侧用户登录后尝试修改密码,被告知需要等待更长时间才能更改密码
- 左侧 root 用户使用
- 使用
chage -W 8 asing1elife
命令可以设置密码过期后多久出现提示信息,如下图-
可以看到倒数第 4 个字段发生了变化
-
- 完整的
chage
命令指令列表可以参考下图
7.2 使用 Linux 组
- 组权限允许多个用户对系统中的文件、目录共享访问
- 每个组都有唯一的 GID ,这在
/etc/passwd
的第四个字段中有体现 - 每个组除了 GID 唯一,还有唯一的组名,和用户名类似
- 用户名和 UID 的信息存放在
/etc/passwd
中,组名和 GID 的信息则存放在/etc/group
中
7.2.1 /etc/group 文件
-
/etc/group
中包含系统中用到的每个组的信息,如下图 - 和 系统账户 一样,系统组 的 GID 通常也被限制在 500 以下,而用户组的 GID 则从 500 之后开始分配
-
每组的信息具体如下图
- 对于最后一个字段:属于该组的用户列表 ,这个值得好好探讨一下,如下图
- 在
/etc/passwd
查看 asing1elife 用户的组信息,可以看到该用户属于 GID 为 1000 的组,对应的组名也是 asing1elife 组 - 但是在
/etc/group
的 asing1elife 组最后一个字段中没有出现该用户的名字 - 之后新建一个用户,默认在 GID 为 1001 的组,使用
usermod -g asing1elife 3umb1ebee
将用户 3umb1ebee 切换到 asing1elife 组 - 再次查看
/etc/group
的 asing1elife 组,发现最后一个字段依旧没有值,这是为什么呢???
- 在
- 这是因为,当一个用户将某个组作为默认组时,这个用户就不会出现在 /etc/group 中对应组的组成员列表下
- 用户 asing1elife 和 3umb1ebe 的默认组都是 GID 为 1000 的 asing1elife 组,所以在该组的组成员列表中这两个用户都不会出现
- 依据上面的描述,还有一点需要注意的,不要直接在 /etc/group 中对将用户加入到对应组的组成员中 ,应该使用
usermod -g
命令来修改对应用户的组信息
7.2.2 groupadd 命令创建新组
- 使用
groupadd
命令可以创建一个新的用户组,如下图- 在创建新组时,默认没有用户被分配到该组
-
groupadd
命令也没有提供添加用户到指定组中的指令 - 要添加用户到指定组中,需要使用
usermod -G
命令,这个在 7.1.5.1 usermod 命令修改用户信息 章节中有详细解析
7.2.3 groupmod 命令修改组
- 使用
groupmod
命令可以修改指定的组的信息,如下图-
-g
指令可以修改指定组的 GID -
-n
指令可以修改指定组的名称 -
-p
指令和usermod -p
命令一样不实用
-
- 使用
groupmod -g
命令修改指定组的 GID 时,属于该组的用户对应的组信息也会随之更改,如下图- 可以看到 asing1elife 用户的默认组是 shared ,同时也属于 asing1elife 组
- 使用
groupmod -g 1002 asing1elife
命令将 asing1elife 组的 GID 从 1001 修改为 1002 后,asing1elife 用户依旧属于该组 - 使用
groupmod -g 1001 shared
命令将 shared 组的 GID 从 1000 修改为 1001 后,asing1elife 用户的默认组信息也随之修改为 1001
7.3 理解文件权限
7.3.1 使用文件权限符
- 使用
ls -l
命令获取文件信息列表时,信息的第一个字段就是 文件权限符 ,如下图-
ll
命令是使用alias
命令做的ls -l
命令的别名
-
- 文件权限符 看上去很难懂,详细解析如下图
- 通过下图的解析,可以得知上图中的 teamnote 是一个目录
- teamnote 目录的所属用户对该目录拥有可读、可写、可执行的完整权限
- teamnote 目录的所属用户组对该目录拥有可读、可执行的部分权限
-
当前系统中的其他用户( 既不是 root 用户,也不属于 root 用户组 )对于 teamnote 目录拥有可读、可执行的部分权限
7.3.2 umask 命令设置默认文件权限
- 使用
umask
命令可以设置创建文件或目录时的默认权限,但设置方式比较复杂,当我们直接使用umask
命令尝试获取当前系统的默认文件权限时,得到的数值仅仅只是一个 掩码 ,想用从这个掩码中得到真正的文件权限需要经过好几次换算 -
查看系统默认文件权限的方式如下图
- 那么 0022 和上述新建文件、目录的权限之间是如何关联起来的,如下图
-
完整的 Linux 文件权限码对照图如下
7.3.2.1 使用 umask 命令修改默认文件权限
- 通过上述图示了解了 umask 值的转换规则后,可以来尝试修改默认文件权限
- 现在已经可以知道,默认的 022 掩码表示的文件权限是 644 ,目录权限是 755
- 那么如果想要把默认的文件权限改成 640 ,具体权限为
rw-r-----
,需要设置的掩码是多少? - 使用文件的完整权限 666 ,减去真实的文件权限 640 ,得到的掩码值是 026
- 所以使用
umask 026
命令就可以实现预期效果,如下图- 可以看到,testFile 文件的权限值和我们预期的一模一样
- 同时需要注意的是,目录和文件使用的掩码是同一个,所以当通过文件的真实权限得到对应掩码后,其实默认目录的权限也会随之更改
- 比如下图中 testDir 目录的权限是
rwxr-x--x
,对应的真实权限是 751 ,其实也就是目录的完整权限 777 ,减去掩码 026 后得出的值
7.4 改变安全性设置
7.4.1 chmod 命令改变权限
- 使用
chmod
命令可以改变文件或目录的权限,如下图- 和
umask
命令不同的是,chmod
命令可以直接通过对应权限的八进制值进行设置,不需要使用掩码 -
chmod 777
命令就是赋予对象完整权限
- 和
- 上述对
chmod
命令的使用方式其实是 八进制模式 - 而
chmod
命令还支持另外一种 符号模式
7.4.1.1 chmod 命令使用符号模式改变权限
- 符号模式 相对于 八进制模式 要复杂的多,可选指令组合如下图
- 了解 符号模式 对应的指令组合之后,可以尝试修改一下文件权限,如下图
- testFile 文件本来拥有完整权限,现在使用
chmod o=r testFile
命令将其他用户的权限指定为只读,之后使用ll
命令可以看到生效了 - 再使用
chmod o+wx testFile
命令重新加可写、可执行权限赋予其他用户,之后使用ll
命令可以看到生效了,说明可以同时操作指定对象的多个权限
- testFile 文件本来拥有完整权限,现在使用
7.4.1.2 chmod -R 命令递归改变权限
- 使用
chmod -R
命令可以实现递归的改变目录权限,也就是在改变根目录权限的同时,目录中所有的文件、目录都会被赋予相同的权限,如下图- testDir 目录原始的权限是 751 ,使用
chmod 711 testDir
命令后,该目录的权限发生了更改 - 但查看目录内部的 testFile1 文件的权限,并没有发生任何变化,还是 640
- 再次使用
chmod -R 755 testDir
命令修改目录权限,可以看到目录和目录内部的文件的权限变成一样的了,都是 755
- testDir 目录原始的权限是 751 ,使用
7.4.2 chown 命令和 chgrp 命令改变所属关系
- 使用
chown
命令可以改变文件、目录所属的用户,如下图- 使用
chown asing1elife testFile
命令将该文件的所属用户从 root 改为 asing1elife - 使用
chown 1000 testDir
命令将该目录的所属用户从 root 改为 asing1elife - 说明
chown
命令可以使用用户名或 UID 来改变所属用户
- 使用
- 使用
chown user.group fileName
命令还可以同时改变文件或目录的所属用户和所属用户组,如下图- 用户和用户组并不一定要有所属关联,例如 asing1elife 用户并不属于 root 用户组,但依旧可以通过
asing1elife.root
来实现将 testFile 的所属关系修改为属于 asing1elife 用户,以及 root 用户组
- 用户和用户组并不一定要有所属关联,例如 asing1elife 用户并不属于 root 用户组,但依旧可以通过
- 使用
chown -R
命令也可以实现递归修改目录的所属关系,如下图
-
chown
命令的完整功能是即可改变文件、目录的所属用户,也可以改变其所属用户组- 但只有 root 用户可以使用完整的功能
- 其他用户只能改变属于自己的文件、目录的所属用户组,而且还必须是准备改变的目标用户组的组成员
7.4.2.1 chgrp 命令改变文件、目录的所属用户组
- 使用
chgrp
命令可以改变文件、目录的所属用户组,如下图- 相比
chown
命令的强大,chgrp
命令就要弱鸡很多
- 相比
- 由于其他用户在使用
chown
命令时,也只能得到和chgrp
命令一样的效果,所以chgrp
命令更推荐非 root 用户使用
7.5 共享文件
- Linux 实现共享文件的方式是将需要共享的文件放置在相同的共享组中
- 然后属于这个共享组的用户都可以共享访问这个文件
- 具体设置太纠结了,我觉得使用场景也不丰富,所以就不实践了
7.6 小结
- Linux 通过 UID 和 GID 来限制对文件、目录的访问权限
-
/etc/passwd
文件用户存放用户信息 -
/etc/group
文件用户存放用户组信息 -
/etc/shadow
文件用户存放用户密码信息 -
useradd
命令可以创建用户 -
usermod
命令可以修改用户 -
userdel
命令可以删除用户- 通常会加上
-r
指令,用于在删除用户时,删除该用户对应的 HOME 目录
- 通常会加上
-
groupadd
命令可以创建用户组 -
groupmod
命令可以修改用户组 -
groupdel
命令可以删除用户组 - 每个文件、目录都可以为以下三个对象设置权限
- 所属用户
- 所属用户组
- 系统中其他用户
- 每个对象的权限都可以细分为以下三个等级,如果都不具备,则是用符号
-
作为占位符- 可读 r
- 可写 w
- 可执行 x
-
umask
命令可以查看和设置默认的文件、目录权限- 但设置过程比较复杂,需要先将掩码转换为真实的八进制值
- 再将三位八进制值拆分后与三个对象一一对应,找到真实的权限码
-
chmod
命令可以修改文件、目录的权限- 可以使用简单的 八进制模式
- 也可以使用复杂的 符号模式
-
chown
命令可以修改文件、目录的所属用户和所属用户组- 只有 root 用户可以修改文件、目录的所属用户
- 其他用户只能修改属于自己的文件、目录的所属用户组,而且自己还必须是目标用户组的组成员
-
chgrp
命令可以修改文件、目录的所属用户组