转载:Linux的sudo指令,背后做了什么?
在实际工作中,我们经常使用 Linux的sudo
指令进行操作。那么,sudo
是什么?它背后做了什么?为什么使用sudo
而不是直接使用root
,它对安全性有什么影响?这篇文章,我们将全面分析sudo
1. 什么是sudo?
sudo
(superuser do的缩写)是一个允许授权用户以别的用户身份(通常是root)运行程序的程序。它最初由Bob Coggeshall和Cliff Spencer在1980年代开发,旨在提供一种比传统的su(切换用户)更安全、更灵活的权限管理方式。
2. 为什么使用 sudo而不是直接使用root?
直接使用root
账户存在诸多风险:
- 安全性:
root
账户缺乏保护,一旦泄露,攻击者将拥有系统的完全控制权。 - 审计和日志:通过
root
执行的操作难以追踪来源,不利于审计和问题排查。 - 误操作风险:长期使用
root
账户容易导致误操作,可能对系统造成不可逆转的损害。
sudo
通过以下方式缓解上述问题:
- 最小权限原则:仅授予必要的权限,减少误操作和潜在的安全风险。
- 日志记录:所有使用sudo执行的命令都会被记录,便于审计和追踪。
- 细粒度控制:可以针对不同用户或用户组,设置不同的权限规则。
3. 基本用法
3.1 基本语法
sudo [选项] 命令
常用选项:
-u 用户
:以指定用户的身份运行命令,默认为root。-s
:以shell形式运行命令。-i
:模拟完整的登录环境。-k
:无视和清除之前的认证缓存。
3.2 使用示例
以root身份执行命令
sudo apt update sudo yum install nginx
以其他用户身份执行命令
sudo -u www-data ls /var/www
以shell形式切换到root
sudo -s
以登录shell形式切换到指定用户
sudo -i -u username
4. 配置sudo
sudo
的行为和权限由/etc/sudoers
文件控制。直接编辑此文件存在风险,为避免语法错误导致的系统问题,建议使用visudo
命令进行编辑。
sudoers文件主要由以下部分组成:
- 别名定义:定义用户、主机、命令等别名,便于管理。
- 权限规则:指定哪些用户或用户组可以执行哪些命令。
4.1 别名定义
别名定义包括用户别名,主机别名和命令别名。
User_Alias:定义用户别名。如下示例:
User_Alias ADMINS = alice, bob
HOST_Alias:定义主机别名。如下示例:
Host_Alias SERVER = server1, server2
COMMAND_Alias:定义命令别名。如下示例:
Cmnd_Alias WEB_CMDS = /usr/bin/systemctl start nginx, /usr/bin/systemctl stop nginx
4.2 权限规则
权限规则指定哪些用户可以在特定主机上执行特定命令,以何种方式执行。
# 格式 用户 别名 = (运行身份) 命令别名 # 示例:允许用户alice在主机SERVER上以root身份执行WEB_CMDS中的命令,而且无需输入密码。 alice SERVER = (root) NOPASSWD: WEB_CMDS
4.3 常见配置示例
允许用户组sudo执行任何命令
%sudo ALL=(ALL:ALL) ALL
其中,%sudo
表示用户组sudo,ALL
表示所有主机,(ALL:ALL)
表示以所有用户和组身份运行,最后的ALL
表示所有命令。
允许特定用户执行特定命令
john ALL=(ALL) /usr/bin/systemctl restart nginx, /usr/bin/systemctl status nginx
上述规则允许用户john在所有主机上以任何用户身份执行systemctl restart nginx
和systemctl status nginx
命令。
允许用户无需输入密码执行命令
jane ALL=(ALL) NOPASSWD: /usr/bin/apt update, /usr/bin/apt upgrade
这样配置后,用户jane无需输入密码即可执行apt update
和apt upgrade
命令。
5. 管理sudo权限
5.1 添加用户到sudo组
在许多 Linux发行版中,默认的sudo
权限是授予特定用户组(如 sudo或 wheel)。通过将用户添加到相应的组,可以赋予其sudo
权限。
在Debian/Ubuntu上将用户添加到sudo组
sudo usermod -aG sudo username
在Red Hat/CentOS/Fedora上将用户添加到wheel组
sudo usermod -aG wheel username
创建自定义用户组
有时,需要为不同的权限需求创建专门的用户组。可以按照下面的方式来实现:
1. 创建一个新组
sudo groupadd devadmins
2. 将用户添加到新组
sudo usermod -aG devadmins username
3. 在sudoers文件中配置新组的权限
%devadmins ALL=(ALL) /usr/bin/systemctl, /usr/bin/apt
5.2 移除用户的sudo权限
要移除用户的sudo权限,可以将其从sudo组(或相应的权限组)中移除。
sudo deluser username sudo # Debian/Ubuntu sudo gpasswd -d username wheel # Red Hat/CentOS/Fedora
6. sudo高级功能
6.1 sudoers中的别名
别名使得sudoers文件更具可读性和可维护性。利用User_Alias、Host_Alias和Command_Alias,可以将复杂的权限规则简化为简洁的配置。
6.2 组合使用别名
User_Alias ADMINS = alice, bob Host_Alias DATABASE_SERVERS = db1, db2 Cmnd_Alias DB_CMDS = /usr/bin/mysql, /usr/bin/mysqldump ADMINS DATABASE_SERVERS = (dbadmin) DB_CMDS
上述配置允许ADMINS组中的用户在DATABASE_SERVERS主机上以dbadmin身份执行DB_CMDS中的命令。
6.3 环境变量的管理
sudo可以控制用户在执行命令时继承的环境变量,以提高安全性。使用env_keep和env_reset:
env_keep
:指定允许保留的环境变量。env_reset
:重置环境变量,仅保留默认允许的变量。
Defaults env_reset Defaults env_keep += "PATH LANG"
6.4 计时戳和超时设置
sudo有一个计时戳,用于管理认证缓存。默认情况下,用户在一定时间内无须重新输入密码。
可以通过设置timestamp_timeout
来调整超时时间(单位:分钟)。
Defaults timestamp_timeout=10
上述配置将超时时间设置为10分钟。设置为0
将每次都要求输入密码,设置为-1
则禁用超时机制。
6.5 运行别名用户
sudo允许用户以不同的用户身份运行命令,不仅限于root。这对于需要以特定用户身份执行某些任务的场景非常有用。
sudo -u www-data /usr/bin/systemctl restart nginx
6.6 运行别名组
除单个用户外,还可以设置组别的权限。
%webadmins ALL=(www-data) /usr/bin/systemctl restart nginx
这样,webadmins组中的所有用户都可以以www-data身份重启nginx服务。
7. 排查常见sudo问题
7.1 权限不足:权限被拒绝
原因
- 用户未在sudoers文件中配置。
- 用户未在正确的用户组中。
- sudoers文件配置错误。
解决方法
- 确认用户所在的组是否赋予了sudo权限。
- 使用
visudo
检查sudoers配置是否正确。 - 查看系统日志了解详细错误信息。
7.2 sudoers文件语法错误
原因
- 手动编辑sudoers文件时出现语法错误。
- 误用别名或权限规则。
解决方法
- 始终使用
visudo
编辑sudoers文件,避免语法错误。 - 如果语法错误导致无法使用sudo,可以使用root用户或通过单用户模式修复sudoers文件。
7.3 码缓存问题
有时,用户可能会发现sudo不再要求输入密码,或总是要求输入密码。
解决方法
- 检查sudoers文件中的NOPASSWD选项。
- 检查
timestamp_timeout
设置。 - 确认用户的认证缓存正常工作。
7.4 用户无法运行指定命令
原因
- sudoers文件中未正确配置允许用户执行的命令。
- 命令的路径不正确。
解决方法
- 确认sudoers中命令的绝对路径是否正确。
- 使用别名或通配符正确配置命令权限。
8. sudo的替代方案
虽然sudo功能强大,但在某些场景下,可能需要其他工具作为替代或补充。
8.1 su
su
(switch user)允许用户切换到另一个用户身份,默认切换到root。然而,su需要知道目标用户的密码,不如sudo
灵活和安全。
8.2 doas
doas
是OpenBSD开发的一个轻量级的权限提升工具,语法简洁,配置简单。近年来在Linux社区也逐渐受到关注,被认为是sudo
的一个简洁替代方案。
安装doas
# 在Debian/Ubuntu上 sudo apt install opendoas # 在Arch Linux上 sudo pacman -S opendoas
配置doas
配置文件通常位于/etc/doas.conf
,示例配置:
permit :wheel permit john as root cmd /usr/bin/systemctl
8.3 Polkit
Polkit(PolicyKit)是一个用于定义非特权进程与特权进程之间交互的框架,常用于桌面环境中权限管理,与sudo
不同,更多用于系统服务的权限控制。
8.4 pkexec
pkexec
是Polkit的一部分,允许用户以另一个用户身份(通常是root)执行命令。与sudo
类似,但依赖于Polkit进行权限管理。