Permission denied 是最常见的 Linux 报错之一,解决办法就是加 sudo。但 sudo 远不止"提权执行"这么简单:为什么有的用户能用 sudo 有的不行?怎么给某个人只放行某条命令?sudo 和 su 有什么区别?这篇文章把 sudo 的原理、配置和坑一次讲清。
一、sudo 和 su 的区别
- su:切换到另一个用户(默认 root),需要输入目标用户的密码,切过去就是完整身份;
- sudo:以其他用户身份执行单条命令,只需输入当前用户自己的密码(甚至免密),用完即退。
su - # 切到 root,要输 root 密码
sudo ls /root # 以 root 执行单条命令,输自己的密码
推荐用 sudo 而非 su:sudo 有审计日志、可精细授权、不用分享 root 密码,是服务器管理的标准做法。
二、sudo 基本用法
sudo command # 以 root 执行
sudo -u www ls /var/www # 以指定用户(www)执行
sudo -i # 进入 root shell(相当于 su -)
sudo -s # 进入 root shell(保留当前环境变量)
sudo -l # 查看自己有哪些 sudo 权限(最常用)
sudo -k # 强制重新输密码(清空缓存)
密码缓存:一次输密码后 15 分钟内(默认)再 sudo 不用重复输,-k 可立即清空。
三、sudoers 配置:给谁什么权限
sudo 权限全部写在 /etc/sudoers,必须用 visudo 命令编辑(自动检查语法,防止配错锁死 sudo):
sudo visudo
常用配置行:
# 1. 普通用户获得全部 sudo 权限
zhangsan ALL=(ALL:ALL) ALL
# 2. 用户组整体授权(% 开头是组名,wheel 组是惯例)
%wheel ALL=(ALL:ALL) ALL
# 3. 只允许执行特定命令(禁止其他所有)
zhangsan ALL=(ALL) /usr/bin/systemctl restart nginx, /usr/bin/ls
# 4. 指定命令免密执行
zhangsan ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx
# 5. 完全免密(仅限可信的隔离环境)
zhangsan ALL=(ALL) NOPASSWD: ALL
# 6. 禁止执行特定命令
zhangsan ALL=(ALL) ALL, !/usr/bin/passwd root, !/usr/sbin/useradd
配置格式:用户/组 主机=(可切换身份) 命令列表。ALL 是最宽松的写法,生产环境建议最小授权:只放行需要的命令,危险命令(passwd root、visudo、useradd、shutdown)用 ! 排除。
四、验证与测试
sudo -l # 查看自己的权限(列出 ALL 或具体命令)
sudo -l -U zhangsan # root 查看别人的权限
配错了怎么办:visudo 保存时会校验语法,语法错误会提示并拒绝保存。万一真把 sudoers 改坏导致 sudo 全不能用:
- 有 root 会话(已 su - 或控制台 VNC)就
visudo改回来; - 没有 root 会话时,重启进单用户模式(GRUB 菜单加
single)或从 rescue 模式挂载盘修复。
五、常见问题排查
zhangsan is not in the sudoers file. This incident will be reported.:该用户没被授权,root 用visudo添加(加入%wheel组更省事:usermod -aG wheel zhangsan,Ubuntu 是sudo组);sorry, you must have a tty to run sudo:脚本/Web 环境没有终端,改Defaults requiretty(注释掉该行)或用sudo -S从标准输入读密码;command not found(sudo 下命令找不到):sudo 默认 PATH 与当前用户不同,用绝对路径执行:sudo /usr/local/bin/xxx;sudo: no tty present and no askpass program specified:同上,脚本里用sudo -n且已配置 NOPASSWD,或加-S传密码(不建议明文传);- 输入密码没反应:sudo 输入密码时不回显,直接敲完回车即可;
operation not permitted(加了 sudo 也不行):权限超出 sudo 范围(如内核参数、特定文件系统限制),检查 SELinux/AppArmor 或确认命令本身需要更高特权。
六、安全建议
- 别把 sudo 密码设太弱,sudo 权限等于半个 root;
- 用命令级白名单代替
ALL,危险命令显式排除; - 关注 sudo 日志:
journalctl -u sudo或/var/log/auth.log里的sudo记录; - 永远不要
chmod 777sudoers,权限必须 440 root 属主; - 多管理员时用
%wheel组统一管理,离职直接移出组。
总结:sudo 一句话——sudo 命令 以 root 执行单条命令,权限由 /etc/sudoers 控制。日常记住 sudo -l 看权限、visudo 改配置(别直接编辑文件)、NOPASSWD 用于脚本。生产环境遵循最小授权,sudo 就是安全又灵活的提权方式。



