Linux sudo 的工作机制

发布时间 - 2026-01-26 00:00:00    点击率:
sudo 权限唯一来自 /etc/sudoers,按行匹配用户、主机、目标身份、命令四要素,首条匹配即生效;验证的是用户自身密码(PAM),非 root 密码;执行时以 root 身份调用 seteuid 切换有效 UID,环境变量默认被清理。

sudo 是怎么知道谁有权限的?

sudo 的权限来源只有一个地方:/etc/sudoers。它不是读取用户组(比如 sudowheel)就直接放行,而是严格按该文件里定义的规则逐行匹配:用户、来源主机、可切换身份、允许执行的命令——四者全对才通过。哪怕你被加进了 %sudo 组,如果那一行被注释了或写在了拒绝规则后面,照样被拒。

  • 永远用 visudo 编辑 /etc/sudoers,它会语法检查,避免锁死 sudo
  • 规则顺序很重要:sudo 从上到下匹配,遇到第一条匹配即停止,不会继续找“更精确”的
  • ALL=(ALL:ALL) ALL 看似宽松,但若前面有 user1 ALL=(root) /bin/ls,user1 就只能跑 ls,后面的 ALL 不生效

为什么输的是自己的密码,而不是 root 的?

因为 sudo 的设计哲学是「验证操作者身份」,不是「获取 root 账户凭证」。它要求你证明“此刻坐在终端前的就是你本人”,所以校验的是你的用户密码(由 PAM 模块完成),而非 root 密码。这也是它比 su 更安全的基础——root 密码无需暴露给普通用户。

  • 若配置了 NOPASSWD,这一步直接跳过,但仅限于规则中明确列出的命令
  • 密码错误三次后,sudo 默认会记录日志并可能触发告警(取决于 /etc/sudoers 中的 badpass_message 或 syslog 配置)
  • 输入密码时屏幕不显示任何字符(包括 *),这是故意的安全行为,不是卡住了

执行命令时,权限到底怎么切换的?

sudo 并不启动新 shell 再 setuid,而是自身以 root 权限运行,fork 出子进程后,在子进程中调用 seteuid()setegid() 切换有效 UID/GID,再 execve() 执行目标命令。这意味着:命令看到的 geteuid() 是 root,但 getuid() 仍是原用户——部分程序(如某些脚本检测)会据此判断是否“真 root”。

  • 环境变量默认被清理,PATH 重设为 secure_path(在 /etc/sudoers 中定义),所以 sudo myscript.sh 可能报 command not found,即使 myscript.sh 在你 home 下
  • 要用当前环境变量,得加 -E;要完整继承 shell 环境(含 alias、函数),得用 sudo -isudo -s
  • sudo -u user2 cmd 时,实际是以 root 身份调用 seteuid(user2),不是先 su 到 user2 再执行——所以 user2 的 shell 配置文件(如 ~user2/.bashrc)不会自动加载

为什么有时输完密码还提示“不在 sudoers 文件中”?

这不是权限不足,而是根本没被授权——sudo 在解析 /etc/sudoers 时,连你的用户名都没匹配上任何一条规则。常见原因不是漏加用户,而是:用户属于 %sudo 组,但该组那行被注释了;或用了 Defaults requiretty,而你在非 tty 环境(如 cron、SSH 无 PTY)下调用 sudo;又或者系统用的是 wheel 组策略(如 CentOS),但你被加进了 sudo 组。

  • 快速自查:运行 sudo -l,如果直接报错“not in sudoers file”,说明零授权;如果列出了命令,说明有权限但可能受限
  • 别手动改 /etc/sudoers 权限(如 chmod u+w),现代发行版多启用

    sudoers.d
    目录,推荐把自定义规则放进 /etc/sudoers.d/myrule 并保持 0440 权限
  • SELinux 或 AppArmor 启用时,还可能拦截 sudo 行为,此时 dmesg | grep avc 会看到拒绝日志
