↑↓ 选择↵ 打开⌫ 切换范围完整搜索

PG.CENTER 连接 PostgreSQL 文档、百科与生态知识。由 Pigsty 维护。

HAProxy 3.4.4

13. 安全注意事项

HAProxy 3.4 入门、配置与管理三套完整手册的简体中文译本

HAProxy 旨在以极低的权限运行。使用它的标准方式是将其隔离到 chroot 环境中,并将其权限降级为非 root 用户,且该用户在该环境内没有任何权限,从而确保未来若发现任何漏洞,其被攻破也不会影响系统其余部分。

为执行 chroot 操作,进程必须首先以 root 用户身份启动。手动构建 chroot 环境并在其中启动进程毫无意义,这类 chroot 环境难以构建,通常无法得到妥善维护,且包含的缺陷远多于主文件系统。一旦发生入侵,攻击者可利用特意构建的文件系统。不幸的是,许多系统管理员混淆了“以 root 身份启动”与“以 root 身份运行”的区别,导致在启动 HAProxy 之前就更改了用户 ID,从而削弱了实际的安全限制。

HAProxy 必须以 root 身份启动,以实现以下目的:

  • 调整文件描述符限制
  • 绑定到特权端口编号
  • 绑定到特定网络接口
  • 透明地监听外部地址
  • 在 chroot 沙箱内隔离自身
  • 降权至另一个非特权 UID

HAProxy 可能需要以 root 身份运行,以实现以下目的:

  • 绑定到接口以发起出站连接
  • 绑定到特权源端口以发起出站连接
  • 透明地绑定到外部地址以发起出站连接

大多数用户无需使用“以 root 身份运行”的情况。但“以 root 身份启动”涵盖了大多数使用场景。

安全的配置应满足以下要求:

  • 一个指向空位置且无任何访问权限的 chroot 语句。可通过 UNIX 命令行按如下方式准备:
# mkdir /var/empty && chmod 0 /var/empty || echo "Failed"

并在 HAProxy 配置的 global 段中以如下方式引用:

chroot /var/empty
  • 在 global 段中同时使用 uid/user 和 gid/group 语句:
user haproxy
group haproxy
  • 设置统计信息套接字的模式、所有者用户 ID 和所有者组 ID,使其与允许访问 CLI 的用户和/或组匹配,以确保无人可访问:
stats socket /var/run/haproxy.stat uid hatop gid hatop mode 600

13.1. Linux 能力支持

自 v2.9 版本起,HAProxy 支持 Linux 能力。若二进制文件编译时 USE_LINUX_CAP=1,则在从 root 用户切换至非 root 用户时,能够保留通过 ‘setcap’ 关键字赋予的能力。

自 v3.1 版本起,HAProxy 也会检查通过 ‘setcap’ 关键字指定的权限是否已在二进制文件中由管理员设置为允许集(通过 capget 系统调用)。若存在此情况,HAProxy 在以非 root 用户运行时,将通过 capset 系统调用将其权限从允许集转移到进程的有效集。

此举旨在避免 HAProxy 以 root 用户启动并运行时可能出现的所有使用场景:透明代理模式、绑定到特权端口。

‘setcap’ 关键字支持以下网络能力:

  • cap_net_admin:透明代理、将套接字绑定到特定网络接口、使用 set-mark 动作;
  • cap_net_raw(cap_net_admin 的子集):透明代理;
  • cap_net_bind_service:将套接字绑定到特定网络接口;
  • cap_sys_admin:在特定网络命名空间中创建套接字。

HAProxy 不会在未将这些能力列为 ‘setcap’ 参数的情况下,将其从允许集(Permitted set)转移到有效集(Effective)。有关 ‘setcap’ 关键字及支持能力的更多信息,请参见配置指南第 3.1 节“进程管理与安全”。

系统管理员可在 HAProxy 二进制文件中添加所需功能,允许集可通过以下命令设置:

示例:

# setcap cap_net_admin,cap_net_bind_service=p /usr/local/sbin/haproxy

新增的功能将在进程启动后于其允许集(Permitted set)中体现。若相同的功能作为 ‘setcap’ 关键字的参数,也可在进程有效集(Effective set)中观察到。可通过以下命令进行验证:

示例:

# grep Cap /proc/<haproxy PID>/status

CapInh: 0000000000000000 CapPrm: 0000000000001400 CapEff: 0000000000001400 CapBnd: 000001ffffffffff CapAmb: 0000000000000000

有关 setcap 和能力集的更多详细信息,请参阅 Linux 手册页(capabilities(7))。

在某些使用场景中,例如透明代理或在特定网络命名空间中创建套接字时,配置文件解析器会检测到需要 cap_net_raw、cap_sys_admin 或其他受支持的能力。随后,在初始化阶段,HAProxy 进程会检查这些能力是否可被添加到其有效能力集(Effective set)中。若因 capget 或 capset 系统调用失败(某些安全模块如 SELinux、Seccomp 等对系统调用施加了限制)而导致无法完成,进程将发出诊断警告(以 -dD 开头)。

由于支持多种不同平台及其各异的系统设置,解析器无法从配置文件中推断出是否将绑定到特权端口。因此,在权限不足(以非 root 用户运行)的情况下,进程仅会以如下告警信息终止。用户需自行检查配置文件及 HAProxy 二进制文件的权限能力设置。

示例:

$ haproxy -dD -f haproxy.cfg
...
[ALERT]    (96797): Binding [haproxy.cfg:36] for frontend fe: cannot bind socket (Permission denied) for [0.0.0.0:80]
[ALERT]    (96797): [haproxy.main()] Some protocols failed to start their listeners! Exiting.
来源与许可

文档取自 pig.center · 上游文档

版本
3.4.4
许可
GPL-2.0-only
来源修订
1dff183d0ca5a430d10324c5bbc64f9853ed77ae5df299827b47b2f54e352f65
译文修订
1dff183d0ca5a430d10324c5bbc64f9853ed77ae5df299827b47b2f54e352f65
原始 Markdown