一、基本概念和作用
1.su(Switch User/Substitute User)
- 作用:切换用户身份,主要用于切换到root用户
- 语法:
su [选项] [用户名] - 核心功能:完全切换到另一个用户的shell环境
su,su -,su root均可切换到root用户;
2.sudo(SuperUser DO / Substitute User DO)
- 作用:以超级用户或其他用户权限执行特定命令
- 语法:
sudo [选项] 命令 - 核心功能:临时提升权限执行单个命令
二、详细对比表
| 特性 | su | sudo |
|---|---|---|
| 主要用途 | 切换用户身份,常用来切换到root | 以root权限执行单个命令 |
| 密码要求 | 需要目标用户的密码 | 需要当前用户的密码(配置决定) |
| 权限控制 | 要么有完整权限,要么没有 | 可通过配置精细控制命令权限 |
| 日志记录 | 只记录用户切换,不记录具体命令 | 详细记录所有执行的命令(/var/log/auth.log) |
| 环境变量 | 默认不加载目标用户的环境变量(除非用-) | 保留当前用户的环境变量 |
| 安全等级 | 较低(需要共享root密码) | 较高(无需知道root密码) |
| 使用场景 | 需要长时间使用root权限 | 临时执行需要特权的命令 |
三、常用命令和场景(带示例结果)
su的常见用法:
# 1. 切换到root用户(需要root密码)$su密码:********# 切换成功,但仍在当前目录# 提示符变为 # 表示现在是root用户root@server:/home/alice## 2. 切换到root并加载环境变量(推荐)$su- 密码:********# 完全切换到root环境,目录变为/rootroot@server:~# pwd/root# 3. 切换到其他用户$subob 密码:******** bob@server:/home/alice$whoamibob# 4. 切换到其他用户并执行命令后返回$su-c"id"bob 密码:********uid=1001(bob)gid=1001(bob)groups=1001(bob)$whoami# 命令执行后自动返回原用户alice# 5. 验证是否成功切换$su- 密码:******** root@server:~# whoamiroot root@server:~# echo $USERroot root@server:~# exit # 退出root$whoamialicesudo的常见用法:
# 1. 以root权限执行命令$sudoaptupdate[sudo]alice的密码:******** 命中:1 http://archive.ubuntu.com/ubuntu focal InRelease 获取:2 http://archive.ubuntu.com/ubuntu focal-updates InRelease[114kB]... $whoami# 命令执行后仍然是普通用户alice# 2. 以其他用户身份执行命令$sudo-u bobwhoami[sudo]alice的密码:******** bob# 3. 切换到root的交互式shell$sudo-i[sudo]alice的密码:********# 进入root的shell,环境变量已加载root@server:~# pwd/root root@server:~# exit$# 4. 查看当前用户的sudo权限$sudo-l 匹配 %alice 在 server 上的默认条目: env_reset, mail_badpass,secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin 用户 alice 可以在 server 上运行以下命令:(ALL:ALL)ALL# 5. 保留当前目录和环境$pwd/home/alice/projects $sudo-Eenv|grepPATHPATH=/home/alice/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin# 6. 在脚本中使用sudo(需要配置免密码)$sudo-naptlist --upgradable Listing... Done四、实际应用场景(带示例结果)
使用su的场景:
场景1:系统维护- 需要长时间以root身份操作
$whoamialice $su- 密码:******** root@server:~# systemctl stop nginxroot@server:~# tar -czf /backup/nginx-$(date +%Y%m%d).tar.gz /etc/nginxroot@server:~# ls -lh /backup/总用量4.0K -rw-r--r--1root root2.3K Apr1510:30 nginx-20240415.tar.gz root@server:~# systemctl start nginxroot@server:~# exit$whoamialice场景2:切换服务账户- 以服务用户身份操作
$sudo-u postgres psql psql(13.7)输入"help"来获取帮助信息.postgres=# \l数据库列表 名称|拥有者|字元编码|校对规则|Ctype|存取权限 -----------+----------+----------+-------------+-------------+------------------- postgres|postgres|UTF8|en_US.UTF-8|en_US.UTF-8|template0|postgres|UTF8|en_US.UTF-8|en_US.UTF-8|=c/postgres +|||||postgres=CTc/postgres template1|postgres|UTF8|en_US.UTF-8|en_US.UTF-8|=c/postgres +|||||postgres=CTc/postgres(3行记录)使用sudo的场景:
场景1:日常管理- 临时安装软件
$sudoaptinstallnginx[sudo]alice的密码:******** 正在读取软件包列表... 完成 正在分析软件包的依赖关系树... 完成 正在读取状态信息... 完成 下列【新】软件包将被安装: nginx 升级了0个软件包,新安装了1个软件包,要卸载0个软件包,有23个软件包未被升级。 需要下载0B/51.6 kB 的归档。 解压缩后会消耗143kB 的额外空间。... $sudosystemctl status nginx ● nginx.service - A high performance web server and a reverse proxy server Loaded: loaded(/lib/systemd/system/nginx.service;enabled;vendor preset: enabled)Active: active(running)since Mon2024-04-1510:30:00 CST;1min ago场景2:受限权限- 普通用户管理特定服务
# 假设用户alice只能管理nginx服务$sudo-l 用户 alice 可以在 server 上运行以下命令:(root)/usr/bin/systemctl start nginx,(root)/usr/bin/systemctl stop nginx,(root)/usr/bin/systemctl status nginx $sudosystemctl restart nginx[sudo]alice的密码:******** $sudosystemctl status nginx|grepActive Active: active(running)since Mon2024-04-1510:31:00 CST;1s ago# 尝试其他命令会被拒绝$sudoaptupdate 对不起,用户 alice 无权以 root 的身份在 server 上执行 /usr/bin/apt update。场景3:审计跟踪- 查看sudo执行记录
# 管理员查看sudo日志$sudogrepsudo/var/log/auth.log|tail-5 Apr1510:30:00 server sudo: alice:TTY=pts/0;PWD=/home/alice;USER=root;COMMAND=/usr/bin/apt update Apr1510:30:15 server sudo: alice:TTY=pts/0;PWD=/home/alice;USER=root;COMMAND=/usr/bin/systemctl status nginx Apr1510:31:00 server sudo: alice:TTY=pts/0;PWD=/home/alice;USER=root;COMMAND=/usr/bin/systemctl restart nginx五、权限配置示例
配置/etc/sudoers:
# 使用visudo安全编辑(检查语法)$sudovisudo# 添加以下内容后的实际效果:# 1. 允许用户alice执行所有命令(需要密码)aliceALL=(ALL:ALL)ALL# 测试配置$sudo-u bobwhoami[sudo]alice的密码:******** bob# 2. 允许用户bob执行apt命令(无需密码)bobALL=(ALL)NOPASSWD: /usr/bin/apt# 测试配置(bob用户)$sudo-u bobbash-c"sudo -n apt update"# 直接执行,无需输入密码命中:1 http://archive.ubuntu.com/ubuntu focal InRelease# 3. 允许wheel组的所有成员%wheelALL=(ALL:ALL)ALL# 将用户加入wheel组$sudousermod-aG wheel charlie $groupscharlie charlie:charlie wheel# 4. 创建单独的配置文件$echo"%developers ALL=(ALL) /usr/bin/git, /usr/bin/docker"|sudotee/etc/sudoers.d/developers %developersALL=(ALL)/usr/bin/git, /usr/bin/docker# 测试$sudo-u developer1gitstatus[sudo]developer1的密码:******** 位于分支 main 无文件要提交,干净的工作区六、实际工作流程示例
场景:部署Web应用
# 开发人员alice的工作流程$whoamialice# 1. 拉取代码(无需特权)$gitpull origin main remote: Enumerating objects:5, done. remote: Counting objects:100%(5/5), done. remote: Compressing objects:100%(3/3), done. remote: Total3(delta2), reused0(delta0), pack-reused0展开对象中:100%(3/3), 完成。# 2. 重启服务(需要特权)$sudosystemctl restart myapp[sudo]alice的密码:********# 3. 查看日志(需要特权但只读)$sudotail-f /var/log/myapp.log2024-04-1510:35:00 INFO: Application started successfully2024-04-1510:35:01 INFO: Connected to database at localhost:5432# 4. 遇到复杂问题需要深入调试$sudo-i[sudo]alice的密码:******** root@server:~# journalctl -u myapp --since "10 minutes ago"-- Logs begin at Mon2024-04-15 09:00:00 CST, end at Mon2024-04-1510:36:00 CST. -- Apr1510:35:00 server systemd[1]: Started My Application Service. Apr1510:35:00 server myapp[1234]: Starting application with config: /etc/myapp/config.yaml root@server:~# exit$whoami# 已返回普通用户alice七、故障排除示例
问题1:用户不在sudoers文件中
$sudoaptupdate alice 不在 sudoers 文件中。此事将被报告。# 解决方案:用root用户添加$su- 密码:******** root@server:~# usermod -aG sudo aliceroot@server:~# exit$sudoaptupdate# 再次尝试[sudo]alice的密码:******** 命中:1 http://archive.ubuntu.com/ubuntu focal InRelease问题2:su认证失败
$subob 密码:******** su: 认证失败# 检查用户是否存在$ getentpasswdbob bob:x:1001:1001::/home/bob:/bin/bash# 可能原因:密码错误或用户被锁定$sudopasswd-S bob bob P 04/15/20240999997-1# P表示密码可用# 如果是root用户,Ubuntu默认被锁定$su- 密码:******** su: 认证失败 $sudo-i# 使用sudo代替[sudo]alice的密码:******** root@server:~#问题3:sudo配置语法错误
# 错误配置导致sudo无法使用$sudovisudo>>>在文件中添加错误语法<<<aliceALL=(ALL:ALL)ALLL# 多了一个L# 保存时报错>>>/etc/sudoers: 语法错误 near line28<<<现在做什么? 选项有:1)重新编辑2)不保存退出3)仍然保存 选择2# 选择不保存退出八、安全最佳实践示例
配置sudo免密码需谨慎:
# 危险配置:完全免密码aliceALL=(ALL)NOPASSWD: ALL# 安全配置:仅特定命令免密码aliceALL=(ALL)NOPASSWD: /usr/bin/apt update, /usr/bin/apt upgrade# 测试安全配置$sudo-naptupdate# 无需密码命中:1 http://archive.ubuntu.com/ubuntu focal InRelease $sudo-naptinstallnginx# 需要密码[sudo]alice的密码:********限制su的使用:
# 编辑PAM配置,只允许wheel组成员使用su$sudonano/etc/pam.d/su# 取消注释或添加auth required pam_wheel.so use_uid# 测试效果$groupsalice alice:alicesudo# 不在wheel组$su- 密码:******** su: 拒绝权限# 将用户加入wheel组$sudousermod-aG wheel alice $su- 密码:********# 现在可以成功切换root@server:~#九、总结建议
| 情况 | 推荐使用 | 示例命令 | 理由 |
|---|---|---|---|
| 日常管理 | sudo | sudo apt update | 安全、可审计、无需共享root密码 |
| 长时间root操作 | sudo -i | sudo -i | 有完整的root环境,操作完成后自动退出 |
| 服务账户操作 | sudo -u serviceuser | sudo -u postgres psql | 更安全,无需知道服务账户密码 |
| 自动化脚本 | 配置免密码sudo | sudo -n command | 避免硬编码密码,安全可控 |
| 多管理员环境 | 每人配置特定sudo权限 | alice ALL=(ALL) /usr/bin/systemctl * nginx | 权责分明,便于审计 |
黄金法则示例:
# ❌ 不要这样做(共享root密码)# "这是root密码,大家都可以用"# ✅ 应该这样做(每人独立账户+sudo权限)$whoamialice $sudosystemctl restart nginx# 执行需要特权的任务[sudo]alice的密码:********# 查看谁做了什么$sudogrepalice /var/log/auth.log Apr1510:40:00 server sudo: alice:TTY=pts/0;PWD=/home/alice;USER=root;COMMAND=/usr/bin/systemctl restart nginx实践建议:
- 为新用户配置sudo权限而非共享root密码
- 定期审计sudo日志:
sudo grep COMMAND /var/log/auth.log - 使用
sudo -l检查自己的权限 - 配置完成后用
visudo -c验证语法 - 始终遵循最小权限原则
通过以上详细的命令示例和结果展示,您可以清楚地了解su和sudo在实际工作中的使用方式和区别,从而更安全高效地管理系统。