03-用户与权限管理
完成系统安装与初始化之后,下一项基础工作就是建立可控的账号和权限体系。Linux 服务器的权限管理不是单个命令的问题,而是一套围绕身份、认证、授权、文件访问控制、提权审计和账号生命周期的治理机制。账号创建得随意、共享 root 密码、业务目录权限过宽、sudo 规则没有边界,都会让后续的。

概述
完成系统安装与初始化之后,下一项基础工作就是建立可控的账号和权限体系。Linux 服务器的权限管理不是单个命令的问题,而是一套围绕身份、认证、授权、文件访问控制、提权审计和账号生命周期的治理机制。账号创建得随意、共享 root 密码、业务目录权限过宽、sudo 规则没有边界,都会让后续的软件部署、日志审计和故障定位变得混乱。
本文是 Linux 系统管理系列第 3 篇,承接上一篇《系统安装与初始化》。前一篇已经完成主机名、网络、时间同步、防火墙、SSH 等基础配置;本文进一步说明如何把“谁能登录、能做什么、能访问哪些文件、操作如何留痕”落到日常运维流程中。
为什么用户与权限管理是安全基线的核心
权限边界
- 身份是审计的起点:所有登录、sudo、文件修改、服务启动记录都需要追溯到明确的账号。多人共享同一个管理员账号会让审计失效。
- 最小权限降低误操作半径:普通用户只拥有工作所需权限,管理员通过 sudo 临时提权,可以减少误删系统文件、误改服务配置的概率。
- 文件权限决定数据边界:业务配置、密钥、日志、脚本、备份文件的 owner、group、mode 直接决定可读写范围。
- 账号生命周期影响长期风险:离职人员、临时外包、过期项目账号如果不及时禁用,会形成长期暴露面。
- 标准化权限便于自动化:Ansible、CI/CD、备份、监控代理都依赖稳定的用户、组和目录权限模型。
学习目标
通过本文的学习,您将能够:
- 理解 Linux 用户、组、UID、GID、主组和附加组的关系。
- 掌握 useradd、usermod、passwd、chage、groupadd、id 等账号管理命令。
- 配置 sudo 最小授权,并避免直接编辑 sudoers 导致系统不可管理。
- 使用 chmod、chown、umask、ACL 管理文件访问权限。
- 建立用户创建、权限申请、定期复核、账号禁用的运维流程。
理论基础
Linux 身份模型
身份模型
Linux 将“身份”拆分为用户和组。用户用于表示执行命令、拥有文件、登录系统的主体;组用于表达一组用户对资源的共同访问权限。每个进程都有真实用户 ID、有效用户 ID、真实组 ID、有效组 ID 和附加组列表,内核在访问文件、绑定端口、修改系统资源时会根据这些身份判断是否允许操作。
常见身份文件如下:
| 文件 | 作用 | 运维关注点 |
|---|---|---|
/etc/passwd |
保存账号名、UID、GID、家目录、登录 shell 等基础信息 | 不再保存明文密码;所有用户通常可读 |
/etc/shadow |
保存密码哈希、密码有效期、账号过期字段 | 只应由 root 或受控进程读取 |
/etc/group |
保存组名、GID、组成员 | 附加组授权的主要来源 |
/etc/gshadow |
保存组密码和组管理员信息 | 普通环境很少直接维护 |
/etc/login.defs |
定义 UID/GID 范围、密码有效期、umask 等默认策略 | 不同发行版默认值可能不同 |
/etc/default/useradd |
useradd 默认家目录、shell、过期策略等 | 批量创建用户前需要检查 |
UID、GID 与账号类型
Linux 内核最终识别的是数字 UID/GID,而不是用户名。用户名只是便于人类理解的映射。因此,跨主机复制文件、挂载 NFS、迁移容器卷、恢复备份时,必须关注 UID/GID 是否一致。
常见账号类型如下:
| 类型 | 典型 UID 范围 | 典型用途 | 管理建议 |
|---|---|---|---|
| root | 0 | 超级管理员 | 禁止多人共享;SSH 通常禁用 root 直接登录 |
| 系统账号 | 通常低于普通用户范围 | 运行服务进程,如 nginx、postgres、node_exporter | 不设置可登录 shell,权限绑定到服务目录 |
| 普通账号 | 通常从 1000 开始 | 运维人员、开发人员、应用部署账号 | 明确负责人、用途、有效期 |
| 临时账号 | 视策略而定 | 外包、审计、临时排障 | 必须设置过期时间并纳入复核 |
不同发行版的 UID/GID 默认范围可能不同,实际以 /etc/login.defs、useradd -D 和发行版策略为准。不要在生产环境中假设“1000 一定是第一个普通用户”之外的更多细节。
文件权限模型
Linux 传统权限由三组对象和三类权限组成:
-rw-r----- 1 app app 2048 May 19 10:00 config.yml
│││ │││
│││ │└└─ other 权限
│││ └── group 权限
│└└──── owner 权限
└────── 文件类型
| 权限 | 对文件的含义 | 对目录的含义 |
|---|---|---|
r |
读取文件内容 | 列出目录项 |
w |
修改文件内容 | 创建、删除、重命名目录内对象 |
x |
执行文件 | 进入目录、访问目录下路径 |
目录权限尤其容易被误解。一个用户即使对某个文件有读权限,如果缺少上级目录的执行权限,也无法访问该文件路径。反过来,目录有写权限意味着可以删除目录中的文件;删除动作取决于目录权限,而不是文件本身的写权限。
特殊权限位
除普通 rwx 外,Linux 还支持 setuid、setgid 和 sticky bit:
| 权限位 | 常见表示 | 作用 | 典型场景 |
|---|---|---|---|
| setuid | u+s |
执行文件时使用文件 owner 的有效 UID | /usr/bin/passwd 需要修改 shadow |
| setgid | g+s |
执行文件时使用文件 group;目录中新文件继承目录组 | 团队共享目录 |
| sticky bit | +t |
目录内文件只能由文件 owner、目录 owner 或 root 删除 | /tmp |
特殊权限位要谨慎使用,尤其是 setuid root 程序。自研脚本一般不应通过 setuid 获取 root 权限,应该使用 sudo、systemd unit 或受控自动化平台进行授权。
sudo 与 su 的区别
su 是切换到另一个用户的会话,通常需要目标用户密码。sudo 是按规则允许某个用户以 root 或其他用户身份执行指定命令,通常使用当前用户密码并记录审计日志。生产环境更推荐 sudo,因为它可以做到按用户授权、按命令授权、按主机授权,并保留提权记录。
sudo 的核心原则是:
- 用组授权,不对每个人复制规则。
- 用
visudo修改规则,避免语法错误导致 sudo 不可用。 - 优先把自定义规则放到
/etc/sudoers.d/。 - 不要滥用
NOPASSWD,更不要给普通用户无边界的ALL=(ALL) NOPASSWD:ALL。 - 需要自动化免密时,限制到明确命令和明确参数路径。
权限治理模型
用户与权限管理不应只靠命令清单。生产环境需要先定义权限治理模型,再落到 useradd、chmod、sudo、ACL 和 systemd 配置。治理模型至少包括账号分类、权限层级、授权流程、审计记录和复核周期。
账号分类决定管理方式。个人账号用于人与系统交互,必须能追溯到自然人;服务账号用于运行进程,通常不允许交互登录;自动化账号用于 CI/CD、备份、监控、配置管理等平台调用,必须限制密钥和命令范围;临时账号用于外包、审计、排障,必须有过期时间。不同类型账号如果混用,审计很快失效。
权限层级决定风险半径。普通用户只能访问自己的家目录和授权业务目录;发布用户可以写入指定应用目录,但不能修改系统服务定义;运维用户可以查看日志、重启指定服务、执行诊断命令;平台管理员才允许管理软件包、网络、防火墙和系统级服务。把所有人都加入 sudo 或 wheel,短期方便,长期会让责任边界消失。
授权流程决定权限是否可解释。每一次提权都应能回答:谁申请,为什么需要,访问哪个系统,执行什么操作,持续多久,谁批准,何时复核。小团队可以用工单或表格,大团队可以接入 IAM、堡垒机或权限管理平台。工具不同,但原则相同:授权必须有理由、有范围、有期限、有记录。
审计记录决定事后能否还原事实。Linux 本地可以通过 sudo 日志、auth.log/secure、journald、auditd、shell history、文件时间戳等收集证据。生产环境不要依赖用户本地 history 作为唯一审计,因为它容易被清理或绕过。更可靠的方式是结合堡垒机、集中日志和 sudo/auditd 记录。
复核周期决定权限是否持续有效。账号和权限不是创建后永久有效。人员转岗、项目结束、外包退场、服务下线、自动化平台替换,都会让原权限失去必要性。建议每月至少复核高权限账号和 sudo 规则,每季度复核普通账号和服务账号,每次重大组织调整后做专项复核。
账号生命周期
账号生命周期可以分为申请、创建、授权、使用、变更、禁用、删除和归档八个阶段。
申请阶段要明确用途。一个账号是给人登录、给服务运行,还是给自动化平台使用,决定了它是否需要家目录、登录 shell、密码、SSH key、sudo 权限和过期时间。不要先创建账号,再补用途说明。
创建阶段要遵守命名规范。个人账号建议与企业身份一致,例如拼音、工号或统一账号名;服务账号可以使用 svc_应用名 或应用专用名称;自动化账号可以使用 bot_用途 或平台统一命名。命名不是形式问题,它影响审计和批量管理。
授权阶段要遵守最小权限。给用户加入组、配置 sudo、授权目录、写入 SSH key,都应只覆盖当前工作需要。需要临时扩大权限时,应记录原因和到期时间。
使用阶段要保留证据。管理员登录、sudo 提权、修改关键配置、重启服务、变更权限,都应能在日志中看到。若通过跳板机或堡垒机登录,还应保留会话记录。
变更阶段要重新评估权限。人员转岗、项目范围变化、服务目录迁移、应用拆分、自动化平台替换,都可能要求调整用户、组、ACL 和 sudo 规则。
禁用阶段用于保留证据。离职或长期不用账号,通常先锁定密码、禁用 SSH key、移除 sudo 和关键组,保留家目录和文件归属一段时间。直接删除账号可能导致文件只剩数字 UID,不利于追溯。
删除阶段要谨慎处理文件。删除前先查找用户拥有的文件、计划任务、systemd user 服务、SSH key、sudoers 规则和业务目录权限。确认无依赖后再删除账号。
归档阶段要保留审计记录。账号申请、授权、变更、禁用和删除记录应保留到组织规定期限,便于安全审计和事故复盘。
服务账号设计
服务账号是生产 Linux 管理里最容易被低估的一类账号。很多服务为了省事直接用 root 启动,或者多个应用共用同一个 app 用户。这样做会扩大故障和攻击半径:一个应用被攻破,就能访问同一用户下的其他应用文件;一个脚本误删目录,也可能影响多个服务。
服务账号设计应遵循三个原则。第一,一服务一账号或一应用域一账号。简单环境可以按应用域合并,但不要让无关业务共用同一个高权限账号。第二,服务账号默认不可交互登录,shell 可以设置为 /usr/sbin/nologin 或 /bin/false。第三,服务账号只拥有必要目录权限,例如配置只读、数据目录可写、日志目录可写,不能拥有系统目录写权限。
systemd 可以进一步收紧服务权限。除了 User=、Group=、UMask=,还可以使用 NoNewPrivileges=、PrivateTmp=、ProtectSystem=、ProtectHome=、ReadWritePaths= 等选项。但这些选项必须逐项验证,因为服务可能需要读证书、写缓存、访问设备或调用外部命令。安全选项不能机械复制。
服务账号还要和部署流程配合。发布用户不一定等于运行用户。发布用户可以把包部署到暂存目录,再由受控脚本或 systemd 重启服务;运行用户只负责进程运行和必要读写。这样能减少发布脚本误改运行权限的风险。
集中身份与本地账号
单台服务器可以只靠本地账号管理,多主机环境则应考虑集中身份。常见方式包括 LDAP、FreeIPA、Active Directory、SSSD、堡垒机账号映射和云平台 IAM。集中身份的好处是统一账号生命周期、减少本地重复创建、便于禁用离职人员和集中审计。
集中身份并不意味着本地账号消失。系统仍需要 root、服务账号、应急账号和部分本地自动化账号。关键是明确本地账号和域账号的职责边界。域账号适合人登录和集中授权;本地服务账号适合运行进程;应急账号适合身份系统不可用时进入服务器,但必须严格保管和审计。
引入集中身份时要关注 NSS 和 PAM。NSS 决定系统如何解析用户和组,PAM 决定认证和会话策略。配置错误可能导致无法登录,甚至把管理员锁在系统外。变更前应保留本地应急账号和控制台访问,并在测试服务器验证。
UID/GID 规划也更重要。集中身份会给用户分配数字 ID,如果与本地账号或历史 NFS 文件冲突,可能造成文件归属混乱。跨主机共享目录、NFS、容器卷和备份恢复都要考虑 UID/GID 一致性。
权限复核清单
权限复核要从“账号、组、sudo、文件、特殊位、密钥、服务”七个角度进行。
账号复核看是否有过期、离职、长期未登录、无负责人账号。组复核看高权限组成员是否合理,是否存在临时成员没有移除。sudo 复核看是否有 ALL=(ALL) ALL、NOPASSWD、通配符过宽、脚本路径可被普通用户修改等问题。文件复核看业务目录 owner/group/mode 是否符合预期,是否存在 world-writable 文件。特殊位复核看 setuid/setgid 文件是否异常。密钥复核看 authorized_keys 是否有未知 key。服务复核看 systemd unit 是否使用 root 或过宽目录权限。
可以把复核结果分成三类:立即整改、限期整改、接受风险。立即整改包括离职账号仍可登录、普通用户拥有 root 级 sudo、业务目录 777、私钥可被多人读取。限期整改包括服务账号缺少负责人、sudo 规则过宽但有业务依赖、UID/GID 不规范。接受风险则必须记录原因和复核日期。
权限复核的目标不是追求零例外,而是让每个例外可见、可解释、可跟踪。
sudo 规则设计
sudo 规则设计要从操作场景出发,而不是从用户职级出发。常见错误是把“运维人员”等同于“所有命令都能执行”。更稳妥的方式是把操作拆成若干命令集合,例如查看状态、重启指定服务、查看日志、发布应用、执行备份、管理网络、安装软件包,再按组授权。
例如,应用运维可能只需要查看和重启某个服务:
Cmnd_Alias DEMO_STATUS = /bin/systemctl status demo.service, /bin/journalctl -u demo.service *
Cmnd_Alias DEMO_RESTART = /bin/systemctl restart demo.service
%demo-ops ALL=(root) DEMO_STATUS, DEMO_RESTART
这个规则比 ALL=(ALL) ALL 安全得多,但仍要注意路径和参数。若允许执行一个可被普通用户修改的脚本,即使 sudoers 看起来限制了命令,也可能被绕过。因此,被 sudo 调用的脚本必须由 root 或受控组拥有,普通用户不能写。
自动化账号的 sudo 规则要更严格。备份账号可能只需要读取指定目录和执行备份命令;发布账号可能只需要同步文件、切换软链接、reload 服务;监控账号通常只需要只读命令。不要因为自动化需要免密,就给它 NOPASSWD:ALL。免密不是问题,问题是免密范围失控。
sudo 日志也要纳入集中采集。至少要能看到谁在什么时间、从哪台主机、执行了什么 sudo 命令、返回结果如何。对高风险命令,例如修改 sudoers、删除目录、改防火墙、改网络、安装软件包,应进入安全审计或运维值班视图。
业务目录权限样例
以 /srv/apps/demo 为例,一个常见权限设计如下:
/srv/apps/demo/
releases/ 发布包目录,deploy 组可写
current -> releases/20260612
shared/
config/ 配置目录,root 管理,应用只读
logs/ 日志目录,应用可写,运维可读
data/ 业务数据目录,应用可写,备份可读
对应的权限可以这样规划:
| 路径 | owner | group | mode | 说明 |
|---|---|---|---|---|
/srv/apps/demo |
root | deploy | 2750 |
setgid 让新文件继承组 |
releases |
deploy | deploy | 2770 |
发布组写入 |
shared/config |
root | demoapp | 2750 |
应用读配置,不能改配置 |
shared/logs |
demoapp | ops | 2750 |
应用写日志,运维读日志 |
shared/data |
demoapp | backup | 2750 |
应用写数据,备份读数据 |
这种设计把发布、运行、运维、备份拆开,避免一个用户拥有所有能力。实际环境中还可以通过 ACL 给某个排障账号临时读日志权限,排障结束后撤销 ACL,而不是把他永久加入高权限组。
设置权限时要先创建组和服务账号:
sudo groupadd deploy
sudo groupadd ops
sudo groupadd backup
sudo useradd --system --no-create-home --shell /usr/sbin/nologin demoapp
sudo mkdir -p /srv/apps/demo/{releases,shared/config,shared/logs,shared/data}
sudo chown root:deploy /srv/apps/demo
sudo chmod 2750 /srv/apps/demo
sudo chown deploy:deploy /srv/apps/demo/releases
sudo chmod 2770 /srv/apps/demo/releases
sudo chown root:demoapp /srv/apps/demo/shared/config
sudo chmod 2750 /srv/apps/demo/shared/config
sudo chown demoapp:ops /srv/apps/demo/shared/logs
sudo chmod 2750 /srv/apps/demo/shared/logs
sudo chown demoapp:backup /srv/apps/demo/shared/data
sudo chmod 2750 /srv/apps/demo/shared/data
执行后要用不同身份验证,而不是只看 ls -l:
sudo -u demoapp test -r /srv/apps/demo/shared/config/app.yml
sudo -u demoapp test -w /srv/apps/demo/shared/logs
sudo -u demoapp test -w /srv/apps/demo/shared/data
sudo -u demoapp test ! -w /srv/apps/demo/shared/config
权限设计的核心是“按职责拆分写权限”。读权限可以相对宽一些,但写权限必须清楚地落到责任主体上。
密钥和凭据管理
Linux 用户权限不只体现在密码和 sudo。SSH key、API token、数据库密码、私钥文件、云凭据、备份密钥都属于权限边界。很多服务器事故不是账号本身泄露,而是某个用户家目录中的私钥或配置文件被其他用户读取。
SSH authorized_keys 应定期复核。个人账号的 key 应来自可信设备或统一堡垒机,不应长期保留临时 key。服务账号如果必须使用 SSH key,应限制来源、命令和用途,例如使用 from=、command= 等 OpenSSH authorized_keys 选项,或者通过部署平台统一管理。
敏感文件权限建议遵守保守原则:私钥 600,包含密码的配置文件不超过 640,目录不超过 750,owner 和 group 必须明确。不要为了让服务能读配置就把配置目录改成 777。如果服务无法读取,应该分析运行用户、组、ACL 和 systemd 限制,而不是直接放宽所有权限。
离职、转岗和应急账号
离职和转岗是权限管理中最容易被拖延的环节。人员离开团队后,账号应立即锁定或禁用,SSH key 应删除,sudo 和高权限组应移除,堡垒机、VPN、云平台和代码仓库权限也要同步处理。不要只删除 Linux 本地账号,而忽略集中身份和自动化平台中的授权。
离职账号不一定马上删除。对生产服务器,可以先锁定账号并保留家目录一段时间,用于审计和文件归属确认。处理步骤可以是:锁定密码、禁用 SSH key、移除 sudo、移出业务组、检查计划任务、检查 systemd user 服务、查找该用户拥有的文件、归档必要资料,最后按保留策略删除。
转岗账号要重新评估权限。一个人从运维转到项目管理,或者从数据库团队转到应用团队,原有 sudo、数据库备份、生产日志和发布权限可能不再需要。转岗不能只改组织架构系统,必须同步权限复核。
应急账号用于集中身份不可用、堡垒机故障或关键系统排障。应急账号必须少量、强密码、离线保管、定期演练、使用后立即轮换密码,并在日志中标记使用原因。不要把应急账号变成日常共享管理员账号。
权限管理的成熟度体现在异常场景。平时创建账号很容易,真正考验流程的是人员离开、系统故障、身份源不可用、业务紧急发布和安全事件响应时,权限是否仍然可控。
这些场景都应进入演练清单,避免真正故障时临时放权,留下新的安全缺口和审计盲区,影响追溯和整改闭环效率提升。
环境规划
本文示例以常见服务器环境为基准:
| 项目 | 示例规划 |
|---|---|
| 发行版 | Ubuntu Server 22.04/24.04、Debian 12、Rocky Linux 9、RHEL 9 同类环境均可参考 |
| 管理方式 | SSH 登录 + sudo 提权 |
| 账号策略 | 个人账号登录,禁止共享 root;服务账号不可交互登录 |
| 普通用户组 | ops 运维组、deploy 发布组、audit 审计组 |
| 业务目录 | /srv/apps/demo |
| 参考命令 | shadow-utils、coreutils、sudo、acl 工具集 |
执行前先确认当前环境:
cat /etc/os-release
id
getent passwd root
getent group sudo || getent group wheel
useradd -D
grep -E '^(UID_MIN|UID_MAX|SYS_UID_MIN|SYS_UID_MAX|UMASK|PASS_)' /etc/login.defs
不同发行版存在命令差异:
| 场景 | Debian/Ubuntu | RHEL/Rocky/Alma |
|---|---|---|
| 管理员组 | sudo |
wheel |
| 添加交互用户常用工具 | adduser 或 useradd |
useradd |
| sudo 包 | sudo |
sudo |
| ACL 工具包 | acl |
acl |
| 日志查看 | /var/log/auth.log、journald |
/var/log/secure、journald |
本文使用更通用的 useradd、groupadd、usermod 命令演示。Debian/Ubuntu 的 adduser 是更友好的前端工具,在人工创建用户时也可以使用。
实战操作
账号路径
1. 查看当前用户与组
# 查看当前登录身份
id
whoami
groups
# 查看指定用户
id root
getent passwd root
getent shadow root
# 查看组
getent group sudo
getent group wheel
getent 比直接 cat /etc/passwd 更适合生产环境,因为它会通过 Name Service Switch 查询系统配置的身份来源,包括本地文件、LDAP、SSSD 等。
2. 创建运维组和发布组
# 创建基础组
sudo groupadd ops
sudo groupadd deploy
sudo groupadd audit
# 验证组是否存在
getent group ops
getent group deploy
getent group audit
如果命令提示组已存在,不要直接删除重建。应先确认该组是否已经被目录、服务或 sudo 规则引用:
getent group ops
find / -xdev -group ops -ls 2>/dev/null | head
sudo grep -R "ops" /etc/sudoers /etc/sudoers.d 2>/dev/null
3. 创建普通运维用户
以下示例创建个人账号 zhangsan,指定注释、家目录、shell,并加入 ops 附加组:
sudo useradd \
--create-home \
--comment "Ops engineer Zhang San" \
--shell /bin/bash \
--groups ops \
zhangsan
sudo passwd zhangsan
id zhangsan
getent passwd zhangsan
关键参数说明:
| 参数 | 含义 | 注意事项 |
|---|---|---|
--create-home / -m |
创建家目录并复制 /etc/skel |
系统账号通常不需要家目录 |
--comment / -c |
设置 GECOS 备注 | 建议写清负责人和用途 |
--shell / -s |
设置登录 shell | 服务账号可用 /usr/sbin/nologin |
--groups / -G |
设置附加组 | 修改已有用户附加组时注意 -aG |
给已有用户追加组时必须使用 -aG,否则会覆盖原有附加组:
# 正确:追加 deploy 组
sudo usermod -aG deploy zhangsan
# 危险:不带 -a 会把附加组替换为 deploy
sudo usermod -G deploy zhangsan
用户组变更通常需要用户重新登录后才会在新会话中生效。排障时要确认当前会话的 id 输出,而不是只看 /etc/group。
4. 创建不可交互登录的服务账号
业务服务不应使用个人账号运行,也不应使用 root 直接运行。可以创建专用系统账号:
sudo useradd \
--system \
--no-create-home \
--shell /usr/sbin/nologin \
--comment "Demo application service account" \
demoapp
id demoapp
getent passwd demoapp
如果某些发行版没有 /usr/sbin/nologin,可用以下命令确认可用路径:
command -v nologin
grep nologin /etc/shells 2>/dev/null || true
服务账号目录建议放在 /srv、/var/lib、/opt 等明确位置,并把 owner 设为服务账号或部署组:
sudo mkdir -p /srv/apps/demo/{current,shared,logs}
sudo chown -R demoapp:deploy /srv/apps/demo
sudo chmod 2750 /srv/apps/demo
sudo chmod 2770 /srv/apps/demo/{shared,logs}
这里的 2 是 setgid 位,表示目录中新建文件默认继承目录所属组,适合团队共享部署目录。
5. 设置密码有效期和账号过期时间
查看密码策略:
sudo chage -l zhangsan
grep -E '^(PASS_MAX_DAYS|PASS_MIN_DAYS|PASS_WARN_AGE)' /etc/login.defs
设置单个用户的密码周期:
# 最长 90 天、最短 1 天、提前 14 天提醒
sudo chage -M 90 -m 1 -W 14 zhangsan
# 强制下次登录修改密码
sudo passwd --expire zhangsan
设置临时账号过期:
sudo useradd -m -s /bin/bash -e 2026-06-30 temp_vendor
sudo passwd temp_vendor
sudo chage -l temp_vendor
临时账号必须记录申请人、用途和到期时间。到期后建议先锁定观察,再按流程删除:
sudo usermod --lock temp_vendor
sudo usermod --expiredate 1 temp_vendor
6. 配置 sudo 最小授权
Ubuntu/Debian 通常使用 sudo 组,RHEL/Rocky 通常使用 wheel 组。添加管理员组:
# Ubuntu/Debian
sudo usermod -aG sudo zhangsan
# RHEL/Rocky
sudo usermod -aG wheel zhangsan
更推荐为业务操作创建专门规则。例如允许 deploy 组重启 demo 服务、查看服务状态,但不允许任意 root shell:
sudo visudo -f /etc/sudoers.d/demo-deploy
写入以下内容:
%deploy ALL=(root) /bin/systemctl status demo.service, /bin/systemctl restart demo.service, /bin/journalctl -u demo.service
保存后检查语法:
sudo visudo -cf /etc/sudoers
sudo visudo -cf /etc/sudoers.d/demo-deploy
sudo -l -U zhangsan
如果 systemctl 路径不同,先用 command -v systemctl 确认。sudoers 中的命令路径应使用绝对路径,不要写相对路径。
7. 管理文件 owner、group 和 mode
创建业务配置目录:
sudo mkdir -p /etc/demoapp
sudo touch /etc/demoapp/config.yml
sudo chown root:deploy /etc/demoapp/config.yml
sudo chmod 640 /etc/demoapp/config.yml
ls -l /etc/demoapp/config.yml
含义是:
| 对象 | 权限 | 说明 |
|---|---|---|
owner root |
rw- |
只有 root 可以修改 |
group deploy |
r-- |
发布组可以读取 |
| other | --- |
其他用户无权限 |
递归修改权限时要谨慎,尤其不要在根目录、系统目录或挂载点误执行:
# 推荐先预览
find /srv/apps/demo -maxdepth 2 -ls
# 分别设置目录和文件权限
sudo find /srv/apps/demo -type d -exec chmod 2750 {} \;
sudo find /srv/apps/demo -type f -exec chmod 640 {} \;
不要使用 chmod -R 777 解决权限问题。它会把读写执行权限开放给所有本地用户,并且可能暴露密钥、配置和日志。
8. 使用 umask 控制新文件默认权限
umask 决定新建文件和目录会屏蔽哪些权限。常见值:
| umask | 新文件常见权限 | 新目录常见权限 | 适用场景 |
|---|---|---|---|
022 |
644 |
755 |
系统默认、普通只读共享 |
027 |
640 |
750 |
企业服务器常见收紧策略 |
077 |
600 |
700 |
密钥、个人敏感文件 |
查看当前 umask:
umask
对服务进程,优先在 systemd unit 中设置:
[Service]
User=demoapp
Group=deploy
UMask=0027
修改后重载并重启服务:
sudo systemctl daemon-reload
sudo systemctl restart demo.service
9. 使用 ACL 处理例外权限
传统 owner/group/other 权限无法表达“多给某个用户读权限,但不改变文件所属组”的需求。此时可以使用 ACL:
# 安装 ACL 工具
sudo apt install -y acl
# 或
sudo dnf install -y acl
# 给 audit 用户读取权限
sudo setfacl -m u:audituser:r /etc/demoapp/config.yml
getfacl /etc/demoapp/config.yml
# 设置目录默认 ACL,让新文件继承
sudo setfacl -m d:g:audit:rx /srv/apps/demo/logs
sudo setfacl -m g:audit:rx /srv/apps/demo/logs
getfacl /srv/apps/demo/logs
ACL 适合处理少量例外,不适合替代整体权限设计。若某个目录存在大量 ACL 规则,应重新评估组模型是否设计不合理。
10. 禁用、锁定和删除账号
账号退出使用时,建议按“锁定 -> 观察 -> 归档 -> 删除”的顺序处理:
# 锁定密码登录
sudo passwd --lock zhangsan
# 禁用账号登录
sudo usermod --expiredate 1 zhangsan
# 确认仍有哪些文件属于该用户
sudo find / -xdev -user zhangsan -ls 2>/dev/null
# 删除账号但保留家目录
sudo userdel zhangsan
# 删除账号并删除家目录,执行前必须确认备份
sudo userdel --remove zhangsan
如果账号拥有定时任务、systemd user service、SSH key、sudo 规则或业务目录权限,删除前要一并清理:
sudo crontab -u zhangsan -l
sudo grep -R "zhangsan" /etc/sudoers /etc/sudoers.d /etc/ssh 2>/dev/null
sudo find /srv /opt /var -xdev -user zhangsan -ls 2>/dev/null
配置详解
/etc/passwd 字段
示例:
zhangsan:x:1001:1001:Ops engineer Zhang San:/home/zhangsan:/bin/bash
字段含义:
| 字段 | 示例 | 含义 |
|---|---|---|
| 用户名 | zhangsan |
登录名 |
| 密码占位 | x |
表示密码哈希在 /etc/shadow |
| UID | 1001 |
用户数字 ID |
| GID | 1001 |
主组数字 ID |
| GECOS | Ops engineer Zhang San |
备注信息 |
| 家目录 | /home/zhangsan |
登录后的默认目录 |
| shell | /bin/bash |
登录 shell |
/etc/shadow 的关键字段
/etc/shadow 包含密码哈希和有效期信息。不要手工编辑密码哈希,优先使用 passwd、chage、usermod 等工具。
常见状态:
| 状态 | 表现 | 含义 |
|---|---|---|
| 有哈希 | $y$...、$6$... 等 |
可使用密码认证 |
! 或 * |
密码字段被锁定 | 不能用密码登录 |
| 过期日期已到 | chage -l 显示过期 |
账号不可正常登录 |
sudoers 规则结构
%deploy ALL=(root) /bin/systemctl restart demo.service
字段解释:
| 片段 | 含义 |
|---|---|
%deploy |
deploy 组成员 |
ALL |
在所有主机上生效 |
(root) |
以 root 身份执行 |
/bin/systemctl restart demo.service |
允许执行的命令 |
如果需要限制参数,必须把参数写完整。允许 /bin/systemctl * demo.service 这类宽泛匹配时,要评估是否会绕过边界。
权限数字表示法
chmod 640 file 中每一位是权限求和:
| 数字 | 权限 |
|---|---|
| 4 | read |
| 2 | write |
| 1 | execute |
因此:
| 模式 | 含义 |
|---|---|
600 |
owner 读写,其他无权限 |
640 |
owner 读写,group 只读 |
750 |
owner 全权限,group 读和执行 |
2750 |
在 750 基础上增加 setgid |
1777 |
所有人可写目录,但启用 sticky bit |
验证与测试
审计路径
1. 验证账号创建
getent passwd zhangsan
id zhangsan
sudo chage -l zhangsan
成功标准:
getent passwd能查到用户。id显示正确 UID、主组和附加组。chage -l显示符合预期的密码有效期和账号过期策略。
2. 验证 sudo 授权
sudo -l -U zhangsan
再使用目标用户新建 SSH 会话验证:
sudo systemctl status demo.service
sudo systemctl restart demo.service
sudo -i
成功标准:
- 被授权命令可以执行或进入正常权限检查。
- 未授权命令被拒绝。
- sudo 日志能记录执行用户、目标命令和时间。
3. 验证目录权限
namei -l /srv/apps/demo/shared
ls -ld /srv/apps/demo /srv/apps/demo/shared
sudo -u demoapp test -w /srv/apps/demo/logs && echo writable
sudo -u nobody test -r /etc/demoapp/config.yml || echo denied
namei -l 可以逐级显示路径权限,适合排查“文件权限看起来正确但仍无法访问”的问题。
4. 验证 ACL
getfacl /etc/demoapp/config.yml
sudo -u audituser test -r /etc/demoapp/config.yml && echo readable
如果 ACL 未生效,检查文件系统挂载选项、上级目录执行权限和 ACL mask。
5. 审计高风险权限
# 查找 world-writable 目录
sudo find / -xdev -type d -perm -0002 -ls 2>/dev/null
# 查找 setuid 文件
sudo find / -xdev -perm -4000 -type f -ls 2>/dev/null
# 查找无属主文件
sudo find / -xdev \( -nouser -o -nogroup \) -ls 2>/dev/null
# 查找 SSH 私钥权限过宽的情况
sudo find /home -xdev -name "id_*" -type f -not -perm 600 -ls 2>/dev/null
这些命令可能输出较多,生产环境建议限定目录、纳入定期巡检,并人工确认误报。
故障排查
1. 用户已经加入组,但仍然没有权限
常见原因:
- 当前 shell 会话还没有重新加载组成员关系。
- 使用
usermod -G覆盖了原有附加组。 - 目标路径上级目录缺少执行权限。
- ACL mask 限制了实际权限。
排查命令:
id
id zhangsan
namei -l /path/to/resource
getfacl /path/to/resource
处理方式:
# 重新登录最可靠;临时测试可使用
newgrp deploy
2. sudo 提示用户不在 sudoers 文件中
检查用户所属组和发行版管理员组:
id zhangsan
getent group sudo
getent group wheel
sudo -l -U zhangsan
修复方式:
# Ubuntu/Debian
sudo usermod -aG sudo zhangsan
# RHEL/Rocky
sudo usermod -aG wheel zhangsan
如果 sudoers 文件语法错误,应从 root 控制台、云厂商救援模式或单用户模式修复,并使用 visudo -c 验证。
3. SSH 密钥登录失败
重点检查:
ls -ld /home/zhangsan /home/zhangsan/.ssh
ls -l /home/zhangsan/.ssh/authorized_keys
sudo tail -n 100 /var/log/auth.log 2>/dev/null || sudo tail -n 100 /var/log/secure 2>/dev/null
sudo journalctl -u ssh -u sshd --since "30 min ago"
常见权限要求:
sudo chown -R zhangsan:zhangsan /home/zhangsan/.ssh
sudo chmod 700 /home/zhangsan/.ssh
sudo chmod 600 /home/zhangsan/.ssh/authorized_keys
还要检查账号是否被锁定、shell 是否为 nologin、家目录是否存在。
4. 服务账号无法写日志
排查顺序:
id demoapp
namei -l /srv/apps/demo/logs/app.log
ls -ld /srv/apps/demo/logs
getfacl /srv/apps/demo/logs
sudo -u demoapp test -w /srv/apps/demo/logs && echo ok
如果服务由 systemd 管理,还要检查 unit 中的 User=、Group=、ReadWritePaths=、ProtectSystem=、DynamicUser= 等安全限制。
5. 删除用户后文件显示数字 UID
原因是文件系统保存的是 UID/GID,用户名删除后映射消失。先确认文件归属和业务影响:
sudo find / -xdev -nouser -ls 2>/dev/null
sudo find / -xdev -nogroup -ls 2>/dev/null
处理方式:
sudo chown -R newowner:newgroup /path/to/data
不要为了“让名字回来”而随意创建同 UID 用户,除非这是经过确认的恢复方案。
6. chmod 后权限仍然不符合预期
可能原因:
- 有 ACL,实际权限受 ACL mask 影响。
- 目录 setgid 导致新文件继承组。
- 服务进程 umask 覆盖了默认权限。
- 容器、NFS、CIFS 等挂载层有额外权限映射。
排查命令:
getfacl /path/to/file
stat /path/to/file
findmnt /path/to/file
systemctl show demo.service -p UMask -p User -p Group
运维建议
1. 建立账号申请模板
账号申请至少记录:
| 字段 | 示例 |
|---|---|
| 申请人 | 张三 |
| 账号名 | zhangsan |
| 用途 | 日常运维 |
| 所属组 | ops |
| sudo 权限 | 仅查看服务状态、重启指定服务 |
| 有效期 | 长期或明确到期日 |
| 审批人 | 运维负责人 |
2. 禁止共享高权限账号
建议策略:
- root 不直接用于 SSH 登录。
- 管理员使用个人账号登录,再通过 sudo 提权。
- 自动化任务使用专用服务账号,并限制命令、目录和密钥用途。
- 临时排障账号设置过期时间。
3. 定期复核用户和 sudo 权限
每月至少检查:
getent passwd | awk -F: '$3 >= 1000 {print $1, $3, $6, $7}'
getent group sudo
getent group wheel
sudo grep -R "ALL" /etc/sudoers /etc/sudoers.d 2>/dev/null
sudo find / -xdev -perm -4000 -type f -ls 2>/dev/null
复核重点:
- 是否存在离职、转岗、过期账号。
- 是否存在无负责人服务账号。
- 是否存在过宽 sudo 规则。
- 是否存在异常 setuid 文件。
- 是否存在 world-writable 业务目录。
4. 统一 UID/GID 规划
多主机环境建议提前规划:
- 本地普通用户使用默认范围即可。
- 跨主机共享目录、NFS、备份恢复涉及的服务账号,应固定 UID/GID。
- LDAP/FreeIPA/AD/SSSD 环境中,本地账号和域账号范围不要冲突。
- 容器宿主机要关注
/etc/subuid、/etc/subgid对 rootless 容器的影响。
5. 服务权限与 systemd 安全选项结合
服务账号只是第一层隔离。systemd unit 中还可以叠加:
[Service]
User=demoapp
Group=deploy
UMask=0027
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/srv/apps/demo /var/log/demoapp
这些选项需要结合服务实际读写路径逐项验证,不能直接照搬到生产服务,否则可能导致服务无法启动或无法写入必要文件。
总结
用户与权限管理是 Linux 服务器安全和可维护性的底座。本文从身份模型、账号文件、UID/GID、sudo、文件权限、umask、ACL 和账号生命周期几个角度,构建了一套可落地的管理方法。
关键要点回顾:
- 用户和组是权限控制的基础,生产环境应使用个人账号和专用服务账号,避免共享 root。
- 创建用户前先规划用途、组、shell、家目录和有效期,创建后用
id、getent、chage验证。 - sudo 应采用最小授权,优先通过
/etc/sudoers.d/和visudo管理。 - 文件权限要同时检查 owner、group、mode、ACL、umask 和上级目录执行权限。
- 账号禁用、删除、权限复核应成为固定运维流程,而不是故障后补救动作,责任边界也要同步记录。
下一步学习: 在掌握用户与权限管理之后,建议继续学习《文件系统管理》,系统理解 Linux 文件系统层级、挂载、磁盘空间、inode、LVM 与常见文件系统维护方法。
参考资料
- useradd(8) - Linux manual page
- passwd(1) - Linux manual page
- chown(2) - Linux manual page
- chmod(2) - Linux manual page
- systemd-sysusers - freedesktop.org manual
- sudoers manual - sudo.ws
本文最后更新于 2026-05-22