Перейти к содержанию

12. Другие секции

Трассировка, пользователи, почтовые серверы, ошибки, кольцевые буферы, сертификаты, ACME и глобальные проверки работоспособности

Секции, описанные ниже, реже используются и обычно поддерживают лишь несколько параметров. Между ними нет неявной связи. Они все начинаются с одного ключевого слова. Ни одна из них не допускается до секции “global”. Поддержка некоторых из них может зависеть от опций сборки (например, что касается SSL).

12.1. Трассировка

Для отладки можно включить трассировку подсистемы HAProxy. При этом выводятся отладочные сообщения об определённой подсистеме. Это мощное средство диагностики проблем. Трассировку можно динамически настраивать через CLI. Некоторые параметры также можно заранее задать в файле конфигурации, в отдельных секциях “traces”. Подробнее о трассировке см. руководство по управлению. Это инструмент разработчика для сложных сеансов отладки. Он выводит много сообщений и требует дополнительных ресурсов, поэтому используйте его осторожно. Поскольку это инструмент разработчика, обратная совместимость этой секции не гарантируется.

traces

traces

Начинает новую секцию traces. Одна или несколько секций “traces” могут быть использованы. Все директивы оцениваются в порядке объявления, последующие перекрывают предыдущие.

trace <source> <args...>

trace <source> <args...>

Настраивает подсистему “trace”. Каждая подсистема описана в руководстве по управлению; синтаксис в точности совпадает. Весь вывод команды “trace” появляется при разборе секции. Обычно это ошибки и предупреждения, но некоторые неполные команды могут перечислять допустимые варианты. Команда не предназначена для обычного использования: как правило, разработчики рекомендуют её при сложной отладке. В зависимости от уровня и подробности трассировка может существенно снизить общую производительность. Синтаксис команд приведён в руководстве по управлению.

Пример:

ring buf1
  size 10485760 # 10MB
  format timed
  backing-file /tmp/h1.traces

ring buf2
  size 10485760 # 10MB
  format timed
  backing-file /tmp/h2.traces

traces
  trace h1 sink buf1 level developer verbosity complete start now
  trace h2 sink buf1 level developer verbosity complete start now

12.2. Списки пользователей

Доступ к секциям frontend/backend/listen или статистике HTTP можно ограничить, разрешив его только пользователям, прошедшим аутентификацию и авторизацию. Для этого необходимо создать хотя бы один список пользователей и определить в нём пользователей.

userlist <listname>

userlist <listname>

Создаёт новый пользовательский список с именем <listname>. Множество независимых пользовательских списков может быть использовано для хранения данных аутентификации и авторизации для независимых клиентов.

group <groupname> [users <user>,<user>,(...)]

group <groupname> [users <user>,<user>,(...)]

Добавляет группу <groupname> в текущий список пользователей. Также можно включить в неё пользователей, указав после ключевого слова “users” список имён через запятую.

user <username> [password|insecure-password <password>]

user <username> [password|insecure-password <password>]
                [groups <group>,<group>,(...)]

Добавляет пользователя <username> в текущий список. Допускаются как защищённые, зашифрованные пароли, так и незащищённые, незашифрованные. Зашифрованные пароли проверяются функцией crypt(3), поэтому набор алгоритмов зависит от возможностей системы. Например, современные системы Linux на основе Glibc поддерживают MD5, SHA-256, SHA-512 и классический алгоритм шифрования паролей на основе DES.

Внимание: зашифрованные пароли могут значительно повысить нагрузку на CPU в зависимости от числа запросов и выбранного алгоритма. При любом варианте с хешированием пароль каждого запроса необходимо обработать выбранным алгоритмом перед сравнением со значением в файле конфигурации. Большинство современных алгоритмов специально требует больших вычислительных затрат для защиты от перебора. Соль и хеширование применяются к открытому паролю не один, а тысячи раз. Это может быстро стать существенной частью общей нагрузки HAProxy на CPU и даже привести к аварийному завершению приложения!

Один из способов снизить нагрузку хеш-функций на CPU — уменьшить число раундов хеширования для алгоритмов семейства SHA либо снизить «стоимость» функции, если алгоритм это поддерживает.

Также можно учесть, что реализации musl, например в Alpine Linux, вычисляют хеши медленнее аналогов из glibc.

Все пароли считаются обычными аргументами, поэтому к ним применяются правила кавычек и экранирования из раздела 2.2 . Рекомендуется заключать пароли в одинарные кавычки.

Пример:

userlist L1
  group G1 users tiger,scott
  group G2 users xdb,scott

  user tiger password $6$k6y3o.eP$JlKBx9za9667qe4(...)xHSwRv6J.C0/D7cV91
  user scott insecure-password 'elgato'
  user xdb insecure-password 'hello'

userlist L2
  group G1
  group G2

  user tiger password $6$k6y3o.eP$JlKBx(...)xHSwRv6J.C0/D7cV91 groups G1
  user scott insecure-password 'elgato' groups G1,G2
  user xdb insecure-password 'hello' groups G2

Оба списка функционально идентичны.

12.3. Почтовые серверы

При изменении состояния серверов можно отправлять уведомления по электронной почте. Если уведомления настроены, они передаются каждому почтовому серверу из секции mailers. Для отправки используется Lua (см. examples/lua/mailers.lua).

mailers <mailersect>

mailers <mailersect>

Создаёт список почтовых серверов с именем <mailersect>. Это независимая секция, на которую ссылаются один или несколько прокси.

mailer <mailername> <ip>:<port>

mailer <mailername> <ip>:<port>

Определяет почтовый сервер в секции mailers.

Пример:

global
    # mailers.lua file as provided in the git repository
    # adjust path as needed
    lua-load examples/lua/mailers.lua

mailers mymailers
    mailer smtp1 192.168.0.1:587
    mailer smtp2 192.168.0.2:587

backend mybackend
    mode tcp
    balance roundrobin

    email-alert mailers mymailers
    email-alert from test1@horms.org
    email-alert to test2@horms.org

    server srv1 192.168.0.30:80
    server srv2 192.168.0.31:80

