13. 安全注意事项
HAProxy 旨在以极低的权限运行。使用它的标准方式是将其隔离到 chroot 环境中,并将其权限降级为非 root 用户,且该用户在该环境内没有任何权限,从而确保未来若发现任何漏洞,其被攻破也不会影响系统其余部分。
为执行 chroot 操作,进程必须首先以 root 用户身份启动。手动构建 chroot 环境并在其中启动进程毫无意义,这类 chroot 环境难以构建,通常无法得到妥善维护,且包含的缺陷远多于主文件系统。一旦发生入侵,攻击者可利用特意构建的文件系统。不幸的是,许多系统管理员混淆了“以 root 身份启动”与“以 root 身份运行”的区别,导致在启动 HAProxy 之前就更改了用户 ID,从而削弱了实际的安全限制。
HAProxy 必须以 root 身份启动,以实现以下目的:
- 调整文件描述符限制
- 绑定到特权端口编号
- 绑定到特定网络接口
- 透明地监听外部地址
- 在 chroot 沙箱内隔离自身
- 降权至另一个非特权 UID
HAProxy 可能需要以 root 身份运行,以实现以下目的:
- 绑定到接口以发起出站连接
- 绑定到特权源端口以发起出站连接
- 透明地绑定到外部地址以发起出站连接
大多数用户无需使用“以 root 身份运行”的情况。但“以 root 身份启动”涵盖了大多数使用场景。
安全的配置应满足以下要求:
- 一个指向空位置且无任何访问权限的 chroot 语句。可通过 UNIX 命令行按如下方式准备:
并在 HAProxy 配置的 global 段中以如下方式引用:
- 在 global 段中同时使用 uid/user 和 gid/group 语句:
- 设置统计信息套接字的模式、所有者用户 ID 和所有者组 ID,使其与允许访问 CLI 的用户和/或组匹配,以确保无人可访问:
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 二进制文件中添加所需功能,允许集可通过以下命令设置:
示例:
新增的功能将在进程启动后于其允许集(Permitted set)中体现。若相同的功能作为 ‘setcap’ 关键字的参数,也可在进程有效集(Effective set)中观察到。可通过以下命令进行验证:
示例:
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 二进制文件的权限能力设置。
示例: