13. Соображения безопасности
HAProxy рассчитан на работу с очень ограниченными привилегиями. Стандартный способ его использования — изолировать его в окружении chroot и сбросить привилегии до обычного пользователя, не имеющего никаких разрешений внутри этого окружения. Тогда, если в будущем обнаружится уязвимость, компрометация HAProxy не затронет остальную систему.
Чтобы выполнить chroot, процесс сначала нужно запустить от имени root. Создавать окружения chroot вручную и запускать процесс уже внутри них бессмысленно: их трудно создавать, их никогда не сопровождают должным образом, и ошибок в них всегда гораздо больше, чем в основной файловой системе. Кроме того, при компрометации злоумышленник сможет воспользоваться специально подготовленной файловой системой. К сожалению, многие администраторы путают «запустить от имени root» и «работать от имени root», из-за чего меняют UID ещё до запуска haproxy и тем самым ослабляют действующие ограничения безопасности.
HAProxy нужно запускать от имени root, чтобы:
- изменять ограничения на число файловых дескрипторов;
- привязываться к привилегированным портам;
- привязываться к определённому сетевому интерфейсу;
- прозрачно прослушивать чужой адрес;
- изолировать себя в окружении chroot;
- переходить на другой непривилегированный UID.
HAProxy может потребоваться работать от имени root, чтобы:
- привязываться к интерфейсу для исходящих соединений;
- привязываться к привилегированным исходным портам для исходящих соединений;
- прозрачно привязываться к чужому адресу для исходящих соединений.
Большинству пользователей никогда не понадобится «работать от имени root». Однако «запуск от имени root» охватывает большинство сценариев использования.
Безопасная конфигурация содержит:
- Директиву chroot, указывающую на пустой каталог без каких-либо прав доступа. Его можно подготовить следующей командой UNIX:
и указать следующим образом в секции global конфигурации HAProxy:
- Обе директивы uid/user и gid/group в секции global:
- Сокет stats, у которого mode, uid и gid соответствуют пользователю и/или группе, которым разрешён доступ к CLI, чтобы посторонние не могли получить к нему доступ:
13.1. Поддержка Linux capabilities
Начиная с версии v2.9 haproxy поддерживает Linux capabilities. Если исполняемый файл собран с USE_LINUX_CAP=1, он может сохранять возможности, указанные в директиве ‘setcap’, при переходе от пользователя root к обычному пользователю.
Начиная с версии v3.1 haproxy также проверяет, установил ли администратор возможности из директивы ‘setcap’ в наборе Permitted его исполняемого файла (системный вызов capget). Если это так, он переносит эти возможности в набор Effective своего процесса (системный вызов capset), работая от имени обычного пользователя.
Это сделано, чтобы исключить все возможные случаи, когда haproxy запускается и работает от имени root: режим прозрачного прокси и привязку к привилегированным портам.
Директива ‘setcap’ поддерживает следующие сетевые возможности:
- cap_net_admin: прозрачное проксирование, привязка сокета к определённому сетевому интерфейсу, использование действия set-mark;
- cap_net_raw (подмножество cap_net_admin): прозрачное проксирование;
- cap_net_bind_service: привязка сокета к определённому сетевому интерфейсу;
- cap_sys_admin: создание сокета в определённом сетевом пространстве имён.
HAProxy никогда не переносит эти возможности из своего набора Permitted в Effective, если они не перечислены в аргументе ‘setcap’. Дополнительные сведения о директиве ‘setcap’ и поддерживаемых возможностях приведены в главе 3.1 «Управление процессами и безопасность» руководства по конфигурации.
Администратор может добавить необходимые возможности в набор Permitted исполняемого файла haproxy следующей командой:
Пример:
Добавленные возможности будут видны в наборе Permitted процесса после его запуска. Если те же возможности указаны в аргументах директивы ‘setcap’, они также могут быть видны в наборе Effective процесса. Это можно проверить следующей командой:
Пример:
CapInh: 0000000000000000
CapPrm: 0000000000001400
CapEff: 0000000000001400
CapBnd: 000001ffffffffff
CapAmb: 0000000000000000
Дополнительные сведения о setcap и наборах возможностей приведены в справочных страницах Linux (capabilities(7)).
В некоторых сценариях, например при прозрачном проксировании или создании сокета в определённом сетевом пространстве имён, парсер конфигурации определяет, что требуются cap_net_raw, cap_sys_admin или другие поддерживаемые возможности. Затем на этапе инициализации процесс haproxy проверяет, можно ли включить их в свой набор Effective. Если это невозможно из-за сбоя системного вызова capget или capset (например, из-за ограничений на системные вызовы, наложенных модулями безопасности SELinux, Seccomp и т. п.), процесс выводит диагностические предупреждения (при запуске с -dD).
Из-за поддержки множества платформ с разными системными настройками парсер не может определить по файлу конфигурации, будет ли выполняться привязка к привилегированным портам. Поэтому при недостаточных привилегиях (работа от имени обычного пользователя) процесс завершится только с сообщением об ошибке наподобие приведённого ниже. Пользователь должен самостоятельно перепроверить конфигурацию и набор возможностей исполняемого файла haproxy.
Пример: