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
⚠️ 注意: 删除用户前,一定要确认这个用户没有正在运行的进程。我曾经在生产环境上直接删了一个用户,结果那个用户启动的Java进程还在跑,但已经查不到是谁的了。排查了半天。

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/ 目录下。每个服务都有自己的配置文件,比如 sshdloginsudo

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直接拒绝。安全多了。

💡 提示: PAM配置错误会导致无法登录系统。修改前一定要备份原文件。我习惯用 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 来管理权限。

好了,用户与权限管理这块,核心内容就这些。记住几个原则:最小权限、按需分配、定期审计。下一章咱们聊聊进程管理和系统监控,这些都是运维的日常操作。