首页 / 资讯中心 / 文章详情

Linux账号与权限管理实战:从用户组设计到运维排查

Linux账号与权限管理实战:从用户组设计到运维排查 ★ FEATURED ARTICLE
管人、管组、管权限这事说大不大说小不小但你要是没弄明白服务器哪天被人删了库、改了配置、提了权回头看日志的时候十有八九就是账号和权限这块埋的雷。我自己做了这么多年运维接手过的环境里因为权限配置不当出事故的比例远比什么内核参数、网络配置出问题的概率高得多。这不是吓唬人“Linux账号和权限管理”就是这么个看着基础、实际上门道极多的领域值得每个跟服务器打交道的人静下心捋一遍。这篇文章不打算给你堆一堆命令手册我想用我自己实际踩坑和解决问题的经验把用户账号怎么设计、权限模型怎么理解、实操流程怎么落地、出问题了怎么排查串成一条完整的链路。写的时候默认你有一台能折腾的Linux机器最好拿虚拟机练手因为权限这种东西光看不练看十遍也记不住错一次就记住了。1. 账号体系设计先想清楚用户和组的边界很多新手拿到服务器上来就是useradd建用户、passwd设密码完事。但账号体系的乱象往往就是从这一步开始的。等到服务器上几十个账号混在一起新来的同事要用哪个组、旧同事离职了账号该不该删、共享目录到底该给谁开权限全乱套了。账号体系设计本质上是在回答三个问题谁要用这台机器、这些人的工作边界在哪、他们需要用到哪些资源。1.1 用户和组的关系别等建完再回头改Linux里的用户和组是一对多的关系。一个用户可以有一个主组primary group也可以同时加入若干个附加组supplementary group。这个设计非常实用但同时也是混乱的源头。举个例子你给某人创建了账号主组设成了他自己的私有组比如user1然后他发现要读某个项目目录而那个目录的属组是webgroup。这时候你有两条路一是用usermod -G webgroup user1把他加进附加组二是用chgrp去改目录的属组。我的习惯是尽量保持主组干净私有组就是私有组别让一堆人共享一个主组需要访问共享资源时用附加组解决。原因很简单主组一旦被多个账号共用将来你执行chown 文件 用户:组的时候很容易把不该共享的属组关系搞混。这里有一个非常容易踩的坑usermod -G后面跟的组列表是“覆盖式”的。如果你原来给用户加了A组和B组后来想再补一个C组执行usermod -G C user1那他身上就只剩C组了A和B全部被清掉。正确做法是把完整列表写全usermod -G A,B,C user1。我在这上面栽过不止一次后来养成了习惯所有涉及组成员变更的操作先执行id 用户名看一下当前成员关系再动手改。1.2 密码策略什么才算一个“合格”的密码密码这块常见的误区是只关注“够不够复杂”忽略了“什么时候失效”。系统管理员给账号设置密码至少要关注四个维度密码本身强度、密码过期时间、密码最短使用时间、过期前多少天提醒。对应的工具是chage命令。我一般会执行chage -M 90 用户名把密码寿命设成90天chage -m 7强制用户不能7天内频繁改密码防止用户来回改回原密码chage -W 15让系统提前15天提醒。还有一个动作经常被漏掉第一次给用户设置密码后让他下次登录时强制改掉命令是chage -d 0 用户名。这一步在交付账号给新同事时特别有用因为初始密码是管理员设的理论上管理员知道不改掉就是安全隐患。但不建议只依赖chage密码本身的强度也要把住。很多发行版默认装了pwquality这个模块你可以在/etc/security/pwquality.conf里配置最小长度、复杂度要求。我自己的经验是别把所有策略都写在/etc/login.defs里那只是新账号默认值真正生效的是PAM配置。新手排查“为什么我改了密码策略不起作用”十有八九是改错了地方。1.3 用户生命周期创建、冻结、删除的完整闭环账号管理不是建完就完了从创建到删除每一步都有讲究。创建阶段useradd -m -U -s /bin/bash 用户名-m自动建家目录-U同时创建同名的私有组-s设定登录shell。如果需要指定UID可以用-u参数比如要跟某台机器上的账号UID对齐避免文件属主显示成数字。使用阶段定期检查哪些账号长时间没登录。lastlog命令可以列出所有用户最近一次登录时间看到那种半年没登录的账号就要考虑冻结了。冻结用usermod -L 用户名这是锁定密码比直接删账号温和万一人家还要回来用解锁就行不用重建环境和权限。删除阶段userdel -r 用户名会删除用户并清理家目录和邮件池。但这里有个大坑如果这个用户曾经在系统里创建过文件删除账号后那些文件会变成无主文件显示成UID数字。我在生产环境里见过磁盘空间被一堆无主的大日志文件占满排查半天发现是某个被删账号之前跑的任务留下的。所以删除前先执行find / -user 用户名 2/dev/null把用户名下的文件找出来决定是保留、迁移还是删除再做userdel -r。这里要特别强调一下UID是账号的“真实身份”。用户名没了但UID还在文件就还“认”这个数字。所以某些场合我宁愿用usermod -L冻结也不轻易删账号尤其是那些跑过计划任务的账号删了之后旧任务日志全变无主文件后续处理非常被动。2. 权限模型从rwx到特殊权限的完整认知权限管理这一章是Linux系统管理里概念最密集的部分。很多人一知半解会用chmod 777救火但从不深究背后发生了什么。其实权限模型搞清楚之后很多“玄学”问题都会变成“一眼看穿”的必然。2.1 基础权限的判定流程别只看数值r读、w写、x执行这三个权限配合属主user、属组group、其他other在ls -l输出里就是-rwxr-xr--这一串字符。我见过太多人只看数字比如755、644却忘了去理解这串数字背后系统是怎么判定一个进程能不能访问某个文件的。关键点是权限判定是“互斥优先”的。当一个用户访问一个文件时系统先看这个用户是不是文件的属主是——直接按属主权限来后面的属组和其他根本没机会参与判定不是的话再看他属不属于文件属组属于——按属组权限来还不是——落到其他人的权限。这就解释了一个经典问题为什么文件属组的权限是---但其他用户还能碰因为那个“其他用户”可能压根不在属组里系统判定走的是others分支两边互不干扰。举个例子假设有个文件属主是root属组是webgroup权限是-rw-r-----。那webgroup里的成员可以读但不能写而不在webgroup里的用户连读都不行。但如果你把这个文件的属组权限改成rw-那所有webgroup成员都能写——注意这里和你给目录加不加粘滞位、是不是共享目录都有关系后面细说。权限数值的计算r4w2x1这是要背下来的。为什么是这个权重4是二进制1002是0101是001三位的组合能覆盖0到7的所有情况。理解了这个底层逻辑你就不会把755和775背混了。2.2 特殊权限SUID/SGID/Sticky三种情况详解这是权限模型里最容易让新手懵掉的部分。特殊权限一共三个SUID4、SGID2、Sticky1。SUID作用于可执行文件效果是当普通用户执行这个文件时进程的有效身份临时变成文件属主。最经典的例子是/usr/bin/passwd。这个文件属主是root权限里带SUIDrwsr-xr-x所以普通用户修改自己密码时能临时以root身份去写/etc/shadow改完这个临时身份就结束。如果去掉SUID普通用户就改不了自己密码了——因为/etc/shadow对普通用户是不可写的。这解释了为什么passwd命令能完成普通用户不可能完成的“写受限文件”操作。SGID就有意思了它既可以作用于文件也可以作用于目录。作用于目录时效果是新创建的子文件和子目录其属组自动继承父目录的属组而不是创建者自己的主组。这个特性在多人协作的共享目录里极其好用我下面实操章节会专门演示。注意作用于可执行文件时效果类似SUID但临时身份换成文件的属组这个场景很少用了因为安全风险大一般不建议。Sticky粘滞位作用于目录。效果是目录里的文件谁创建谁才有权删除其他人哪怕对这个目录有写权限也删不掉别人的文件。典型就是/tmp目录。没有粘滞位的共享目录会出现一种很恶心的场景A用户费劲创建的文件B用户进去一个rm就给删了因为B对目录有写权限rm的权限判定看的是“对目录的写权限”跟文件本身权限无关。所以共享目录一旦要开放多人写务必带上粘滞位。2.3 umask与默认权限的计算逻辑新建文件和目录的默认权限不是系统随机生成的而是由umask值算出来的。这里有个规律新建文件的默认基础权限一般没有执行权限因为安全考量不会默认给你可执行所以文件是666减去umask目录是777减去umask。我常用的是umask 022。算一下新建文件是666 - 022 644即-rw-r--r--属主可读写其他人只读新建目录是777 - 022 755即drwxr-xr-x。umask 002的话文件是664目录是775适合共享协作。注意这个计算是基于“初始权限全集”的减法逻辑不是简单的数值相减但实践上直接减是没问题的。改umask可以临时执行umask 002想要永久生效写到用户家目录的.bashrc或/etc/profile里。还有个细节有些发行版会在创建用户时设定一个User Private Groups模式默认umask可能是002或022不同发行版之间还有点差别不建议背死数值而是每次拿到新环境先执行umask看一眼。3. 实操笔记一套可复制的共享目录授权流程前面讲了不少原理这一节我以一个真实场景来串一遍流程。假设你管理的服务器上有个团队十几个人要共用一个项目目录。目录要求是团队成员都能读写但谁创建的文件只有自己能删粘滞位场景同时有个子目录是给核心几个人用的其他人连看都不能看。这是非常典型的权限需求我按我的习惯走一遍。3.1 创建用户组和成员账号先建组再建用户再绑定关系。组名我带项目走比如projcore。groupadd projcore useradd -m -G projcore alice useradd -m -G projcore bob useradd -m -G projcore carol passwd alice passwd bob passwd carol这里有个细节实际生产中如果团队成员多我不会逐条执行useradd而是写一个简单的shell循环从用户清单文件里读取用户名批量创建。别图省事一个个敲批量操作可重复执行也方便留档。绑定完组之后一定要逐个id确认一遍id alice id bob id carol看到他们都有projcore这个附加组再进入下一步。这一步是给后面排查省时间别跳过。3.2 创建共享目录并设置属组和SGID目录规划/data/projcore作为共享根目录/data/projcore/private作为核心小组私有目录。mkdir -p /data/projcore/private chown root:projcore /data/projcore chmod 2770 /data/projcore chown root:projcore /data/projcore/private chmod 2770 /data/projcore/private注意这个chmod 27702就是SGID。加了SGID之后alice在/data/projcore下新建的文件属组自动变成projcore而不是alice自己的私有组。这意味着组内所有人都能按组权限访问这些文件而不是“只有alice自己能碰”。如果不加SGID后遗症就是其他人对目录有写权限但子文件的属组是alice的主组其他组员连读都读不了共享目录等于白建。设置完之后再验证一下。用alice登录touch一个测试文件然后ls -l看属组确认是projcore。3.3 用ACL处理特殊子目录的访问控制现在处理private子目录需求是核心成员才能访问其他人无权限。普通的chmod做不到这种灰色地带不能只对组内一部分人开放这时候就要用ACL了。setfacl -m g:coregroup:rwx /data/projcore/private setfacl -m d:g:coregroup:rwx /data/projcore/private先用groupadd coregroup建一个核心组把需要访问private的人加进去。这两条命令第一条是给coregroup这个组设置对该目录的rwx权限第二条是设置默认ACL让之后在private目录里新建的文件自动继承这个ACL——这个“继承”机制非常关键少了默认ACL你以后在private里建的文件别人还是进不去。验证用getfacl /data/projcore/private。我看到很多初学者用ACL之后ls -l的输出会多一个加号drwxrwx---这个加号就是提示“这个目录有额外的ACL规则”。以后排查权限问题看到带加号的目录第一反应用getfacl看ACL全貌而不是只看chmod数字。3.4 配合sudo解决紧急提权需求普通成员有时需要执行一些管理员命令比如重启某个服务、查看系统日志。原则是绝不给root密码用sudo精准授权。编辑sudo规则一定要用visudo命令它带语法检查能防你把自己锁死在/etc/sudoers.d/下建一个独立文件来管理比直接改主配置文件清爽。visudo -f /etc/sudoers.d/projcore-team内容示例%projcore ALL(ALL) /usr/bin/systemctl restart myweb %projcore ALL(ALL) /usr/bin/tail /var/log/messages解释一下这行规则projcore组的成员可以在任何主机上以root身份执行systemctl restart myweb和tail /var/log/messages。注意命令要写绝对路径防止用户用别名或PATH劫持绕过。这个细节真实发生过有人被授权可以执行/bin/cat结果他通过PATH环境变量搞了个同名脚本拿到了超出预期的权限。所以sudo授权命令一律绝对路径。另外sudo的日志默认记在/var/log/secure或/var/log/auth.log里出问题回溯时不要忘记查。谁在什么时候执行了什么sudo命令这里记得清清楚楚。4. 常见问题与排查技巧实录这块内容是实实在在踩坑总结出来的建议收藏。权限类问题的特点是表面症状千奇百怪根因通常集中在几个点上。4.1 sudoers被改坏后的自救这个必须写在最前面因为它是自己坑自己最典型的例子。去编辑/etc/sudoers语法写错了保存退出然后发现所有sudo命令都报错连sudo都用不了了。雪上加霜的是系统可能提示“sudo: /etc/sudoers is world writable”或者语法错误直接拒绝执行任何sudo。自救方法用root身份如果当前还是root执行pkexec visudo或者直接切到root再执行visudo修正。但如果你连su都切不过去就得用Rescue模式或者重启进单用户模式去改文件。生产环境最稳的做法是用visudo -c校验语法编辑完不要直接退出先另开一个终端执行sudo -l确认没问题再走。养成这个习惯能避开90%的自锁事故。如果报错是“/etc/sudoers is world writable”说明文件权限错了。sudo对自己的配置文件权限极度敏感要求owner必须是root权限必须是440或0440。修复命令是chown root:root /etc/sudoers chmod 440 /etc/sudoers。4.2 文件删不掉权限全对却操作失败场景复现用户在共享目录里目录的属组也对了权限也够写但rm文件时提示“Operation not permitted”。我先检查Sticky粘滞位如果目录带t权限比如drwxrwxrwt那么删除文件就受“创建者才能删”的限制。你不是文件创建者即使对目录有写权限也删不掉。另一个常见元凶是文件系统层面的不可变属性。用lsattr查看如果看到i属性immutable那谁来了都删不掉包括root。处理方法是用chattr -i文件名去掉属性再删。这个属性用来保护关键文件很方便但出问题了也很隐蔽正常人根本想不到去查lsattr。还有一个更隐蔽的场景目录有写权限但目录本身不可进入x权限没有。你要在目录里删文件需要同时具备对目录的w和x权限。缺x你就进不去缺w进去了也删不了。这两个缺一不可。4.3 切换用户后环境变量“丢”了很多人用su切换用户后发现命令找不到、PATH不对。核心问题在于su的两种用法su 用户名保留当前环境变量只切换用户身份。su - 用户名模拟登录重新读取目标用户的环境配置文件相当于重新登录。如果你从root切到普通用户发现PATH还是root的、但权限不对或者干脆提示找不到某些命令大概率是用了su而非su -。我自己的习惯是跨用户切换一律用su -避免带着上一家的环境变量去新环境里跑命令省掉一堆莫名其妙的问题。sudo同理默认会重置环境变量除非配置了env_keep。所以你在sudo后找不到自己之前设置的变量是正常现象不是系统出问题了。4.4 快速排查权限问题的一条命令链路权限问题排查我有一套固定的链路遇到问题就从头走一遍效率极高先看身份id 用户名。确认用户属于哪些组是不是你预期的组成员关系。很多时候问题是组关系错了不是权限错了。再看对象ls -ld 目标路径。看属主、属组、权限位、是否有加号ACL、是否有特殊权限位。多层路径的话每一层都要看因为权限是“路径上的每一层目录都要有x权限才能穿过”。然后看扩展getfacl 目标路径。确认有没有ACL规则在影响访问判断。必要时再看进程检查程序是以什么身份跑的。比如web服务以www用户运行它想读某个配置文件那这个问题就只跟你、root无关只看www用户有没有权限。用ps -ef | grep 进程名确认运行身份这个步骤经常被忽略。最后查日志dmesg | tail、/var/log/messages、audit日志看看有没有权限拒绝记录。有些系统开了auditd权限拒绝会被记录在/var/log/audit/audit.log。4.5 无主文件与重复UID的隐患前面提到删账号会产生无主文件这里再展开一下。无主文件的危险在于如果这个系统里存在另一个账号恰好用了相同的UID那么这些文件就会“归属”到这个新账号头上。这不是理论上的巧合我实际碰到过一个旧账号删了后来新同事入职系统自动按顺序给它分配了跟旧账号一样的UID结果新同事发现自己家目录里平白多出一堆日志文件还能访问——因为这些旧文件的属主UID和他一样。防止这个问题我的建议是删除账号前先find找出所有属于该用户的文件要么chown给别人、要么归档、要么明确删除。同时手工指定UID创建账号时要谨慎先执行awk -F: {print $3} /etc/passwd确认这个UID没有被占用。UID是个数字系统只认数字不认名字这是很多权限异常事故的真正根源。最后再分享一条个人经验权限管理里最怕的不是不懂命令而是“自我感觉良好”。你给用户开了写权限、给目录配了ACL、给sudo设了规则但从来没真正切到那个用户身份去实测一遍。我见过无数次“权限配置没问题啊但他死活说不能访问”的争执最后自己去试一遍发现要么是基础权限和ACL叠加时理解偏了要么是路径中间某层目录权限挡路。所以我的习惯是每配完一轮权限就su到对应用户实际走一遍他要做的操作。能通过测试再交付。这比任何检查脚本都靠谱。
阅读完成 · 觉得有帮助?
咨询建站