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_timeout15 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方式二直接写入 sudoerstest 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。支持以下类型短主机名 / FQDNtest web01(ALL:ALL) NOPASSWD: /usr/bin/systemctl restart nginx单个 IPtest 192.168.1.10(ALL:ALL) NOPASSWD: /usr/bin/systemctl restart nginxCIDR 网段test 192.168.1.0/24(ALL:ALL) NOPASSWD: /usr/bin/systemctl restart nginxHost_AliasHost_Alias WEBS web01, web02, web03, 192.168.1.10, 192.168.1.11 test WEBS(ALL:ALL) NOPASSWD: /usr/bin/systemctl restart nginxNetgroupNIS/域环境前缀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 执行流程失败成功未授权已授权普通用户输入命令sudo验证用户身份验证结果密码错误退出检查授权规则授权结果拒绝执行以指定用户执行返回结果结束1.6 sudoers 配置约束命令使用绝对路径带参数条目为精确匹配NOPASSWD 仅用于信任主体与自动化场景别名统一大写修改后执行sudo -l验证2 sudo 常用操作通用语法sudo [选项] 命令2.1 切换 root shellsudo-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-capt update -y apt upgrade -y systemctl restart sshd2.6 保留环境变量sudo-E/usr/local/nginx/sbin/nginx-sreloadsudo-Eenv|grepPATH3 sudo 安全机制3.1 密码超时默认timestamp_timeout15单位分钟。Defaults timestamp_timeout30 Defaults timestamp_timeout0 Defaults timestamp_timeout-10每次调用均校验密码-1永久缓存3.2 审计日志默认路径CentOS / RHEL/var/log/secureUbuntu / 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.loggreprm -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:/binenv_reset开启时清理用户环境secure_path单独覆盖 PATH防止路径劫持。PATH 相关故障程序不在 secure_path 内sudo 提示 command not found。处理方式调用绝对路径sudo -E修改 secure_path4 高级用法4.1 远端 SSH 提权执行前置SSH 免密通道。test ALL(ALL:ALL) /usr/bin/ssh root192.168.1.100sudosshroot192.168.1.100sudosshroot192.168.1.100systemctl restart nginx4.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 sudosudoers 启用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 - rootroot 登录后修复配置su 同样不可用进入单用户模式修复附加检查项文件权限 440、包重装、磁盘空间、文件系统只读状态6.7 修改密码后 sudo 验证失败缓存旧密码清除缓存sudo-k6.8 sudo 执行卡住CtrlC终止进程检查系统负载top检查日志文件写入权限SSH 远端执行添加-t分配 TTYjournalctl -u sudo查看日志7 同类工具对比7.1 su原生切换用户工具su - root需要 root 密码无细粒度权限控制审计能力弱。适合单主机应急。7.2 doasOpenBSD 项目配置简洁体积更小主流发行版不预装。aptinstalldoas yuminstalldoas配置文件/etc/doas.confpermit test as root cmd nginx7.3 pkexecPolicyKit 组件面向图形会话提权服务器终端场景不适用。pkexec gedit /etc/hosts8 su、sudo 环境与 PATH 行为8.1 基础释义suswitch user切换用户sudosuperuser do以超级用户身份执行命令-su ---login登录式切换加载目标用户配置进入目标用户家目录-isudo -i交互式登录 shell-ssudo -s启动 shell不执行登录初始化8.2 root 切换方式对比命令模式工作目录环境来源PATH 行为需要 root 密码su非登录 shell保持原目录继承当前用户大部分环境变量通常加载目标用户~/.bashrc保留原用户 PATHsu -/su -l/su - root登录 shell/root加载 root 的/etc/profile、~/.profile/~/.bash_profile通常再 source~/.bashrc使用 root 登录环境 PATHsudo cmdsudo 单次执行保持原目录受env_reset限制仅保留少量变量可通过env_keep/-E保留指定变量默认使用secure_pathsudo -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 问题处理方案侵入性升序单次传递 PATHsudoenvPATH$PATHmy_commandsudoenvPATH$PATHenv|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/binechoDefaults 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 PATHshell 别名aliaspsudosudo env PATH$PATHpsudo my_command8.4 PATH 劫持原理用户可控 PATH 中包含可写目录时同名恶意程序会优先匹配并以 root 权限运行。secure_path仅使用管理员管控目录阻断该链路。8.5 排查项sudo -V | grep PATH查看 secure_path区分两类问题sudo 程序检索失败、程序内部子进程 PATH 缺失优先使用单次 env 传递或绝对路径减少全局变更如果你需要我可以单独导出一份可直接打印的精简速查版只保留表格、常用命令、故障清单。Referencecommand line - Environment variables when run with ‘sudo’ - Ask Ubuntuhttps://askubuntu.com/questions/57915/environment-variables-when-run-with-sudolinux - Why are PATH variables different when running via sudo and su? - Unix Linux Stack Exchangehttps://unix.stackexchange.com/questions/8646/why-are-path-variables-different-when-running-via-sudo-and-suenvironment variables - Why does sudo change the PATH? - Stack Overflowhttps://stackoverflow.com/questions/257616/why-does-sudo-change-the-pathHow to makesudopreserve $PATH? - Unix Linux Stack Exchangehttps://unix.stackexchange.com/questions/83191/how-to-make-sudo-preserve-pathlinux - Why are PATH variables different when running via sudo and su? - Unix Linux Stack Exchangehttps://unix.stackexchange.com/questions/8646/why-are-path-variables-different-when-running-via-sudo-and-susecurity - Which is the safest way to get root privileges: sudo, su or login? - Unix Linux Stack Exchangehttps://unix.stackexchange.com/questions/8581/which-is-the-safest-way-to-get-root-privileges-sudo-su-or-loginsudo 命令完全指南从入门到精通https://mp.weixin.qq.com/s/CbTSZvrDQzDiBrc6wE_2Yg