拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Ubuntu 新建用户并赋予 sudo 管理权限:完整流程与排错指南

Ubuntu 新建用户并赋予 sudo 管理权限:完整流程与排错指南

在 Ubuntu 上新建用户并赋予管理权限,看起来是个两三分钟就能搞定的小事,但我在工作中见过太多因此翻车的案例:有人直接把 /etc/sudoers 改坏,导致整台机器上没人能用 sudo;有人用 useradd 建完用户后忘记创建家目录,程序启动时疯狂报错;还有人图省事把所有账号都塞进 sudo 组,结果一条误操作把数据库目录清空。这篇文章就不绕弯子,直接把 Ubuntu 22.04 上从 adduser 新建用户,到用 usermod 和 visudo 赋予管理权限,再到验证和排错的完整链路讲清楚。不管你刚接触 Linux 还是在生产环境做运维,按这套流程走,既能开箱即用,又能避开常见的坑。

1. 整体思路拆解:为什么建独立用户,而不是直接操作 root

1.1 直接使用 root 的隐患

很多教程,尤其是老版的 Linux 入门资料,上来就让你用 root 登录,然后在 root 家目录下做一切事情。这种习惯在一次性虚拟机里没什么问题,但放到长期使用的服务器上,风险非常大。

root 是系统里权限最高的账号,它不需要任何审批机制,rm -rf 这类命令敲下去就直接执行了,系统不会拦你,也不会提醒你。之前在帮客户做等保检查时遇到过一台机器,某位同事在 root 环境下清理日志,路径写错一个字符,直接删掉了 /var 下的数据库目录。如果当时用的是普通用户加 sudo,至少还有一次密码确认的机会,能让人停下来想一想。

另外,多人协作时如果大家都拿 root 上手,服务器上就没有身份区分了。出了问题排查日志,只能看到 root,看不到具体是谁在何时执行了哪条命令。而独立用户的方案就清晰很多:每个人有自己的账号,操作时通过 sudo 提权,系统的 auth.log 和 journald 会在第一时间记录下命令来源。

所以在 Ubuntu 22.04 上,正规做法永远是:先建普通用户,再按需给管理权限。这也是这篇文章的出发点。

1.2 adduser 与 useradd 怎么选

Ubuntu 系统里有两个建用户的命令:adduser 和 useradd。第一次接触的人经常混,因为它们在命令行只差一个字母,行为却天差地别。

useradd 是系统原生的低级工具,它很机械:你给它什么参数它就做什么,不会主动创建家目录,不会帮你设置密码,也不会复制 /etc/skel 下的默认配置文件。这是因为它面向的是脚本和自动化场景,一切行为都要由调用方显式指出。如果新手直接用 useradd 建用户,后面往往会发现 home 目录不存在,登录后连命令提示符都不正常。

adduser 则是对 useradd 的 Perl 封装,它把创建用户的全流程串起来了:自动建家目录、自动复制 /etc/skel 里的文件、自动设置用户 shell、交互式让你填密码和用户信息。对新手最友好,对老手来说也省事。

所以我在这篇文章里主推 adduser,日常交互操作基本都用它。如果你以后要写部署脚本,那再去研究 useradd 也不迟,后面会额外补充非交互式的命令写法。

1.3 sudo 权限组的工作原理

Ubuntu 的默认 sudo 配置里,其实预先定义好了两个管理组:sudo 组和 admin 组。你打开 /etc/sudoers 就能看到类似下面的规则:

%sudo ALL=(ALL:ALL) ALL %admin ALL=(ALL:ALL) ALL

第一列的 %sudo 表示组名,后面几个 ALL 分别代表主机名、可切换成哪个用户、以及可执行什么命令。翻译成人话就是:只要某个用户属于 sudo 组,它就能在任意主机上,以任意用户身份,执行任意命令。

这也是 Ubuntu 和 RHEL 系发行版的一个重要区别:RHEL 系列默认管理组是 wheel,Ubuntu 则是 sudo 或 admin。如果你之前习惯改 /etc/sudoers 给用户添加 wheel 组,迁移到 Ubuntu 就很容易踩空。选对组名,权限才给得进去。

将这些规则理清楚之后,下面进入实操环节。

2. 动手前确认环境:版本、当前账号与 sudo 状态

2.1 用两条命令确认 Ubuntu 版本

