云计算百科
云计算领域专业知识百科平台

LInux | sudo 与 su 操作

sudo 与 su 操作手册

目录

  • sudoers 配置
  • sudo 常用操作
  • sudo 安全机制
  • sudo 高级用法
  • 安全规范
  • 故障排查
  • 同类工具对比
  • su、sudo 环境与 PATH 行为

  • 1 sudoers 配置

    sudo 的权限控制依托 /etc/sudoers,文件默认权限 440。

    不直接使用 vi、vim 编辑,语法错误会造成 sudo 不可用;编辑统一使用 visudo,该工具内置语法校验。

    # 普通用户执行,需要已有 sudo 权限
    sudo visudo
    # root 直接执行
    visudo

    编辑完成,vi 模式下按 Esc,输入 :wq 保存退出。

    存在语法错误时终端输出 syntax error,需要修正后重新保存。

    1.1 sudoers 文件结构

    文件分为 Defaults、用户权限、组权限三段。通用规则格式:

    用户/组 主机 =(身份) 可执行命令 # 为注释标记。

    # Defaults 段:全局行为控制
    Defaults env_reset
    Defaults mail_badpass
    Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
    Defaults timestamp_timeout=15
    Defaults env_keep += "SSH_AUTH_SOCK"

    # 用户权限规则
    root ALL=(ALL:ALL) ALL

    # 组权限规则,组名前缀 %
    %wheel ALL=(ALL:ALL) ALL
    %sudo ALL=(ALL:ALL) ALL

    字段释义:

    • 主机:规则生效主机范围
    • (ALL:ALL):可切换用户:可切换组
    • ALL:代表全部命令

    1.2 配置场景

    1.2.1 授予完整 sudo 权限

    方式一:加入系统授权组

    # Ubuntu
    usermod -aG sudo test
    # CentOS / RHEL
    usermod -aG wheel test

    方式二:直接写入 sudoers

    test ALL=(ALL:ALL) ALL

    1.2.2 限定可执行命令

    命令必须填写绝对路径,可携带参数实现精确匹配。

    test ALL=(ALL:ALL) /usr/bin/systemctl restart nginx, /sbin/ifconfig eth0, /sbin/ifup eth0

    仅允许指定命令免密执行:

    deploy ALL=(ALL:ALL) NOPASSWD: /usr/bin/systemctl restart nginx

    1.2.3 免密码授权

    # 全部命令免密
    test ALL=(ALL:ALL) NOPASSWD: ALL
    # 指定命令免密
    test ALL=(ALL:ALL) NOPASSWD: /usr/sbin/reboot, /usr/bin/systemctl restart nginx

    1.2.4 限定切换目标用户

    test ALL=(nginx:ALL) ALL

    该配置下用户仅可切换至 nginx,无法切换至 root。

    1.2.5 黑名单管控

    ! 标记禁止项;黑名单条目置于白名单之后,规则从上至下顺序匹配。

    %sudo ALL=(ALL:ALL) ALL, !/usr/bin/rm -rf *
    test ALL=(ALL:ALL) ALL, !/usr/sbin/visudo

    1.2.6 别名定义

    别名名称使用大写,分为 User_Alias、Cmnd_Alias、Host_Alias。

    User_Alias OPS = user1, user2, user3
    Cmnd_Alias PACKAGES = /usr/bin/apt, /usr/bin/yum, /usr/bin/dnf
    Cmnd_Alias SERVICES = /usr/bin/systemctl, /usr/sbin/service
    OPS ALL=(ALL:ALL) PACKAGES, SERVICES

    1.3 主机字段匹配规则

    主机字段在本机完成匹配,匹配对象为主机名、FQDN、IP。支持以下类型:

  • 短主机名 / FQDNtest web01=(ALL:ALL) NOPASSWD: /usr/bin/systemctl restart nginx
  • 单个 IPtest 192.168.1.10=(ALL:ALL) NOPASSWD: /usr/bin/systemctl restart nginx
  • CIDR 网段test 192.168.1.0/24=(ALL:ALL) NOPASSWD: /usr/bin/systemctl restart nginx
  • Host_AliasHost_Alias WEBS = web01, web02, web03, 192.168.1.10, 192.168.1.11
    test WEBS=(ALL:ALL) NOPASSWD: /usr/bin/systemctl restart nginx
  • Netgroup(NIS/域环境,前缀 +)test +webservers=(ALL:ALL) NOPASSWD: /usr/bin/systemctl restart nginx
  • 取反 !test ALL,!web03=(ALL:ALL) NOPASSWD: /usr/bin/systemctl restart nginx
  • 逗号分隔主机列表test web01,web02,192.168.1.20=(ALL:ALL) NOPASSWD: /usr/bin/systemctl restart nginx
  • 主机名解析依赖 /etc/hosts 或 DNS,解析异常会造成匹配失败。

    1.4 多主机部署方案

    • 小规模集群:分发主 sudoers 文件,或在 /etc/sudoers.d/ 下放独立规则文件,使用 Ansible 推送
    • 大规模域环境:LDAP 集中维护 sudoHost

    推荐将自定义规则放入 /etc/sudoers.d/,不修改主文件,便于分发与回滚。

    visudo -f /etc/sudoers.d/90_custom_rules

    模板:

    deploy web01,web02=(ALL:ALL) NOPASSWD: /usr/bin/systemctl restart nginx, /usr/bin/tar

    配置完成后,切换对应用户执行 sudo -l 校验权限。

    1.5 sudo 执行流程

    #mermaid-svg-GODb4VugpWdzvx7p{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-GODb4VugpWdzvx7p .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-GODb4VugpWdzvx7p .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-GODb4VugpWdzvx7p .error-icon{fill:#552222;}#mermaid-svg-GODb4VugpWdzvx7p .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-GODb4VugpWdzvx7p .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-GODb4VugpWdzvx7p .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-GODb4VugpWdzvx7p .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-GODb4VugpWdzvx7p .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-GODb4VugpWdzvx7p .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-GODb4VugpWdzvx7p .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-GODb4VugpWdzvx7p .marker{fill:#333333;stroke:#333333;}#mermaid-svg-GODb4VugpWdzvx7p .marker.cross{stroke:#333333;}#mermaid-svg-GODb4VugpWdzvx7p svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-GODb4VugpWdzvx7p p{margin:0;}#mermaid-svg-GODb4VugpWdzvx7p .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-GODb4VugpWdzvx7p .cluster-label text{fill:#333;}#mermaid-svg-GODb4VugpWdzvx7p .cluster-label span{color:#333;}#mermaid-svg-GODb4VugpWdzvx7p .cluster-label span p{background-color:transparent;}#mermaid-svg-GODb4VugpWdzvx7p .label text,#mermaid-svg-GODb4VugpWdzvx7p span{fill:#333;color:#333;}#mermaid-svg-GODb4VugpWdzvx7p .node rect,#mermaid-svg-GODb4VugpWdzvx7p .node circle,#mermaid-svg-GODb4VugpWdzvx7p .node ellipse,#mermaid-svg-GODb4VugpWdzvx7p .node polygon,#mermaid-svg-GODb4VugpWdzvx7p .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-GODb4VugpWdzvx7p .rough-node .label text,#mermaid-svg-GODb4VugpWdzvx7p .node .label text,#mermaid-svg-GODb4VugpWdzvx7p .image-shape .label,#mermaid-svg-GODb4VugpWdzvx7p .icon-shape .label{text-anchor:middle;}#mermaid-svg-GODb4VugpWdzvx7p .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-GODb4VugpWdzvx7p .rough-node .label,#mermaid-svg-GODb4VugpWdzvx7p .node .label,#mermaid-svg-GODb4VugpWdzvx7p .image-shape .label,#mermaid-svg-GODb4VugpWdzvx7p .icon-shape .label{text-align:center;}#mermaid-svg-GODb4VugpWdzvx7p .node.clickable{cursor:pointer;}#mermaid-svg-GODb4VugpWdzvx7p .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-GODb4VugpWdzvx7p .arrowheadPath{fill:#333333;}#mermaid-svg-GODb4VugpWdzvx7p .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-GODb4VugpWdzvx7p .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-GODb4VugpWdzvx7p .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-GODb4VugpWdzvx7p .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-GODb4VugpWdzvx7p .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-GODb4VugpWdzvx7p .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-GODb4VugpWdzvx7p .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-GODb4VugpWdzvx7p .cluster text{fill:#333;}#mermaid-svg-GODb4VugpWdzvx7p .cluster span{color:#333;}#mermaid-svg-GODb4VugpWdzvx7p div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-GODb4VugpWdzvx7p .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-GODb4VugpWdzvx7p rect.text{fill:none;stroke-width:0;}#mermaid-svg-GODb4VugpWdzvx7p .icon-shape,#mermaid-svg-GODb4VugpWdzvx7p .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-GODb4VugpWdzvx7p .icon-shape p,#mermaid-svg-GODb4VugpWdzvx7p .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-GODb4VugpWdzvx7p .icon-shape .label rect,#mermaid-svg-GODb4VugpWdzvx7p .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-GODb4VugpWdzvx7p .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-GODb4VugpWdzvx7p .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-GODb4VugpWdzvx7p :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    失败

    成功

    未授权

    已授权

    普通用户

    输入命令

    sudo

    验证用户身份

    验证结果

    密码错误

    退出

    检查授权规则

    授权结果

    拒绝执行

    以指定用户执行

    返回结果

    结束

    1.6 sudoers 配置约束

    • 命令使用绝对路径,带参数条目为精确匹配
    • NOPASSWD 仅用于信任主体与自动化场景
    • 别名统一大写
    • 修改后执行 sudo -l 验证

    2 sudo 常用操作

    通用语法:sudo [选项] 命令

    2.1 切换 root shell

    sudo -i
    sudo su –
    sudo -s
    exit

    2.2 指定身份执行

    sudo -u nginx /usr/sbin/nginx
    sudo -u www-data ls -l /var/www/html
    sudo -u nginx whoami

    2.3 查看权限清单

    sudo -l

    2.4 密码缓存控制

    # 刷新缓存计时,重新校验密码
    sudo -v
    # 清除密码缓存
    sudo -k

    2.5 多条命令批量执行

    sudo bash -c 'apt update -y && apt upgrade -y && systemctl restart sshd'

    2.6 保留环境变量

    sudo -E /usr/local/nginx/sbin/nginx -s reload
    sudo -E env | grep PATH


    3 sudo 安全机制

    3.1 密码超时

    默认 timestamp_timeout=15,单位分钟。

    Defaults timestamp_timeout=30
    Defaults timestamp_timeout=0
    Defaults timestamp_timeout=-1

    • 0:每次调用均校验密码
    • -1:永久缓存

    3.2 审计日志

    默认路径:

    • CentOS / RHEL:/var/log/secure
    • Ubuntu / Debian:/var/log/auth.log

    自定义日志配置:

    Defaults logfile="/var/log/sudo.log"
    Defaults log_format="%u : %h : %t : %p : %m"

    检索命令:

    grep sudo /var/log/secure
    grep sudo /var/log/auth.log
    tail -f /var/log/sudo.log
    grep "rm -rf" /var/log/sudo.log

    3.3 环境变量管控

    Defaults env_reset
    Defaults env_keep += "SSH_AUTH_SOCK"
    Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

    env_reset 开启时清理用户环境;secure_path 单独覆盖 PATH,防止路径劫持。

    PATH 相关故障:程序不在 secure_path 内,sudo 提示 command not found。处理方式:

  • 调用绝对路径
  • sudo -E
  • 修改 secure_path

  • 4 高级用法

    4.1 远端 SSH 提权执行

    前置:SSH 免密通道。

    test ALL=(ALL:ALL) /usr/bin/ssh root@192.168.1.100

    sudo ssh root@192.168.1.100
    sudo ssh root@192.168.1.100 'systemctl restart nginx'

    4.2 自动化脚本

    遵循最小权限,仅开放脚本所需命令免密:

    test ALL=(ALL:ALL) NOPASSWD: /usr/bin/systemctl restart nginx, /usr/bin/tar, /bin/rm


    5 安全规范

  • 遵循最小权限,避免 NOPASSWD: ALL、ALL 全权限
  • SSH 配置 PermitRootLogin no,禁止 root 直接密码登录
  • 定期审计 sudo 日志
  • 保持 /etc/sudoers 权限 440
  • 自动化、cron 场景注释 Defaults requiretty
  • 脚本禁止明文写入密码
  • 及时升级 sudo 软件包,修复漏洞
  • 多主机场景使用堡垒机集中审计
  • 周期性清理失效权限、离职用户规则

  • 6 故障排查

    6.1 xxx is not in the sudoers file

    用户未加入授权组、无匹配 sudoers 规则。

    su – root
    usermod -aG sudo test
    usermod -aG wheel test
    visudo
    test ALL=(ALL:ALL) ALL

    修改后重新登录用户。

    6.2 must have a tty to run sudo

    sudoers 启用 requiretty,非交互式场景报错。

    # Defaults requiretty

    6.3 unable to resolve host

    /etc/hosts 缺少主机名映射,补充条目:

    127.0.0.1 localhost linux-server
    ::1 localhost linux-server

    6.4 command not found

    • 程序未安装
    • 程序路径不在 secure_path
    • 未使用绝对路径

    6.5 password incorrect

    • 输入大小写、特殊字符错误
    • 用户密码过期,chage -l test 查看,passwd test 修改
    • sudoers 语法错误,visudo -c 校验
    • 用户名、组名拼写错误

    6.6 sudo 整体失效

    优先执行语法校验:

    visudo -c

    • 可 su – root:root 登录后修复配置
    • su 同样不可用:进入单用户模式修复 附加检查项:文件权限 440、包重装、磁盘空间、文件系统只读状态

    6.7 修改密码后 sudo 验证失败

    缓存旧密码,清除缓存:

    sudo -k

    6.8 sudo 执行卡住

    • Ctrl+C 终止进程
    • 检查系统负载 top
    • 检查日志文件写入权限
    • SSH 远端执行添加 -t 分配 TTY
    • journalctl -u sudo 查看日志

    7 同类工具对比

    7.1 su

    原生切换用户工具;su – root 需要 root 密码;无细粒度权限控制,审计能力弱。适合单主机应急。

    7.2 doas

    OpenBSD 项目,配置简洁,体积更小;主流发行版不预装。

    apt install doas
    yum install doas

    配置文件 /etc/doas.conf

    permit test as root cmd nginx

    7.3 pkexec

    PolicyKit 组件,面向图形会话提权;服务器终端场景不适用。

    pkexec gedit /etc/hosts


    8 su、sudo 环境与 PATH 行为

    8.1 基础释义

    • su:switch user,切换用户
    • sudo:superuser do,以超级用户身份执行命令
    • -(su -):–login,登录式切换,加载目标用户配置,进入目标用户家目录
    • -i(sudo -i):交互式登录 shell
    • -s(sudo -s):启动 shell,不执行登录初始化

    8.2 root 切换方式对比

    命令模式工作目录环境来源PATH 行为需要 root 密码
    su 非登录 shell 保持原目录 继承当前用户大部分环境变量;通常加载目标用户 ~/.bashrc 保留原用户 PATH
    su – / su -l / su – root 登录 shell /root 加载 root 的 /etc/profile、~/.profile/~/.bash_profile,通常再 source ~/.bashrc 使用 root 登录环境 PATH
    sudo cmd sudo 单次执行 保持原目录 受 env_reset 限制,仅保留少量变量;可通过 env_keep / -E 保留指定变量 默认使用 secure_path
    sudo -i 模拟 root 登录 shell /root 构造 root 登录环境,读取 root 登录配置文件 接近 root 登录 PATH,但可能受 secure_path 影响
    sudo su – 登录 shell /root 先通过 sudo 提权,再执行 su -,加载 root 登录配置 与 su – 基本一致
    sudo -s 非登录 root shell 保持原目录(HOME 通常仍为调用者) 受 sudoers 环境规则约束;通常只加载 root ~/.bashrc 受 secure_path / env_reset 约束

    注:sudo su – 与 sudo -i 最终都能获得 root 登录环境,但 sudo -i 更直接,只产生一层 sudo 进程;

    sudo su – 会先提权再调用 su,属于冗余写法。

    • su 系列需要知道 目标用户密码;sudo 系列通常验证 当前用户密码,并依赖 /etc/sudoers 授权。
    • sudo 默认启用 env_reset,并通过 secure_path 限制 PATH;这是 sudo cmd 找不到自定义命令的常见原因。
    • 生产环境建议优先使用 sudo / sudo -i,避免直接使用 su 或 sudo su -,便于审计和权限控制。

    退出命令统一为:

    exit

    8.3 PATH 问题处理方案(侵入性升序)

  • 单次传递 PATH
  • sudo env PATH="$PATH" my_command
    sudo env PATH="$PATH" env | grep ^PATH

  • 调用绝对路径
  • sudo $(which my_command)

  • 软链接至 secure_path 目录
  • sudo ln -s /usr/local/bin/cmd /usr/sbin/cmd

  • 修改 secure_path(全局)
  • Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

    echo 'Defaults secure_path="/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin"' | sudo tee /etc/sudoers.d/custom_path

  • sudo -i,使用 root 登录环境
  • env_keep 保留 PATH(存在劫持风险,不推荐常规使用)
  • Defaults env_keep += "PATH"

  • shell 别名
  • alias psudo='sudo env PATH="$PATH"'
    psudo my_command

    8.4 PATH 劫持原理

    用户可控 PATH 中包含可写目录时,同名恶意程序会优先匹配并以 root 权限运行。secure_path 仅使用管理员管控目录,阻断该链路。

    8.5 排查项

    • sudo -V | grep PATH 查看 secure_path
    • 区分两类问题:sudo 程序检索失败、程序内部子进程 PATH 缺失
    • 优先使用单次 env 传递或绝对路径,减少全局变更

    如果你需要,我可以单独导出一份可直接打印的精简速查版(只保留表格、常用命令、故障清单)。


    Reference

    • command line – Environment variables when run with ‘sudo’ – Ask Ubuntu https://askubuntu.com/questions/57915/environment-variables-when-run-with-sudo
    • linux – Why are PATH variables different when running via sudo and su? – Unix & Linux Stack Exchange https://unix.stackexchange.com/questions/8646/why-are-path-variables-different-when-running-via-sudo-and-su
    • environment variables – Why does sudo change the PATH? – Stack Overflow https://stackoverflow.com/questions/257616/why-does-sudo-change-the-path
    • How to make sudo preserve $PATH? – Unix & Linux Stack Exchange https://unix.stackexchange.com/questions/83191/how-to-make-sudo-preserve-path
    • linux – Why are PATH variables different when running via sudo and su? – Unix & Linux Stack Exchange https://unix.stackexchange.com/questions/8646/why-are-path-variables-different-when-running-via-sudo-and-su
    • security – Which is the safest way to get root privileges: sudo, su or login? – Unix & Linux Stack Exchange https://unix.stackexchange.com/questions/8581/which-is-the-safest-way-to-get-root-privileges-sudo-su-or-login
    • sudo 命令完全指南:从入门到精通 https://mp.weixin.qq.com/s/CbTSZvrDQzDiBrc6wE_2Yg
    赞(0)
    未经允许不得转载:网硕互联帮助中心 » LInux | sudo 与 su 操作
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!