真正容易被忽略的是:sudo 的“5 分钟免密窗口”是 per-tty 的,不是 per-user。你在终端 A 输过密码,终端 B 仍要再输一次;而且这个计时器只对成功认证有效,输错三次后,下次成功仍要重新认证——这些细节在自动化脚本或 tmux 多窗格场景下常引发意外中断。


# linux  # centos  # app  # 环境变量  # 配置文件  # 为什么  # 继承  # ssh  # 自动化  # 的是  # 你在  # 进了  # 自己的  # 这是  # 出了  # 都没  # 是怎么  # 设为  # 计时器 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: php打包exe后无法访问网络共享_共享权限设置方法【教程】  Laravel storage目录权限问题_Laravel文件写入权限设置  LinuxCD持续部署教程_自动发布与回滚机制  千库网官网入口推荐 千库网设计创意平台入口  javascript事件捕获机制【深入分析IE和DOM中的事件模型】  Laravel如何处理和验证JSON类型的数据库字段  javascript中数组(Array)对象和字符串(String)对象的常用方法总结  C++时间戳转换成日期时间的步骤和示例代码  微信小程序 wx.uploadFile无法上传解决办法  大连网站制作公司哪家好一点,大连买房网站哪个好?  Laravel如何从数据库删除数据_Laravel destroy和delete方法区别  如何获取上海专业网站定制建站电话?  Laravel怎么实现搜索功能_Laravel使用Eloquent实现模糊查询与多条件搜索【实例】  如何在 Go 中优雅地映射具有动态字段的 JSON 对象到结构体  Python自动化办公教程_ExcelWordPDF批量处理案例  如何在云主机快速搭建网站站点?  如何快速搭建高效简练网站?  深圳网站制作的公司有哪些,dido官方网站?  EditPlus中的正则表达式 实战(4)  如何在云主机上快速搭建网站?  智能起名网站制作软件有哪些,制作logo的软件?  uc浏览器二维码扫描入口_uc浏览器扫码功能使用地址  Laravel如何实现多对多模型关联?(Eloquent教程)  Windows家庭版如何开启组策略(gpedit.msc)?(安装方法)  Laravel Telescope怎么调试_使用Laravel Telescope进行应用监控与调试  如何用AI一键生成爆款短视频文案?小红书AI文案写作指令【教程】  如何在建站主机中优化服务器配置?  ChatGPT怎么生成Excel公式_ChatGPT公式生成方法【指南】  太平洋网站制作公司,网络用语太平洋是什么意思?  如何在搬瓦工VPS快速搭建网站?  Laravel如何集成第三方登录_Laravel Socialite实现微信QQ微博登录  Laravel怎么实现观察者模式Observer_Laravel模型事件监听与解耦开发【指南】  ,交易猫的商品怎么发布到网站上去?  Laravel如何使用Livewire构建动态组件?(入门代码)  Laravel如何记录日志_Laravel Logging系统配置与自定义日志通道  如何基于PHP生成高效IDC网络公司建站源码?  韩国服务器如何优化跨境访问实现高效连接?  香港服务器网站搭建教程-电商部署、配置优化与安全稳定指南  Laravel如何实现本地化和多语言支持?(i18n教程)  Win11怎么关闭专注助手 Win11关闭免打扰模式设置【操作】  零基础网站服务器架设实战:轻量应用与域名解析配置指南  手机怎么制作网站教程步骤,手机怎么做自己的网页链接?  PythonWeb开发入门教程_Flask快速构建Web应用  如何在不使用负向后查找的情况下匹配特定条件前的换行符  Win11怎么恢复误删照片_Win11数据恢复工具使用【推荐】  iOS验证手机号的正则表达式  HTML5空格和margin有啥区别_空格与外边距的使用场景【说明】  网站制作软件免费下载安装,有哪些免费下载的软件网站?  Laravel Session怎么存储_Laravel Session驱动配置详解  猪八戒网站制作视频,开发一个猪八戒网站,大约需要多少?或者自己请程序员,需要什么程序员,多少程序员能完成?