timeout mail <time>

timeout mail <time>

Определяет время, доступное для установления соединения и передачи письма на сервер. Если не определено, значение по умолчанию — 10 секунд. Для обеспечения передачи как минимум двух SYN-ACK пакетов в ходе инициализации TCP рукопожатия рекомендуется сохранять это значение выше 4 секунд.

Пример:

mailers mymailers
    timeout mail 20s
    mailer smtp1 192.168.0.1:587

12.4. Ошибки HTTP

Можно глобально объявить несколько групп ошибок HTTP, а затем импортировать их в любые секции прокси. На одну группу можно ссылаться из нескольких мест и импортировать её полностью или частично.

http-errors <name>

http-errors <name>

Создаёт группу http-errors с именем <name>. Это независимая секция, на которую по имени могут ссылаться один или несколько прокси.

errorfile <code> <file>

errorfile <code> <file>

Связывает содержимое файла с кодом ошибки HTTP.

Аргументы:

<code>    — код состояния HTTP. Сейчас HAProxy может выдавать коды
          200, 400, 401, 403, 404, 405, 407, 408, 410,
          425, 429, 500, 501, 502, 503 и 504.

<file>    — файл с полным ответом HTTP. Рекомендуется добавлять к имени
          расширение ".http", чтобы не путать ответ со страницами ошибок
          HTML, и использовать абсолютные пути, поскольку файлы читаются
          до выполнения chroot.

Подробнее см. описание “errorfile” в разделе 4 .

Пример:

http-errors website-1
    errorfile 400 /etc/haproxy/errorfiles/site1/400.http
    errorfile 404 /etc/haproxy/errorfiles/site1/404.http
    errorfile 408 /dev/null  # work around Chrome pre-connect bug

http-errors website-2
    errorfile 400 /etc/haproxy/errorfiles/site2/400.http
    errorfile 404 /etc/haproxy/errorfiles/site2/404.http
    errorfile 408 /dev/null  # work around Chrome pre-connect bug

12.5. Кольцевые буферы

Можно глобально объявить кольцевые буферы для использования в качестве получателей сообщений журналов или трассировок.

ring <ringname>

ring <ringname>

Создаёт новый кольцевой буфер с именем <ringname>.

backing-file <path>

backing-file <path>

Заменяет обычное выделение памяти для кольцевого буфера файлом, отображённым в память. Это удобно для сбора трассировок или журналов для анализа после завершения процесса без подключения медленного клиента к CLI. Новое содержимое автоматически заменяет старое, поэтому последние данные всегда доступны. Записанные в буфер данные будут видны в файле после остановки процесса. Обычно они видны вскоре после записи, но это не гарантируется, поскольку запись не синхронная.

При использовании этого параметра полезный объём области хранения уменьшается на размер “struct ring”, размещаемой в её начале и необходимой для восстановления содержимого. Владельцем создаваемого файла становится пользователь, запускающий процесс; режим доступа — 0600, размер задаётся директивой “size”. При разборе директивы, в том числе при проверке конфигурации, существующий непустой файл сначала переименовывается с добавлением суффикса “.bak”, а прежний файл с суффиксом “.bak” удаляется. Это защищает ценные отладочные данные при немедленной перезагрузке конфигурации или перезапуске процесса и даёт администратору время заметить новый файл “.bak” и при необходимости сохранить его в архиве. После аварийного завершения самые свежие данные находятся в <path>, а после перезапуска службы — в “<path>.bak”. Поэтому общий требуемый объём хранения вдвое больше размера кольцевого буфера. Ошибки ротации файла игнорируются без сообщений. Если резервная копия не нужна, достаточно поместить файл в каталог без права записи.

ПРЕДУПРЕЖДЕНИЕ: эта возможность влияет на стабильность и безопасность. Во-первых, размещение буфера на медленном устройстве, например физическом жёстком диске, может заметно замедлить доступ и даже вызвать аварийное завершение, если за доступ конкурирует слишком много потоков. Во-вторых, изменение области внешним процессом может привести к аварийному завершению haproxy или перезаписи части его собственной памяти данными трассировки. В-третьих, если файловая система заполнится раньше буфера, запись в буфер может вызвать аварийное завершение процесса.

Данные в этом кольцевом буфере структурированы и НЕ предназначены для непосредственного чтения текстовым редактором, хотя большую их часть с трудом можно разобрать. Содержимое файла предназначено только для разработчиков.

description <text>

description <text>

Описание — это необязательная строка описания кольца. Оно будет отображаться на CLI. По умолчанию, <name> используется для заполнения этого поля.

format <format>

format <format>

Формат хранения событий в кольцевом буфере.

Аргументы:

