4. Linux用户与权限管理:用户与用户组管理、sudo权限配置、PAM模块简介、ACL访问控制
说实话,权限管理这块,是很多运维事故的根源。我见过太多因为权限配置不当,导致整个服务被误删、配置文件被篡改的案例。今天咱们就把这块彻底捋清楚。
4.1 用户与用户组管理
Linux是个多用户系统,这个大家都知道。但你真的理解用户和用户组的关系吗?
用户,说白了就是一个身份凭证。每个用户都有一个唯一的UID。用户组呢,就是一群用户的集合。一个用户可以属于多个组,但只有一个主组。
4.1.1 用户管理核心命令
useradd — 创建用户
我个人习惯用这个命令创建用户:
# 创建用户并指定家目录和shell
useradd -m -d /home/devops -s /bin/bash devops
# 创建系统用户(无家目录,不能登录)
useradd -r -s /sbin/nologin appuser
这里有个坑,我曾经遇到过:不加 -m 参数,有些系统不会自动创建家目录。结果用户登录后直接进了根目录,一脸懵。
usermod — 修改用户属性
# 修改用户的主组
usermod -g devgroup devops
# 将用户添加到多个附加组
usermod -G docker,www-data devops
# 锁定用户(不让登录)
usermod -L devops
# 解锁用户
usermod -U devops
你想想看,为什么要有附加组?举个例子,一个开发人员,他既属于开发组,又需要访问docker组。这时候附加组就派上用场了。
userdel — 删除用户
# 删除用户,保留家目录
userdel devops
# 删除用户及其家目录、邮件池
userdel -r devops
4.1.2 用户组管理
groupadd — 创建组
# 创建普通组
groupadd devgroup
# 创建系统组(GID小于1000)
groupadd -r sysgroup
groupmod — 修改组
# 修改组名
groupmod -n newgroup oldgroup
# 修改GID
groupmod -g 2000 devgroup
groupdel — 删除组
groupdel devgroup
groups 用户名 或者 id 用户名。我经常用 id 命令,因为它还能显示UID和GID。
4.2 sudo权限配置
为什么要用sudo?说白了,就是让普通用户能执行管理员命令,但又不用把root密码告诉所有人。
sudo的配置文件在 /etc/sudoers。注意,千万别直接编辑这个文件!要用 visudo 命令。它会检查语法,防止你把自己锁在外面。
4.2.1 基本配置语法
# 用户 主机=(可切换用户) 命令
root ALL=(ALL:ALL) ALL
# 让devops用户能以任何用户身份执行任何命令
devops ALL=(ALL:ALL) ALL
# 让devops组的成员能执行所有命令,但需要输入密码
%devops ALL=(ALL:ALL) ALL
# 让devops用户无需密码就能重启nginx
devops ALL=(root) NOPASSWD: /usr/bin/systemctl restart nginx
嗯,这里要注意。我曾经给一个开发人员配置了 NOPASSWD: ALL,结果他写脚本时不小心执行了 sudo rm -rf /。虽然现在系统有保护机制,但那次还是吓得我够呛。
4.2.2 实战配置示例
我一般这样配置:
# 创建运维组
groupadd -r ops
# 给运维组配置sudo权限
%ops ALL=(ALL) /usr/bin/systemctl, /usr/bin/journalctl, /usr/bin/tail
# 限制只能查看日志,不能修改
%ops ALL=(root) /usr/bin/tail /var/log/*.log
核心原则: 最小权限原则。只给用户完成工作所需的最小权限。别图省事直接给ALL。
4.3 PAM模块简介
PAM,全称Pluggable Authentication Modules。说白了,就是Linux的认证框架。它把认证过程模块化了,你想用密码认证、指纹认证、还是LDAP认证,都行。
PAM的配置文件在 /etc/pam.d/ 目录下。每个服务都有自己的配置文件,比如 sshd、login、sudo。
4.3.1 PAM配置语法
# 类型 控制标志 模块路径 参数
auth required pam_unix.so
account required pam_unix.so
password required pam_unix.so
session required pam_unix.so
控制标志有几种:
- required:必须通过,但失败后不立即返回,等所有模块执行完
- requisite:必须通过,失败后立即返回
- sufficient:如果通过,不再执行后续模块
- optional:可选,不影响结果
4.3.2 实战案例:限制root远程登录
我记得有一次,服务器被暴力破解,root密码差点被攻破。后来我通过PAM配置,直接禁止root远程登录:
# 编辑 /etc/pam.d/sshd
# 添加这一行
auth required pam_listfile.so onerr=succeed item=user sense=deny file=/etc/ssh/denyusers
# 创建 /etc/ssh/denyusers 文件,写入 root
echo "root" >> /etc/ssh/denyusers
这样配置后,root用户只能从本地登录,远程SSH直接拒绝。安全多了。
cp /etc/pam.d/sshd /etc/pam.d/sshd.bak 先备份。
4.4 ACL访问控制
传统的Linux权限只有三种:所有者、所属组、其他人。但实际工作中,这远远不够。比如,一个文件我想让两个不同的用户都有读写权限,但又不属于同一个组。这时候ACL就派上用场了。
ACL,全称Access Control List。它允许你为任意用户或组设置权限。
4.4.1 启用ACL
首先,文件系统要支持ACL。现在大部分Linux发行版默认就支持。如果不支持,可以这样挂载:
mount -o remount,acl /
4.4.2 设置ACL权限
# 给用户zhangsan设置读写权限
setfacl -m u:zhangsan:rw /data/project/logs
# 给组devgroup设置读权限
setfacl -m g:devgroup:r /data/project/logs
# 移除用户权限
setfacl -x u:zhangsan /data/project/logs
# 查看ACL权限
getfacl /data/project/logs
4.4.3 实战:共享目录权限管理
我在项目中遇到过这样一个场景:多个开发人员需要共享一个日志目录,但每个人只能看自己的日志文件。用传统权限根本搞不定。ACL轻松解决:
# 创建共享目录
mkdir -p /data/shared/logs
# 设置默认ACL,新创建的文件自动继承
setfacl -d -m u::rwx,g::rx,o::--- /data/shared/logs
# 给特定用户设置权限
setfacl -m u:zhangsan:rwx /data/shared/logs
setfacl -m u:lisi:rwx /data/shared/logs
# 查看效果
getfacl /data/shared/logs
关键点: 使用 -d 参数设置默认ACL,这样新创建的文件和目录会自动继承ACL权限。否则每次新建文件都要手动设置,太麻烦了。
4.4.4 ACL的mask机制
这里有个容易踩的坑。ACL有一个mask值,它限制了所有用户和组的最大权限。比如:
# 设置mask为只读
setfacl -m m::r /data/project/logs
# 这时候即使给用户设置了rwx,实际权限也只有r
setfacl -m u:zhangsan:rwx /data/project/logs
getfacl /data/project/logs
# 输出显示:user:zhangsan:rwx #effective:r--
为什么会这样?因为mask限制了。我刚开始用ACL时就被这个坑过,给用户设置了全部权限,结果还是写不进去。排查了半天才发现是mask的问题。
chmod 命令修改文件权限时,会重置mask值。所以如果你用了ACL,尽量用 setfacl 来管理权限。
好了,用户与权限管理这块,核心内容就这些。记住几个原则:最小权限、按需分配、定期审计。下一章咱们聊聊进程管理和系统监控,这些都是运维的日常操作。