不管是新装的系统还是接手别人留下的旧服务器,第一步永远先看版本。很多旧资料沿用 18.04 或 20.04 的包名和配置路径,搬到 22.04 上不一定兼容。

看版本很简单:

lsb_release -a cat /etc/os-release

如果系统里没有 lsb_release 命令,那就看 /etc/os-release,Ubuntu 22.04 的内容会明确写着 VERSION_ID="22.04",版本名称是 jammy。确认好版本,后面的源配置和软件安装才有基础。

2.2 确认当前用户是谁、有没有 sudo 权限

接下来要确认自己现在的身份,以及是否具备提权条件。用以下三条命令:

whoami id sudo -l

whoami 看当前用户名,id 看 uid、gid 和所属组,sudo -l 列出当前用户被允许执行的 sudo 命令。假如你本来就是 root,可以在创建用户时省略 sudo 前缀;假如当前用户在 sudo 组里,那就直接走正常流程;如果 sudo -l 报错,说当前用户不在 sudoers 文件中,说明这个账号本身没有管理权限,你得先想办法用别的管理员把它加进去,否则后面什么也做不了。

2.3 顺手检查软件源和系统时间

创建用户本身不依赖网络,也不依赖软件源,但创建完成后往往想马上装个软件验证权限,所以建议顺便确认两点。

第一是软件源状态,执行一次:

sudo apt update

能正常拉取索引就没有问题。第二是系统时间,date 命令看一眼。时间偏差会导致 sudo 相关认证异常,这类故障排查起来非常隐蔽,日志里也不会直接提示时区问题。如果你后面遇到 sudo 反复询问密码、明明输对了却说密码错误,可以先怀疑时间同步。

3. 新建用户完整流程:adduser 命令一步步详解

3.1 交互式创建用户

现在开始建用户。以创建一个名为 deploy 的账号为例,命令是:

sudo adduser deploy

当前是 root 的话可以去掉 sudo。执行后 adduser 会自动配置 shell 为 /bin/bash,创建 /home/deploy 家目录,并把 /etc/skel 下的默认隐藏文件复制进去。然后它会进入交互界面,先让你设置密码,再让你填一堆可选信息。

3.2 交互过程中每个字段的含义

整个交互过程大致是这样的:

  • 输入新用户的密码,确认密码。要注意终端里输入密码时不会显示任何字符,这是正常行为,不是键盘坏了。
  • 接下来是 Full Name,直接回车跳过即可。
  • 然后是 Room Number、Work Phone、Home Phone、Other,这些默认信息在绝大多数场景都不需要,一路回车。
  • 最后会问 Is the information correct?,输入 Y 确认。

确认后,adduser 会完成用户创建、家目录初始化等工作。这里有一个关键点:adduser 默认建出来的用户只是一个普通用户,不属于 sudo 组,也不能执行 sudo。所以你输完密码以为大功告成,其实管理权限还在下一步。

也许有人会问,既然最终要管理权限,为什么不直接在 adduser 里把组一次性加上?adduser 本身没有加 sudo 组的标准参数,而且在实际工作中,建账号和给权限往往是两个审批步骤。先建普通账号,再授权,逻辑上更清晰,也方便审计。

3.3 创建后立即检查家目录和属主

建完用户不要急着走,先用下面两条命令验证:

id deploy ls -ld /home/deploy

id 会显示该用户当前的 uid、gid 和 groups。正常情况下,groups 里只有 deploy 自己,看不到 sudo。ls -ld 则验证家目录是否归属 deploy。如果显示的属主是 root,后续用户会无法正常写入自己的 home,出现各种权限报错。遇到这种情况,用 chown 修一下:

sudo chown -R deploy:deploy /home/deploy

但更推荐从源头确认,adduser 默认不会犯这个错,除非你之前手动动了什么配置。

3.4 非交互式创建用户的方法

写脚本或者批量初始化机器时,没法像交互式那样一路回车,这时候用 useradd 更合适。例如:

sudo useradd -m -s /bin/bash -G sudo -p $(openssl passwd -6 'YourPass123') ops

这里 -m 表示创建家目录,-s 指定 shell,-G sudo 表示直接把用户加入 sudo 组,-p 接收的是加密后的密码,不是明文,所以要先用 openssl passwd 或 mkpasswd 生成哈希。如果你不想在命令行里写哈希,也可以先用 useradd 建普通用户,再用 passwd 交互式设密码,最后用 usermod -aG sudo 加入管理组,效果完全一样。

