sudo 与 su 操作手册
目录
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。支持以下类型:
test WEBS=(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。处理方式:
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 安全规范
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 切换方式对比
| 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 问题处理方案(侵入性升序)
sudo env PATH="$PATH" my_command
sudo env PATH="$PATH" env | grep ^PATH
sudo $(which my_command)
sudo ln -s /usr/local/bin/cmd /usr/sbin/cmd
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
Defaults env_keep += "PATH"
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
网硕互联帮助中心




评论前必须登录!
注册