2026/10/2 19:55:26

Linux用户管理入门到实战:登录、用户组与权限配置全解析

Linux用户管理入门到实战:登录、用户组与权限配置全解析 1. 写在前面这节笔记要解决什么问题Linux用户管理这块经常被人当成“会敲几个命令就行”的小事。可实际一上手添加用户、删除用户、切换用户、调整用户组每一步都可能踩坑。这篇笔记围绕用户登录与注销、用户管理以及用户组来展开把我在实际使用中整理过的命令、参数和踩坑记录一起写出来算是《Linux笔记》系列的第三篇。这篇内容适合谁看给两类人。一类是刚装好虚拟机、刚开始接触Linux的初学者另一类是准备运维面试、需要把用户权限这部分知识系统过一遍的兄弟。看完之后你能搞清楚登录和注销背后的身份验证机制能独立完成添加、删除、查询用户的操作能分清su和sudo的关系也能弄明白“所有者、所在组和其他组”这三个权限维度到底是怎么回事。文中的所有命令我都在CentOS和Ubuntu上实测过Debian系和RedHat系在细节上会有一点点差异用到的时候我会单独说明。有一点提前说清楚Linux下很多操作需要root权限我默认你是在自己的测试环境里折腾别拿生产服务器练手这是原则问题。2. 用户登录与注销从开机到命令行的完整过程2.1 登录的本质系统如何验证你的身份很多人觉得登录不就是输入用户名和密码吗其实没那么简单。Linux的登录验证过程核心是核对两份文件/etc/passwd和/etc/shadow。/etc/passwd保存用户的基本信息比如用户名、UID、用户组ID、家目录和登录Shell/etc/shadow保存加密后的密码哈希、密码修改时间、过期时间等敏感字段。/etc/passwd是全局可读的所以密码绝对不能放在里面只能放在权限为000的/etc/shadow里。我们拿一条典型的passwd记录来拆解root:x:0:0:root:/root:/bin/bash用冒号分成7个字段用户名密码占位符xUIDGID描述信息家目录登录Shell。其中UID为0表示超级用户普通用户的UID一般是1000以后系统用户像bin、daemon这些通常是1到999。登录的时候系统会先用你输入的用户名去/passwd里查找UID再去/shadow里比对密码哈希。如果都通过就会调用passwd记录中指定的登录Shell通常会启动一个bash同时加载环境变量文件比如/etc/profile、~/.bash_profile、~/.bashrc这些。这也是为什么有时候你用su切换用户之后环境变量感觉“不对劲”多半是Shell加载的初始化文件不对。2.2 注销与退出别把关机当成注销注销和关机是两码事。注销是结束当前登录会话回到登录界面系统还在运行关机是关闭整个系统。在图形界面里注销通常是“退出账户”在命令行里注销方式主要有三种exit、logout、CtrlD。exit退出当前Shell进程。如果在登录Shell里执行就相当于注销如果在子Shell或脚本里执行只退出当前Shell层。logout只能用于登录Shell就是那个直接由登录流程启动的Shell普通子Shell里执行会提示“not login shell”。CtrlD向终端发送EOF主动终止当前Shell输入流效果等同于exit但习惯上大家更常用exit。我经常看到有人问“为什么我敲了logout没反应”多半是你当前处在子Shell里比如通过su切换用户但没有用su -或者手动bash进入了一个新的子Shell。这时候用exit才对。2.3 实操演示切换虚拟终端与注销登录Linux默认提供6个文本终端可以通过CtrlAltF1到F6切换F7或更高通常是图形界面。不同的发行版可能略有不同比如Ubuntu桌面版可能CtrlAltF1到F6是文本终端F7回到图形界面。CentOS/RHEL也类似。比如你现在在tty1想切到tty2按CtrlAltF2想退出当前登录直接输入exit。如果想查看当前有哪些登录会话可以用who命令who # 输出示例 # root tty1 2025-01-15 09:32 # zhangsan pts/0 2025-01-15 10:25 (192.168.1.100)第一列是用户名第二列是登录终端tty开头是本地终端pts开头是远程终端比如SSH后面是登录时间和来源IP。这个命令在排查多用户入侵或异常登录时非常实用我建议你把这个命令记牢。3. 用户管理动手添加、删除和查询用户3.1 添加用户useradd与adduser的区别添加用户的命令主要有两个useradd和adduser。这里先给你提个醒在RedHat系发行版CentOS、RHEL、Fedora里useradd和adduser基本是同一个命令只是符号链接或者兼容别名但在Debian系Ubuntu、Debian里adduser是一个Perl脚本它会交互式地帮你创建家目录、设置密码、填备注信息用起来更友好。新手在Ubuntu上直接adduser在CentOS上老老实实用useradd。useradd的常用参数我整理成一张表参数作用示例-m创建家目录useradd -m zhangsan-s指定登录Shelluseradd -m -s /bin/bash zhangsan-d指定家目录路径useradd -m -d /home/zhangsan zhangsan-G指定附加组useradd -m -G wheel zhangsan-u指定UIDuseradd -m -u 1500 zhangsan-c添加备注useradd -m -c Zhang San zhangsan只看参数还不行关键是要理解哪些是必选项。如果你在CentOS上执行useradd zhangsan而不加-m系统不会自动创建/home/zhangsan目录这时候用户登录后会没有家目录可能出现无法写入配置文件的奇怪问题。Ubuntu的useradd默认行为也不一样默认不会创建家目录但adduser会创建。我个人的习惯是不管在哪个发行版上都显式加上-m -s /bin/bash这样行为可预期不会因为发行版差异翻车。创建用户之后还要设置密码否则用户无法登录passwd zhangsan执行后会提示输入两次新密码。注意密码输入的时候不会显示任何字符这不是没输入而是安全设计别被吓到。3.2 查询用户信息id、whoami、finger、w查询用户信息这个环节容易被忽略但它其实最能反映你对系统的掌控度。先看id命令id zhangsan # uid1002(zhangsan) gid1002(zhangsan) 组1002(zhangsan)id会输出用户的UID、主组GID和所有附加组。如果你发现用户不在某个组里用id一眼就能看出来。whoami是“我是谁”输出当前有效用户名适合在脚本里判断当前身份。finger可以查看用户更详细的信息比如真实姓名、家目录、Shell、最后一次登录时间等不过有些系统默认没装finger需要手动安装。w命令是who的升级版能显示当前登录用户以及他们正在执行的命令还能显示load average和uptime。我在排查系统负载异常的时候第一件事就是跑w看是不是有人跑了奇怪的进程。last命令则用来查登录历史会读取/var/log/wtmp文件显示用户、终端、登录时间、登出时间、来源IP。如果有人从异常IP登录过last里能看到。3.3 修改与删除用户usermod与userdel修改用户信息用usermod它和useradd参数长得几乎一样区别在于useradd是新建usermod是修改。常用场景有几个修改用户登录Shellusermod -s /sbin/nologin zhangsan锁定用户禁止登录usermod -L zhangsan解锁用户usermod -U zhangsan修改用户附加组usermod -G docker zhangsan修改用户的家目录usermod -d /new/home -m zhangsan这里特别注意用usermod -G docker zhangsan时如果不加-aappend会把用户从原有附加组里踢出去只保留docker组。所以正确的追加方式应该是usermod -aG docker zhangsan。这个坑我踩过不止一次折腾完发现用户突然不在sudo组里了排查半天才反应过来。删除用户用userdel常用参数是-r表示连同家目录和邮件目录一起删除userdel -r zhangsan如果不带-r用户删除后家目录还会残留时间长了会堆积很多没主的垃圾文件。但反过来如果你有保留该用户数据的需求就别带-r。生产环境删除用户前一定要确认该用户名下是否有系统服务或者计划任务先检查再删除。3.4 实操注意事项UID、家目录与Shell的坑用户管理的坑主要来自几个容易被忽略的地方。第一个是UID冲突。如果你手工指定UID比如useradd -u 1002 zhangsan但系统里已经存在一个UID 1002的用户系统会报错。Linux识别用户其实是靠UID不是靠用户名。你在ls -l里看到文件所有者显示成数字而不是用户名大概率就是那个UID对应的用户已经不存在了。第二个是Shell问题。如果用户被设置为/sbin/nologin或/bin/false他通过SSH登录会直接被拒绝提示“This account is currently not available”。这通常用于那些只需要运行服务、不允许人登录的系统账户。如果哪天你发现某个用户登录不了先用finger 用户名或getent passwd 用户名看一眼他的Shell。第三个是家目录权限。创建用户后家目录的权限默认是700只有用户自己能访问。如果你希望组内其他用户能访问比如共享目录需要单独调整。这是设计使然不是bug。我在搭测试环境时经常要给多个用户开放同一个工作目录这时候就要用用户组配合目录权限来解决具体在第5章展开。4. 切换用户su和sudo别再傻傻分不清4.1 su的基础用法切换用户与加载环境变量suswitch user是我们最常用的切换用户命令。最基础的用法su zhangsan # 切换到zhangsan但保留当前环境变量 su - zhangsan # 切换到zhangsan并模拟其完整登录环境 su - # 直接切换到root并加载root环境有横杠-和没横杠的区别非常关键新手经常因为没加横杠导致环境变量混乱。例如你当前是root执行su zhangsan后你虽然变成了zhangsan的身份但环境变量PATH、HOME可能还是root的这时候你敲echo $HOME会发现还是/root安装或执行某些依赖HOME路径的程序就会出现诡异现象。而su - zhangsan会重新读取zhangsan的登录初始化文件PATH变成/usr/local/bin:/usr/bin:/bin这种普通用户路径HOME变成/home/zhangsan一切回到“zhangsan正常登录”的样子。所以在切换用户时我强烈建议你习惯性带上-。另外普通用户执行su切换到root时需要输入root密码而root切换到其他用户不需要密码。如果你明明知道root密码却提示认证失败看一下是不是键盘布局或者大小写问题我就遇到过密码没错但NumLock没开的尴尬。4.2 sudo的权限委派机制su的弊端很明显普通用户一旦知道root密码就能以root身份干任何事这不是很好的权限管控方式。sudo的出现解决了这个问题普通用户输入自己的密码获得被授予的root权限而不是共享root密码。sudo的配置在/etc/sudoers文件里强烈建议用visudo命令来编辑因为visudo会做语法检查避免你写错配置后sudo直接不可用。一个常见配置是把用户加入wheel组RedHat系或sudo组Debian系该组默认具备sudo权限。所以我们在添加用户时如果希望它能执行管理命令可以这样操作usermod -aG wheel zhangsan # CentOS/RHEL usermod -aG sudo zhangsan # Ubuntu/Debian如果你需要更精细的权限可以在/etc/sudoers里指定zhangsan ALL(ALL) ALL这行含义是用户zhangsan可以从任何主机登录以任何用户身份执行任何命令。还有更精细的比如只允许重启服务zhangsan ALL(ALL) /usr/bin/systemctl restart nginx这样zhangsan只能执行指定命令其他sudo命令一律拒绝。4.3 实操对比su - root vs sudo su很多教程会告诉你直接sudo su切到root但这个操作其实值得琢磨一下。sudo su的意思是先用sudo的权限执行su因为sudo已经把当前用户临时提升为root所以su不需要再输入root密码直接变成root。这种方式有没有问题有。一是日志层面/var/log/secure里记录的会变成当前用户通过sudo执行了su但后续所有操作仍然以root身份进行审计线索会被模糊掉。如果运维规范强调审计更推荐的做法是每一条管理命令都加sudo而不是一次性切到root乱搞。二是权限管控失效。如果所有普通用户都能sudo su那sudo的精细授权就名存实亡了。所以好的习惯是少用sudo su尽量用sudo command直接执行某条命令。如果需要持续操作就明确使用su - root并输入root密码至少在审计上是清晰的。我在实际工作中日常管理服务器都是用自己的普通账号加上sudo执行具体命令只有需要批量修改系统配置、安装软件包时才会su到root。这个习惯能帮你减少很多“误操作把系统搞挂”的风险。5. 用户组所有者、所在组和其他组5.1 用户组的概念为什么要分组用户组group就是把一堆用户归到一个集合里方便统一管理权限。Linux的权限模型里每个用户必须属于一个主组primary group同时可以属于多个附加组supplementary groups。主组决定用户创建文件时默认的组归属附加组决定用户能访问哪些额外权限资源。我们为什么需要用户组典型场景一个项目组有三个人要在服务器上共享一个目录但又不希望其他用户看到。如果逐个用户给目录授权权限会非常混乱。正确的做法是创建一个dev组把三个人加进去然后把共享目录的所属组改成dev目录权限设置为770这样只有dev组内的用户能读、写、执行其他用户一概不能访问。用户组信息保存在/etc/group文件里每个组一行格式是组名:密码占位符:GID:组成员列表比如dev:x:1005:zhangsan,lisi,wangwu。组成员列表只包含附加组用户不包含主组成员。5.2 关键命令groupadd、usermod -G、gpasswd创建用户组用groupaddgroupadd dev如果需要指定GID加-g 2000。删除组用groupdel但前提是该组不是任何用户的主组。如果你删一个正在使用的主组系统会报错这是保护机制。把用户加入组可以用usermod也可以用gpasswdusermod -aG dev zhangsan gpasswd -a zhangsan dev # 和上面等效把用户移出组gpasswd -d zhangsan dev注意usermod -G不带-a是覆盖式修改前面第3章已经提过这里再说一遍日常维护中除非你真的想清空用户的附加组否则不要丢-a。另外一个隐藏知识点用户加入新组之后如果当前已经登录组权限不会立即生效必须重新登录或者使用newgrp命令激活。5.3 文件权限三元组中的所有者、所在组和其他组理解了用户组才能看懂Linux文件权限的长列表。随便找一个文件跑ls -l你会看到类似这样的输出-rw-r--r-- 1 root root 1234 Jan 15 10:00 test.txt权限位rw-r--r--共9个字符按3个一组划分所有者user所在组group其他用户other。所有者就是文件创建者所在组就是文件归属的用户组其他组就是除前两者之外的所有用户。每个组有r读、w写、x执行三个权限位。第5.1节的例子共享目录权限770表示所有者和所在组都有rwx权限其他用户什么都没有0。修改文件所有者和所在组的命令是chown和chgrpchown zhangsan:dev test.txt # 修改所有者为zhangsan所在组为dev chgrp dev test.txt # 只修改所在组 chown :dev test.txt # 同上只修改所在组修改权限用chmod既可以用数字r4, w2, x1也可以用符号chmod 770 test.txt chmod urwx,grwx,o-rwx test.txt # 效果一样5.4 实操示例创建组并分配用户实现目录隔离我在这里给你演示一个完整的操作流程这也是我在搭项目环境时常用的一个模板。假设我要在/data/project下建共享目录让dev组里的三个用户可以访问其他用户禁止访问。# 1. 创建用户组 groupadd dev # 2. 创建三个用户并加入dev组 useradd -m -s /bin/bash zhangsan useradd -m -s /bin/bash lisi useradd -m -s /bin/bash wangwu usermod -aG dev zhangsan usermod -aG dev lisi usermod -aG dev wangwu # 3. 创建共享目录并设置属组和权限 mkdir -p /data/project chown root:dev /data/project chmod 770 /data/project # 4. 验证 ls -ld /data/project # drwxrwx--- 2 root dev 6 Jan 15 11:00 /data/project这样设置后dev组三名成员都能在/data/project里创建和修改文件其他用户连进入目录的权限都没有。但有个细节要注意默认情况下用户在共享目录里新建的文件用户主组如果是dev新建文件的所在组就是dev如果用户主组是zhangsan自己新建文件的所在组就是zhangsan而不是dev这样组内其他人就没法改了。所以如果希望所有人在共享目录里创建的文件都自动归dev组需要设置目录的setgid位chmod 2770 /data/project权限数字前多出来的2就是setgid位。设置后任何人在该目录创建新文件文件的所在组自动继承为dev组。这个细节非常实用也是很多运维面试喜欢考的隐藏点。6. 常见问题与排查技巧实录6.1 用户创建后无法登录表现用户用SSH登录一直提示密码错误或者密码正确但连接被拒绝。排查步骤用getent passwd 用户名确认用户存在。用passwd -S 用户名查看用户状态L开头说明被锁定了passwd -u解锁。检查/etc/shadow里密码字段是否显示为!或*是的话说明没有正常设置密码。检查用户Shell是否被设为/sbin/nologin如果是且确实需要登录用usermod -s /bin/bash改回来。还有一个容易被忽略的SSH服务如果限制了AllowUsers就算系统账号正常也登不进去检查/etc/ssh/sshd_config里有没有AllowUsers或AllowGroups配置。6.2 切换用户后提示符没有变化表现执行su zhangsan后命令行提示符依然是之前的root或用户名敲whoami却显示新用户令人困惑。原因su不带-不会切换环境变量PS1提示符变量也没有被重新加载。解决办法不是去改PS1而是切换时使用su - zhangsan。如果你确实想保留当前环境又想清晰看到身份可以手动执行bash加载login shell配置但更好的选择还是用su -。我见过很多新手在这上面纠结其实只要记住需要完整登录环境就用带横杠的su只需要快速切换身份执行命令就临时用不带横杠的su然后命令执行完exit回来。6.3 删除用户后文件归属显示为数字UID表现删除用户后ls -l显示文件所有者和所在组变成一串数字。原因系统只通过UID和GID来识别用户和组删除用户后UID和GID在用户数据库里不存在了系统没法反查名字只能显示原始数字。如果这个文件还有保留价值可以把它的属主改为现有用户chown -R zhangsan:zhangsan /path/to/file如果文件确实不需要了直接删除即可。这其实也是提醒我们删除用户前一定要先盘点它遗留的文件特别是/var/spool、/home和临时目录下的东西。6.4 用户加入组后权限不生效表现执行usermod -aG docker zhangsan后zhangsan已经登录但执行docker命令还是提示权限不足。原因用户会话在启动时就已经确定了Groups成员关系新加入的组需要重新登录才能生效。解决办法是退出当前会话重新登录或者使用newgrp docker快速切换当前Shell的有效组。对于没有安装newgrp的环境直接重新SSH登录即可。这个问题的本质是内核在创建进程时把附加组ID列表固化到了进程里不会动态更新。所以如果你在写自动化脚本需要立即生效可以考虑用sg docker -c command来指定组执行命令。6.5 误删了用户组导致用户状态异常表现某个用户报错id: cannot find name for group ID 1002或者用户组信息丢失。原因可能你删除了某个用户指定的主组。系统不会阻止这种行为但这个用户的GID已经指向不存在的组显示时就会出现找不到组名的情况。修复方法先用id确认现有GID再创建一个新的组号为原GID的组或者直接修改用户主组groupadd -g 1002 oldgroup usermod -g oldgroup username我更推荐后者逻辑清晰也不会引发文件归属混乱。如果用户已经有很多文件归属旧GID重新建组能让这些文件的组归属恢复显示。7. 几个值得长期坚持的实操习惯最后分享几个我在实际使用中慢慢养成的习惯这些不是命令手册上会写的但确实能帮你少走弯路。第一添加用户永远显式指定-m -s /bin/bash这样家目录一定存在Shell一定可用不受发行版默认策略影响。如果你创建的是系统账户比如跑Nginx的账户那就用-r参数系统账户不建家目录、不给交互Shell权限尽量最小。第二凡是修改用户组的操作统一使用usermod -aG把“追加”写进肌肉记忆。覆盖式-G只有在你想重置用户附加组时才用而且要格外小心。第三在生产环境操作前先备份关键配置文件尤其是/etc/passwd、/etc/shadow、/etc/group、/etc/sudoers。Linux用户管理虽然灵活但一旦改错轻则普通用户登不进去重则root权限丢失。我通常在批量操作前执行cp -p /etc/passwd /etc/passwd.bak.$(date %Y%m%d) cp -p /etc/shadow /etc/shadow.bak.$(date %Y%m%d) cp -p /etc/group /etc/group.bak.$(date %Y%m%d) cp -p /etc/sudoers /etc/sudoers.bak.$(date %Y%m%d)第四多练多试。用户管理是Linux里最基础也最核心的一块你可以拿虚拟机反复折腾创建用户、加组、改权限、删用户把每个命令的输出仔仔细细看一遍。熟了之后后面学文件权限、进程权限、容器权限都会轻松很多。第五遇到权限相关的问题先看id输出再看文件权限位最后看进程是什么身份启动的。这个排查顺序可以解决90%以上的“明明有权限但操作不了”的疑难杂症。