4. 赋予管理权限的三种操作方案

4.1 方案一:用 usermod -aG sudo 加入管理组

把用户加入 sudo 组,最常见也最不容易出错:

sudo usermod -aG sudo deploy

这个命令里有几个细节非常重要。第一,-a 表示 append,也就是追加,不是覆盖。如果漏写 -a,命令会变成 -G sudo,这时候系统会把用户从所有其他附加组中移除,只保留 sudo 这一个组,导致用户原本所在的 docker、developers 等组权限全部丢失。第二,-G 后面指定的是附加组,这里写 sudo。

加组后不需要重启机器,但当前会话不会立刻刷新。新用户需要注销重新登录,或者执行 newgrp sudo 临时刷新一次组信息,然后才能让 sudo 生效。

4.2 方案二:用 visudo 在 sudoers 主文件里加规则

另一种方式是直接编辑 /etc/sudoers,给指定用户单独写一条授权规则。但这里我必须强调:永远别用 vim 直接打开 /etc/sudoers 改,一定用 visudo。

原因在于,visudo 保存时会检查语法,如果语法错误,它会阻止保存并提示修复选项。而 vim 直接编辑的话,哪怕只打错一个符号,也有可能让整个系统里所有用户都无法执行 sudo,到时候你连恢复错误的机会都没有,只能进单用户模式或救援盘。

在 visudo 打开的界面里,找到类似的一行:

root ALL=(ALL:ALL) ALL

在其下方插入:

deploy ALL=(ALL:ALL) ALL

保存退出。这种方案的价值在于,它为特定用户写了一条显式规则,运维审计时能直观看到谁有权限。如果你只想给单个用户开完整管理权限,不打算让整个组都拥有,这个方案比加组更精确。

4.3 方案三:在 /etc/sudoers.d/ 下创建独立规则文件

如果你的机器上会有多个用户和多种权限需求,我强烈推荐第三种方式:在 /etc/sudoers.d 目录下为每个用户或每个业务建一个独立文件。

Ubuntu 默认在 /etc/sudoers 文件末尾 include 了这个目录,所以你不用改主文件,只要把新文件放进去即可。编辑时同样建议用 visudo 的专用参数:

sudo visudo -f /etc/sudoers.d/deploy

然后写入:

deploy ALL=(ALL:ALL) ALL

保存退出后,权限立即生效。这个方案最大的优点是模块化:多个用户的规则互不干扰,哪怕其中某个文件写坏了,影响的也只是一个独立文件,不至于牵连整个 sudo 配置。清理时也更方便,删除对应文件就撤销了相关授权。

4.4 三种方案怎么选

我一般按场景这样区分:

方案复杂度适用场景优点注意点
usermod -aG sudo低单用户授权、个人开发机命令简单,符合 Ubuntu 社区习惯授权粒度较粗,组内成员可执行任意命令
visudo 主文件规则中单个用户精确授权规则直观,审计方便主文件内容多了之后有合并风险
/etc/sudoers.d 独立文件中多用户、批量运维场景模块化、易清理需要记得目录存在,别漏看 include

就个人日常使用而言,我 90% 的场景都用 usermod -aG sudo,因为它符合 Ubuntu 的用户习惯,而且 id 命令一看就知道权限范围。到了生产环境要做命令级白名单时,再去建 /etc/sudoers.d 文件。

5. 验证权限与高频故障排查

5.1 从新用户视角验证 sudo 是否生效

授权完成后,别急着安心,先切换过去实测一次:

su - deploy sudo whoami

这里有个小坑:如果你使用 su deploy 而不是 su - deploy,环境变量可能残留上一个用户的状态,sudo 有时会报一些诡异的问题。su - 会完整加载目标用户的环境,所以习惯上要带横杠。

sudo whoami 如果输出 root,说明管理权限已经生效。然后再执行 sudo -l,它会详细列出当前用户在所有主机上被允许执行的命令。看到形如 (ALL : ALL) ALL 的内容,就说明授权没有遗漏。

5.2 高频故障速查表

我把这些年常遇到的情况整理成一个表,覆盖了大部分求助帖里的问题。

