sudo(superuser do)是Linux系统中用于授权普通用户以超级用户(root)或其他用户身份执行命令的工具。它提供了细粒度的访问控制,并记录所有sudo操作,增强了系统的安全性。
| 对比项 | sudo | su |
|---|---|---|
| 工作方式 | 以root权限执行单个命令 | 切换到root用户会话 |
| 密码要求 | 输入当前用户密码 | 输入root用户密码 |
| 权限控制 | 细粒度控制,可限制特定命令 | 获得完整root权限 |
| 日志记录 | 详细记录所有sudo操作 | 仅记录登录事件 |
| 安全性 | 更高,最小权限原则 | 较低,完全权限暴露 |
| 推荐使用 | 生产环境、多用户系统 | 单用户环境、系统维护 |
sudo [选项] 命令
| 选项 | 说明 |
|---|---|
-u 用户 |
以指定用户身份执行命令 |
-g 组 |
以指定组身份执行命令 |
-l |
列出当前用户的sudo权限 |
-v |
更新sudo身份验证时间戳 |
-k |
清除身份验证时间戳 |
-b |
在后台运行命令 |
-E |
保留当前用户环境变量 |
-H |
设置HOME环境变量为目标用户的家目录 |
-s |
运行shell |
-i |
模拟登录shell环境 |
# 安装软件
sudo apt-get install nginx
# 编辑系统文件
sudo vim /etc/hosts
# 查看root权限文件
sudo ls -la /root/
# 以www-data用户运行Web服务
sudo -u www-data /usr/sbin/nginx
# 以mysql用户查看数据目录
sudo -u mysql ls -la /var/lib/mysql/
# 以postgres用户执行psql
sudo -u postgres psql -c "SELECT version();"
# 查看当前用户的sudo权限
sudo -l
# 输出示例:
User alice may run the following commands on server1:
(ALL) ALL
(root) /usr/bin/apt-get update, /usr/bin/apt-get upgrade
# 模拟root登录环境
sudo -i
# 使用bash作为root
sudo -s
# 切换到其他用户环境
sudo -iu mysql
/etc/sudoers 文件控制sudo权限,应使用 visudo 命令编辑:
永远不要直接编辑/etc/sudoers文件,使用 visudo 命令可以检查语法错误,避免配置文件错误导致无法使用sudo。
用户 主机=(目标用户) 命令 [NOPASSWD:]
# 允许alice在所有主机上执行所有命令
alice ALL=(ALL:ALL) ALL
# 允许bob在server1上以root身份重启服务
bob server1=(root) /usr/bin/systemctl restart nginx
# 允许组wheel的所有成员无密码执行所有命令
%wheel ALL=(ALL) NOPASSWD: ALL
# 允许用户执行特定命令,无密码
charlie ALL=(ALL) NOPASSWD: /usr/bin/apt-get update, /usr/bin/apt-get upgrade
# 允许用户以特定用户身份执行命令
david ALL=(www-data) /usr/bin/vim /var/www/html/*
# 禁止用户执行特定命令
eve ALL=(ALL) ALL, !/usr/bin/passwd root
# 用户别名
User_Alias ADMINS = alice, bob, %wheel
User_Alias DEVELOPERS = charlie, david
# 主机别名
Host_Alias WEBSERVERS = web1, web2, web3
Host_Alias DBSERVERS = db1, db2
# 命令别名
Cmnd_Alias PROC_MGMT = /bin/kill, /usr/bin/killall
Cmnd_Alias APT_CMDS = /usr/bin/apt-get update, /usr/bin/apt-get upgrade
# 使用别名
ADMINS WEBSERVERS=(ALL) ALL
DEVELOPERS DBSERVERS=(postgres) /usr/bin/psql
# 在sudoers文件中设置
Defaults env_reset
Defaults env_keep += "LANG DISPLAY"
Defaults env_keep += "HTTP_PROXY HTTPS_PROXY"
Defaults env_keep += "EDITOR VISUAL"
# 配置syslog日志
Defaults syslog=auth
Defaults log_host, log_year
# 自定义日志文件
Defaults logfile=/var/log/sudo.log
# 设置密码尝试次数
Defaults passwd_tries=3
# 设置密码超时时间(分钟)
Defaults timestamp_timeout=15
# 要求tty终端
Defaults requiretty
# 使用root时保留环境变量
Defaults:root !env_reset
# 包含/etc/sudoers.d/目录下所有文件
#includedir /etc/sudoers.d
# 创建单独配置文件
sudo visudo -f /etc/sudoers.d/web-admins
# /etc/sudoers.d/developers 文件内容
# 开发团队可以重启Web服务
User_Alias DEVELOPERS = %dev-team
Cmnd_Alias WEB_SERVICES = /usr/bin/systemctl restart nginx, \
/usr/bin/systemctl restart apache2
DEVELOPERS ALL=(root) WEB_SERVICES
# 允许查看日志,无需密码
DEVELOPERS ALL=(root) NOPASSWD: /usr/bin/tail -f /var/log/nginx/*.log
# /etc/sudoers.d/dba 文件内容
User_Alias DBAS = alice, bob
Cmnd_Alias DB_COMMANDS = /usr/bin/mysql, /usr/bin/mysqldump, \
/usr/bin/systemctl restart mysql
DBAS ALL=(root) DB_COMMANDS
DBAS ALL=(mysql) ALL
#!/bin/bash
# backup_script.sh
# 配置sudoers允许此脚本以root身份运行备份
# sudoers配置:
# backup-user ALL=(root) NOPASSWD: /usr/local/bin/backup_script.sh
echo "开始系统备份..."
sudo /usr/bin/tar -czf /backup/system-$(date +%Y%m%d).tar.gz /etc /home
echo "备份完成"
# 查看系统日志中的sudo记录
sudo grep sudo /var/log/auth.log
sudo grep sudo /var/log/secure
# 查看特定用户的sudo记录
sudo grep "sudo.*alice" /var/log/auth.log
# 使用journalctl(systemd系统)
sudo journalctl | grep sudo
Jan 12 14:30:01 server1 sudo: alice : TTY=pts/0 ; PWD=/home/alice ; USER=root ; COMMAND=/usr/bin/apt-get update
Jan 12 14:35:22 server1 sudo: bob : user NOT in sudoers ; TTY=pts/1 ; PWD=/home/bob ; USER=root ; COMMAND=/bin/bash
# 在sudoers中配置
Defaults log_host, log_year, log_input, log_output
Defaults iolog_dir=/var/log/sudo-io/%{user}
错误信息:user is not in the sudoers file. This incident will be reported.
# 解决方案:将用户添加到sudo组或配置sudoers
sudo usermod -aG sudo username # Ubuntu/Debian
sudo usermod -aG wheel username # CentOS/RHEL
# 或者直接编辑sudoers
sudo visudo
# 添加:username ALL=(ALL:ALL) ALL
# 检查sudoers文件语法
sudo visudo -c
# 检查用户组信息
id username
# 检查sudo二进制文件权限
ls -la /usr/bin/sudo
# 检查PAM配置
sudo pam-auth-update
# 安装sudo
# Ubuntu/Debian
apt-get install sudo
# CentOS/RHEL
yum install sudo
# 检查PATH环境变量
echo $PATH
# 使用完整路径
/usr/bin/sudo ls
# 安全sudoers配置示例
Defaults env_reset
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
Defaults logfile="/var/log/sudo.log"
Defaults log_host, log_year, log_input
Defaults iolog_dir="/var/log/sudo-io/%{user}"
Defaults passwd_timeout=0
Defaults requiretty
Defaults passwd_tries=3
Defaults badpass_message="密码错误!请重新输入。"
A: 在生产环境中,sudo通常更好,因为它提供更细粒度的控制和完整的审计日志。
A: sudo默认记住密码15分钟。可以修改timestamp_timeout参数,但出于安全考虑不建议延长时间。
# 在sudoers中
user ALL=(root) /usr/bin/apt-get update
# 这样用户只能执行"apt-get update",不能执行"apt-get upgrade"
# 将用户从sudo组移除
sudo gpasswd -d username sudo
# 或注释掉sudoers中的对应行
| 命令 | 功能 |
|---|---|
visudo |
安全编辑sudoers文件 |
su |
切换用户身份 |
gpasswd |
管理组和组成员 |
whoami |
显示当前用户 |
id |
显示用户和组信息 |
newgrp |
切换主要组 |
sudo !! 以sudo权限重新执行上一条命令#!/usr/bin/env bash 和 set -e 确保安全执行sudo -v 刷新sudo时间戳而不执行命令sudoedit 安全编辑受保护的文件SUDO_EDITOR 环境变量指定默认编辑器