<format> — формат журнала при формировании сообщений syslog.
         Допустимы следующие значения:

  iso     Сообщение содержит только дату ISO и следующий за ней текст.
          PID, имя процесса и имя системы опускаются. Предназначено
          для локального сервера журналов.

  local   Аналог формата syslog rfc3164 без поля hostname.
          Это значение по умолчанию.
          Примечание: параметр "log-send-hostname" меняет значение
          по умолчанию на rfc3164.

  raw     Сообщение содержит только текст. Уровень, PID, дата, время,
          имя процесса и имя системы опускаются. Предназначено для
          контейнеров или разработки, где важность сообщения зависит
          только от файлового дескриптора (stdout/stderr).
          Это значение по умолчанию.

  rfc3164 Формат сообщений syslog RFC3164.
          (https://tools.ietf.org/html/rfc3164)

  rfc5424 Формат сообщений syslog RFC5424.
          (https://tools.ietf.org/html/rfc5424)

  short   Сообщение содержит только уровень в угловых скобках,
          например '<3>', и следующий за ним текст. PID, дата, время,
          имя процесса и имя системы опускаются. Предназначено для
          локального сервера журналов. Формат совместим со средством
          приёма журналов systemd.

 priority Сообщение содержит только уровень вместе с категорией syslog
          в угловых скобках, например '<63>', и следующий за ним текст.
          PID, дата, время, имя процесса и имя системы опускаются.
          Предназначено для локального сервера журналов.

  timed   Сообщение содержит только уровень в угловых скобках,
          например '<3>', затем дату ISO и текст. PID, имя процесса
          и имя системы опускаются. Предназначено для локального
          сервера журналов.

maxlen <length>

maxlen <length>

Максимальная длина сообщения о событии, хранящегося в кольце, включая сформированный заголовок. Если длина сообщения о событии превышает <length>, оно будет обрезано до этой длины.

server <name> <address> [param*]

server <name> <address> [param*]

Настраивает сервер syslog по tcp для пересылки сообщений из кольцевого буфера. Поддерживаются все параметры “server” из пункта 5.2. Некоторые из них не имеют смысла для секций “ring”. Важный момент: добавлять в кольцевой буфер несколько серверов почти бессмысленно, поскольку каждый из них получает одну и ту же копию его содержимого, и буфер продвигается со скоростью самого медленного сервера. Если один сервер не отвечает, старые сообщения нельзя будет удалять, что может заблокировать добавление новых. Для отправки сообщений нескольким серверам следует использовать отдельный кольцевой буфер для каждого сервера журналирования, а не привязывать несколько серверов к одному буферу. Специальная директива сервера “log-proto” задаёт протокол отправки сообщений.

size <size>

size <size>

Необязательный размер кольцевого буфера в байтах. По умолчанию равен BUFSIZE.

timeout connect <timeout>

timeout connect <timeout>

Задаёт максимальное время ожидания успешного установления соединения с сервером.

Аргументы:

<timeout> — тайм-аут, по умолчанию в миллисекундах. Можно использовать
          и другие единицы, добавляя их обозначение после числа,
          как объяснено в начале документа.

timeout server <timeout>

timeout server <timeout>

Задаёт максимальное время нахождения ожидающих отправки данных в выходном буфере.

Аргументы:

<timeout> — тайм-аут, по умолчанию в миллисекундах. Можно использовать
          и другие единицы, добавляя их обозначение после числа,
          как объяснено в начале документа.

Пример:

global
    log ring@myring local7

ring myring
    description "My local buffer"
    format rfc5424
    maxlen 1200
    size 32764
    timeout connect 5s
    timeout server 10s
    server mysyslogsrv 127.0.0.1:6514 log-proto octet-count

12.6. Пересылка журналов

Можно объявить одну или несколько секций пересылки журналов. HAProxy будет пересылать все полученные сообщения журналов серверам из заданного списка.

log-forward <name>

log-forward <name>

Создаёт прокси для пересылки журналов с именем <name>.

backlog <conns>

backlog <conns>

Сообщает системе желаемый приблизительный размер очереди ожидающих принятия соединений.

bind <addr> [param*]

bind <addr> [param*]

Настраивает потоковый слушатель журналов, принимающий сообщения для пересылки. Поддерживаются параметры “bind” из раздела 5.1, включая ssl, хотя некоторые директивы, например “alpn”, могут быть неуместны для syslog поверх TCP. Слушатели поддерживают оба режима из rfc-6587: подсчёт октетов (“Octet Counting”) и непрозрачное разделение сообщений (“Non-Transparent-Framing”).

dgram-bind <addr> [param*]

dgram-bind <addr> [param*]

Настраивает датаграммный слушатель журналов, принимающий сообщения для пересылки. Адрес должен иметь формат IPv4 или IPv6 с последующим портом. Поддерживаются некоторые параметры “bind” из раздела 5.1, в том числе “interface”, “namespace” и “transparent”. Остальные игнорируются без сообщений, поскольку неприменимы к UDP/syslog.

log global

log global
log <target> [len <length>] [format <format>] [sample <ranges>:<sample_size>]
    <facility> [<level> [<minlevel>]]

Настраивает целевые серверы журналов; подробнее см. документацию по прокси. Если формат не указан, HAProxy пытается сохранить формат входящего сообщения. Настроенная категория facility игнорируется, кроме случая, когда во входящем сообщении её нет, а выходной формат требует её наличия. Если во входном формате нет временной метки, но соответствующее поле есть в выходном, HAProxy использует локальную дату.

Пример:

global
   log stderr format iso local7

ring myring
    description "My local buffer"
    format rfc5424
    maxlen 1200
    size 32764
    timeout connect 5s
    timeout server 10s
    # syslog tcp server
    server mysyslogsrv 127.0.0.1:514 log-proto octet-count

log-forward sylog-loadb
    dgram-bind 127.0.0.1:1514
    bind 127.0.0.1:1514
    # all messages on stderr
    log global
    # all messages on local tcp syslog server
    log ring@myring local0
    # load balance messages on 4 udp syslog servers
    log 127.0.0.1:10001 sample 1:4 local0
    log 127.0.0.1:10002 sample 2:4 local0
    log 127.0.0.1:10003 sample 3:4 local0
    log 127.0.0.1:10004 sample 4:4 local0

maxconn <conns>

maxconn <conns>

Задаёт максимальное число одновременных соединений для пересылки журналов. По умолчанию — 10.

timeout client <timeout>

timeout client <timeout>

Задаёт максимальное время бездействия на стороне клиента.

option assume-rfc6587-ntf

option assume-rfc6587-ntf

Предписывает HAProxy всегда считать, что входящие потоки журналов по TCP используют непрозрачное разделение сообщений. Это упрощает логику разделения и обеспечивает единообразную обработку, особенно при некорректных начальных символах.

option dont-parse-log

option dont-parse-log

Позволяет HAProxy пересылать сообщения syslog без разбора и изменения структуры. Это удобно для сообщений, которые могут не соответствовать обычным форматам. Параметр следует сочетать с настройкой format raw у целевых получателей журналов, чтобы сохранить исходное содержимое сообщения.

option host { replace | fill | keep | append }

option host { replace | fill | keep | append }

Задаёт стратегию обработки поля hostname в секции log-forward для исходящих сообщений syslog в форматах rfc3164 или rfc5424.

  replace Если во входящем сообщении уже есть поле hostname, его значение
          заменяется исходным IP-адресом отправителя.
          Если значения поля hostname нет (например, во входящем сообщении
          rfc5424 стоит '-' либо сообщение не соответствует rfc3164 или
          rfc5424), в поле hostname подставляется исходный IP-адрес
          отправителя.

  fill    Если во входящем сообщении уже есть значение поля hostname,
          оно сохраняется.
          Если значения поля hostname нет (например, во входящем сообщении
          rfc5424 стоит '-' либо сообщение не соответствует rfc3164 или
          rfc5424), в поле hostname подставляется исходный IP-адрес
          отправителя.
          (Это значение по умолчанию.)

  keep    Если во входящем сообщении уже есть значение поля hostname,
          оно сохраняется.
          Если значения поля hostname нет, задаётся 'localhost' (rfc3164)
          или '-' (rfc5424).

  append  Если во входящем сообщении уже есть значение поля hostname,
          к нему добавляются запятая и IP-адрес отправителя.
          Если значения поля hostname нет, используется исходный IP-адрес
          отправителя.

Для всех перечисленных вариантов, если исходный IP-адрес отправителя недоступен, например при сокете UNIX/ABNS, применяется стратегия “keep”.

Этот параметр имеет смысл только для целевого формата журнала rfc3164 или rfc5424. В остальных случаях он не даёт видимого эффекта.

12.7. Хранилище сертификатов

HAProxy использует внутренний механизм хранения для загрузки и хранения сертификатов, используемых в конфигурации. Этот механизм хранения может быть настроен с помощью секции “crt-store”. Она позволяет настроить определения сертификатов и указать, какие файлы должны быть загружены в неё. Определение сертификата должно быть записано до его использования в других частях конфигурации.

crt-store [<name>]

Секция “crt-store” принимает необязательное имя. Если оно задано, на каждый сертификат этого хранилища необходимо ссылаться как “@<name>/<crt>” или “@<name>/<alias>”.

Файлы в хранилище сертификатов также можно обновлять динамически через CLI. См. “set ssl cert” в разделе 9.3 руководства по управлению.

В секции “crt-store” поддерживаются следующие ключевые слова:

  • crt-base
  • key-base
  • load

crt-base <dir>

crt-base <dir>

Задаёт каталог по умолчанию для загрузки сертификатов SSL, если в директивах “crt” указан относительный путь. Абсолютный путь имеет приоритет: “crt-base” для него игнорируется. При использовании в crt-store значение crt-base из секции global игнорируется.

key-base <dir>

key-base <dir>

Задаёт каталог по умолчанию для загрузки закрытых ключей SSL, если в директивах “key” указан относительный путь. Абсолютный путь имеет приоритет: “key-base” для него игнорируется. При использовании в crt-store значение key-base из секции global игнорируется.

load [crt <filename>] [param*]

load [crt <filename>] [param*]

Загружает файлы SSL в хранилище сертификатов. Список параметров приведён в разделе «12.7.1. Параметры загрузки».

Пример:

crt-store
    load crt "site1.crt" key "site1.key" ocsp "site1.ocsp" alias "site1"
    load crt "site2.crt" key "site2.key"

frontend in2
    bind *:443 ssl crt "@/site1" crt "site2.crt"

crt-store web
    crt-base /etc/ssl/certs/
    key-base /etc/ssl/private/
    load crt "site3.crt" alias "site3"
    load crt "site4.crt" key "site4.key"

frontend in2
    bind *:443 ssl crt "@/site1" crt "site2.crt"  crt "@web/site3" crt "@web/site4.crt"

12.7.1. Параметры загрузки

Загружает файлы SSL в хранилище сертификатов. Ключевое слово load принимает несколько параметров, перечисленных ниже. Они также допустимы в crt-list.

crt <filename>

crt <filename>

Обязательный аргумент. Загружает файл PEM, который должен содержать публичный сертификат, а также может содержать промежуточные сертификаты и закрытый ключ. Если закрытого ключа в файле нет, его можно задать ключевым словом “key”.

acme <string>

acme <string>

Этот параметр позволяет настроить протокол ACME для заданного сертификата. Это экспериментальная функция, требующая ключевого слова “expose-experimental-directives” в секции global.

Ключевое слово “acme” в crt-store позволяет запуститься без готового сертификата на диске. До получения сертификата ACME используется временная пара ключей. Это поведение доступно только в crt-store: ни строка crt-list, ни строка ssl-f-use не дают такого результата без предварительного объявления crt-store.

См. также раздел 12.8 (“ACME”) и “domains” в этом разделе.

alias <string>

alias <string>

Необязательный аргумент. Задаёт псевдоним сертификата для ссылок на него в конфигурации. При обращении из других частей конфигурации перед псевдонимом должен стоять префикс ‘@/’.

domains <string>

domains <string>

Задаёт список доменов для сертификатов ACME. Первый домен используется как CN. Домены в списке разделяются запятыми.

См. также раздел 12.8 (“ACME”) и “acme” в этом разделе.

Пример:

load crt "example.com.pem" acme LE domains "bar.example.com,foo.example.com"

ips <string>

ips <string>

Задаёт список IP-адресов, включаемых в сертификат ACME как IP SAN. Адреса в списке разделяются запятыми.

Создание сертификата с IP-адресами может потребовать использования профиля “shortlived”.

См. также раздел 12.8 (“ACME”), “acme” и “domains” в этом разделе.

Пример:

load crt "server.pem" acme LE ips "192.0.2.1,2001:db8::1"

key <filename>

key <filename>

Необязательный аргумент. Загружает закрытый ключ в формате PEM. Если ключ уже задан в “crt”, он будет заменён.

ocsp <filename>

ocsp <filename>

Необязательный аргумент. Загружает ответ OCSP в формате DER. Ответ можно обновлять через CLI.

issuer <filename>

issuer <filename>

Необязательный аргумент. Загружает сертификат издателя OCSP в формате PEM. Сертификат издателя необходим, чтобы определить, к какому сертификату относится ответ OCSP. Если его нет в файле “crt”, этот аргумент позволяет загрузить его из отдельного файла.

sctl <filename>

sctl <filename>

Необязательный аргумент. Включает поддержку расширения TLS Certificate Transparency (RFC6962). Файл должен содержать корректный список подписанных временных меток сертификатов (Signed Certificate Timestamp List), описанный в RFC. При разборе проверяется базовый синтаксис, но подписи не проверяются.

ocsp-update [ off | on ]

ocsp-update [ off | on ]

При значении ‘on’ включает автоматическое обновление ответов OCSP, иначе отключает его. По умолчанию — ‘off’. Для автоматического обновления OCSP в строке bind можно задать этот параметр в crt-store либо глобальный параметр “tune.ocsp-update.mode”. Если один сертификат используется в нескольких crt-lists с разными значениями ‘ocsp-update’, возникает ошибка. Такая же ошибка возникает, если сертификат в строке bind наследует глобальный параметр, а в crt-list для него явно задано несовместимое значение ‘ocsp-update’.

Примеры:

Вот пример конфигурации, включающей его с помощью crt-list:

haproxy.cfg:

frontend fe
    bind :443 ssl crt-list haproxy.list

haproxy.list:

server_cert.pem [ocsp-update on] foo.bar

Вот пример конфигурации, включающей его с использованием crt-store:

haproxy.cfg:

crt-store
  load crt foobar.pem ocsp-update on

frontend fe
    bind :443 ssl crt foobar.pem

При значении ‘on’ HAProxy пытается получить ответ ocsp, если в сертификате фронтенда найден uri ocsp. Единственное ограничение режима — издатель сертификата должен быть известен, чтобы можно было сформировать OCSP certid. Каждый ответ OCSP обновляется не реже раза в час, а если его срок действия истекает раньше — чаще. Минимальный интервал остаётся равным 5 минутам, чтобы не обновлять слишком часто ответы с очень коротким сроком действия или вообще без ‘Next Update’. Из-за этого ограничения при автоматическом обновлении ‘on’ любой ответ OCSP, загруженный при инициализации, обновится не раньше чем через 5 минут, даже если истекает до now+5m. Обычно это не должно создавать серьёзных затруднений: при загрузке во время инициализации ответ OCSP обязан быть действительным, с будущим сроком истечения, поэтому столь быстрое истечение маловероятно. Если же в сертификате указан OCSP uri, а ответа OCSP ещё нет, значение ‘on’ обеспечивает его автоматическое получение сразу после инициализации. Минимальную и максимальную задержки по умолчанию, соответственно 5 минут и 1 час, можно настроить глобальными параметрами “ocsp-update.maxdelay” и “ocsp-update.mindelay”.

При каждом обновлении ответа OCSP автоматической задачей или командой CLI “update ssl ocsp-response” формируется отдельная строка журнала. Её специальный формат содержит заголовок “<OCSP-UPDATE>”, затем сведения об OCSP: путь к соответствующему сертификату фронтенда, числовой и текстовый статусы обновления, число неудачных и успешных обновлений этого ответа. Полный список кодов и сообщений об ошибках приведён в описании команды CLI “show ssl ocsp-updates”. Строка выводится независимо от успеха обновления. Запрос и ответ OCSP передаются через экземпляр http_client с параметром dontlog-normal; при ошибке, например недоступности сервера OCSP, он использует обычный формат журнала HTTP. В таком случае рядом с обычной строкой OCSP, скорее всего со статусом “HTTP error”, появляется ещё одна строка со сведениями об HTTP. При ошибке именно уровня HTTP, например недоступности сервера OCSP, дополнительная строка соответствует обычному HTTP log-format. Ниже приведены примеры: сначала успешное обновление OCSP, затем ошибка HTTP с двумя разными строками. Для удобства чтения строки разбиты, а URL сокращён:

<133>Mar  6 11:16:53 haproxy[14872]: <OCSP-UPDATE> /path_to_cert/foo.pem 1 \
        "Update successful" 0 1

<133>Mar  6 11:18:55 haproxy[14872]: <OCSP-UPDATE> /path_to_cert/bar.pem 2 \
        "HTTP error" 1 0
<133>Mar  6 11:18:55 haproxy[14872]: -:- [06/Mar/2023:11:18:52.200] \
        <OCSP-UPDATE> -/- 2/0/-1/-1/3009 503 217 - - SC-- 0/0/0/0/3 0/0 {} \
        "GET http://127.0.0.1:12345/MEMwQT HTTP/1.1"

Устранение неполадок: при использовании сертификатов Let’s Encrypt часто возникает ошибка, если DNS возвращает адрес IPv6, а в системе нет подходящего исходящего маршрута IPv6. В этом случае можно создать маршрут или задать “httpclient.resolvers.prefer ipv4” в секции global. При ошибке “OCSP response check failure” следует проверить корректность предоставленного сертификата издателя. После общего сообщения в скобках может появиться более точное описание. Это возможно для ошибок “OCSP response check failure” и “Error during insertion”.

jwt [ off | on ]

jwt [ off | on ]

При значении ‘on’ разрешает использовать этот сертификат для проверки или расшифровки JWT преобразователями “jwt_verify_cert”, “jwt_decrypt_cert” и “jwt_decrypt”. По умолчанию — ‘off’.

При значении ‘on’ для сертификата команда CLI “del ssl cert” не работает. Для удаления сертификат не должен использоваться ни в рукопожатиях SSL, ни для проверки JWT.

Эту опцию можно изменить в режиме работы с помощью команд “add ssl jwt” и “del ssl jwt” CLI. См. также команду “show ssl jwt” CLI.

generate-dummy [ off | on ]

generate-dummy [ off | on ]

При значении ‘on’ разрешает генерацию закрытого ключа и его самоподписанного сертификата во время разбора конфигурации. Это может пригодиться, например, при тестировании без готового сертификата. Параметры “keytype”, “bits” и “curves” позволяют настроить закрытый ключ. По умолчанию, если параметр не задан, используется ‘off’. См. также “keytype”, “bits” и “curves”.

keytype [ RSA | ECDSA ]

keytype [ RSA | ECDSA ]

Позволяет выбрать тип закрытого ключа для генерации самоподписанного сертификата при разборе конфигурации, если для сертификата задано “generate-dummy” со значением ‘on’. По умолчанию — ‘RSA’. См. также “generate-dummy”.

bits <number>

bits <number>

Задаёт число бит для генерации самоподписанного сертификата RSA, если для него “generate-dummy” установлен в ‘on’, а “keytype” — в ‘RSA’. По умолчанию — 2048. См. также “generate-dummy”.

curves <string>

curves <string>

Задаёт кривые для самоподписанного сертификата, если “generate-dummy” установлен в ‘on’, а “keytype” — в ‘ECDSA’. По умолчанию — ‘P-384’.

12.8. ACME

acme <name>

Протокол ACME может быть настроен с помощью секции “acme”. Секция принимает аргумент “<name>”, который используется для привязки сертификата к секции.

Секция ACME позволяет настроить HAProxy как клиента ACMEv2. Эта функция является экспериментальной, что означает, что “expose-experimental-directives” должен быть указан в глобальной секции, чтобы можно было использовать эту функцию.

Руководство доступно на HAProxy wiki https://github.com/haproxy/wiki/wiki/ACME:--native-haproxy

Текущие ограничения:

- Возможность ограничена проверками http-01, dns-01 и dns-persist-01

- Возможность ограничена проверками http-01, dns-01 и dns-persist-01

на данный момент. Проверка http-01 полностью выполняется HAProxy, но dns-01 и dns-persist-01 требуют dataplaneAPI либо другого инструмента третьей стороны для обращения к API провайдера DNS. Для dns-persist-01 запись TXT достаточно задать один раз, поэтому её можно установить вручную, без дополнительного инструмента.

- Можно запуститься без готового сертификата на диске. Для этого

- Можно запуститься без готового сертификата на диске. Для этого

сертификат должен быть настроен в crt-store. При использовании ключевого слова “acme” в crt-store до получения сертификата ACME применяется временная пара ключей.

- Текущая архитектура HAProxy неблокирующая; обращение к диску

- Текущая архитектура HAProxy неблокирующая; обращение к диску

после загрузки конфигурации не предполагается, поскольку может заблокировать цикл событий и обработку трафика в том же потоке. Поэтому созданные HAProxy сертификаты и ключи необходимо выгружать извне, вызывая “dump ssl cert” через сокет статистики. Выгрузку можно автоматизировать с помощью dataplaneAPI или скрипта haproxy-dump-certs из каталога admin/cli/.

Планировщик ACME запускается вместе с HAProxy. Он перебирает сертификаты и запускает задачу продления ACME, когда notAfter проходит порог curtime + (notAfter - notBefore) / 12; если notBefore не задан, используется 7 дней. Затем планировщик засыпает и просыпается через 12 часов. Задачу продления можно запустить вручную командой “acme renew”. См. также “acme status” в руководстве по управлению.

Следующие ключевые слова доступны в секции ACME:

account-key <filename>

account-key <filename>

Задаёт путь к ключу учётной записи. Ключ необходимо создать до запуска HAProxy. Если ключевое слово account не используется, секция acme пытается загрузить файл “<name>.account.key”, названный по имени секции. Если файла нет, HAProxy создаёт его с параметрами из секции acme.

Закрытый ключ RSA также можно создать вручную с помощью openssl:

openssl genrsa -out account.key 2048

Или ключ ecdsa:

openssl ecparam -name secp384r1 -genkey -noout -out account.key

acme-vars <string>

acme-vars <string>

Передаёт произвольные переменные внешнему инструменту настройки DNS, например dataplaneAPI, через получатель “dpapi”. Смысл переменных зависит от инструмента; см. его документацию.

Ключевое слово имеет смысл только для проверок типа “dns-01” или “dns-persist-01”.

См. также: “challenge”, “provider-name”

bits <number>

bits <number>

Задаёт число бит для генерации сертификата RSA. По умолчанию — 2048. Слишком большое значение может вызвать предупреждение, если машина недостаточно производительна. Порог предупреждения настраивается через “warn-blocked-traffic-after”, но длительная блокировка трафика может привести к срабатыванию сторожевого таймера.

challenge <string>

challenge <string>

Принимает тип проверки: он должен быть http-01, dns-01 или dns-persist-01. По умолчанию, если параметр не задан, используется http-01.

dns-persist-01 реализует draft-ietf-acme-dns-persist. В отличие от dns-01, он использует статическую запись TXT по имени “_validation-persist.<domain>”, которая задаётся один раз и не меняется между продлениями сертификата. Запись должна содержать URI учётной записи и может содержать политику. Этот тип проверки не требует доступа на запись к API провайдера DNS при каждом продлении.

challenge-ready <value>[,<value>]*

challenge-ready <value>[,<value>]*

Задаёт условия, которые необходимо выполнить, прежде чем уведомлять сервер ACME о готовности проверки dns-01. Допустимы следующие значения:

cli  — ждёт, пока оператор подтвердит готовность командой CLI
       "acme challenge_ready <crt> domain <domain>" через CLI главного
       процесса или сокет статистики. Внешний инструмент настройки DNS
       может так подтвердить установку записи TXT перед продолжением
       работы HAProxy.

dns  — выполняет предварительную проверку DNS: разрешает запись TXT
       "_acme-challenge.<domain>" через настроенную секцию resolvers
       "default", а не через авторитетные серверы имён. Проверка ACME
       не запрашивается, пока запись TXT не совпадёт с ожидаемым токеном.
       Поэтому на результат может влиять кеш DNS на резолвере. Интервал
       между попытками разрешения задаётся "dns-delay". Этот параметр
       не зависит от команды CLI и не требует вмешательства человека.

       Для dns-01 разрешается запись TXT "_acme-challenge.<domain>",
       которая должна совпадать с ожидаемым токеном. Для dns-persist-01
       разрешается запись TXT "_validation-persist.<domain>", причём
       проверяется только её наличие.

delay — начальное ожидание "dns-delay" перед продолжением. Без "dns"
        проверка запрашивается по истечении задержки. В сочетании с "dns"
        начальная задержка применяется до предварительных проверок DNS.

none — нет условий готовности: запрос проверки сразу отправляется
       серверу ACME без ожидания внешнего подтверждения.
       Это значение нельзя сочетать с другими.

Несколько значений можно объединить через запятую. Если задано несколько условий, HAProxy сначала ждёт подтверждения через CLI (“cli”), затем выдерживает начальную задержку (“delay”), а после выполняет предварительные проверки DNS (“dns”).

Параметр совместим только с проверками типа dns-01 и dns-persist-01.

Когда “challenge” установлен в “dns-01” и этот параметр не настроен, значение по умолчанию — “cli”.

Когда “challenge” установлен в “dns-persist-01” и этот параметр не настроен, значение по умолчанию равно “dns,delay”.

Если “challenge” установлен в “dns-persist-01”, перед оценкой условий challenge-ready всегда выполняется пробная проверка DNS. Запись TXT “_validation-persist.<domain>” задаётся один раз и не меняется между продлениями, поэтому при продлении HAProxy проверяет, существует ли она уже. Если проверка успешна для всех доменов, запрос проверки сразу отправляется серверу ACME без этапов challenge-ready (cli, delay, dns). При неудаче HAProxy переходит к обычной последовательности challenge-ready.

Пример:

# Wait for CLI confirmation, then verify DNS propagation
challenge-ready cli,dns

contact <string>

contact <string>

Электронная почта для связи, которая будет привязана к ключу учетной записи в CA.

curves <string>

curves <string>

При использовании типа ключа ECDSA настройте кривые. По умолчанию — P-384.

directory <string>

directory <string>

Задаёт URL каталога центра сертификации (CA), используемого этой секцией acme. Параметр обязателен: URL по умолчанию отсутствует.

Пример:

directory https://acme-staging-v02.api.letsencrypt.org/directory

dns-delay <time>

dns-delay <time>

Настройте задержку, используемую условиями “challenge-ready” «delay» и «dns». Значение — время, выраженное в формате времени HAProxy (например, «5m», «300s»). По умолчанию — 30 секунд.

Её роль зависит от используемых условий “challenge-ready”:

delay     — проверка запрашивается по истечении задержки,
            без предварительной проверки DNS.

dns       — интервал между последовательными попытками разрешения DNS.
            Первая попытка выполняется сразу, без начального ожидания.

dns+delay — начальное ожидание перед первой попыткой разрешения DNS
            и интервал между последующими попытками.

Разрешение имён выполняется через настроенную секцию resolvers с именем “default”, а не через авторитетные серверы имён. Поэтому на результат по-прежнему может влиять кеш DNS на резолвере.

dns-timeout <time>

dns-timeout <time>

Если “challenge-ready” включает “dns”, задаёт максимальное время на успешное разрешение записи TXT до прерывания проверки. Значение указывается в формате времени HAProxy, например “10m” или “600s”. По умолчанию — 600 секунд.

Отсчёт начинается с первой попытки разрешения DNS после начальной задержки “dns-delay”. Если следующая попытка должна начаться уже после истечения тайм-аута, проверка прерывается с ошибкой. Это предотвращает бесконечные повторные попытки при проблемах распространения записи DNS.

См. также: “dns-delay”

keytype <string>

keytype <string>

Настройте тип ключа, который будет сгенерирован. Значение может быть либо “RSA”, либо “ECDSA”. Вы также можете настроить “curves” для ECDSA и количество “bits” для RSA. По умолчанию генерируются ключи EC384.

map <map>

map <map>

Настройте карту, которая будет использоваться для хранения токена (ключ) и отпечатка (значение), что позволяет отвечать на вызов при использовании нескольких аккаунтов. Задача acme добавит записи до проверки вызова и удалит их в конце выполнения задачи.

profile <string>

profile <string>

Запрашивает у центра сертификации определённый профиль сертификата, добавляя поле “profile” в запрос newOrder. Реализует draft-ietf-acme-profiles.

Имена профилей — короткие идентификаторы, зависящие от CA, например “classic” и “shortlived”. Если профиль задан, его имя передаётся без изменений в JSON-теле запроса newOrder. CA может проигнорировать запрос или вернуть ошибку, если профиль не поддерживается. Если профиль не задан, поле profile не включается и CA применяет политику выдачи по умолчанию.

См. https://letsencrypt.org/docs/profiles/ для профилей Let’s Encrypt.

Пример:

# Request short-lived certificates
profile shortlived

provider-name <string>

provider-name <string>

Задаёт имя провайдера DNS, передаваемое внешнему инструменту настройки DNS, например dataplaneAPI, через получатель “dpapi”. Допустимые значения зависят от инструмента; см. его документацию.

Ключевое слово имеет смысл только для проверок типа “dns-01” или “dns-persist-01”.

См. также: “challenge”, “acme-vars”

reuse-key { on | off }

reuse-key { on | off }

Если установлено “on”, HAProxy не генерирует новый приватный ключ и сохраняет предыдущий. Ротация приватных ключей рекомендуется; при включении этой опции рекомендуется регулярно вручную пересоздавать ключи.

Параметр может пригодиться для ключей RSA больше 2048, генерация которых занимает время и может замедлить выполняющий её поток.

Использование одного и того же ключа может быть полезным при работе с кэшем вашего ACME сервера, так как это поможет получить соответствующий действительный сертификат для текущего ключа.

Значение по умолчанию — “off”.

Пример:

global
    expose-experimental-directives
    httpclient.resolvers.prefer ipv4

frontend in
    bind *:80
    bind *:443 ssl
    http-request return status 200 content-type text/plain lf-string "%[path,field(-1,/)].%[path,field(-1,/),map(virt@acme)]\n" if { path_beg '/.well-known/acme-challenge/' }
    ssl-f-use crt "foo.example.com.pem.rsa"   acme LE1 domains "foo.example.com.pem,bar.example.com"
    ssl-f-use crt "foo.example.com.pem.ecdsa" acme LE2 domains "foo.example.com.pem,bar.example.com"

acme LE1
    directory https://acme-staging-v02.api.letsencrypt.org/directory
    account-key /etc/haproxy/letsencrypt.account.key
    contact john.doe@example.com
    challenge http-01
    keytype RSA
    bits 2048
    map virt@acme

acme LE2
    directory https://acme-staging-v02.api.letsencrypt.org/directory
    account-key /etc/haproxy/letsencrypt.account.key
    contact john.doe@example.com
    challenge http-01
    keytype ECDSA
    curves P-384
    map virt@acme

eab-key-id <filename>

eab-key-id <filename>

Укажите путь к файлу идентификатора ключа EAB. Средство аутентификации предоставляется Центром сертификации и должно быть размещено на указанном пути до запуска HAProxy. Оно используется только при создании аккаунта.

Файл должен содержать простую строку ASCII.

Учётные данные EAB требуются только при первоначальном создании учётной записи ACME; впоследствии их можно удалить из конфигурации или очистить соответствующие файлы. Пустой файл игнорируется без сообщения. Пробельные символы не игнорируются, за исключением завершающего перевода строки.

См. также: “eab-mac-key”, “eab-mac-alg”

eab-mac-key <filename>

eab-mac-key <filename>

Настройте путь к файлу ключа EAB MAC. Ключ предоставляется CA и должен быть размещён по указанному пути до запуска HAProxy. Используется только при создании учётной записи.

Файл должен содержать закодированный в формате base64url ключ MAC.

Учётные данные EAB требуются только при первоначальном создании учётной записи ACME; впоследствии их можно удалить из конфигурации или очистить соответствующие файлы. Пустой файл игнорируется без сообщения. Пробельные символы не игнорируются, за исключением завершающего перевода строки.

См. также: “eab-key-id”, “eab-mac-alg”

eab-mac-alg { HS256 | HS384 | HS512 }

eab-mac-alg { HS256 | HS384 | HS512 }

Настройте алгоритм MAC, используемый для подписи EAB. По умолчанию — HS256. Ключ EAB MAC должен быть достаточно велик, чтобы поддерживать заданный алгоритм MAC. Не все Центры сертификации поддерживают алгоритмы, кроме HS256.

См. также: “eab-key-id”, “eab-mac-key”

12.9. Проверки работоспособности

Возможно, глобально объявить несколько проверок работоспособности, которые могут быть использованы серверами во всей конфигурации, заменяя локальную конфигурацию прокси.

healthcheck <name>

healthcheck <name>

Создаёт проверку работоспособности с именем <name>. Имя должно быть уникальным. Его следует использовать в строке server для ссылки на конкретную секцию проверки работоспособности.

type <type>

type <type>

Определяет тип проверки работоспособности. Этот параметр обязательный. Поддерживаются следующие типы проверки работоспособности:

* tcp-check
* httpchk
* ssl-hello-chk
* smtpchk
* pgsql-check
* redis-check
* mysql-check
* ldap-check
* spop-check

Каждый тип использует те же параметры, если они есть, что и соответствующий параметр прокси. Например, для “httpchk” можно задать метод, uri и другие значения:

Примеры:

   healthcheck my-http-check
type httpchk GET /health HTTP/1.1 %[srv_name]

См. также: “option tcp-check”, “option httpchk”, “option ssl-hello-chk”, “option smtpchk”, “option mysql-check”, “option pgsql-check”, “option redis-check”, “option ldap-check” и “option spop-check”

http-check comment <string>

http-check comment <string>
http-check connect [default] [port <expr>] [addr <ip>] [send-proxy]
                   [via-socks4] [ssl] [sni <sni>] [alpn <alpn>] [linger]
                   [proto <name>] [comment <msg>]
http-check disable-on-404
http-check expect [min-recv <int>] [comment <msg>]
                  [ok-status <st>] [error-status <st>] [tout-status <st>]
                  [on-success <fmt>] [on-error <fmt>] [status-code <expr>]
                  [!] <match> <pattern>
http-check send [meth <method>] [{ uri <uri> | uri-lf <fmt> }>] [ver <version>]
                [hdr <name> <fmt>]* [{ body <string> | body-lf <fmt> }]
                [comment <msg>]
http-check send-state
http-check set-var(<var-name>[,<cond>...]) <expr>
http-check set-var-fmt(<var-name>[,<cond>...]) <fmt>
http-check unset-var(<var-name>)

Добавляет правило http-check для проверки работоспособности “httpchk”. Синтаксис совпадает с соответствующими директивами прокси; подробности приведены в документации по ним.

tcp-check comment <string>

tcp-check comment <string>
tcp-check connect [default] [port <expr>] [addr <ip>] [send-proxy] [via-socks4]
                  [ssl] [sni <sni>] [alpn <alpn>] [linger]
                  [proto <name>] [comment <msg>]
tcp-check expect [min-recv <int>] [comment <msg>]
                 [ok-status <st>] [error-status <st>] [tout-status <st>]
                 [on-success <fmt>] [on-error <fmt>] [status-code <expr>]
                 [!] <match> <pattern>
tcp-check send <data> [comment <msg>]
tcp-check send-lf <fmt> [comment <msg>]
tcp-check send-binary <hexstring> [comment <msg>]
tcp-check send-binary-lf <hexfmt> [comment <msg>]
tcp-check set-var(<var-name>[,<cond>...]) <expr>
tcp-check set-var-fmt(<var-name>[,<cond>...]) <fmt>
tcp-check unset-var(<var-name>)

Добавляет правило tcp-check для проверки работоспособности “tcp-check”. Синтаксис совпадает с соответствующими директивами прокси; подробности приведены в документации по ним.