现象原因解决办法
user is not in the sudoers file用户不在 sudo 组,也没有显式规则用有权限的账号执行 usermod -aG sudo 用户名
不在 sudoers 文件中,此事将被报告授权未生效,或者组被误删让用户重新登录,检查 /etc/sudoers 语法
sudo: unable to resolve host/etc/hosts 里的主机名和系统 hostname 不匹配修改 /etc/hosts,添加本机主机名解析
Sorry, user xxx is not allowed to executesudoers 规则中的主机别名或命令范围写错用 visudo 检查规则,修正 ALIAS 定义
新用户 sudo 一直提示密码,密码绝对没错系统时间偏差或 PAM 配置异常同步时间,检查 /etc/pam.d/sudo
登录后命令行提示符异常,没有家目录useradd 没加 -m 参数手动创建家目录并 chown 给用户
用户已在 sudo 组但 sudo 仍失败当前会话组信息没刷新用 newgrp sudo 或重新登录

5.3 排查权限问题的正确顺序

排查权限问题时,我习惯按这个顺序来,能省不少时间。

先看 id,确认用户当前属于哪些组。再看 /etc/sudoers 和 /etc/sudoers.d 下有没有相关规则。最后翻日志。Ubuntu 22.04 上,sudo 的每次成功和失败都会记录到认证模块中,查看命令是:

journalctl -u sudo grep sudo /var/log/auth.log

如果用户被拒绝,auth.log 里会直接写明 user not in sudoers 或者 command not allowed。相比对着配置文件猜,日志给出的信息要准确得多。我调试过一次环境变量导致的诡异问题,最后就是靠 auth.log 发现了一个重复的 PAM 配置,这种情况只看 sudoers 永远找不到答案。

6. 权限管理的安全加固与使用心得

6.1 sudo 免密配置怎么做,以及风险在哪

有些自动化脚本不希望每次执行 sudo 都要求输入密码,可以在规则里加 NOPASSWD:

deploy ALL=(ALL) NOPASSWD: ALL

这样配置后,deploy 用户执行 sudo 时不再提示密码。但也要清醒地认识到风险:如果这个账号被爆破或者泄露,攻击者可以直接在整台机器上执行任意命令,连二次确认都没有。所以我建议只在受控的 CI 环境、或一次性测试机中使用免密,并且最好配合下面讲到的命令白名单一起限制。

6.2 限制 sudo 命令范围,把权限缩小到业务所需

如果想给用户一个能管理 nginx 服务但不具备完全 root 能力的账号,可以这样写规则:

deploy ALL=(ALL) /usr/bin/systemctl restart nginx, /usr/bin/systemctl status nginx

要注意,sudoers 里的命令路径必须写绝对路径,可以用 which systemctl 查清楚。这个粒度在生产环境非常实用:既满足日常操作,又不至于让账号拥有无边界的 root 能力。如果你是从 CentOS 迁移过来,记得先确认命令路径,因为两边工具链位置可能不一样,配置好后再用 sudo -l 验证。

6.3 定期梳理有管理权限的账号

机器用久了,总会堆积一些临时账号、离职员工的账号,或者测试用的虚拟账号。我的习惯是定期列出所有具备 sudo 能力的账号:

grep -E "sudo|admin" /etc/group | awk -F: '{print $4}'

再结合 /etc/sudoers 和 /etc/sudoers.d 里的规则,逐条确认。长期不用的账号及时删除,删除命令是:

sudo deluser --remove-home username

它会移除用户并清理家目录。执行前要先确认这个用户没有正在运行的进程,否则会有文件占用,清理不干净,残留一堆僵尸家目录。

6.4 一条长期有效的黄金法则

关于 sudo 配置,我有几条十几年没变过的原则,每次接手新机器都会对照执行。

sudoers 文件永远用 visudo 改,不用 vim 直接改。

授权永远从最小权限开始,缺什么再补什么,而不是一开始就 ALL。

多用户环境尽量使用 /etc/sudoers.d 拆分规则,少动主文件。

不轻易给普通用户添加 NOPASSWD,除非你完全清楚后果。

每次改完权限,立刻新开一个终端验证,不要拖到下次登录才发现问题。

这些原则看起来很小,但就是它们决定了运维事故是多还是少。跑过几年生产环境的人应该都会同意,权限管理最怕的不是配置复杂,而是无规则地瞎给。新建用户、给 sudo,只是整套权限体系的起点,真正值钱的是你愿不愿意花时间去看 auth.log、梳理 sudoers 规则、评估每个账号的最小权限。希望这篇基于 Ubuntu 22.04 的完整流程能帮你少踩我踩过的那些坑,把账号权限管理做得既安全又顺手。

返回列表