Linux

Linux的sudo指令,背后做了什么?

转载: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 nginxsystemctl status nginx命令。

允许用户无需输入密码执行命令

jane ALL=(ALL) NOPASSWD: /usr/bin/apt update, /usr/bin/apt upgrade

这样配置后,用户jane无需输入密码即可执行apt updateapt 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进行权限管理。