LInux | sudo 与 su 操作
sudo 与 su 操作手册
目录
- sudoers 配置
- sudo 常用操作
- sudo 安全机制
- sudo 高级用法
- 安全规范
- 故障排查
- 同类工具对比
- su、sudo 环境与 PATH 行为
1 sudoers 配置
sudo的权限控制依托/etc/sudoers,文件默认权限 440。
不直接使用 vi、vim 编辑,语法错误会造成 sudo 不可用;编辑统一使用visudo,该工具内置语法校验。
# 普通用户执行,需要已有 sudo 权限sudovisudo# 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 权限
方式一:加入系统授权组
# Ubuntuusermod-aGsudotest# CentOS / RHELusermod-aGwheeltest方式二:直接写入 sudoers
test ALL=(ALL:ALL) ALL1.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 nginx1.2.3 免密码授权
# 全部命令免密 test ALL=(ALL:ALL) NOPASSWD: ALL # 指定命令免密 test ALL=(ALL:ALL) NOPASSWD: /usr/sbin/reboot, /usr/bin/systemctl restart nginx1.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/visudo1.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, SERVICES1.3 主机字段匹配规则
主机字段在本机完成匹配,匹配对象为主机名、FQDN、IP。支持以下类型:
- 短主机名 / FQDN
test web01=(ALL:ALL) NOPASSWD: /usr/bin/systemctl restart nginx - 单个 IP
test 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_Alias
Host_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 执行流程
1.6 sudoers 配置约束
- 命令使用绝对路径,带参数条目为精确匹配
- NOPASSWD 仅用于信任主体与自动化场景
- 别名统一大写
- 修改后执行
sudo -l验证
2 sudo 常用操作
通用语法:sudo [选项] 命令
2.1 切换 root shell
sudo-isudosu-sudo-sexit2.2 指定身份执行
sudo-unginx /usr/sbin/nginxsudo-uwww-datals-l/var/www/htmlsudo-unginxwhoami2.3 查看权限清单
sudo-l2.4 密码缓存控制
# 刷新缓存计时,重新校验密码sudo-v# 清除密码缓存sudo-k2.5 多条命令批量执行
sudobash-c'apt update -y && apt upgrade -y && systemctl restart sshd'2.6 保留环境变量
sudo-E/usr/local/nginx/sbin/nginx-sreloadsudo-Eenv|grepPATH3 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"检索命令:
grepsudo/var/log/securegrepsudo/var/log/auth.logtail-f/var/log/sudo.loggrep"rm -rf"/var/log/sudo.log3.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.100sudosshroot@192.168.1.100sudosshroot@192.168.1.100'systemctl restart nginx'4.2 自动化脚本
遵循最小权限,仅开放脚本所需命令免密:
test ALL=(ALL:ALL) NOPASSWD: /usr/bin/systemctl restart nginx, /usr/bin/tar, /bin/rm5 安全规范
- 遵循最小权限,避免
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- rootusermod-aGsudotestusermod-aGwheeltestvisudotestALL=(ALL:ALL)ALL修改后重新登录用户。
6.2 must have a tty to run sudo
sudoers 启用requiretty,非交互式场景报错。
# Defaults requiretty6.3 unable to resolve host
/etc/hosts缺少主机名映射,补充条目:
127.0.0.1 localhost linux-server ::1 localhost linux-server6.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-k6.8 sudo 执行卡住
Ctrl+C终止进程- 检查系统负载
top - 检查日志文件写入权限
- SSH 远端执行添加
-t分配 TTY journalctl -u sudo查看日志
7 同类工具对比
7.1 su
原生切换用户工具;su - root需要 root 密码;无细粒度权限控制,审计能力弱。适合单主机应急。
7.2 doas
OpenBSD 项目,配置简洁,体积更小;主流发行版不预装。
aptinstalldoas yuminstalldoas配置文件/etc/doas.conf
permit test as root cmd nginx7.3 pkexec
PolicyKit 组件,面向图形会话提权;服务器终端场景不适用。
pkexec gedit /etc/hosts8 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 -,便于审计和权限控制。
退出命令统一为:
exit8.3 PATH 问题处理方案(侵入性升序)
- 单次传递 PATH
sudoenvPATH="$PATH"my_commandsudoenvPATH="$PATH"env|grep^PATH- 调用绝对路径
sudo$(whichmy_command)- 软链接至 secure_path 目录
sudoln-s/usr/local/bin/cmd /usr/sbin/cmd- 修改 secure_path(全局)
Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/binecho'Defaults secure_path="/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin"'|sudotee/etc/sudoers.d/custom_pathsudo -i,使用 root 登录环境- env_keep 保留 PATH(存在劫持风险,不推荐常规使用)
Defaults env_keep += "PATH"- shell 别名
aliaspsudo='sudo env PATH="$PATH"'psudo my_command8.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
sudopreserve $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