1. 账号管理的核心逻辑与实操
1.1 用户、组与UID/GID的基本概念
Linux是一个多用户多任务的操作系统,这就决定了它必须有一套完整的机制来区分不同的人和不同的权限边界。当年刚接触Linux时,我犯过一个典型的错误:拿到服务器第一件事直接用root登录,然后所有操作都在root下进行,结果某次误删了一个目录,连带把另一个项目的配置文件也带走了。从那之后,我才真正开始重视Linux账号和权限管理这个基本功。
要理解账号体系,先要清楚Linux里“用户”其实是一个数字身份的抽象。每个用户对应一个唯一的UID,用户组对应GID。系统真正识别的不是用户名,而是这一串数字。用户名是给人看的,UID/GID是给内核看的。你可以在/etc/passwd里看到所有用户的基本信息,但密码并不在这里,而是在/etc/shadow文件里,后者只有root或具备相应权限的账号才能读取。
/etc/passwd中每一行由7个字段组成,用冒号分隔,依次是:用户名、密码占位符、UID、GID、注释信息、家目录、登录Shell。比如:
code复制user01:x:1001:1001::/home/user01:/bin/bash
这里的x就是密码占位符,真正的密码哈希存在/etc/shadow中。系统内置了一些伪用户,比如bin、daemon、adm等,它们通常是服务运行所需的账号,不建议手动改动。UID为0的用户是超级用户,只有一个root,这个规则也是权限模型的基础。理解这一点之后,再去看useradd、usermod、userdel系列命令,就不会觉得它们是零散的了。
1.2 用useradd和usermod正确创建账号
我见过不少新手用useradd建完用户后,发现用户既没有家目录,也没有设置密码,登录之后连Home都没了。原因是CentOS和Ubuntu的useradd默认行为不同,这在面试题里出现过很多次。CentOS系列中useradd会默认创建家目录和Mail Spool,而Debian/Ubuntu系列的默认策略则依赖于/etc/login.defs和/etc/default/useradd配置。
实操中我建议显式指定参数,而不是依赖默认值。创建一个标准的业务账号,我会这样操作:
bash复制useradd -m -d /home/appuser -s /bin/bash -c "Application User" appuser
-m:强制创建家目录-d:指定家目录路径,如果路径和用户名不是默认对应关系,这个参数就很关键-s:指定登录Shell,如果这个用户只跑服务不需要交互登录,可以指定为/sbin/nologin-c:添加注释,团队协作时注释一个“这是谁、干嘛用的”,几个月后你回来看账号列表,会感激当初写注释的自己
创建完用户后立即设置密码或锁定密码。如果暂时不需要密码登录,可以用passwd -l username锁定,或者直接设置一个随机密码:
bash复制echo "RandomStr_2024" | passwd --stdin appuser
注意--stdin这个参数是CentOS系列支持的写法,Debian/Ubuntu下不识别,需要用chpasswd命令替代。这个是跨发行版操作常见的坑。
用usermod可以修改已有用户的属性。给用户追加到附加组、修改家目录、修改Shell、锁定或解锁账号,是日常运维的高频操作:
bash复制usermod -aG docker appuser
usermod -d /newhome/appuser -m appuser
usermod -s /sbin/nologin appuser
-aG这里一定要带上-a,表示append追加,不加-a的话会把用户从原来的附加组里全部移除,只保留新加的组。这个坑我踩过一次,当时一个同事本来在组dev里,我用usermod -G ops把他加进运维组,结果他瞬间失去了dev组的所有权限,报障电话立刻打过来。
1.3 /etc/skel目录与登录Shell的联动
创建用户时,家目录中的初始化文件来自/etc/skel目录。这个目录里默认有.bashrc、.bash_profile、.profile等文件。如果你希望新建用户默认带有某些环境变量、别名或脚本,把它们放到/etc/skel里即可。
举个例子:公司统一使用私有仓库,需要新用户默认配置npm或pip的镜像源,我在/etc/skel/.bashrc末尾追加了:
bash复制export PIP_INDEX_URL=https://mirrors.private.com/pypi/simple
alias ll='ls -lhtr'
这样以后所有新建用户都会自动带上这些配置,不用再一个个去补。这里有个细节:/etc/skel的改动只影响新建用户,对已存在的用户不生效。如果要批量修改存量用户,得写个循环脚本遍历/home下的目录逐个追加。这种批量操作最好先在一台测试机上验证,或者从一个用户开始,确认没有问题再全量执行。
关于登录Shell,我特别建议为服务账号指定/sbin/nologin而不是/bin/bash。比如运行Nginx的nginx用户、运行MySQL的mysql用户,它们本质上是服务进程的身份载体,不是给人登录用的。如果给了bash,一旦Web应用被入侵,攻击者直接su nginx拿到
