4. Прокси
Конфигурация прокси может размещаться в нескольких типах секций:
- defaults [
<name>] [ from<defaults_name>] - frontend
<name>[ from<defaults_name>] - backend
<name>[ from<defaults_name>] - listen
<name>[ from<defaults_name>]
Секция “frontend” описывает набор слушающих сокетов, принимающих клиентские соединения.
Секция “backend” описывает набор серверов, к которым прокси подключается для пересылки входящих соединений.
Секция “listen” определяет полноценный прокси, у которого фронтенд и бэкенд объединены в одной секции. Обычно она удобна для трафика, использующего только TCP.
Секция “defaults” сбрасывает все настройки до документированных значений и задаёт новые значения для последующих секций. Все секции “frontend”, “backend” и “listen” всегда получают начальные настройки из секции defaults; по умолчанию это последняя такая секция перед вновь создаваемой секцией. Можно явно указать конкретную секцию “defaults”, из которой нужно загрузить начальные настройки: для этого в строке секции после необязательного ключевого слова “from” указывают её имя. Хотя имя секции “defaults” не обязательно, рекомендуется задавать его для удобства чтения. Кроме того, это единственный способ выбрать конкретную секцию вместо предыдущей, используемой по умолчанию. Поскольку имена секций “defaults” необязательны, по умолчанию к ним применяются очень мягкие требования и даже допускаются совпадающие имена. Однако если на секцию “defaults” ссылается любая другая секция, её имя должно соответствовать синтаксису имён прокси и быть уникальным среди секций defaults. Независимо от того, что допускается сейчас, в целом рекомендуется избегать повторяющихся имён секций и соблюдать тот же синтаксис, что и для имён прокси. В будущей версии это правило может стать обязательным. Кроме того, выдаётся предупреждение, если один прокси явно использует секцию defaults, а другой одновременно использует её неявно, поскольку она определена последней. Настоятельно рекомендуется не смешивать эти способы: либо всегда использовать явные ссылки, либо добавить в конце общую секцию defaults, предназначенную для всех неявных обращений.
Секция defaults может даже получать начальные настройки из другой такой секции, наследуя настройки через несколько уровней секций defaults. Это удобно для создания профилей конфигурации с группами настроек по умолчанию (например, для TCP и HTTP либо с короткими и длинными тайм-аутами), однако в такой иерархии легко запутаться.
По умолчанию именованные секции defaults сохраняются после разбора конфигурации. Это позволяет повторно использовать их при динамическом создании бэкендов. Такое поведение можно изменить глобально с помощью ключевого слова “tune.defaults.purge”.
Все имена прокси должны состоять из прописных и строчных букв, цифр, символов ‘-’ (дефис), ‘_’ (подчёркивание), ‘.’ (точка) и ‘:’ (двоеточие). Имена ACL чувствительны к регистру, поэтому “www” и “WWW” — два разных прокси.
Раньше имена прокси могли совпадать при выполнении определённых условий (например, если наборы их возможностей фронтенда/бэкенда различались), однако это вызывало слишком много проблем в журналах, а также путаницу при операциях через CLI, именовании таблиц привязок и получении статистики. Теперь два прокси обязательно должны иметь разные имена независимо от их возможностей.
В настоящее время поддерживаются два основных режима прокси: “tcp”, также известный как режим уровня 4, и “http”, также известный как режим уровня 7. В режиме уровня 4 HAProxy просто пересылает двунаправленный трафик между двумя сторонами. В режиме уровня 7 HAProxy анализирует протокол и может взаимодействовать с ним: разрешать, блокировать, переключать, добавлять, изменять или удалять произвольное содержимое запросов и ответов на основе произвольных критериев.
В режиме HTTP обработка запросов и ответов, проходящих через соединение, зависит от сочетания параметров HTTP фронтенда и бэкенда. HAProxy поддерживает 3 режима соединений:
-
KAL: постоянное соединение (“option http-keep-alive”), режим по умолчанию: все запросы и ответы обрабатываются, а между ответами и новыми запросами соединения остаются открытыми, но неактивными.
-
SCL: закрытие соединения с сервером (“option http-server-close”): соединение со стороны сервера закрывается после получения конца ответа, а соединение со стороны клиента остаётся открытым.
-
CLO: закрытие (“option httpclose”): соединение закрывается после окончания ответа, а в обоих направлениях добавляется “Connection: close”.
Итоговый режим соединения, проходящего через фронтенд и бэкенд, определяется режимами обоих прокси по следующей матрице. Режимы симметричны: постоянное соединение имеет самый низкий приоритет, а закрытие — самый высокий.
Режим бэкенда
Можно последовательно соединить фронтенд TCP с бэкендом HTTP. Если обрабатывается только трафик HTTP, это не имеет смысла. Однако такой подход позволяет обрабатывать несколько протоколов в одном фронтенде. В этом случае клиентское соединение сначала обрабатывается как обычное соединение tcp, а затем переводится в режим HTTP. До этого перехода обработка содержимого выполняется над необработанными данными. После перехода данные разбираются и хранятся во внутреннем представлении HTX, поэтому использовать их исходное представление больше невозможно. Обратный переход не предусмотрен.
Существует два типа переходов к HTTP: с сохранением прикладного потока и с его уничтожением. Первый тип — переход от TCP к HTTP/1. В HTTP/1 запросы обрабатываются последовательно, поэтому прикладной поток можно сохранить. Второй тип — переход от TCP к HTTP/2. Поскольку этот протокол использует мультиплексирование, прикладной поток нельзя связать с каким-либо потоком HTTP/2, и он уничтожается. Затем, когда HAProxy получает новые потоки HTTP/2 на нижнем уровне, в мультиплексоре H2, создаются новые прикладные потоки. Это различие необходимо понимать, поскольку оно существенно меняет способ обработки данных. При переходе к HTTP/1 результаты обработки содержимого, уже выполненной над необработанными данными, не теряются, а сама обработка не выполняется повторно. При переходе к HTTP/2 прикладные потоки различаются, и все правила фронтенда последовательно проверяются для каждого из них. Как уже было сказано, первый поток, то есть поток TCP, уничтожается, но только после проверки правил фронтенда.
При обработке HTTP из прокси TCP необходимо учитывать ещё один важный момент. HAProxy может разбирать HTTP/1 на лету в правилах tcp-request content, однако для HTTP/2 это невозможно: разобрать можно только преамбулу HTTP/2. Это серьёзно ограничивает анализ содержимого HTTP в TCP. По сути, можно лишь определить, являются ли полученные данные HTTP. Например, выбрать бэкенд по значению заголовка Host нельзя, хотя в HTTP/1 это делается легко. Однако существует способ смягчить это ограничение.
Перейти к HTTP можно двумя способами. Первый, используемый исторически, — выбрать бэкенд HTTP. Переход происходит при назначении бэкенда. Поэтому при переходе с сохранением потока для обработки данных HTTP учитывается только конфигурация бэкенда. При переходе с уничтожением потока прикладной поток уничтожается и его обработка прекращается. Как отмечено выше, при этом способе возможности выбора бэкенда для соединения HTTP/2 весьма ограничены и почти бесполезны, поскольку поток уничтожается. Второй способ — выполнить переход во время проверки правил tcp-request content с помощью действия “switch-mode http”. В этом случае переход выполняется в контексте фронтенда, в котором можно определить директивы HTTP. При переходе с сохранением потока это позволяет как можно раньше использовать все возможности анализа HTTP. Такой вариант мало отличается от фронтенда HTTP. При переходе с уничтожением потока это ничего не меняет, за исключением того, что выбирать бэкенд по ограниченным данным бессмысленно. Рекомендуется именно этот способ. Таким образом, для перехода к HTTP достаточно проверить протокол запроса в правилах tcp-request content. Остальную обработку HTTP можно перенести в набор правил http-request фронтенда. Однако правила tcp-request content по-прежнему проверяются для каждого потока; изменить это нельзя.
4.1. Матрица ключевых слов прокси
Поддерживается приведённый ниже список ключевых слов. Большинство из них можно использовать только в ограниченном наборе типов секций. Некоторые помечены как «устаревшие», поскольку они унаследованы от старого синтаксиса, который может быть неоднозначным или иметь функциональные ограничения, и для их замены рекомендуются новые ключевые слова. Действие ключевых слов с пометкой “(*)” при необходимости можно инвертировать с помощью префикса “no”, например “no option contstats”. Это имеет смысл, когда параметр включён по умолчанию, но его необходимо отключить для конкретного экземпляра. Перед такими параметрами также можно поставить “default”, чтобы восстановить настройки по умолчанию независимо от того, что было задано в предыдущей секции “defaults”. Ключевые слова, разрешённые в секциях defaults и отмеченные “(!)”, поддерживаются только в именованных секциях defaults, но не в анонимных.
Примечание: некоторые опасные и не рекомендуемые директивы намеренно не включены в следующую матрицу. Это сделано специально. Эти директивы описаны в документации, однако отсутствие их в таблице — ещё один способ предостеречь от их использования.
4.2. Алфавитный справочник ключевых слов
В этом разделе описаны все ключевые слова и их использование.
acl <aclname> <criterion> [flags] [operator] <value> ...
Объявить или дополнить список контроля доступа.
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да(!) | да | да | да
Эта директива доступна только в именованных секциях defaults, а не в анонимных. Списки контроля доступа, определённые в секции defaults, недоступны из других секций, использующих её.
Пример:
Об использовании ACL см. раздел 7 .
backlog <conns>
Сообщить системе ориентировочный желаемый размер очереди входящих соединений
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | нет
Аргументы:
Этот параметр имеет смысл только для потоковых слушателей, включая QUIC. Однако для экземпляров QUIC его поведение отличается.
Для всех слушателей, кроме QUIC, один из способов защиты от атак SYN flood — увеличить размер системной очереди SYN. В одних системах её размер настраивается системным параметром, в других вообще не поддаётся настройке, а в третьих система учитывает подсказки приложения, передаваемые при системном вызове listen(). По умолчанию HAProxy передаёт в listen() значение maxconn фронтенда. На системах, способных использовать это значение, иногда полезно задавать другое значение; для этого и предназначен параметр backlog.
В Linux 2.4 система игнорирует этот параметр. В Linux 2.6 он используется как подсказка: система принимает количество соединений не больше ближайшей большей степени двойки и в любом случае не превышает определённые ограничения (обычно 32768).
Для слушателей QUIC backlog задаёт общий предел как для максимального числа активных согласований соединений, так и для числа соединений, ожидающих принятия. Длительность согласования в основном зависит от сетевой задержки до удалённого узла, а второй этап зависит только от нагрузки на haproxy. Когда достигается любой из этих пределов, haproxy начинает отбрасывать входящие пакеты INITIAL, предотвращая выделение ресурсов под новые соединения до тех пор, пока избыток соединений не начнёт уменьшаться. Это может привести к незаметному для пользователя переходу браузеров на более раннюю версию HTTP и к использованию TCP.
См. также: “maxconn” и руководство по настройке целевой операционной системы.
balance <algorithm> [ <arguments> ]
Определить алгоритм балансировки нагрузки для бэкенда.
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
Алгоритм балансировки нагрузки бэкенда устанавливается в “random”, если не заданы ни другой алгоритм, ни режим, ни параметр. Для каждого бэкенда алгоритм можно задать только один раз.
При использовании схем аутентификации, требующих одного и того же соединения, например NTLM, нельзя использовать алгоритмы на основе URI: последующие запросы будут направляться на разные серверы бэкенда, что нарушит некорректные допущения, на которых основан NTLM.
Примеры TCP/HTTP:
Примеры бэкендов LOG:
Примечание: при использовании расширения “check_post” с “url_param” необходимо учитывать следующие ограничения и особенности:
- Рассматриваются все запросы POST, поскольку невозможно определить,
окажутся ли параметры в теле или сущности, которая может содержать
двоичные данные. Поэтому может потребоваться другой способ, чтобы
исключить из рассмотрения запросы POST, в теле которых нет параметров
URL. (см. acl http_end)
- Значение `<max_wait>`, превышающее размер буфера запроса, не имеет
смысла и бесполезно. Размер буфера задаётся при сборке и по умолчанию
составляет 16 kB.
- Content-Encoding не поддерживается; поиск параметра, вероятно,
завершится неудачей, и балансировка нагрузки вернётся к алгоритму
циклического распределения (Round Robin).
- Expect: 100-continue не поддерживается; балансировка нагрузки
вернётся к алгоритму циклического распределения (Round Robin).
- Transfer-Encoding (RFC7230 3.3.1) поддерживается только в первом
фрагменте. Если полное значение параметра отсутствует в первом
фрагменте, выбор сервера не определён (фактически он определяется
тем, какая малая часть значения оказалась в первом фрагменте).
- Эта возможность не поддерживает формирование ответов 100, 411 или 501.
- В некоторых случаях указание "check_post" МОЖЕТ привести к попытке
просканировать всё содержимое тела сообщения. Обычно сканирование
прекращается при обнаружении линейных пробельных или управляющих
символов, указывающих на конец возможного списка параметров URL.
Вероятно, для тел сообщений типа SGML это не представляет проблемы.
См. также: “dispatch”, “cookie”, “transparent”, “hash-type”.
be-unpublished
Указывает бэкенду начинать работу в неопубликованном состоянии.
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend нет | нет | да | да
По сути, любые правила use_backend и default_backend из другого прокси, ссылающиеся на текущий прокси, игнорируются, и оцениваются следующие правила переключения содержимого. Это поведение можно обойти с помощью правила “force-be-switch”.
Это состояние похоже на отключённое, но имеет некоторые отличия. Во-первых, неопубликованный бэкенд по-прежнему полностью инициализируется, в том числе выполняются проверки работоспособности серверов, которые остаются активными. Наконец, бэкенд можно опубликовать командой “publish backend” через CLI. См. руководство по управлению.
См. также: “force-be-switch”
bind [<address>]:<port_range> [, ...] [param*]
Определяет во фронтенде один или несколько адресов и/или портов для прослушивания.
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend нет | да | да | нет
Аргументы:
Можно указать разделённый запятыми список пар address:port. Фронтенд будет прослушивать все указанные адреса. Фиксированного ограничения на число адресов и портов, которые может прослушивать фронтенд, нет; число директив “bind” во фронтенде также не ограничено.
Пример:
Примечание: для сокетов “abns” HAProxy в абстрактном пространстве имён Linux длина адреса равна полной длине sun_path. Некоторые другие программы, например socat, по умолчанию используют только длину строки. Чтобы определение абстрактного сокета в socat было совместимо с сокетами HAProxy, к нему нужно добавить параметр “,unix-tightsocklen=0”; другой вариант — использовать семейство сокетов “abnsz” HAProxy.
См. также: “source”, “option forwardfor”, “unix-bind” и документацию по протоколу PROXY, а также раздел 5 о параметрах bind.
capture cookie <name> len <length>
Захватывает и записывает в журнал cookie из запроса и ответа.
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend нет | да | да | нет
Аргументы:
Захватывается только первый cookie. Отслеживаются как заголовки запроса “cookie”, так и заголовки ответа “set-cookie”. Это особенно полезно для выявления ошибок приложений, приводящих к смешиванию или краже сеансов между пользователями, поскольку обычно cookie пользователя могут меняться только на странице входа.
Если клиент не передал cookie, в соответствующем столбце журнала указывается “-”. Если в результате запроса сервер не назначает cookie, в столбце ответа указывается “-”.
Захват выполняется только во фронтенде: формат журнала для одного фронтенда должен оставаться одинаковым независимо от бэкендов. В дальнейшем это может измениться. Во фронтенде допускается только одна директива “capture cookie”. Максимальная длина захвата задаётся глобальным параметром “tune.http.cookielen” и по умолчанию составляет 63 символа. В секции “defaults” задавать захват нельзя.
Пример:
См. также: “capture request header”, “capture response header”, а также раздел 8 о ведении журнала.
capture request header <name> len <length>
Захватывает и записывает в журнал последнее вхождение указанного заголовка запроса.
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend нет | да | да | нет
Аргументы:
Захватывается полное значение последнего вхождения заголовка. Оно добавляется в журнал в фигурных скобках (’{}’). При захвате нескольких заголовков их значения разделяются вертикальной чертой (’|’) и выводятся в порядке объявления в конфигурации. Отсутствующие заголовки записываются как пустые строки. Обычно захватывают поле “Host” при виртуальном хостинге, “Content-length” при поддержке загрузки данных, “User-agent” для быстрого различения настоящих пользователей и роботов и “X-Forwarded-For” при работе через прокси, чтобы определить источник запроса.
При захвате заголовков, например “User-agent”, в журнал могут попадать пробелы, что усложняет его анализ. Поэтому следует осторожно выбирать записываемые данные, если известно, что используемый разборщик журналов не умеет определять границы по фигурным скобкам.
Число захватываемых заголовков запроса и их длина не ограничены, однако целесообразно поддерживать небольшие значения обоих параметров, чтобы ограничить расход памяти на поток. Для единого формата журнала в пределах одного фронтенда захват заголовков можно объявлять только во фронтенде. В секции “defaults” задавать захват нельзя.
Пример:
См. также: “capture cookie”, “capture response header”, а также раздел 8 о ведении журнала.
capture response header <name> len <length>
Захватывает и записывает в журнал последнее вхождение указанного заголовка ответа.
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend нет | да | да | нет
Аргументы:
Захватывается полное значение последнего вхождения заголовка. Результат добавляется в журнал в фигурных скобках (’{}’) после захваченных заголовков запроса. При захвате нескольких заголовков их значения разделяются вертикальной чертой (’|’) и выводятся в порядке объявления в конфигурации. Отсутствующие заголовки записываются как пустые строки. Обычно захватывают заголовок “Content-length”, указывающий ожидаемое число байтов в ответе, и “Location” для отслеживания перенаправлений.
Число захватываемых заголовков ответа и их длина не ограничены, однако целесообразно поддерживать небольшие значения обоих параметров, чтобы ограничить расход памяти на поток. Для единого формата журнала в пределах одного фронтенда захват заголовков можно объявлять только во фронтенде. В секции “defaults” задавать захват нельзя.
Пример:
См. также: “capture cookie”, “capture request header”, а также раздел 8 о ведении журнала.
clitcpka-cnt <count>
Задаёт максимальное число проверочных пакетов для поддержания соединения, которые TCP должен отправить перед закрытием соединения на стороне клиента.
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | нет
Аргументы:
Это ключевое слово соответствует параметру сокета TCP_KEEPCNT. Если оно не указано, используется общесистемный параметр TCP (tcp_keepalive_probes). Доступность этой настройки зависит от операционной системы. Известно, что она работает в Linux.
См. также: “option clitcpka”, “clitcpka-idle”, “clitcpka-intvl”.
clitcpka-idle <timeout>
Задаёт время простоя соединения, после которого TCP начинает отправлять проверочные пакеты для поддержания соединения, если отправка пакетов TCP для поддержания соединения на стороне клиента включена.
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | нет
Аргументы:
Это ключевое слово соответствует параметру сокета TCP_KEEPIDLE. Если оно не указано, используется общесистемный параметр TCP (tcp_keepalive_time). Доступность этой настройки зависит от операционной системы. Известно, что она работает в Linux.
См. также: “option clitcpka”, “clitcpka-cnt”, “clitcpka-intvl”.
clitcpka-intvl <timeout>
Задаёт интервал между отдельными проверочными пакетами для поддержания соединения на стороне клиента.
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | нет
Аргументы:
Это ключевое слово соответствует параметру сокета TCP_KEEPINTVL. Если оно не указано, используется общесистемный параметр TCP (tcp_keepalive_intvl). Доступность этой настройки зависит от операционной системы. Известно, что она работает в Linux.
См. также: “option clitcpka”, “clitcpka-cnt”, “clitcpka-idle”.
compression algo <algorithm> ...
Включает сжатие HTTP.
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы:
В настоящее время поддерживаются следующие алгоритмы:
Сжатие включается в зависимости от заголовка запроса Accept-Encoding. При identity этот заголовок не учитывается. Если серверы бэкенда поддерживают сжатие HTTP, эти директивы не оказывают действия: HAProxy обнаруживает сжатый ответ и не сжимает его повторно. Если серверы бэкенда не поддерживают сжатие HTTP, а запрос содержит заголовок Accept-Encoding, HAProxy сжимает соответствующий ответ.
Сжатие отключается, когда: * запрос не объявляет поддерживаемый алгоритм сжатия в заголовке “Accept-Encoding” * ответ использует версию ниже HTTP/1.1 * код состояния HTTP не равен 200, 201, 202 или 203 * ответ не содержит ни заголовка “Content-Length”, ни заголовка “Transfer-Encoding” с последним значением “chunked” * ответ содержит заголовок “Content-Type”, первое значение которого начинается с “multipart” * ответ содержит значение “no-transform” в заголовке “Cache-control” * User-Agent соответствует “Mozilla/4”, кроме MSIE 6 с XP SP2 и MSIE 7 или более поздних версий * ответ содержит заголовок “Content-Encoding”, указывающий, что ответ уже сжат (см. compression offload) * ответ содержит некорректный заголовок “ETag” или несколько заголовков ETag * размер полезной нагрузки меньше минимального (см. compression minsize-res)
Примечание: механизм сжатия не добавляет заголовок Warning.
Примеры:
См. также: “compression offload”, “compression direction”, “compression minsize-req” и “compression minsize-res”
compression minsize-req <size>
Задает минимальный размер полезной нагрузки в байтах, при котором применяется сжатие.
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Полезная нагрузка меньше этого размера не сжимается, чтобы не тратить ресурсы CPU на данные, для которых сжатие не даёт существенного выигрыша. “minsize-req” применяется к запросам, а “minsize-res” — к ответам. Значение по умолчанию — 0.
compression offload
Задаёт для HAProxy роль узла, полностью принимающего на себя сжатие.
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend нет | да | да | да
Параметр “offload” заставляет HAProxy удалять заголовок Accept-Encoding, чтобы серверы бэкенда не сжимали ответы. Настоятельно рекомендуется этого не делать: вся работа по сжатию сосредоточится в одной точке, где находится HAProxy. Однако в некоторых схемах развёртывания HAProxy может находиться перед шлюзом с ошибочной реализацией сжатия HTTP, которую нельзя отключить. Тогда HAProxy может предотвратить отправку шлюзом некорректной полезной нагрузки. Простое удаление заголовка в конфигурации здесь не помогает: оно выполняется до разбора заголовка и лишает HAProxy возможности сжимать данные. В таких случаях следует использовать параметр “offload”.
Если этот параметр используется в секции defaults, будет выдано предупреждение и параметр будет проигнорирован.
См. также: “compression type”, “compression algo”, “compression direction”
compression direction <direction> (deprecated)
Позволяет haproxy сжимать запросы и ответы. Допустимые значения: “request” — сжимать только запросы, “response” — только ответы, “both” — и запросы, и ответы. Значение по умолчанию — “response”.
Эта директива имеет значение только при включённом прежнем “filter compression”: с явными фильтрами comp-req и comp-res указание compression direction избыточно.
Можно использовать в следующих контекстах: http
См. также: “compression type”, “compression algo”, “compression offload”
cookie <name> [ rewrite | insert | prefix ] [ indirect ] [ nocache ]
Включает в бэкенде привязку сеанса на основе cookie.
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
У каждого бэкенда HTTP может быть только один cookie привязки; его можно объявить в секции defaults. Значением cookie будет значение, указанное после ключевого слова “cookie” в директиве “server”. Если для сервера cookie не объявлен, он не задаётся.
Примеры:
См. также: “balance source”, “capture cookie”, “server” и “ignore-persist”.
declare capture [ request | response ] len <length>
Объявляет слот захвата.
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend нет | да | да | нет
Аргументы:
Объявление доступно только в секциях frontend и listen, но зарезервированный слот можно использовать в бэкендах. Ключевое слово “request” выделяет слот захвата для запроса, а “response” — для ответа.
См. также: “capture-req”, “capture-res” (преобразователи образцов), “capture.req.hdr”, “capture.res.hdr” (извлечения образцов), “http-request capture” и “http-response capture”.
default-server [param*]
Изменяет параметры по умолчанию для сервера в бэкенде
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
Пример:
См. также: “server” и раздел 5 о параметрах серверов
default_backend <backend>
Задаёт бэкенд, используемый, если не сработало ни одно правило “use_backend”.
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | нет
Аргументы:
При переключении содержимого между фронтендом и бэкендами с использованием ключевого слова “use_backend”, часто полезно указать, какой бэкенд будет использоваться, если ни одно правило не сработало. Обычно это динамический бэкенд, который перехватывает все неопределённые запросы.
Если бэкенд отключён или не опубликован, правила default_backend, нацеленные на него, будут проигнорированы, и обработка потока останется на исходном прокси.
Пример:
См. также: “use_backend”
description <string>
Описывает объект listen, фронтенд или бэкенд.
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend нет | да | да | да
Аргументы: строка
Позволяет добавить предложение с описанием соответствующего объекта на HTML-странице статистики HAProxy. Описание выводится справа от имени объекта. Пробелы в аргументах <string> не нужно экранировать обратной косой чертой.
disabled
Отключает прокси, фронтенд или бэкенд.
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы: отсутствуют
Ключевое слово “disabled” отключает экземпляр — обычно для освобождения прослушиваемого порта или временного отключения службы. Экземпляр всё равно создаётся, а его конфигурация проверяется, но он создаётся в состоянии “stopped” и так отображается в статистике. Он не принимает трафик, не отправляет проверки работоспособности и не ведёт журнал. Добавление “disabled” в секцию “defaults” позволяет отключить сразу несколько экземпляров.
По умолчанию отключённый бэкенд нельзя выбрать при переключении содержимого. Однако при использовании “force-be-switch” часть трафика может обойти это ограничение.
См. также: “enabled”, “force-be-switch”
dispatch <address>:<port> (deprecated)
Задаёт адрес сервера по умолчанию
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend нет | нет | да | да
Аргументы:
Ключевое слово “dispatch” задаёт сервер по умолчанию, используемый, когда ни один другой сервер не может принять соединение. Раньше его применяли для передачи соединений без привязки сеанса вспомогательному балансировщику нагрузки. Благодаря простому синтаксису его также использовали для простых ретрансляторов TCP. Для большей ясности рекомендуется отказаться от него и использовать директиву “server”.
Это ключевое слово объявлено устаревшим в 3.3 и будет удалено в 3.5 из-за внутренних ограничений, в том числе отсутствия поддержки SSL и простаивающих соединений. При его использовании выводится предупреждение; его можно подавить, включив директиву “expose-deprecated-directives” в секции global.
Чтобы правильно обойтись без этой директивы, достаточно объявить сервер с теми же адресом и портом. Если “dispatch” использовалась вместе с другими серверами, этим серверам следует задать нулевой вес, чтобы алгоритм балансировки нагрузки никогда их не выбирал.
Пример:
См. также: “server”
dynamic-cookie-key <string>
Задаёт секретный ключ динамических cookie для бэкенда.
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы: используемый секретный ключ.
При включённых динамических cookie (см. директиву “dynamic” для cookie) для каждого сервера создаётся динамический cookie, если он не задан явно в строке “server”. Для этого используется хеш адреса IP сервера, порта TCP и секретного ключа. Так обеспечивается привязка сеанса при работе нескольких балансировщиков нагрузки, даже если серверы добавляются или удаляются динамически.
enabled
Включает прокси, фронтенд или бэкенд.
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы: отсутствуют
Ключевое слово “enabled” явно включает экземпляр, если в настройках по умолчанию задано “disabled”. Это используется очень редко.
См. также: “disabled”
errorfile <code> <file>
Возвращает содержимое файла вместо ошибок, сформированных HAProxy
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы:
Эта директива предназначена для замены ошибок, обнаруженных и возвращённых HAProxy, а не ошибок, возвращённых сервером. Поэтому список поддерживаемых ошибок ограничен небольшим набором.
Код 200 возвращается в ответ на запросы, соответствующие правилу “monitor-uri”.
Файлы разбираются при запуске HAProxy и должны соответствовать спецификации HTTP. Их размер не следует делать больше настроенного размера буфера (BUFSIZE), который обычно составляет 16 kB; иначе будет возвращена внутренняя ошибка. Также целесообразно не включать ссылки на локальное содержимое, например изображения: если все серверы недоступны, вместо изображения возвращается ошибка, что может вызвать цикл между клиентом и HAProxy. Наконец, размер ответа не может превышать (tune.bufsize - tune.maxrewrite), чтобы у правил “http-after-response” оставалось место для работы (см. “tune.maxrewrite”).
Файлы читаются одновременно с конфигурацией и сохраняются в памяти. Поэтому ответы об ошибках продолжают возвращаться и после выполнения chroot, а изменения файлов не учитываются, пока процесс работает. Простой способ разрабатывать такие файлы — связать их с кодом состояния 403 и обращаться к заблокированному URL.
См. также: “http-error”, “errorloc”, “errorloc302”, “errorloc303”
Пример:
errorfiles <name> [<code> ...]
Полностью или частично импортирует файлы ошибок, определённые в секции http-errors с именем <name>.
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы:
Ошибки, определённые в секции http-errors с именем <name>, импортируются в текущий прокси. Если коды состояния не указаны, импортируются все файлы ошибок этой секции http-errors. Иначе импортируются только файлы, связанные с перечисленными кодами. Эти файлы заменяют ранее заданные пользовательские ошибки прокси и, в свою очередь, могут быть заменены последующими определениями. Функционально это полностью равнозначно ручному объявлению всех файлов ошибок с помощью директив “errorfile”.
См. также: “http-error”, “errorfile”, “errorloc”, “errorloc302”, “errorloc303” и раздел 12.4 о http-errors.
Пример:
errorloc <code> <url>
Возвращает перенаправление HTTP на URL вместо ошибок, сформированных HAProxy
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы:
Эта директива предназначена для замены ошибок, обнаруженных и возвращённых HAProxy, а не ошибок, возвращённых сервером. Поэтому список поддерживаемых ошибок ограничен небольшим набором.
Код 200 возвращается в ответ на запросы, соответствующие правилу “monitor-uri”.
Оба ключевых слова возвращают код состояния HTTP 302, предписывающий клиенту обратиться к указанному URL тем же методом HTTP. Это может создавать серьёзные проблемы для методов, отличных от GET, например POST: URL, отправленный клиенту, может допускать только GET. Для обхода этой проблемы следует использовать “errorloc303”, которая возвращает код состояния HTTP 303 и указывает клиенту, что URL необходимо получить запросом GET.
См. также: “http-error”, “errorfile”, “errorloc303”
errorloc303 <code> <url>
Возвращает перенаправление HTTP на URL вместо ошибок, сформированных HAProxy
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы:
Эта директива предназначена для замены ошибок, обнаруженных и возвращённых HAProxy, а не ошибок, возвращённых сервером. Поэтому список поддерживаемых ошибок ограничен небольшим набором.
Код 200 возвращается в ответ на запросы, соответствующие правилу “monitor-uri”.
Оба ключевых слова возвращают код состояния HTTP 303, предписывающий клиенту получить указанный URL тем же методом HTTP GET. Это решает обычные проблемы, связанные с “errorloc” и кодом 302. Некоторые очень старые браузеры, созданные до HTTP/1.1, могут не поддерживать такое поведение, однако до настоящего времени о подобных проблемах не сообщалось.
См. также: “http-error”, “errorfile”, “errorloc”, “errorloc302”
email-alert from <emailaddr>
Задаёт адрес отправителя электронных уведомлений как в конверте, так и в заголовке сообщения. С этого адреса отправляются уведомления.
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы:
Также необходимо задать “email-alert mailers” и “email-alert to”; при выполнении этих условий отправка электронных уведомлений для прокси включается.
См. также: “email-alert level”, “email-alert mailers”, “email-alert myhostname”, “email-alert to”, раздел 12.3 о mailers.
email-alert level <level>
Задаёт максимальный уровень журналирования сообщений, для которых отправляются электронные уведомления. Он служит фильтром отправки уведомлений.
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы:
По умолчанию используется уровень alert
Также необходимо задать “email-alert from”, “email-alert mailers” и “email-alert to”; при выполнении этих условий отправка электронных уведомлений для прокси включается.
Уведомления отправляются в следующих случаях:
- Сервер, не находящийся на паузе, помечается как down, а
<level>равен alert или ниже - Приостановленный сервер помечается как down, а
<level>равен notice или ниже - Сервер помечается как up или переходит в состояние drain, а
<level>равен notice или ниже - Включён “option log-health-checks”,
<level>равен info или ниже и происходит обновление состояния проверки работоспособности
См. также: “email-alert from”, “email-alert mailers”, “email-alert myhostname”, “email-alert to”, раздел 12.3 о mailers.
email-alert mailers <mailersect>
Задаёт секцию mailers для отправки электронных уведомлений
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы:
Также необходимо задать “email-alert from” и “email-alert to”; при выполнении этих условий отправка электронных уведомлений для прокси включается.
См. также: “email-alert from”, “email-alert level”, “email-alert myhostname”, “email-alert to”, раздел 12.3 о mailers.
email-alert myhostname <hostname>
Задаёт имя хоста, используемое при взаимодействии с mailers.
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы:
По умолчанию используется имя хоста системы.
Также необходимо задать “email-alert from”, “email-alert mailers” и “email-alert to”; при выполнении этих условий отправка электронных уведомлений для прокси включается.
См. также: “email-alert from”, “email-alert level”, “email-alert mailers”, “email-alert to”, раздел 12.3 о mailers.
email-alert to <emailaddr>
Задаёт адрес получателя электронных уведомлений и в конверте, и в заголовке сообщения. На этот адрес отправляются уведомления.
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы:
Также необходимо задать “email-alert mailers” и “email-alert to”; при выполнении этих условий отправка электронных уведомлений для прокси включается.
См. также: “email-alert from”, “email-alert level”, “email-alert mailers”, “email-alert myhostname”, раздел 12.3 о mailers.
error-log-format <fmt>
Задаёт строку формата журнала для ошибок соединения на стороне фронтенда.
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | нет
Эта директива задаёт строку формата для записей журнала с информацией об ошибках, тайм-аутах, повторных попытках, перераспределении запросов или кодах состояния HTTP 5xx. Этот формат используется для всех записей, на которые распространялся бы параметр “log-separate-errors”, включая ошибки соединения, описанные в разделе 8.2.5 .
Если директива используется в секции defaults, все последующие фронтенды используют один и тот же формат журнала. Подробное описание пользовательской строки формата журнала приведено в разделе 8.2.6 .
Директива “error-log-format” переопределяет предыдущие директивы “error-log-format”.
force-persist { if | unless } <condition>
Задаёт условие принудительной привязки сеанса к недоступным серверам
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend нет | нет | да | да
По умолчанию запросы не направляются на недоступные серверы. Это можно принудительно изменить с помощью “option persist”, однако этот параметр действует безусловно и перенаправляет запрос на работающий сервер, если задана “option redispatch”. Поэтому возможностей направить отдельные запросы на сервер, искусственно помеченный как недоступный для проведения обслуживания, остаётся очень мало.
Директива “force-persist” позволяет задать различные условия на основе ACL. При их выполнении запрос игнорирует недоступное состояние сервера и всё равно пытается установить с ним соединение. Это позволяет запустить сервер, который ещё отвечает ошибкой на проверки работоспособности, и проверить службу с помощью специально настроенного браузера. Например, удобно использовать определённый исходный адрес IP или определённый cookie. У cookie есть и дополнительное преимущество: его легко добавить или удалить в браузере с тестовой страницы. После проверки службы её можно открыть для всех пользователей, начав возвращать корректные ответы на проверки работоспособности.
Принудительная привязка включается при выполнении условия “if” или при невыполнении условия “unless”. При её использовании окончательное перераспределение запроса всегда отключено.
См. также: “option redispatch”, “ignore-persist”, “persist” и раздел 7 об использовании ACL.
external-check command <command>
Исполняемый файл, запускаемый при выполнении external-check
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
Команде передаются следующие аргументы:
<proxy_address> <proxy_port> <server_address> <server_port>
Значения <proxy_address> и <proxy_port> берутся из первого слушателя IPv4, IPv6 или сокета UNIX. Для слушателя на сокете UNIX значение proxy_address содержит путь к сокету, а <proxy_port> — строку “NOT_USED”. В секции backend определить слушатель невозможно, поэтому и <proxy_address>, и <proxy_port> получают строковое значение “NOT_USED”.
Некоторые значения также передаются через переменные окружения.
Переменные окружения:
Если команда выполнена и завершилась с нулевым кодом, проверка считается успешной; в противном случае она считается неуспешной.
Пример:
См. также: “external-check”, “option external-check”, “external-check path”
external-check path <path>
Значение переменной окружения PATH, используемой при запуске external-check
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
Путь по умолчанию — “”.
Пример:
См. также: “external-check”, “option external-check”, “external-check command”
force-be-switch { if | unless } <condition>
Разрешает при переключении содержимого выбирать экземпляр бэкенда, даже если он отключён или не опубликован. Администраторы могут использовать это правило для проверки трафика к службам перед предоставлением внешнего доступа к ним.
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend нет | да | да | нет
См. также: “be-unpublished”, “disabled”
filter <name> [param*]
Добавляет фильтр <name> в список фильтров, прикреплённый к прокси.
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend нет | да | да | да
Аргументы:
Для одного прокси можно использовать несколько строк filter. При необходимости один и тот же фильтр можно указать несколько раз.
Пример:
См. также: раздел 9 .
fullconn <conns>
Задаёт нагрузку бэкенда, при которой серверы достигают своего maxconn
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
Параметр “maxconn” сервера задаёт верхнюю границу числа его одновременных соединений. Дополнительный параметр “minconn” задаёт динамический лимит, зависящий от нагрузки бэкенда. Сервер всегда допускает не менее <minconn> соединений, но никогда не более <maxconn>; пока число одновременных соединений бэкенда меньше <conns>, лимит плавно меняется между этими значениями. Это позволяет ограничивать нагрузку серверов в обычных условиях, увеличивать её при высокой нагрузке и не перегружать серверы при исключительных всплесках.
Поскольку правильно подобрать это значение сложно, HAProxy автоматически устанавливает его равным 10% суммы maxconn всех фронтендов, которые могут направлять трафик в этот бэкенд (по правилам “use_backend” и “default_backend”). Поэтому безопасно оставить значение незаданным. Однако правила “use_backend” с динамическими именами не учитываются: невозможно определить, смогут ли они совпасть.
Пример:
См. также: “maxconn”, “server”
guid <string>
Задаёт для этого прокси глобально уникальный ID с учётом регистра.
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend нет | да | да | да
<string> должна быть уникальной во всей конфигурации haproxy среди объектов всех типов. Формат не задан, чтобы пользователь мог выбрать собственные правила именования. Единственное ограничение — длина не более 127 символов. Допустимы все буквенно-цифровые значения, а также символы ‘.’, ‘:’, ‘-’ и ‘_’. См. также “shm-stats-file”.
hash-balance-factor <factor>
Задаёт коэффициент балансировки для консистентного хеширования с ограниченной нагрузкой
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | нет | да
Аргументы:
Параметр “hash-balance-factor” для сервера с “hash-type consistent” включает алгоритм, который не позволяет одному серверу получить слишком много запросов одновременно, даже если в некоторые корзины хеша попадает значительно больше запросов, чем в другие. Значение <factor> 0 (по умолчанию) отключает эту возможность. В остальных случаях <factor> задаётся в процентах и должен быть больше 100. Например, при <factor> 150 нагрузка ни одного сервера не может превышать среднюю более чем в 1.5 раза. Веса серверов, если они используются, учитываются.
Если первоначально выбранный сервер не подходит, алгоритм выбирает другой на основе хеша запроса, пока не найдёт сервер со свободной ёмкостью. Более высокий <factor> допускает больший дисбаланс между серверами, а более низкий <factor> требует в среднем проверять больше серверов, что влияет на производительность. Разумные значения находятся в диапазоне от 125 до 200.
Эта настройка также используется алгоритмом “balance random”, который внутри опирается на механизм консистентного хеширования.
См. также: “balance” и “hash-type”.
hash-preserve-affinity { always | maxconn | maxqueue }
Задаёт способ назначения потоков серверам при балансировке по хешу, когда серверы полностью загружены или их очередь заполнена.
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Можно указать следующие значения:
- "always" : стратегия по умолчанию. Поток назначается серверу
на основе хеширования независимо от того, полностью ли
загружен этот сервер.
- "maxconn" : пропускаются полностью загруженные серверы, у которых
задан "maxconn". Другой сервер выбирается при обходе
хеш-кольца. Это не влияет на серверы без "maxconn".
Если все серверы полностью загружены, запрос ставится
в очередь последнего сервера в хеш-кольце перед
первоначально выбранным сервером.
- "maxqueue": пропускаются серверы с заданным "maxconn", ненулевым
"maxqueue" (ограниченным размером очереди) и полностью
заполненной очередью. Другой сервер выбирается при
обходе хеш-кольца. Это не влияет на серверы, у которых
отсутствует хотя бы один из параметров "maxconn"
и "maxqueue".
См. также: “maxconn”, “maxqueue”, “hash-balance-factor”
hash-type <method> <function> <modifier>
Задаёт способ сопоставления хешей с серверами
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
Тип хеша по умолчанию — “map-based”; он рекомендуется для большинства случаев. Функция по умолчанию — “sdbm”. Функцию следует выбирать с учётом диапазона хешируемых значений.
См. также: “balance”, “hash-balance-factor”, “hash-preserve-affinity”, “server”
http-after-response <action> <options...> [ { if | unless } <condition> ]
Контроль доступа для всех ответов уровня 7: от серверов, апплетов/служб и внутренних ответов.
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да(!) | да | да | да
Директива http-after-response задаёт набор правил обработки на уровне 7. В секциях frontend, listen и backend правила проверяются в порядке объявления. Поскольку они применяются к ответам, сначала выполняются правила бэкенда, затем фронтенда. За любым правилом можно указать необязательное условие на основе ACL; тогда правило проверяется только при истинном значении условия.
В отличие от правил http-response, эти правила применяются ко всем ответам: от серверов и сформированным самим HAProxy. Они проверяются в конце анализа ответа, до этапа пересылки данных.
Условие проверяется непосредственно перед выполнением действия, а действие выполняется ровно один раз. Поэтому действие может изменять элемент, проверяемый условием, без каких-либо проблем. Несколько действий могут зависеть от одного условия: первое действие, изменяющее результат его проверки, неявно отключает остальные. Это используется, например, при попытках присвоить пустой переменной значение из разных источников. Число директив “http-after-response” в экземпляре не ограничено.
Первое ключевое слово после “http-after-response” в синтаксисе — действие правила; за ним может следовать различное число аргументов действия. Поддерживаемые действия и их синтаксис перечислены в разделе 4.3 «Действия» (нужны действия с отметкой “HTTP Aft”).
Эта директива доступна только в именованных секциях defaults, а в анонимных недоступна. Правила секции defaults проверяются до правил связанной с ней секции прокси. Во избежание неоднозначности одну и ту же секцию defaults нельзя использовать одновременно для прокси с возможностями фронтенда и прокси с возможностями бэкенда. Поэтому секция listen не может использовать секцию defaults с такими правилами.
Примечание: ошибки на ранних этапах разбора запроса обрабатываются мультиплексором на более низком уровне, до анализа http. Поэтому к таким ошибкам набор правил http-after-response не применяется.
Пример:
http-check comment <string>
Задаёт комментарий для следующего правила http-check, который попадает в журнал при неудаче этого правила.
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
Работает только для правил connect, send и expect. Позволяет делать сообщения об ошибках понятнее.
См. также: “option httpchk”, “http-check connect”, “http-check send” и “http-check expect”.
http-check connect [default] [port <expr>] [addr <ip>] [send-proxy]
Открывает новое соединение для проверки работоспособности HTTP
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
Как и для проверок tcp-check, можно настроить соединение для проверки работоспособности HTTP. Эту директиву также следует использовать для описания сценария с несколькими обменами запросами и ответами, возможно на разных портах или с разными серверами.
Если порт TCP не задан ни в строке server, ни директивой server port, первым шагом последовательности http-check необходимо указать порт через “http-check connect”.
В наборе правил http-check требуется ‘connect’, причём набор обязательно должен начинаться правилом ‘connect’. Это позволяет убедиться, что администратор понимает свои действия.
Хотя набор правил должен начинаться с connect, перед ним всё же могут стоять правила set-var, unset-var или comment.
Примеры:
См. также: “option httpchk”, “http-check send”, “http-check expect”
http-check disable-on-404
Включает режим обслуживания при ответе HTTP/404 на проверки работоспособности
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы: отсутствуют
При этом параметре сервер, возвращающий код HTTP 404, исключается из дальнейшей балансировки нагрузки, но продолжает получать соединения с привязкой сеанса. Это очень удобный способ плавно завершать обслуживание серверов для веб-администраторов. Если в этом режиме обнаруживается отказ сервера, формируется только уведомление notice вместо alert. При возобновлении ответов 2xx или 3xx сервер немедленно возвращается в группу. На странице статистики сервер в этом режиме имеет состояние “NOLB”. Параметр работает только совместно с “httpchk”. При сочетании с “http-check expect” он имеет приоритет, поэтому ответы 404 по-прежнему считаются мягкой остановкой. Уже остановленный сервер остаётся остановленным, даже если отвечает 404. Параметр проверяется только для работающих серверов.
См. также: “option httpchk” и “http-check expect”.
http-check expect [min-recv <int>] [comment <msg>]
Позволяет проверкам работоспособности HTTP учитывать содержимое ответа или определённые коды состояния
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
По умолчанию “option httpchk” считает коды состояния 2xx и 3xx допустимыми, а остальные недопустимыми. “http-check expect” определяет, что считать допустимым и недопустимым. В бэкенде поддерживается только одна директива “http-check”. Если сервер не отвечает или истекает тайм-аут, проверка, очевидно, завершается неудачей. Доступные способы сопоставления:
Размер ответов ограничивается глобальным параметром “tune.bufsize”, по умолчанию 16384 байта. Поэтому в слишком большом ответе при “string” или “rstring” может отсутствовать обязательный шаблон. Если большой ответ совершенно необходим, максимальный размер по умолчанию можно изменить глобальной переменной. Однако разбор очень больших ответов может расходовать лишние циклы CPU, особенно с регулярными выражениями; всегда лучше направлять проверки на меньшие ресурсы.
В наборе правил http-check последнее правило expect может быть неявным. Если после последнего “http-check send” правило expect не указано, неявно задаётся правило expect для кодов состояния 2xx или 3xx. Оно задаётся даже при полном отсутствии правил “http-check”, если установлена только “option httpchk”.
Наконец, если “http-check expect” комбинируется с “http-check disable-on-404”, то последнее имеет приоритет при ответе сервера с кодом 404.
Примеры:
См. также: “option httpchk”, “http-check connect”, “http-check disable-on-404” и “http-check send”.
http-check send [meth <method>] [{ uri <uri> | uri-lf <fmt> }>] [ver <version>]
Позволяет добавить список заголовков и/или тело в запрос, отправляемый при проверках работоспособности HTTP.
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
В дополнение к строке запроса, заданной директивой “option httpchk”, эта директива является правильным способом добавить заголовки и необязательное тело в запрос проверки работоспособности HTTP. При заданном теле соответствующий заголовок “Content-Length” добавляется автоматически. Поэтому этот заголовок и заголовок “Transfer-encoding” не следует включать в запрос, заданный через “http-check send”: если они там присутствуют, они игнорируются. Старый приём добавления заголовков после строки версии в строке “option httpchk” теперь устарел.
Кроме того, “http-check send” не поддерживает постоянные соединения HTTP. Заголовок “Connection: close” добавляется автоматически, если заголовок Connection ещё не настроен записью hdr.
Заголовок Host и компонент authority запроса, если оба заданы, автоматически синхронизируются. Это означает, что при отправке запроса HTTP добавление Host в запрос соответственно обновляет компонент authority. Поэтому значение заголовка Host может перезаписать настроенный компонент authority запроса.
Кроме того, сейчас заголовок Host не добавляется автоматически в запросы HTTP/1.1 и выше. Его следует добавлять явно.
См. также: “option httpchk”, “http-check send-state” и “http-check expect”.
http-check send-state
Включает отправку заголовка состояния при проверках работоспособности HTTP
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы: отсутствуют
При включённом параметре HAProxy всегда отправляет специальный заголовок “X-Haproxy-Server-State” со списком параметров, показывающих каждому серверу, каким его видит HAProxy. Например, это удобно при работе с сервером без доступа к HAProxy, когда оператору нужно знать, считает ли HAProxy сервер работающим или является ли он последним в группе.
Заголовок состоит из полей, разделённых точками с запятой. Первое поле — слово (“UP”, “DOWN”, “NOLB”), за которым может следовать число успешных проверок относительно общего числа, требуемого до перехода, как в интерфейсе статистики. Следующие поля имеют вид “<variable>=<value>” и в произвольном порядке указывают некоторые доступные в интерфейсе статистики значения: - переменная “address” содержит адрес сервера бэкенда и соответствует полю <address> в объявлении сервера. Для сокетов домена unix используется “unix”.
- Переменная "port" содержит порт сервера бэкенда и соответствует полю `<port>` в объявлении сервера. Для сокетов домена unix используется "unix".
- Переменная "name" содержит имя бэкенда, косую черту ("/"), затем имя сервера. Это удобно при проверках одного сервера в нескольких бэкендах.
- Переменная "node" содержит имя узла HAProxy, заданное глобальной переменной "node", либо имя хоста системы, если переменная не задана.
- Переменная "weight" содержит вес сервера, косую черту ("/") и общий вес группы с учётом только пригодных к работе серверов. Это помогает понять, доступны ли другие серверы для обработки нагрузки при отказе этого сервера.
- Переменная "scur" содержит текущее число одновременных соединений на сервере, косую черту ("/"), затем общее число соединений на всех серверах того же бэкенда.
- Переменная "qcur" содержит текущее число запросов в очереди сервера.
Пример заголовка, полученного прикладным сервером:
См. также: “option httpchk”, “http-check disable-on-404” и “http-check send”.
http-check set-var(<var-name>[,<cond>...]) <expr>
Эта операция устанавливает содержимое переменной. Переменная объявляется непосредственно при использовании.
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
Примеры:
http-check unset-var(<var-name>)
Освобождает ссылку на переменную в пределах её области видимости.
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
Примеры:
http-error status <code> [content-type <type>]
file `<file>` | lf-file `<file>` | string `<str>` | lf-string `<fmt>` } ]
[ hdr `<name>` `<fmt>` ]*
Определяет пользовательское сообщение об ошибке, которое будет использоваться вместо ошибок, генерируемых HAProxy.
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы:
Эту директиву можно использовать вместо “errorfile” для задания пользовательского сообщения об ошибке. Как и “errorfile”, она применяется к ошибкам, обнаруженным и возвращаемым HAProxy. Если задан errorfile, он разбирается при запуске HAProxy и должен соответствовать стандартам HTTP. Созданный ответ не должен превышать настроенный размер буфера (BUFFSIZE); иначе возвращается внутренняя ошибка. Наконец, если планируется переписывать эти ошибки правилами http-after-response, следует оставить доступным зарезервированное пространство буфера (см. “tune.maxrewrite”).
Файлы читаются одновременно с конфигурацией и сохраняются в памяти. По этой причине ошибки продолжают возвращаться даже при chroot, и изменения файла не учитываются во время работы процесса.
Примечание: ошибки 400/408/500, возникающие на ранней стадии разбора запроса, обрабатываются мультиплексором на более низком уровне. Пользовательское форматирование там не поддерживается, поэтому поддерживаются только статические сообщения об ошибках, заданные директивой “errorfile”. Однако ограничение действует лишь во время разбора заголовков запроса или между двумя транзакциями.
См. также: “errorfile”, “errorfiles”, “errorloc”, “errorloc302”, “errorloc303” и раздел 12.4 о http-errors.
http-request <action> [options...] [ { if | unless } <condition> ]
Управление доступом для запросов уровня 7
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да(!) | да | да | да
Директива http-request определяет набор правил обработки уровня 7. В секции frontend, listen или backend правила проверяются в порядке объявления. После любого правила может следовать необязательное условие на основе ACL; тогда правило проверяется лишь при истинном результате условия.
Условие проверяется непосредственно перед выполнением действия, а действие выполняется ровно один раз. Поэтому действие может без проблем менять элемент, проверяемый условием. Несколько действий также могут зависеть от одного условия: первого действия, меняющего результат его проверки, достаточно для неявного отключения остальных действий. Например, так пустой переменной пытаются присвоить значение из разных источников. Число директив “http-request” на экземпляр не ограничено.
Первое ключевое слово после “http-request” в синтаксисе — действие правила. За ним может следовать разное число аргументов этого действия. Поддерживаемые действия и их синтаксис перечислены в разделе 4.3 «Действия» (см. действия с отметкой “HTTP Req”).
Эта директива доступна только в именованных секциях defaults, а в анонимных недоступна. Правила секции defaults проверяются до правил связанной с ней секции прокси. Во избежание неоднозначности одну и ту же секцию defaults нельзя использовать одновременно для прокси с возможностями фронтенда и прокси с возможностями бэкенда. Поэтому секция listen не может использовать секцию defaults с такими правилами.
Пример:
Пример:
Пример:
См. также: “stats http-request”, раздел 12.2 о списках пользователей и раздел 7 об использовании ACL.
http-response <action> <options...> [ { if | unless } <condition> ]
Управление доступом для ответов уровня 7
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да(!) | да | да | да
Директива http-response определяет набор правил обработки уровня 7. В секции frontend, listen или backend правила проверяются в порядке объявления. Поскольку они применяются к ответам, сначала выполняются правила бэкенда, затем правила фронтенда. После любого правила может следовать необязательное условие на основе ACL; тогда правило проверяется лишь при истинном результате условия.
Условие проверяется непосредственно перед выполнением действия, а действие выполняется ровно один раз. Поэтому действие может без проблем менять элемент, проверяемый условием. Несколько действий также могут зависеть от одного условия: первого действия, меняющего результат его проверки, достаточно для неявного отключения остальных действий. Например, так пустой переменной пытаются присвоить значение из разных источников. Число директив “http-response” на экземпляр не ограничено.
Первое ключевое слово после “http-response” в синтаксисе — действие правила. За ним может следовать разное число аргументов этого действия. Поддерживаемые действия и их синтаксис перечислены в разделе 4.3 «Действия» (см. действия с отметкой “HTTP Res”).
Эта директива доступна только в именованных секциях defaults, а в анонимных недоступна. Правила секции defaults проверяются до правил связанной с ней секции прокси. Во избежание неоднозначности одну и ту же секцию defaults нельзя использовать одновременно для прокси с возможностями фронтенда и прокси с возможностями бэкенда. Поэтому секция listen не может использовать секцию defaults с такими правилами.
Пример:
Пример:
См. также: “http-request”, раздел 12.2 о списках пользователей и раздел 7 об использовании ACL.
http-reuse { never | safe | aggressive | always }
Определяет, как простаивающие соединения HTTP могут совместно использоваться запросами
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Чтобы не создавать новые соединения с серверами бэкенда для каждого запроса HTTP, HAProxy пытается сохранять использованные соединения открытыми во время простоя. Эти соединения относятся к определённому серверу и хранятся в списке, называемом пулом, где группируются по набору общих ключевых свойств. Последующие запросы HTTP ищут в соответствующем пуле совместимое соединение с идентичными свойствами и повторно используют его вместо создания нового.
Максимальное число простаивающих соединений, сохраняемых на сервере, задаётся серверным ключевым словом “pool-max-conn”. Неиспользуемые соединения периодически удаляются с интервалом “pool-purge-delay”.
Для определения, пригодно ли простаивающее соединение для повторного использования при данном запросе, используются следующие свойства соединения:
- адреса источника и назначения
- протокол proxy
- параметры сокета TOS и mark
- имя соединения, определяемое результатом вычисления выражения “pool-conn-name”, если оно задано; иначе — выражением “sni”, которое по умолчанию равно “req.hdr(host),field(1,:)”, то есть использует поле заголовка “Host” входящего запроса без двоеточия и номера порта.
Иногда из-за дополнительных ограничений поиск или повторное использование соединения не выполняется. Это определяется стратегией повторного использования, заданной аргументом ключевого слова:
- "never" : Простаивающие соединения никогда не используются совместно разными сеансами. Режим можно принудительно включить, чтобы отменить другую стратегию, унаследованную из секции defaults, или для устранения неполадок. Например, старое некорректное приложение может считать, что запросы в одном соединении идут от одного клиента; если исправить приложение нельзя, может быть желательно отключить совместное использование соединений в одном бэкенде. Пример — старый HAProxy со вставкой cookie в режиме туннеля, не проверяющий запросы после первого.
- "safe" : Стратегия по умолчанию и рекомендуемая. Первый запрос сеанса всегда отправляется по собственному соединению; только последующие запросы могут направляться по другим существующим соединениям. Это позволяет браузеру молча повторить запрос, если сервер закроет соединение во время его отправки. Поскольку поведение в точности эквивалентно обычным постоянным соединениям, побочных эффектов быть не должно. Соединения с протоколами, подверженными блокировке начала очереди (бэкенд с h2 или fcgi), обрабатываются особо. При обработке хотя бы одного потока используемое соединение резервируется для потоков того же сеанса. Когда обрабатываемых потоков не остаётся, оно освобождается и может использоваться повторно.
- "aggressive": Режим может быть полезен в окружениях веб-служб, где не все серверы обязательно известны и желательно передавать большинство первых запросов по существующим соединениям. Первые запросы тогда передаются только по соединениям, уже повторно использованным хотя бы один раз: это доказывает правильную поддержку повторного использования сервером. Режим следует применять лишь при уверенности, что клиент иногда может повторить неудачный запрос и выгода от агрессивного повторного использования существенно превышает недостатки редких неудач соединения.
- "always": Режим рекомендуется только при уверенности, что на пути к серверу существующие соединения никогда не разрываются вскоре после освобождения. Первый запрос сеанса может отправляться по существующему соединению. При бэкенде из группы кешей это может заметно повысить производительность по сравнению с "safe": поведение таких компонентов обычно стабильно, а совместное использование соединений им полезно. В этом режиме рекомендуется сохранять низкий тайм-аут "http-keep-alive", чтобы неработающие соединения не оставались доступными для использования. В большинстве случаев прирост производительности будет таким же, как у "aggressive", но с большими рисками. Режим следует использовать только при улучшении ситуации по сравнению с "aggressive".
Также следует учитывать, что соединения с некоторыми сомнительными схемами аутентификации, зависящими от соединения, например NTLM, по возможности помечаются как частные и никогда не используются совместно. Однако это не так при использовании протокола с мультиплексированием и уровня режима повторного использования выше стратегии по умолчанию “safe”: в этом случае ничто не мешает соединению уже использоваться совместно.
Решение о том, оставить ли простаивающее соединение открытым или закрыть его после обработки, также определяется параметрами “tune.pool-low-fd-ratio” (по умолчанию: 20%) и “tune.pool-high-fd-ratio” (по умолчанию: 25%). Они задают долю от общего числа файловых дескрипторов, занятых простаивающими соединениями, при превышении которой HAProxy соответственно перестаёт оставлять соединения открытыми после ответа и начинает активно закрывать простаивающие соединения. В некоторых конфигурациях с очень высокой долей простаивающих соединений — из-за слишком низкого глобального “maxconn” либо большого объёма трафика HTTP/2 или HTTP/3 на фронтенде (мало соединений) при соединениях HTTP/1 на бэкенде — частота повторного использования может снижаться, поскольку открытыми сохраняются слишком немногие соединения. В таком случае может быть полезно изменить эти пороги либо просто увеличить глобальное значение “maxconn”.
В редких случаях, когда имя узла используется для различения исходящих соединений TLS, например в прямом прокси, и большинство запросов обращается к разным узлам, частота повторного использования будет очень низкой. Автоматическое вытеснение редко используемых соединений сработает раньше, чем их успеют использовать повторно, поскольку механизм непрерывно измеряет среднее число соединений, необходимое для обслуживания без исчерпания ресурсов. В таких ситуациях значение “pool-low-conn”, близкое к ожидаемому среднему числу простаивающих соединений, может помочь сохранить больше соединений: оно побуждает потоки создавать собственные, вместо того чтобы пытаться брать соединения других потоков и тем самым сокращать пул доступных соединений.
Если локально размещённый сервер использует один сертификат с несколькими именами узлов или шаблонами имён с подстановочными знаками и обслуживает несколько сайтов, может быть эффективнее указать “no-sni-auto” в строке “server”, чтобы не резервировать соединение для одного имени Host. Это значительно повысит частоту повторного использования. Однако некоторые серверы могут выполнять чрезмерные проверки соответствия Host и SNI и вследствие этого отклонять последующие запросы, поэтому параметр требует предварительной проверки. Поведение по умолчанию (“sni-auto”) обеспечивает безопасность и с такими серверами.
При явном включении групп потоков важно понимать, что простаивающие соединения могут использоваться только потоками одной группы. Поэтому неравномерная нагрузка между группами может потребовать больше простаивающих соединений и снизить частоту повторного использования. В этом случае можно применить то же решение: увеличить глобальный “maxconn” либо доли пула.
См. также: “option http-keep-alive”, “pool-conn-name”, “pool-max-conn”, “pool-purge-delay”, “server maxconn”, “sni”, “thread-groups”, “tune.pool-high-fd-ratio”, “tune.pool-low-fd-ratio”
http-send-name-header [<header>]
Добавляет имя сервера в запрос. Использует строку заголовка, заданную <header>
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
Директива “http-send-name-header” устанавливает в поле заголовка с именем <header> имя целевого сервера непосредственно перед отправкой запроса в сеть. Все существующие вхождения этого заголовка удаляются. При повторных попытках и перераспределениях поле заголовка обновляется и всегда отражает сервер, с которым предпринимается попытка соединения. Поскольку заголовок изменяется очень поздно при установлении соединения, это может неожиданно повлиять на уже изменённые заголовки. Например, использование заголовков транспортного уровня, таких как connection, content-length, transfer-encoding и т. п., скорее всего приведёт к отправке серверу некорректных запросов. Поэтому запрещены следующие имена заголовков: host, content-length, transfer-encoding и connection.
См. также: “server”
id <value>
Задаёт постоянный ID прокси.
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend нет | да | да | да
Аргументы: отсутствуют
Задаёт постоянный ID прокси. ID должен быть уникальным и положительным. Если он не задан, автоматически назначается неиспользованный ID. По историческим причинам значение 1 не используется, если не задано явно. Поэтому наименьшее автоматически назначаемое значение — 2. Сейчас этот ID возвращается только в статистике.
ignore-persist { if | unless } <condition>
Объявляет условие игнорирования привязки сеанса
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend нет | нет | да | да
По умолчанию при включённой привязке сеанса по cookie все запросы с этой cookie безусловно сохраняют привязку, если целевой сервер работает и доступен.
Директива “ignore-persist” позволяет объявить различные условия на основе ACL, при выполнении которых запрос игнорирует привязку сеанса. Иногда это полезно для балансировки запросов статических файлов, которым часто не требуется привязка сеанса. Также это позволяет полностью отключить привязку для определённого User-Agent, например для некоторых поисковых роботов.
Привязка сеанса игнорируется, когда выполняется условие “if” либо когда не выполняется условие “unless”.
Пример:
См. также: “force-persist”, “cookie” и раздел 7 об использовании ACL.
load-server-state-from-file { global | local | none }
Позволяет перезагружать HAProxy без прерывания обслуживания
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Эта директива указывает HAProxy файл, в котором сохранено состояние серверов предыдущего работавшего процесса. При запуске, до начала обработки трафика, новый процесс может применить прежнее состояние к серверам так, словно перезагрузки не было. Директива “load-server-state-from-file” указывает HAProxy, какой файл использовать. Сейчас предусмотрены только 2 аргумента: запретить загрузку состояния либо загрузить его из файла со всеми бэкендами и серверами. Файл состояния можно создать, выполнив команду “show servers state” через сокет статистики и перенаправив вывод.
Формат файла имеет версию и строго определён. Для его понимания следует обратиться к описанию команды “show servers state” в главе 9.3 руководства по управлению.
Аргументы:
Примечания: - адрес IP сервера по умолчанию сохраняется при перезагрузках, но порядок можно изменить параметром сервера “init-addr”. Это означает, что изменение адреса IP через CLI во время работы сохранится, а изменение локального средства разрешения имён, например /etc/hosts, может не иметь эффекта при использовании файла состояния.
- вес сервера переносится из предыдущего работавшего процесса, если он
не изменился между прежним и новым файлами конфигурации.
Пример: минимальная конфигурация
global
stats socket /tmp/socket
server-state-file /tmp/server_state
defaults
load-server-state-from-file global
backend bk
server s1 127.0.0.1:22 check weight 11
server s2 127.0.0.1:22 check weight 12
Затем можно выполнить:
Содержимое файла /tmp/server_state будет примерно таким:
Пример: минимальная конфигурация
global
stats socket /tmp/socket
server-state-base /etc/haproxy/states
defaults
load-server-state-from-file local
backend bk
server s1 127.0.0.1:22 check weight 11
server s2 127.0.0.1:22 check weight 12
Затем можно выполнить:
Содержимое файла /etc/haproxy/states/bk будет примерно таким:
См. также: “server-state-file”, “server-state-file-name” и “show servers state”
log global
Включает ведение журнала событий и трафика для отдельного экземпляра.
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Префикс:
Аргументы:
Важно помнить, что именно фронтенд решает, какие данные соединения журналировать. При переключении по содержимому записи журнала бэкенда игнорируются. Соединения журналируются на уровне “info”.
Однако объявление журналирования в бэкенде определяет, как и куда записываются изменения состояния серверов. Уровень “notice” используется для перехода сервера в рабочее состояние, “warning” — для сигналов завершения и окончательного прекращения работы сервиса, “alert” — при переходе сервера в нерабочее состояние.
Примечание: согласно RFC3164, перед отправкой сообщения обрезаются до 1024 байт.
Пример:
log-format <fmt>
Задаёт пользовательскую строку формата журнала для записей о трафике
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | нет
Эта директива задаёт строку формата журнала для всех записей о трафике, проходящем через фронтенд, в котором указана эта строка. Если директива используется в секции defaults, тот же формат применяют все последующие фронтенды. Подробное описание пользовательской строки формата журнала приведено в разделе 8.2.6 .
Также можно задать отдельный log-format только для ошибок соединения; см. параметр “error-log-format”.
Директива “log-format” переопределяет предыдущие директивы “option tcplog”, “log-format”, “option httplog” и “option httpslog”.
log-format-sd <fmt>
Задаёт пользовательскую строку формата журнала для формирования structured-data RFC5424
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | нет
Эта директива задаёт строку формата журнала structured-data RFC5424 для всех записей о трафике, проходящем через фронтенд, в котором указана эта строка. Если директива используется в секции defaults, тот же формат применяют все последующие фронтенды. Подробное описание строки формата журнала приведено в разделе 8.2.6 .
Подробнее о части structured-data RFC5424 см. https://tools.ietf.org/html/rfc5424#section-6.3 .
Примечание: эта строка формата журнала применяется только к средствам журналирования, для которых задан формат “rfc5424”.
Пример:
log-steps <steps>
Задаёт этапы обработки транзакции, на которых следует формировать записи журнала.
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | нет
Во время обработки транзакций tcp/http HAProxy может формировать записи журнала на разных этапах: accept, connect, request, response, close.
По умолчанию HAProxy формирует одну запись журнала на транзакцию, как только могут быть определены все элементы выражения logformat. На практике это обычно происходит в конце транзакции: после завершения ответа для HTTP либо соединения для TCP, если не используется “option logasap”.
Директива “log-steps” позволяет уточнить моменты формирования записей журнала и даже создавать несколько записей для одной транзакции. Специальное значение ‘all’ включает все доступные источники записей, позволяя отслеживать транзакцию от accept до close. Можно также выборочно задать отдельные источники по именам через запятую, определяя, когда формировать записи.
Распространённые источники записей журнала: accept, connect, request, response, close.
Пример:
Источники записей, указанные как “этапы журналирования”, например accept и close, можно использовать без изменений в log-profiles после директивы ‘on’. Сочетание “log-steps” и log-profiles особенно удобно для точного управления записями, автоматически формируемыми HAProxy при обработке транзакций.
Этот параметр относится только к фронтендам и игнорируется в бэкендах.
См. также: “log-profile”
log-tag <string>
Задаёт метку для всех исходящих записей журнала
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Устанавливает в поле метки заголовка syslog эту строку. По умолчанию используется log-tag, заданный в секции global, либо, если он не задан, имя программы при запуске из командной строки — обычно “HAProxy”. Иногда это помогает различать несколько процессов на одном узле либо экземпляры разных заказчиков внутри одного процесса. В бэкенде записи о переходах серверов в рабочее или нерабочее состояние используют эту метку. Например, удобно задать log-tag для обслуживаемого заказчика в секции defaults, затем разместить все его фронтенды и бэкенды, а для следующего заказчика начать новую секцию defaults. См. также глобальную директиву “log-tag”.
max-keep-alive-queue <value>
Задаёт максимальную длину очереди сервера для сохранения соединений keep-alive
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
HTTP keep-alive по возможности старается повторно использовать одно и то же соединение с сервером, но иногда это мешает работе: например, когда у одного сервера много соединений, а остальные простаивают. Это особенно характерно для серверов статического содержимого.
Этот параметр задаёт порог числа соединений в очереди, при достижении которого HAProxy перестаёт пытаться повторно использовать тот же сервер и предпочитает найти другой. Значение по умолчанию -1 означает отсутствие ограничения. Ноль означает, что запросы keep-alive никогда не ставятся в очередь. Для близко расположенных серверов с низкой задержкой, нечувствительных к разрыву keep-alive, рекомендуется низкое значение: например, для локального сервера статического содержимого — 10 или меньше. Для удалённых серверов с высокой задержкой могут потребоваться более высокие значения, компенсирующие задержку и/или затраты на выбор другого сервера.
Это не влияет на ответы, для которых после ответа 401 сохраняется привязка к тому же серверу. Они всё равно направляются на тот же сервер, даже если должны быть поставлены в очередь.
См. также: “option http-server-close”, “option prefer-last-server”, параметр сервера “maxconn” и привязку сеанса по cookie.
max-session-srv-conns <nb>
Задаёт максимальное число исходящих соединений, которые могут оставаться простаивающими для данного клиентского сеанса. Значение по умолчанию — 5; оно точно равно MAX_SRV_LIST, определяемому при сборке.
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | нет
maxconn <conns>
Задаёт максимальное число одновременных соединений на фронтенде
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | нет
Аргументы:
Если система поддерживает это, на крупных сайтах может быть полезно существенно увеличить этот предел, чтобы HAProxy управлял очередями соединений и не оставлял попытки соединения клиентов без ответа. Значение не следует устанавливать выше глобального maxconn. Нужно также учитывать, что соединение содержит два буфера размером tune.bufsize каждый — по умолчанию 16kB — и другие данные; в итоге каждое установленное соединение потребляет около 33 kB RAM. Поэтому система среднего уровня с 1GB RAM при правильной настройке может выдерживать около 20000-25000 одновременных соединений.
Также при больших значениях <conns> серверы могут быть не рассчитаны на такую нагрузку, поэтому обычно разумно задать для них приемлемые ограничения числа соединений.
Если это значение равно нулю, как по умолчанию, используется глобальное значение “maxconn”.
См. также: “server”, “maxconn” секции global, “fullconn”
mode { tcp|http|log|spop }
Задаёт режим работы или протокол экземпляра. Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да Аргументы:
При переключении содержимого фронтенд и бэкенд обязательно должны работать в одном режиме (обычно HTTP); иначе конфигурация будет отклонена.
Пример:
monitor fail { if | unless } <condition>
Добавляет условие сообщения об отказе в ответ на запрос мониторинга HTTP.
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend нет | да | да | нет
Аргументы:
Эта директива добавляет условие, которое может заставить ответ на запрос мониторинга сообщить об отказе. По умолчанию при запросе внешним компонентом URI для мониторинга возвращается ответ 200. При выполнении одного из условий выше HAProxy возвращает 503 вместо 200. Это удобно для сообщения об отказе площадки внешнему компоненту, который может строить объявления маршрутов между площадками по доступности, сообщаемой HAProxy. В таком случае используется ACL с критерием “nbsrv”. “monitor fail” работает только в режиме HTTP. При необходимости оба сообщения состояния можно изменить с помощью “errorfile” или “errorloc”.
Пример:
См. также: “monitor-uri”, “errorfile”, “errorloc”
monitor-uri <uri>
Перехватывает URI, используемый запросами мониторинга внешних компонентов
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | нет
Аргументы:
При получении во фронтенде запроса HTTP к <uri> HAProxy не пересылает и не журналирует его, а возвращает “HTTP/1.0 200 OK” либо “HTTP/1.0 503 Service unavailable” в зависимости от условий отказа “monitor fail”. Обычно этого достаточно, чтобы внешняя проверка HTTP определила, что служба UP и работает, без пересылки запроса серверу бэкенда. Метод HTTP, версия и все заголовки игнорируются, но сам запрос должен быть корректен хотя бы на уровне HTTP. Ключевое слово можно использовать только во фронтенде в режиме HTTP.
Запросы мониторинга обрабатываются очень рано: сразу после разбора запроса, ещё до любых “http-request”. До них применяются только наборы правил tcp-request. Журналировать эти запросы тоже нельзя, что соответствует их назначению. Для мониторинга можно настроить лишь один URI; при нескольких директивах “monitor-uri” последний определяет используемый URI. Такие запросы служат только для сообщения о работоспособности HAProxy вышестоящему компоненту. Однако можно добавить любое число условий с “monitor fail” и ACL, подстраивая результат под любую проверку (чаще всего число доступных серверов бэкенда).
Примечание: если <uri> начинается с косой черты (’/’), сопоставление выполняется с путём запроса вместо URI запроса. Это обходной путь, позволяющий запросам HTTP/2 совпадать с monitor-uri: в HTTP/2 клиентам рекомендуется отправлять только абсолютные URI.
Пример:
См. также: “monitor fail”
option abortonclose
Включает или отключает досрочное прерывание ещё не начатой обработки при закрытии соединения клиентом
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы: отсутствуют
TCP соединения можно закрывать независимо в каждом направлении; соединение, закрытое лишь в одном направлении, часто называют «полузакрытым». Изначально, когда в экосистеме HTTP преобладал «режим закрытия», при котором на соединение приходились только один запрос и один ответ перед закрытием, скриптовые клиенты довольно часто отправляли запрос, закрывали отправляющую сторону, ждали ответа, получали уведомление о закрытии и завершали работу. Но с появлением постоянных соединений (keep-alive) и более развитых протоколов эта практика практически исчезла. Теперь клиент закрывает соединение до получения ответа главным образом тогда, когда пользователь хочет прервать передачу или когда истекает тайм-аут и соединение закрывается.
Эти две ситуации (полузакрытое соединение и прерывание) неразличимы на стороне сервера (здесь — слушателя HAProxy). Это проблема: сохранение соединения и продолжение обработки запроса после прерывания клиентом может потреблять много ресурсов, особенно если закрытие вызвано нажатием кнопки «перезагрузить». Тогда новые запросы ставятся в очередь, а предыдущие не прерываются. И наоборот, безусловное прерывание при таком полузакрытии нарушило бы работу ряда TCP приложений и даже некоторых HTTP приложений во внутренних сетях, взаимодействующих с устаревшими агентами.
Параметр “abortonclose” позволяет выбрать нужное поведение: - во фронтенде он предотвращает обработку TLS рукопожатий, ожидающих на полузакрытом соединении. Это может произойти, если пользователь нажмёт «перезагрузить» во время HTTPS запроса под высокой нагрузкой, например при переключении VRRP между активным и резервным узлами HAProxy: все клиенты одновременно переподключаются к новому узлу, и всем нужно выполнить дорогостоящее полное TLS рукопожатие. Если оно занимает больше нескольких секунд, некоторые пользователи, вероятно, откажутся ждать, и тратить такты CPU на их рукопожатия бессмысленно. С учётом затрат CPU на TLS рукопожатия рекомендуется оставлять этот параметр включённым на фронтендах, доступных из интернета. Это поведение по умолчанию для входящих TLS соединений.
- в бэкенде он вызывает попытку прервать запрос при полузакрытии соединения,
если запрос ещё не отправлен серверу (то есть ожидает в очереди или при
попытке подключения). Если сервер уже обслуживает запрос, соединение с ним
в свою очередь переводится в полузакрытое состояние, чтобы передать серверу
ту же ситуацию; сервер затем решает, как действовать. Это поведение по
умолчанию для бэкендов в режиме HTTP.
Рекомендуется включать этот параметр на доступных из интернета конечных точках TLS и HTTP сервисах и отключать его для чисто TCP сервисов, а также для устаревших сред, не доступных извне. По умолчанию он включён в HTTP бэкендах; его можно принудительно отключить, добавив перед ним ключевое слово “no” в самой секции backend или в секции “defaults”, из которой она наследует настройки. Он также включён по умолчанию для TLS слушателей и может быть принудительно отключён директивой “no option abortonclose” во фронтенде или в секции “defaults”, из которой он наследует настройки.
Если параметр включён в секции “defaults”, для отдельного экземпляра его можно отключить, добавив перед ним ключевое слово “no”.
См. также: “timeout queue” и параметры сервера “maxconn” и “maxqueue”
option accept-invalid-http-request (deprecated)
Включить или отключить ослабление правил разбора HTTP запросов
Ключевое слово “accept-invalid-http-request” устарело; вместо него используйте “option accept-unsafe-violations-in-http-request”.
option accept-invalid-http-response (deprecated)
Включить или отключить ослабление правил разбора HTTP ответов
Ключевое слово “accept-invalid-http-response” устарело; вместо него используйте “option accept-unsafe-violations-in-http-response”.
option accept-unsafe-violations-in-http-request
Включить или отключить ослабление правил разбора HTTP запросов
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | нет
Аргументы: отсутствуют
По умолчанию HAProxy соблюдает различные HTTP RFC при разборе сообщений. Это означает, что разбор достаточно строг и для некорректных сообщений клиенту возвращается ошибка. Это желательное поведение: такие сообщения в основном используются для атак, эксплуатирующих слабые места серверов и обходящих фильтрацию безопасности. Иногда браузер с ошибками по какой-либо причине (конфигурация, реализация…) не соблюдает эти RCF, и проблему не исправляют сразу. Тогда можно ослабить парсер HAProxy и принять некоторые некорректные запросы, задав этот параметр. По историческим причинам большинство правил относится к разбору H1. Более новые версии HTTP обычно аккуратнее проработаны, и приложения точнее соблюдают эти протоколы.
При включении этого параметра действуют следующие правила:
* Только в H1 недопустимые символы, включая символ NULL, в имени заголовка
не приводят к отклонению сообщения; однако сам заголовок отбрасывается.
* Только в H1 символ NULL в значении заголовка принимается;
* Только в H1 символы с кодом выше 127 в URI принимаются. Список символов,
допустимых в URI, строго определён RFC3986; символы 0-31, 32 (пробел),
34 ('"'), 60 ('<'), 62 ('>'), 92 ('\'), 94 ('^'), 96 ('`'),
123 ('{'), 124 ('|'), 125 ('}'), 127 (удаление) и всё выше обычно запрещены.
В H1 все символы из диапазона (0..32), а также 127 всегда блокируются. Все символы с кодом
выше 127 (не включая его) также блокируются, кроме случая, когда этот
параметр включён. Остальные символы (33..126) вообще не проверяются.
* В H1 и H2 URL, содержащие ссылки на фрагменты ('#' после пути),
принимаются;
* Только в H1 компонент authority для запросов CONNECT не проверяется;
* Только в H1 компонент authority и значение заголовка Host не проверяются.
* Только в H1 проверки версии HTTP ослабляются. Разрешается пропускать
запросы HTTP/0.9 GET (без указания версии), другие имена протоколов
(например, RTSP), а также несколько цифр как в старшей, так и в
младшей части номера версии.
* Только в H1 принимаются запросы WebSocket (RFC6455) без корректного поля
заголовка "Sec-Websocket-Key".
Никогда не следует включать этот параметр по умолчанию: он скрывает ошибки приложений и создаёт бреши в безопасности. Его следует применять только после подтверждения проблемы.
При включении этого параметра некорректные, но принятые H1 запросы перехватываются для последующего анализа командой “show errors” через UNIX сокет статистики. Это также помогает подтвердить, что проблема устранена.
Если параметр включён в секции “defaults”, для отдельного экземпляра его можно отключить, добавив перед ним ключевое слово “no”.
См. также: “option accept-unsafe-violations-in-http-response” и “show errors” в сокете статистики.
option accept-unsafe-violations-in-http-response
Включить или отключить ослабление правил разбора HTTP ответов
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы: отсутствуют
Как и “option accept-unsafe-violations-in-http-request”, этот параметр можно использовать для ослабления правил разбора HTTP ответов. Его следует включать только для доверенных устаревших серверов, чтобы принимать некоторые некорректные ответы. По историческим причинам большинство правил относится к разбору H1. Более новые версии HTTP обычно аккуратнее проработаны, и приложения точнее соблюдают эти протоколы.
При включении этого параметра действуют следующие правила:
* Только в H1 коды состояния длиннее 3 цифр, значение которых помещается
в 16 бит, не отклоняются.
* Только в H1 недопустимые символы, включая символ NULL, в имени заголовка
не приводят к отклонению сообщения; однако сам заголовок отбрасывается.
* Только в H1 символ NULL в значении заголовка принимается;
* Только в H1 допускаются пустые значения заголовка Transfer-Encoding
или несколько вхождений значения "chunked";
* Только в H1 компонент authority и значение заголовка Host не проверяются.
* Только в H1 проверки версии HTTP становятся менее строгими. Допускаются
другие имена протоколов (например, RTSP) и несколько цифр как в старшей,
так и в младшей части номера версии.
* Только в H1 допускаются ответы WebSocket (RFC6455), в которых отсутствует
корректное поле заголовка "Sec-Websocket-Accept".
Никогда не следует включать этот параметр по умолчанию: он скрывает ошибки приложений и создаёт бреши в безопасности. Его следует применять только после подтверждения проблемы.
Когда эта опция включена, некорректные имена заголовков по-прежнему допускаются в ответах, но весь ответ сохраняется для последующего анализа с помощью запроса “show errors” через UNIX-сокет статистики. Это также помогает убедиться, что проблема устранена.
Если параметр включён в секции “defaults”, для отдельного экземпляра его можно отключить, добавив перед ним ключевое слово “no”.
См. также: “option accept-unsafe-violations-in-http-request” и “show errors” через сокет статистики.
option allbackups
Использовать все резервные серверы одновременно либо только первый из них
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы: отсутствуют
По умолчанию первый работоспособный резервный сервер получает весь трафик, когда все основные серверы недоступны. Иногда предпочтительно использовать несколько резервных серверов одновременно, поскольку одного недостаточно. Когда включена “option allbackups”, при недоступности всех основных серверов нагрузка распределяется между всеми резервными серверами. Используется тот же алгоритм балансировки с учётом весов серверов. Таким образом, резервные серверы больше не имеют приоритета друг перед другом.
Эта опция чаще всего используется со статическими группами серверов, предназначенными для возврата страницы с извинениями (“sorry”), когда приложение полностью недоступно.
Если параметр включён в секции “defaults”, для отдельного экземпляра его можно отключить, добавив перед ним ключевое слово “no”.
option checkcache
Анализировать все ответы серверов и блокировать ответы с cookie, которые могут попасть в кэш
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы: отсутствуют
Некоторые высокоуровневые фреймворки повсеместно устанавливают cookie приложения и не всегда дают разработчику достаточно возможностей управлять кэшированием ответов. Если с объектом, допускающим кэширование, возвращается cookie сеанса, возникает высокий риск смешения или кражи сеансов пользователей, проходящих через одни и те же кэши. В некоторых ситуациях лучше заблокировать ответ, чем допустить утечку конфиденциальных сведений о сеансе.
Опция “checkcache” включает глубокую проверку всех ответов серверов на строгое соответствие спецификации HTTP в части кэширования. Она тщательно проверяет заголовки “Cache-control”, “Pragma” и “Set-cookie” в ответе сервера, чтобы выявить риск кэширования cookie прокси на стороне клиента. Когда эта опция включена, клиенту могут быть переданы только следующие ответы: - все ответы без заголовка “Set-Cookie”; - все ответы с кодом, отличным от 200, 203, 204, 206, 300, 301, 404, 405, 410, 414, 501, при условии, что сервер не установил поле заголовка “Cache-control: public”; - все ответы на запросы с методом, отличным от GET, HEAD, OPTIONS, TRACE, при условии, что сервер не установил поле заголовка ‘Cache-Control: public’; - ответы с заголовком ‘Pragma: no-cache’ - ответы с заголовком ‘Cache-control: private’ - ответы с заголовком ‘Cache-control: no-store’ - ответы с заголовком ‘Cache-control: max-age=0’ - ответы с заголовком ‘Cache-control: s-maxage=0’ - ответы с заголовком ‘Cache-control: no-cache’ - ответы с заголовком ‘Cache-control: no-cache=“set-cookie”’ - ответы с заголовком ‘Cache-control: no-cache=“set-cookie,’ (допускающим другие поля после set-cookie) - ответы, не содержащие ни сведений о свежести (“Cache-control” с “max-age” либо “s-maxage” или заголовка “Expires”), ни валидатора (заголовка “ETag” или “Last-Modified”), поскольку соответствующий спецификации кэш не сохраняет такой ответ.
Если ответ не соответствует этим требованиям, он блокируется так же, как правилом “http-response deny”, с ответом “HTTP 502 bad gateway”. Состояние сеанса отображается как “PH–”, что означает блокировку ответа прокси во время обработки заголовков. Кроме того, в журнал записывается оповещение, чтобы администраторы знали о необходимости исправления.
Из-за существенного влияния на приложение перед вводом в эксплуатацию следует тщательно протестировать его с включённой опцией. Также полезно всегда включать её при тестировании, даже если она не используется в рабочей среде: она сообщает о потенциально опасном поведении приложения.
Если параметр включён в секции “defaults”, для отдельного экземпляра его можно отключить, добавив перед ним ключевое слово “no”.
option clitcpka
Включает или отключает отправку пакетов TCP для поддержания соединения на стороне клиента
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | нет
Аргументы: отсутствуют
Если между клиентом и сервером находится межсетевой экран или другой компонент, учитывающий состояние сеанса, а протокол предполагает очень долгие сеансы с длительными периодами простоя (например, удалённые рабочие столы), один из промежуточных компонентов может решить, что слишком долго простаивавший сеанс истёк.
Включение поддержания соединений TCP на уровне сокета заставляет систему регулярно отправлять пакеты на другой конец соединения, сохраняя его активным. Интервал между проверочными пакетами задаётся только системой и зависит от операционной системы и её настроек.
Важно понимать, что пакеты поддержания соединения не отправляются и не принимаются на уровне приложения: их видят только сетевые стеки. Поэтому даже если одна сторона прокси уже использует такие пакеты для сохранения соединения, они не пересылаются на другую сторону прокси.
Это никак не связано с постоянными соединениями HTTP.
Параметр “clitcpka” включает отправку проверочных пакетов TCP для поддержания соединения на клиентской стороне. Это должно помочь, если наблюдается истечение времени жизни сеансов между HAProxy и клиентом.
Если параметр включён в секции “defaults”, для отдельного экземпляра его можно отключить, добавив перед ним ключевое слово “no”.
См. также: “option srvtcpka”, “option tcpka”
option contstats
Включить непрерывное обновление статистики трафика
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | нет
Аргументы: отсутствуют
По умолчанию счётчики, используемые для расчёта статистики, увеличиваются только при завершении потока. Это достаточно хорошо работает при обслуживании небольших объектов, но для больших объектов (например, крупных изображений или архивов) либо потоковой передачи аудио и видео график, построенный по счётчикам HAProxy, напоминает ежа. Если включить эту опцию, счётчики будут регулярно увеличиваться во время передачи потока, обычно каждые 5 секунд, чего зачастую достаточно для получения ровных графиков. Пересчёт напрямую затрагивает часто выполняемый участок кода, поэтому по умолчанию он не включён: при очень большом числе сеансов он может вызывать множество пробуждений и небольшое снижение производительности.
option disable-h2-upgrade
Включить или выключить неявное переключение клиентского соединения HTTP/1.x на HTTP/2.
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | нет
Аргументы: отсутствуют
По умолчанию HAProxy может неявно переключить клиентское соединение HTTP/1.x на HTTP/2, если первый запрос, полученный по данному HTTP-соединению, совпадает с преамбулой соединения HTTP/2 (то есть строкой “PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n”). Это позволяет поддерживать клиентов HTTP/1.x и HTTP/2 в соединениях без SSL. Для отключения неявного переключения необходимо использовать эту опцию. Учтите, что такое переключение поддерживается только для HTTP-прокси; это ограничение распространяется и на опцию. Кроме того, можно принудительно использовать HTTP/2 в незашифрованных соединениях, указав “proto h2” в строке bind. Эта опция применяется ко всем строкам bind. Чтобы отключить неявное переключение на HTTP/2 для конкретной строки bind, можно использовать “proto h1”.
Если параметр включён в секции “defaults”, для отдельного экземпляра его можно отключить, добавив перед ним ключевое слово “no”.
option dontlog-normal
Включить или выключить запись в журнал обычных успешных соединений
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | нет
Аргументы: отсутствуют
Существуют крупные сайты, обрабатывающие несколько тысяч соединений в секунду, для которых ведение журнала создаёт серьёзные трудности. Некоторые даже вынуждены выключать журналы и теряют возможность диагностировать проблемы в рабочей среде. Эта опция гарантирует, что обычные соединения, в которых не было ошибок, тайм-аутов, повторных попыток или перенаправления на другой сервер, не попадут в журнал. Тем самым место на диске остаётся для аномалий. В режиме HTTP проверяется код состояния ответа, и ответы с кодами 5xx всё равно записываются в журнал.
Настоятельно не рекомендуется использовать эту опцию: чаще всего ключ к решению сложных проблем содержится в обычных записях журнала, которые в данном случае отсутствуют. Если требуется разделить журналы, см. опцию “log-separate-errors”.
См. также: “log”, “dontlognull”, “log-separate-errors” и раздел 8 о ведении журнала.
option dontlognull
Включить или выключить запись в журнал пустых соединений
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | нет
Аргументы: отсутствуют
В некоторых средах отдельные компоненты регулярно подключаются к различным системам, чтобы убедиться, что те работают. Такие подключения могут исходить как от другого балансировщика, так и от систем мониторинга. По умолчанию даже простая проверка или сканирование порта создаёт запись в журнале. Если эти соединения слишком сильно засоряют журналы, можно включить опцию “dontlognull”: соединение, по которому не было передано данных, не будет записываться в журнал. Обычно этому условию соответствуют такие проверки. Учтите, что ошибки по-прежнему возвращаются клиенту и учитываются в статистике. Если это нежелательно, можно использовать опцию option http-ignore-probes.
Как правило, в неконтролируемых средах (например, в интернете) рекомендуется не использовать эту опцию, иначе сканирование и другие вредоносные действия не будут записываться в журнал.
Если параметр включён в секции “defaults”, для отдельного экземпляра его можно отключить, добавив перед ним ключевое слово “no”.
См. также: “log”, “http-ignore-probes”, “monitor-uri” и раздел 8 о ведении журнала.
option external-check
Использовать внешние процессы для проверок работоспособности серверов
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Работоспособность сервера можно проверять с помощью внешней команды. Для этого запускается исполняемый файл, заданный директивой “external-check command”.
Требуется включить глобальную директиву “external-check”.
См. также: “external-check”, “external-check command”, “external-check path”
option forwarded [ proto ]
Включить добавление заголовка forwarded по rfc 7239 в запросы, отправляемые серверам
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
Поскольку HAProxy работает в режиме обратного прокси, серверы теряют часть контекста запроса (его происхождение: IP-адрес клиента, используемый протокол и т. д.).
Распространённый способ обойти это ограничение — использовать известный заголовок x-forward-for и другие заголовки x-forward-*, чтобы передать часть контекста серверам и приложениям за прокси. Хотя этот подход работает и широко применяется, IETF официально его не поддерживает, и он может стать причиной проблем совместимости и безопасности.
Для решения этой проблемы IETF описал новое расширение HTTP: заголовок forwarded (RFC7239). Дополнительные сведения: https://www.rfc-editor.org/rfc/rfc7239.html
Один этот заголовок позволяет передать множество сведений и, главное, решает проблему цепочек прокси. (RFC допускает, чтобы несколько последовательно расположенных прокси добавляли собственные значения в уже существующий заголовок.)
Эту опцию можно указать в секциях defaults, listen или backend, но в секциях frontend она игнорируется.
Директива option forwarded без аргументов использует неявное поведение по умолчанию: включает параметр proto и добавляет исходный IP-адрес клиента.
Эквивалентная явная конфигурация, заданная вручную:
Ключевое слово ‘by’ включает параметр ‘by’ (“nodename”) в заголовке forwarded и позволяет добавить сведения о прокси, через который проходит запрос. Значением ‘by’ будет IP-адрес прокси (адрес назначения). Если он недоступен (например, для UNIX-слушателя), ‘by’ получит значение “unknown”.
Ключевое слово ‘by-expr’ включает параметр ‘by’ (“nodename”) в заголовке forwarded и позволяет
добавить сведения о прокси, через который проходит запрос. Значением ‘by’ будет результат выражения
образца <by_expr>, если он корректен; иначе устанавливается “unknown”.
Ключевое слово ‘for’ включает параметр ‘for’ (“nodename”) в заголовке forwarded и позволяет добавить сведения о клиенте, от которого поступил запрос. Значением ‘for’ будет IP-адрес клиента (адрес источника). Если он недоступен (например, для UNIX-слушателя), ‘for’ получит значение “unknown”.
Ключевое слово ‘for-expr’ включает параметр ‘for’ (“nodename”) в заголовке forwarded и позволяет
добавить сведения о клиенте, от которого поступил запрос. Значением ‘for’ будет результат выражения
образца <for_expr>, если он корректен; иначе устанавливается “unknown”.
Ключевое слово ‘by_port’ добавляет сведения “nodeport” к параметру ‘by’. Для ‘by_port’ необходимо задать ‘by’ или ‘by-expr’, иначе оно игнорируется. Если порт прокси (порт назначения) доступен, “nodeport” получает его значение; в противном случае он игнорируется.
Ключевое слово ‘by_port-expr’ добавляет сведения “nodeport” к параметру ‘by’. Для ‘by_port-expr’
необходимо задать ‘by’ или ‘by-expr’, иначе оно игнорируется. Значением “nodeport” будет результат
выражения образца <by_port_expr>, если он корректен; иначе он игнорируется.
Ключевое слово ‘for_port’ добавляет сведения “nodeport” к параметру ‘for’. Для ‘for_port’ необходимо задать ‘for’ или ‘for-expr’, иначе оно игнорируется. Если порт клиента (порт источника) доступен, “nodeport” получает его значение; в противном случае он игнорируется.
Ключевое слово ‘for_port-expr’ добавляет сведения “nodeport” к параметру ‘for’. Для ‘for_port-expr’
необходимо задать ‘for’ или ‘for-expr’, иначе оно игнорируется. Значением “nodeport” будет результат
выражения образца <for_port_expr>, если он корректен; иначе он игнорируется.
Примеры:
См. также: “option forwardfor”, “option originalto”
option forwardfor [ except <network> ] [ header <name> ] [ if-none ]
Включить добавление заголовка X-Forwarded-For в запросы, отправляемые серверам
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы:
Поскольку HAProxy работает в режиме обратного прокси, серверы видят его IP-адрес как адрес клиента. Это иногда неудобно, если в журналах сервера должен быть указан IP-адрес клиента. Чтобы решить эту проблему, HAProxy может добавлять известный HTTP-заголовок “X-Forwarded-For” ко всем запросам, отправляемым серверу. Значение этого заголовка содержит IP-адрес клиента. Поскольку заголовок всегда добавляется в конец существующего списка заголовков, сервер необходимо настроить на использование только последнего вхождения этого заголовка. Способ включения поддержки данного стандартного заголовка описан в руководстве сервера. Учтите, что необходимо использовать только последнее вхождение: клиент вполне может уже передать собственный такой заголовок.
Ключевое слово “header” позволяет задать другое имя заголовка вместо стандартного “X-Forwarded-For”. Это полезно, если заголовок “X-Forwarded-For” уже поступает от другого приложения (например, stunnel) и его требуется сохранить. Также это полезно, если сервер бэкенда не использует “X-Forwarded-For” и требует другой заголовок (например, серверы Zeus требуют “X-Cluster-Client-IP”).
Иногда один экземпляр HAProxy обслуживает как прямой доступ клиентов, так и доступ через обратный прокси (например, если обратный SSL-прокси расшифровывает HTTPS-трафик). Можно отключить добавление заголовка для известного адреса или сети источника, указав ключевое слово “except”, а затем адрес сети. В этом случае заголовок не добавляется для IP-адресов источника, входящих в эту сеть. Чаще всего это применяется для частных сетей или 127.0.0.1. Поддерживаются как IPv4, так и IPv6.
Другой вариант — ключевое слово “if-none”: заголовок добавляется, только если он ещё отсутствует. Его следует использовать исключительно в полностью доверенной среде, поскольку контроль конечного пользователя над заголовками, поступающими в HAProxy, может привести к проблеме безопасности.
Эту опцию можно указать во фронтенде или бэкенде. Если она используется хотя бы в одном из них, заголовок добавляется. Если подчинённый аргумент header задан и во фронтенде, и в бэкенде, значение бэкенда имеет приоритет. Что касается аргумента “if-none”, если хотя бы один из них его не задаёт, он требует обязательного добавления заголовка, и это требование имеет приоритет.
Пример:
См. также: “option httpclose”, “option http-server-close”, “option http-keep-alive”
option h1-case-adjust-bogus-client
Включить или выключить изменение регистра заголовков HTTP/1, отправляемых некорректно работающим клиентам
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | нет
Аргументы: отсутствуют
Стандартный регистр имён заголовков отсутствует: согласно RFC7230, регистр для них не имеет значения. Поэтому приложения должны обрабатывать их без учёта регистра. Однако некоторые некорректно работающие приложения нарушают стандарты и ошибочно полагаются на регистр, чаще всего используемый браузерами. Проблема становится критической в HTTP/2: все имена заголовков должны передаваться в нижнем регистре, и HAProxy следует тому же правилу. Все имена заголовков отправляются клиентам и серверам в нижнем регистре независимо от версии HTTP.
Когда HAProxy получает ответ HTTP/1, имена его заголовков преобразуются в нижний регистр; дальнейшая обработка и отправка клиентам выполняются в этом виде. Если известно, что клиент нарушает стандарты HTTP и не может обработать ответ HAProxy, можно преобразовать имена заголовков из нижнего регистра в другой формат при формировании ответа и его отправке клиенту. Для этого нужно включить эту опцию и задать список преобразуемых заголовков глобальными директивами “h1-case-adjust” или “h1-case-adjust-file”. Это обязательно должно быть лишь временным обходным решением на период исправления клиента: клиенты, которым требуются такие меры, могут быть уязвимы к атакам с контрабандой содержимого (content smuggling), и их обязательно нужно исправить.
Учтите, что эта опция не влияет на клиентов, соблюдающих стандарты.
Если параметр включён в секции “defaults”, для отдельного экземпляра его можно отключить, добавив перед ним ключевое слово “no”.
См. также: “option h1-case-adjust-bogus-server”, “h1-case-adjust”, “h1-case-adjust-file”.
option h1-case-adjust-bogus-server
Включить или выключить изменение регистра заголовков HTTP/1, отправляемых некорректно работающим серверам
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы: отсутствуют
Стандартный регистр имён заголовков отсутствует: согласно RFC7230, регистр для них не имеет значения. Поэтому приложения должны обрабатывать их без учёта регистра. Однако некоторые некорректно работающие приложения нарушают стандарты и ошибочно полагаются на регистр, чаще всего используемый браузерами. Проблема становится критической в HTTP/2: все имена заголовков должны передаваться в нижнем регистре, и HAProxy следует тому же правилу. Все имена заголовков отправляются клиентам и серверам в нижнем регистре независимо от версии HTTP.
Когда HAProxy получает запрос HTTP/1, имена его заголовков преобразуются в нижний регистр; дальнейшая обработка и отправка серверам выполняются в этом виде. Если известно, что сервер нарушает стандарты HTTP и не может обработать запрос HAProxy, можно преобразовать имена заголовков из нижнего регистра в другой формат при формировании запроса и его отправке серверу. Для этого нужно включить эту опцию и задать список преобразуемых заголовков глобальными директивами “h1-case-adjust” или “h1-case-adjust-file”. Это обязательно должно быть лишь временным обходным решением на период исправления сервера: серверы, которым требуются такие меры, могут быть уязвимы к атакам с контрабандой содержимого (content smuggling), и их обязательно нужно исправить.
Учтите, что эта опция не влияет на серверы, соблюдающие стандарты.
Если параметр включён в секции “defaults”, для отдельного экземпляра его можно отключить, добавив перед ним ключевое слово “no”.
См. также: “option h1-case-adjust-bogus-client”, “h1-case-adjust”, “h1-case-adjust-file”.
option http-buffer-request
Включить или выключить ожидание всего тела HTTP-запроса перед продолжением обработки
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы: отсутствуют
Иногда перед принятием решения желательно дождаться тела HTTP-запроса. Например, так работает “balance url_param”. Первый вариант применения — буферизация запросов медленных клиентов перед подключением к серверу. Другой вариант — выбор маршрута по содержимому тела запроса. Эта опция, указанная во фронтенде или бэкенде, заставляет обработку HTTP ждать, пока не будет получено всё тело либо не заполнится буфер запроса. У некоторых приложений, использующих HTTP нестандартным образом и ожидающих передачу данных между фронтендом и бэкендом без буферизации, это может вызвать нежелательные побочные эффекты. Поэтому эту опцию однозначно не следует включать по умолчанию.
См. также: “option http-no-delay”, “timeout http-request”, “http-request wait-for-body”
option http-drop-request-trailers
Удалять завершающие поля HTTP (trailers) из запроса при его отправке серверу
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | нет | да
Аргументы: отсутствуют
Когда эта опция включена, все завершающие поля HTTP, обнаруженные в запросе, удаляются перед его отправкой серверу.
В RFC9110#section-6.5.1 указано, что завершающие поля можно объединять с полями заголовков. Это следует делать намеренно, но для некоторых приложений такое поведение может оказаться проблемой, особенно если злоумышленники скрывают конфиденциальные поля заголовков в завершающей части запроса, а посредники объединяют их с заголовками без специальных проверок. В этом случае в бэкенде можно включить эту опцию, чтобы удалять все завершающие поля из запросов перед их отправкой серверу.
Если параметр включён в секции “defaults”, для отдельного экземпляра его можно отключить, добавив перед ним ключевое слово “no”.
См. также: “option http-drop-response-trailers”
option http-drop-response-trailers
Удаляет завершающие поля HTTP из ответа при отправке клиенту
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | нет
Аргументы: отсутствуют
Параметр похож на “option http-drop-request-trailers”, но для удаления завершающих полей из ответов перед отправкой клиентам необходимо использовать именно его.
Если параметр включён в секции “defaults”, для отдельного экземпляра его можно отключить, добавив перед ним ключевое слово “no”.
См. также: “option http-drop-request-trailers”
option http-ignore-probes
Включает или отключает журналирование пустых соединений и тайм-аутов запросов
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | нет
Аргументы: отсутствуют
Недавно некоторые браузеры начали реализовывать возможность “pre-connect”: они заранее соединяются с недавно посещёнными сайтами на случай, если пользователь захочет зайти туда снова. В результате с сайтами устанавливается много соединений, заканчивающихся 408 Request Timeout, если тайм-аут наступает первым, либо 400 Bad Request, если браузер первым решает закрыть соединение. Они засоряют журнал и увеличивают счётчики ошибок. “option dontlognull” уже существовал, но здесь его недостаточно. Вместо этого параметр делает следующее: - не отправляет клиенту сообщения 400/408, если по соединению ничего не получено до его закрытия; - не создаёт в этом случае записей журнала; - не увеличивает никакие счётчики ошибок
Таким образом, пустое соединение молча игнорируется. Лучше не использовать параметр без очевидной необходимости: он скроет реальные проблемы. Самая частая причина отсутствия запроса и появления 408 — несогласованность MTU между клиентом и промежуточным компонентом, например VPN, блокирующим слишком большие пакеты. Обычно такие проблемы проявляются в запросах POST и GET с большими cookie. Журналы часто являются единственным способом их обнаружить.
Если параметр включён в секции “defaults”, для отдельного экземпляра его можно отключить, добавив перед ним ключевое слово “no”.
См. также: “log”, “dontlognull”, “errorfile” и раздел 8 о журналировании.
option http-keep-alive
Включает или отключает постоянные соединения HTTP между клиентом и сервером для соединений HTTP/1.x
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы: отсутствуют
По умолчанию HAProxy использует режим постоянных соединений HTTP/1.x: в каждом соединении обрабатывает запросы и ответы, оставляя соединение простаивать с обеих сторон. Режим можно изменить параметрами, например “option http-server-close” или “option httpclose”. Этот параметр возвращает режим постоянных соединений, что удобно, когда в секции defaults задан другой режим.
“option http-keep-alive” включает режим постоянных соединений HTTP на стороне клиента и сервера. Он обеспечивает наименьшую задержку на стороне клиента (в медленной сети) и самое быстрое повторное использование сеансов на стороне сервера ценой сохранения простаивающих соединений с серверами. Для малых объектов с этим параметром обычно можно достичь примерно вдвое большей интенсивности запросов, чем с “http-server-close”. Он может быть полезен главным образом в двух случаях:
- Сервер не соблюдает HTTP и аутентифицирует соединение вместо запросов (например, аутентификация NTLM).
- Стоимость установления соединения с сервером значительна по сравнению со стоимостью получения с него соответствующего объекта.
Последний случай возможен, когда сервер — быстрый статический сервер кеша.
Сейчас журналы не показывают, пришли ли запросы из одного сеанса. Указанное в журналах время приёма соответствует окончанию предыдущего запроса, а время запроса — ожиданию нового. Время запроса в постоянном соединении по-прежнему ограничено “timeout http-keep-alive” либо “timeout http-request”, если первый не задан.
Этот параметр отключает и заменяет любые ранее заданные “option httpclose” или “option http-server-close”.
См. также: “option httpclose”, “option http-server-close”, “option prefer-last-server” и “option http-pretend-keepalive”.
option http-no-delay
Предписать системе отдавать приоритет малой задержке интерактивного обмена перед производительностью HTTP
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы: отсутствуют
В HTTP каждая полезная нагрузка однонаправленная и не предполагает интерактивности. Ожидается, что любой агент в некоторой мере ставит данные в очередь с разумно малой задержкой. Некоторые очень редкие приложения обмена между серверами злоупотребляют HTTP, ожидая высокой интерактивности на этапе полезной нагрузки с множеством чередующихся фрагментов данных в обе стороны в одном запросе. Спецификация HTTP совершенно не поддерживает это, и через большинство прокси или серверов это не работает. Через HAProxy такие приложения работают, но испытывают большие задержки из-за сетевых оптимизаций, повышающих производительность: системе предписывается ждать достаточного объёма данных для отправки лишь полных пакетов. Типичные задержки — около 200 ms на полный цикл обмена. Это происходит только при ненормальном использовании. Обычные сценарии, например запросы CONNECT и WebSockets, не затрагиваются.
При наличии “option http-no-delay” во фронтенде или бэкенде соединения все такие оптимизации отключаются для максимально быстрого обмена. Работоспособность при этом не гарантируется: нарушение может возникнуть в другом месте. Но если приложение работает через HAProxy, оно будет работать максимально быстро. Этот параметр никогда не следует использовать по умолчанию и вообще не следует применять, пока не обнаружено такое ошибочное приложение. Его использование увеличивает расход пропускной способности и CPU, что может значительно снизить производительность в средах с высокой задержкой.
См. также: “option http-buffer-request”
option http-pretend-keepalive
Определить, будет ли HAProxy объявлять постоянное соединение HTTP/1.x с сервером
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы: отсутствуют
При “option http-server-close” или “option httpclose” HAProxy добавляет заголовок “Connection: close” в запрос HTTP/1.x, пересылаемый серверу. К сожалению, некоторые серверы при этом автоматически отказываются от кодирования по частям для ответов неизвестной длины, хотя эти вещи совершенно не связаны. В результате клиент или кэш может получить неполный ответ, не заметив этого, и считать его полным.
При “option http-pretend-keepalive” HAProxy даёт серверу понять, что соединение будет сохраняться открытым. Тогда сервер не переходит к описанному выше ошибочному поведению. Получив весь ответ, HAProxy закрывает соединение с сервером, как при “option httpclose”. Поэтому клиент получает нормальный ответ, а соединение на стороне сервера корректно закрывается.
Не рекомендуется включать этот параметр по умолчанию: большинство серверов эффективнее сами закрывают соединение после последнего пакета и немного раньше освобождают буферы. Дополнительный сетевой пакет также может немного снизить общую пиковую производительность. Однако при включённом параметре у HAProxy немного меньше работы. Если узкое место всей архитектуры — HAProxy, его включение может сэкономить несколько циклов CPU.
Параметр можно задавать в секциях backend и listen. Во фронтенде он игнорируется, и при запуске выдаётся предупреждение. Параметр относится к бэкенду, поэтому задавать его на фронтенде практически незачем.
Если параметр включён в секции “defaults”, для отдельного экземпляра его можно отключить, добавив перед ним ключевое слово “no”.
См. также: “option httpclose”, “option http-server-close” и “option http-keep-alive”
option http-restrict-req-hdr-names { preserve | delete | reject }
Задать политику HAProxy для имён заголовков запросов HTTP с символами вне набора “[a-zA-Z0-9-]”
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы:
Этот параметр позволяет ограничить имена заголовков запросов буквами, цифрами и дефисом ([A-Za-z0-9-]). Это может быть обязательно для взаимодействия с серверами, не соблюдающими HTTP и не обрабатывающими некоторые символы в именах заголовков. Также это может быть обязательно для приложений FastCGI: все символы имён заголовков, кроме букв и цифр, заменяются подчёркиванием (’_’). Поэтому легко смешать имена заголовков и обойти некоторые правила. Например, заголовки “X-Forwarded-For” и “X_Forwarded-For” оба преобразуются в “HTTP_X_FORWARDED_FOR” в FastCGI.
Обратите внимание: параметр вычисляется для каждого прокси после правил http-request.
option http-server-close
Включить или отключить закрытие соединений HTTP/1.x на стороне сервера
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы: отсутствуют
По умолчанию HAProxy использует режим постоянных соединений HTTP/1.x: в каждом соединении обрабатывает запросы и ответы, затем оставляет соединение простаивать с обеих сторон. Изменить режим можно параметрами вроде “option http-server-close” или “option httpclose”. Параметр “option http-server-close” включает закрытие соединения HTTP на стороне сервера, сохраняя поддержку постоянных соединений HTTP и конвейерной передачи на стороне клиента. Это обеспечивает минимальную задержку клиента в медленной сети и самое быстрое повторное использование сеансов на стороне сервера для экономии его ресурсов, как и “option httpclose”. Кроме того, серверы без поддержки постоянных соединений могут обслуживаться в этом режиме для клиентов, если соблюдают требования RFC7230. Некоторые серверы не всегда соблюдают их при “Connection: close” в запросе; тогда постоянные соединения вообще не используются. Обойти проблему позволяет “option http-pretend-keepalive”.
Сейчас журналы не показывают, пришли ли запросы из одного сеанса. Указанное в журналах время приёма соответствует окончанию предыдущего запроса, а время запроса — ожиданию нового. Время запроса в постоянном соединении по-прежнему ограничено “timeout http-keep-alive” либо “timeout http-request”, если первый не задан.
Параметр можно задать во фронтенде и в бэкенде. Он включён, если включён хотя бы во фронтенде или бэкенде данного соединения. Отключает и заменяет любые ранее заданные “option httpclose” или “option http-keep-alive”. Сочетание с другими параметрами при разных настройках фронтенда и бэкенда см. в разделе 4 («Прокси»).
Если параметр включён в секции “defaults”, для отдельного экземпляра его можно отключить, добавив перед ним ключевое слово “no”.
См. также: “option httpclose”, “option http-pretend-keepalive” и “option http-keep-alive”.
option http-use-proxy-header
Использовать нестандартный заголовок Proxy-Connection вместо Connection
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | нет
Аргументы: отсутствуют
Хотя RFC7230 явно требует от агентов HTTP/1.1 использовать заголовок Connection для указания намерения сохранять или закрывать соединения, браузеры и прокси игнорируют его для проксируемых соединений, используя вместо него недокументированный нестандартный Proxy-Connection. При установке балансировщика между браузерами и такими прокси возникает различие между тем, как HAProxy понимает обмен, и тем, о чём договорились клиент и прокси.
При задании параметра во фронтенде HAProxy может автоматически переключаться на нестандартный заголовок, если видит проксируемые запросы. Здесь так называется запрос, URI которого не начинается ни с ‘/’, ни с ‘*’. Это несовместимо с режимом туннеля HTTP. Параметр можно задавать только во фронтенде, и он влияет на запрос в течение всего времени его существования.
Кроме того, при заданном параметре запрос, требующий аутентификации, автоматически переключается на заголовки аутентификации прокси, если сам является проксируемым. Это позволяет проверять или требовать аутентификацию перед существующим прокси.
Обычно этот параметр никогда не следует использовать, кроме как перед прокси.
См. также: “option httpclose” и “option http-server-close”.
option httpchk
Включить протокол HTTP для проверок работоспособности серверов
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
По умолчанию проверки работоспособности сервера лишь пытаются установить соединение TCP. При “option httpchk” после установления TCP отправляется полный запрос HTTP. Ответы 2xx и 3xx считаются допустимыми, а все остальные, включая отсутствие ответа, означают отказ сервера.
В сочетании с директивами “http-check” можно настроить отправляемый запрос HTTP проверки работоспособности или правила сопоставления ответа. Можно также настроить последовательность send/expect, как с директивой “tcp-check” для проверок TCP.
По умолчанию для открытия соединений проверок работоспособности HTTP используется конфигурация сервера. Но параметры сервера можно переопределить правилами “http-check connect”.
Параметр “httpchk” не обязательно требует бэкенд HTTP и работает также с обычными бэкендами TCP. Это особенно полезно для проверки простых сценариев на отдельных портах через демон inetd. Но внутри всегда используется мультиплексор HTX, поэтому форматирование запроса и разбор ответа строгие.
Примеры:
См. также: “option ssl-hello-chk”, “option smtpchk”, “option mysql-check”, “option pgsql-check”, “http-check”, а также параметры сервера “check”, “port” и “inter”.
option httpclose
Включить или отключить закрытие соединений HTTP/1.x
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы: отсутствуют
По умолчанию HAProxy использует режим постоянных соединений HTTP/1.x: в каждом соединении обрабатывает запросы и ответы, затем оставляет соединение простаивать с обеих сторон. Изменить режим можно параметрами вроде “option http-server-close” или “option httpclose”.
При “option httpclose” HAProxy закрывает соединение клиента или сервера в зависимости от места настройки. Фронтенд отвечает за клиентские соединения, бэкенд — за серверные. На слушателе параметр применяется к обеим сторонам. В каждом направлении проверяется наличие заголовка “Connection: close”, и при его отсутствии он добавляется.
Параметр можно сочетать с “option http-pretend-keepalive”: тогда заголовок запроса “Connection: close” не отправляется, но соединение всё равно закрывается после получения всего ответа.
Отключает и заменяет любые ранее заданные “option http-server-close” или “option http-keep-alive”.
Если параметр включён в секции “defaults”, для отдельного экземпляра его можно отключить, добавив перед ним ключевое слово “no”.
См. также: “option http-server-close”.
option httplog [ clf ]
Включить запись запроса HTTP, состояния потока и таймеров в журнал
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | нет
Аргументы:
По умолчанию формат журнала содержит мало данных: только адреса источника и назначения и имя экземпляра. При “option httplog” каждая строка получает гораздо более подробный формат: среди прочего запрос HTTP, таймеры соединения, состояние потока, числа соединений, захваченные заголовки и cookie, имена фронтенда, бэкенда и сервера и, конечно, адрес источника и порты.
Указание только “option httplog” автоматически сбрасывает режим ‘clf’, если он был задан по умолчанию.
“option httplog” переопределяет любую ранее заданную директиву “log-format”.
См. также раздел 8 о ведении журнала.
option httpslog
Включить запись запроса HTTPS, состояния потока и таймеров в журнал
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | нет
По умолчанию формат журнала содержит мало данных: только адреса источника и назначения и имя экземпляра. При “option httpslog” каждая строка получает гораздо более подробный формат: среди прочего запрос HTTP, таймеры соединения, состояние потока, числа соединений, захваченные заголовки и cookie, имена фронтенда, бэкенда и сервера, состояния проверки сертификата SSL и рукопожатия SSL и, конечно, адрес источника и порты.
“option httpslog” переопределяет любую ранее заданную директиву “log-format”.
См. также раздел 8 о ведении журнала.
option idle-close-on-response
Не закрывать простаивающие соединения фронтенда во время мягкой остановки
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | нет
Аргументы: отсутствуют
По умолчанию простаивающие соединения закрываются при мягкой остановке. В некоторых средах клиент прокси может заранее подготовить простаивающие соединения для последующей отправки запросов. Без корректного повтора при ошибках записи это может вызвать ошибки при перезагрузке haproxy. Хотя правильной реализации следует повторять попытку при ошибках соединения или записи, параметр введён для обратной совместимости с haproxy до версии 2.4. До v2.4 haproxy ожидал последнего запроса и ответа, чтобы добавить заголовок “connection: close” перед закрытием и сообщить клиенту, что соединение больше нельзя использовать повторно.
На практике такое поведение наблюдалось в AWS с ALB перед haproxy. В результате ALB отправлял 502 при перезагрузках haproxy.
Следует учитывать, что параметр может увеличить число старых процессов, если соединения слишком долго простаивают. При частых перезагрузках может потребоваться соответствующая настройка клиентских тайм-аутов и/или “hard-stop-after”.
См. также: “timeout client”, “timeout client-fin”, “timeout http-request”, “hard-stop-after”
option independent-streams
Включить или отключить независимую обработку тайм-аутов обоих направлений
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы: отсутствуют
По умолчанию при отправке данных через сокет обновляются и тайм-аут записи, и тайм-аут чтения этого сокета: считается, что на нём есть активность, а других способов понять, следует ли ожидать данные, нет.
Хотя такое поведение подходит почти всем приложениям, иногда желательно отключить его и обновлять тайм-аут чтения только при входящих данных. Это касается потоков с большими тайм-аутами и малым объёмом обмена, например сеанса telnet. Если сервер внезапно исчезает, исходящие данные накапливаются в системных буферах сокета, оба тайм-аута правильно обновляются, а узнать, что сервер не получает данные, невозможно, поэтому тайм-аут не наступает. Но если протокол всегда возвращает отправленные данные, одного тайм-аута чтения достаточно для обнаружения проблемы. В более многословных протоколах такой проблемы нет, поскольку данные не задерживаются надолго в буферах сокета.
Во фронтенде параметр отключает обновление тайм-аута чтения при отправке данных клиенту. Вероятно, этот случай редко полезен. В бэкенде отключает обновление тайм-аута чтения при отправке серверу. Обычно это нарушает передачу больших запросов HTTP POST по медленным каналам, поэтому использовать следует осторожно.
См. также: “timeout client”, “timeout server” и “timeout tunnel”
option ldap-check
Использовать проверки работоспособности LDAPv3 для серверов
Можно использовать в следующих контекстах: tcp
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы: отсутствуют
Можно проверять правильную работу сервера с LDAPv3 вместо простого приёма соединения TCP. При включённом параметре серверу отправляется сообщение анонимной простой операции bind LDAPv3, а ответ анализируется на наличие сообщения ответа bind LDAPv3.
Сервер считается работоспособным только при значении success в resultCode ответа LDAP (http://tools.ietf.org/html/rfc4511#section-4.1.9 ).
Запись запросов bind в журнал зависит от сервера; способ настройки см. в его документации.
Пример:
См. также: “option httpchk”
option log-health-checks
Включить или отключить запись изменений состояния проверок работоспособности в журнал
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы: отсутствуют
По умолчанию неудачные проверки работоспособности журналируются при состоянии сервера UP, а успешные — при DOWN, поэтому объём дополнительной информации ограничен.
При включённом параметре журналируются любые изменения состояния проверки или работоспособности сервера. Это позволяет узнать, что перед аварией сервер иногда не проходил проверки, либо точно определить, когда он перестал возвращать допустимый статус HTTP, затем когда порт начал отклонять соединения и когда сервер совсем перестал отвечать.
Обратите внимание: изменения состояния, не вызванные проверками работоспособности, например включение или отключение через CLI, намеренно не журналируются этим параметром.
См. также: “option httpchk”, “option ldap-check”, “option mysql-check”, “option pgsql-check”, “option redis-check”, “option smtpchk”, “option tcp-check”, “log” и раздел 8 о ведении журнала.
option log-separate-errors
Изменить уровень журнала для не вполне успешных соединений
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | нет
Аргументы: отсутствуют
Иногда искать ошибки в журналах трудно. Этот параметр повышает уровень записей HAProxy с потенциально полезной информацией: ошибками, тайм-аутами, повторными попытками, повторным распределением запросов или кодами HTTP 5xx. Уровень меняется с “info” на “err”, позволяя большинству демонов syslog записывать их отдельно в другой файл. Не следует удалять их из исходного файла: иначе теряется порядок событий, содержащий очень важные сведения.
С этим параметром крупные сайты с несколькими тысячами соединений в секунду могут записывать обычный трафик в буфер с ротацией, архивируя только меньшие журналы ошибок.
См. также: “log”, “dontlognull”, “dontlog-normal” и раздел 8 о ведении журнала.
option logasap
Включить или отключить раннюю запись в журнал.
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | нет
Аргументы: отсутствуют
По умолчанию записи журнала создаются, когда все псевдонимы формата журнала и функции извлечения образцов в определении строки log-format возвращают значение либо когда поток завершается. Это позволяет встроенным строкам log-format учитывать время передачи или число байт в сообщениях журнала.
При долгих соединениях, например передаче больших файлов или RDP, запрос или соединение может появиться в журнале нескоро. С “option logasap” сообщение создаётся сразу после установления серверного соединения в режиме tcp либо после отправки сервером полных заголовков в режиме http. Журналу будет недоставать общего числа байт: оно покажет лишь данные, переданные до создания сообщения, а общее время не учтёт оставшееся время существования соединения или передачи. Для HTTP полезно захватывать заголовок ответа Content-Length, чтобы журнал хотя бы показывал ожидаемое число передаваемых байт.
Примеры:
См. также: “option httplog”, “capture response header” и раздел 8 о ведении журнала.
option mysql-check [ user <username> [ { post-41 | pre-41 | post-80 } ] ]
Использовать проверки работоспособности MySQL для серверов
Можно использовать в следующих контекстах: tcp
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
При заданном имени пользователя проверка отправляет два пакета MySQL: Client Authentication и QUIT, чтобы корректно закрыть сеанс MySQL. Затем разбирается пакет MySQL Handshake Initialization и/или Error. Это простая, но полезная проверка, не создающая на сервере ошибок или прерванных соединений. Однако нужен незаблокированный авторизованный пользователь без пароля. Для создания простого пользователя MySQL с ограниченными правами и необязательными ограничениями ресурсов:
Без имени пользователя, что устарело и не рекомендуется, проверка лишь разбирает пакет Mysql Handshake Initialization или Error, ничего не отправляя. Сообщалось, что это может вызвать блокировку при слишком частых проверках и/или недостаточном трафике. Следует проверить значение MySQL “max_connect_errors”: если после прерванного соединения новое успешно устанавливается за меньшее число попыток, чем MySQL “max_connect_errors”, счётчик ошибок узла сбрасывается в ноль. Если сервер HAProxy заблокирован, разблокировать его можно только оператором “FLUSH HOSTS”.
Следует помнить, что наличие или согласованность базы данных не проверяется. Для этого можно использовать внешнюю проверку, например через xinetd.
Проверка требует MySQL >=3.22; для более ранних версий следует использовать проверку TCP.
Принимающему серверу MySQL часто нужно видеть IP-адрес клиента, в частности для проверки прав по IP и ведения журнала соединений. По возможности разумно подставлять IP-адрес клиента при соединении с сервером через аргумент “usesrc” ключевого слова “source”. Для этого требуется сборка с поддержкой прозрачного прокси и маршрутизация сервером MySQL трафика клиента через машину HAProxy.
См. также: “option httpchk”
option nolinger
Включить или отключить немедленную очистку ресурсов сеанса после закрытия
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы: отсутствуют
Если клиент или сервер некорректно обрывает соединение, например физически отключается, срабатывают тайм-ауты и сеанс закрывается. Но в системе он некоторое время остаётся в FIN_WAIT1, занимая ресурсы и, возможно, ограничивая установление новых соединений.
В таком случае можно включить “option nolinger”, который заставляет систему немедленно удалять ожидающие данные сокета при закрытии. Отправляется TCP RST, ожидающие данные обрезаются, а сеанс сразу удаляется из системных таблиц. Клиент обычно видит усечённые ответы, если закрытие происходит с последним блоком данных, например при перенаправлении или ответе об ошибке. На стороне сервера это может сразу освободить исходные порты при пересылке клиентского прерывания в туннелях. В обоих случаях отправляется сброс TCP; поскольку сеанс сразу уничтожается, повторной передачи не будет. В сети с потерями это может усугубить проблемы, особенно если на стороне с потерями есть межсетевой экран: он может увидеть и обработать сброс, удалив свой сеанс, а затем блокировать любой дальнейший трафик этого сеанса, включая повторные передачи с другой стороны. Если другая сторона не получила сброс, она больше никогда не получит RST, а межсетевой экран может записывать в журнал множество заблокированных пакетов.
По всем этим причинам настоятельно рекомендуется НЕ использовать параметр, кроме случаев крайней необходимости как последнего средства. Обычно тайм-ауты “client-fin” или “server-fin” дают сходный результат с более надёжным поведением. В Linux также можно использовать “tcp-ut” в настройках bind или server.
Параметр можно использовать во фронтендах и бэкендах в зависимости от нужной стороны: на фронтенде для клиентов, на бэкенде для серверов. Хотя он технически поддерживается в секциях “defaults”, там его действительно нельзя использовать: он может случайно распространиться на секции, где его применять нельзя, и вызвать проблемы.
Если параметр включён в секции “defaults”, для отдельного экземпляра его можно отключить, добавив перед ним ключевое слово “no”.
См. также: “timeout client-fin”, “timeout server-fin”, ключевые слова “tcp-ut” для bind или server.
option originalto [ except <network> ] [ header <name> ]
Включить добавление заголовка X-Original-To в запросы к серверам
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы:
Поскольку HAProxy может работать прозрачно, любой запрос клиента может перенаправляться на прокси, а HAProxy может пересылать его в сложную среду SQUID, теряя узел назначения из SO_ORIGINAL_DST. Это мешает правилам доступа на основе адресов назначения. Для решения HAProxy может добавлять новый заголовок HTTP “X-Original-To” во все запросы серверу. Его значение представляет исходный IP-адрес назначения. Использование заголовка должно быть настроено так, чтобы всегда учитывалось только последнее вхождение. Обратите внимание: должно использоваться только последнее вхождение, поскольку клиент вполне может уже передать такой заголовок.
Ключевое слово “header” позволяет задать другое имя вместо “X-Original-To” по умолчанию. Это может быть полезно, если уже есть заголовок “X-Original-To” другого приложения, который нужно сохранить, либо если сервер бэкенда не использует “X-Original-To” и требует другой заголовок.
Иногда один экземпляр HAProxy обслуживает прямой доступ клиентов и доступ через обратный прокси, например SSL-прокси для расшифровки HTTPS. Добавление заголовка можно отключить для известного адреса или сети назначения, задав “except” и адрес сети. Тогда для любого IP назначения, соответствующего сети, заголовок не добавляется. Чаще всего используются частные сети или 127.0.0.1. Поддерживаются IPv4 и IPv6.
Параметр можно задать во фронтенде или бэкенде. Если его использует хотя бы один из них, заголовок добавляется. Если оба задают вложенный аргумент header, значение бэкенда имеет приоритет над значением фронтенда.
Примеры:
См. также: “option httpclose”, “option http-server-close”.
option persist
Включить или отключить принудительное сохранение привязки к неработающим серверам
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы: отсутствуют
Если запрос HTTP приходит в бэкенд с cookie, указывающим на неработающий сервер, по умолчанию он перераспределяется другому серверу. При крайней необходимости “option persist” позволяет сначала принудительно отправить его неработающему серверу. Частый случай — чрезвычайная нагрузка и постоянные переключения состояния серверов. Тогда пользователи всё равно направляются серверу, на котором открыли сеанс, в надежде на корректное обслуживание. Рекомендуется вместе использовать “option redispatch”: если соединиться совсем невозможно и сервер окончательно не работает, клиент в итоге перенаправляется другому работоспособному серверу.
Если параметр включён в секции “defaults”, для отдельного экземпляра его можно отключить, добавив перед ним ключевое слово “no”.
См. также: “option redispatch”, “retries”, “force-persist”
option pgsql-check user <username>
Использовать проверки работоспособности PostgreSQL для серверов
Можно использовать в следующих контекстах: tcp
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
Проверка отправляет PostgreSQL StartupMessage и ждёт запрос Authentication либо сообщение ErrorResponse. Это простая, но полезная проверка, не создающая на сервере ошибок или прерванных соединений. Она идентична “mysql-check”.
См. также: “option httpchk”
option prefer-last-server
Позволить нескольким балансируемым запросам оставаться на одном сервере
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы: отсутствуют
Если используемый алгоритм балансировки недетерминированный и предыдущий запрос отправлен серверу, соединение с которым ещё сохраняется у HAProxy, иногда желательно по возможности направлять последующие запросы того же сеанса этому серверу. Это отличается от привязки сеанса: задаётся лишь предпочтение, которое HAProxy пытается соблюсти без каких-либо гарантий. Основное применение — постоянные соединения с серверами. HAProxy пытается повторно использовать то же соединение с сервером вместо перераспределения другому серверу с закрытием соединения. Это разумно для серверов статических файлов и мало полезно вместе с алгоритмами хеширования. При недетерминированном алгоритме HAProxy уже автоматически пытается сохранять привязку к серверу с ответом 401 или прокси с 407, требующим аутентификации. Это обязательно для работы с некорректным механизмом запроса аутентификации NTLM и значительно помогает при устранении неполадок ошибочных приложений. Параметр option prefer-last-server тоже может быть полезен в таких средах, чтобы не перераспределять трафик после каждого иного ответа.
Полезно уточнить, какие алгоритмы считаются детерминированными. Они всегда выбирают один сервер для заданных данных клиента, если набор доступных серверов не изменился. Обычно для выбора используются хеширование или поиск по входящим запросам, но не всегда: “static-rr” тоже можно считать детерминированным, поскольку выбор основан на статическом весе сервера и предсказуем. Алгоритм “sticky” обеспечивает детерминированную маршрутизацию для возвращающихся клиентов.
Недетерминированные алгоритмы выбирают сервер по динамическому состоянию серверов или простому циклическому обходу, поэтому два последовательных запроса не обязательно попадут на один сервер. Именно для них предназначен option prefer-last-server. Примеры — roundrobin и leastconn.
Если параметр включён в секции “defaults”, для отдельного экземпляра его можно отключить, добавив перед ним ключевое слово “no”.
См. также: “option http-keep-alive”
option redispatch
Включить или отключить перераспределение сеансов при неудачном соединении
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
В режиме HTTP, если сервер из cookie не работает, клиенты могут окончательно остаться привязанными к нему, например при “option persist” или “force-persist”, поскольку не могут сбросить cookie и больше не получат доступ к службе.
Параметр “option redispatch” позволяет прокси нарушить привязку на основе cookie или консистентного хеширования и перераспределить клиентов работоспособному серверу.
Активные серверы выбираются из подмножества доступных. Активные серверы, которые не отказали и не находятся в режиме обслуживания, то есть серверы без проверок работоспособности либо проверенные как “up”, выбираются в следующем порядке:
При повторной попытке HAProxy старается выбрать другой сервер вместо предыдущего. Новый сервер выбирается из текущего списка серверов.
Однако если между повторными попытками список обновится, соединения иногда могут быть перенаправлены на резервный сервер. Например, многочисленные попытки могут длиться дольше, чем требуется для обнаружения отказа сервера, удаления его из списка и перехода к списку резервных серверов.
Это также позволяет при нескольких неудачах установления соединения повторить попытку на другом сервере. Разумеется, для этого “retries” должен иметь ненулевое значение.
Если параметр включён в секции “defaults”, для отдельного экземпляра его можно отключить, добавив перед ним ключевое слово “no”.
См. также: “option persist”, “force-persist”, “retries”
option redis-check
Использует проверки работоспособности redis для проверки серверов
Можно использовать в следующих контекстах: tcp
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы: отсутствуют
Можно проверить, правильно ли сервер работает по протоколу REDIS, вместо простой проверки принятия соединения TCP. При включённом параметре серверу отправляется команда redis PING, затем ответ анализируется на наличие сообщения “+PONG”.
Пример:
См. также: “option httpchk”, “option tcp-check”, “tcp-check expect”
option smtpchk
Использует проверки работоспособности SMTP для проверки серверов
Можно использовать в следующих контекстах: tcp
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
При “option smtpchk” проверки работоспособности состоят из установления соединения TCP и последующей команды SMTP. По умолчанию это “HELO localhost”. Анализируется код возврата сервера: допустимыми считаются только коды, начинающиеся с “2”. Все остальные ответы, включая отсутствие ответа, считаются ошибкой и означают неработающий сервер.
Эта проверка предназначена для серверов или ретрансляторов SMTP. В зависимости от запроса некоторые серверы могут не журналировать каждую попытку соединения; можно поэкспериментировать для улучшения поведения. Часто проще воспользоваться telnet на порту 25, чем менять конфигурацию.
Входящему серверу SMTP чаще всего нужен адрес IP клиента для разных целей, включая фильтрацию спама, защиту от подмены и журналирование. Когда это возможно, при соединении с сервером часто целесообразно подставлять адрес IP клиента с помощью аргумента “usesrc” ключевого слова “source”. Для этого поддержка прозрачного прокси должна быть включена при сборке.
Пример:
См. также: “option httpchk”, “source”
Включает или отключает сбор и предоставление отдельной статистики для каждого сокета.
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | нет
Аргументы: отсутствуют
option splice-auto
Включает или отключает автоматическое ускорение сокетов ядром в обоих направлениях
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы: отсутствуют
При включении параметра во фронтенде или бэкенде HAProxy автоматически оценивает целесообразность использовать механизм TCP splicing ядра для пересылки данных между клиентом и сервером в каждом направлении. Эвристики HAProxy оценивают, может ли этот механизм повысить производительность. Оба направления обрабатываются независимо. Эвристики не слишком агрессивны, чтобы ограничить чрезмерное использование splicing. Его поддержка должна быть включена при сборке; глобальный параметр “nosplice” позволяет отключить её глобально. Поскольку splice использует каналы, требуется достаточное число свободных каналов.
Важное примечание: TCP splicing на уровне ядра — возможность только Linux, впервые появившаяся в ядре 2.6.25. Она ускоряет передачу данных между сокетами без копирования в пространство пользователя, заметно повышая производительность и экономя циклы CPU. Во многих ранних реализациях есть ошибки, приводящие к повреждению данных и/или низкой эффективности. Поэтому возможность по умолчанию выключена и использовать её следует крайне осторожно. Проверить корректность реализации невозможно, но 2.6.29 — первая версия с правильно работающей реализацией. При сомнениях splicing можно отключить глобально ключевым словом “nosplice”.
Пример:
Если параметр включён в секции “defaults”, в отдельном экземпляре его можно отключить, добавив перед ним ключевое слово “no”.
См. также: “option splice-request”, “option splice-response” и глобальные параметры “nosplice” и “maxpipes”
option splice-request
Включает или отключает автоматическое ускорение сокетов ядром для запросов
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы: отсутствуют
При включении параметра во фронтенде или бэкенде HAProxy по возможности использует механизм TCP splicing ядра для пересылки данных от клиента к серверу. Если свободных каналов не осталось, он может по-прежнему использовать схему recv/send. Поддержка splicing должна быть включена при сборке; глобальный параметр “nosplice” позволяет отключить её глобально. Поскольку splice использует каналы, требуется достаточное число свободных каналов.
Важное примечание: ограничения применения см. в “option splice-auto”.
Пример:
Если параметр включён в секции “defaults”, в отдельном экземпляре его можно отключить, добавив перед ним ключевое слово “no”.
См. также: “option splice-auto”, “option splice-response” и глобальные параметры “nosplice” и “maxpipes”
option splice-response
Включает или отключает автоматическое ускорение сокетов ядром для ответов
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы: отсутствуют
При включении параметра во фронтенде или бэкенде HAProxy по возможности использует механизм TCP splicing ядра для пересылки данных от сервера к клиенту. Если свободных каналов не осталось, он может по-прежнему использовать схему recv/send. Поддержка splicing должна быть включена при сборке; глобальный параметр “nosplice” позволяет отключить её глобально. Поскольку splice использует каналы, требуется достаточное число свободных каналов.
Важное примечание: ограничения применения см. в “option splice-auto”.
Пример:
Если параметр включён в секции “defaults”, в отдельном экземпляре его можно отключить, добавив перед ним ключевое слово “no”.
См. также: “option splice-auto”, “option splice-request” и глобальные параметры “nosplice” и “maxpipes”
option spop-check
Использует проверки работоспособности SPOP для проверки серверов
Можно использовать в следующих контекстах: tcp
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы: отсутствуют
Можно проверить, правильно ли сервер работает по протоколу SPOP, вместо простой проверки принятия соединения TCP. При включённом параметре между HAProxy и сервером выполняется рукопожатие HELLO, затем ответ анализируется, чтобы убедиться в отсутствии сообщения об ошибке.
Пример:
См. также: “option httpchk”
option srvtcpka
Включает или отключает отправку пакетов TCP для поддержания соединения на стороне сервера
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы: отсутствуют
Если между клиентом и сервером находится межсетевой экран или другой компонент, учитывающий состояние сеанса, а протокол предполагает очень долгие сеансы с длительными периодами простоя (например, удалённые рабочие столы), один из промежуточных компонентов может решить, что слишком долго простаивавший сеанс истёк.
Включение поддержания соединений TCP на уровне сокета заставляет систему регулярно отправлять пакеты на другой конец соединения, сохраняя его активным. Интервал между проверочными пакетами задаётся только системой и зависит от операционной системы и её настроек.
Важно понимать, что пакеты поддержания соединения не отправляются и не принимаются на уровне приложения: их видят только сетевые стеки. Поэтому даже если одна сторона прокси уже использует такие пакеты для сохранения соединения, они не пересылаются на другую сторону прокси.
Это никак не связано с постоянными соединениями HTTP.
Параметр “srvtcpka” включает отправку проверочных пакетов TCP для поддержания соединения на серверной стороне. Это должно помочь, когда наблюдается истечение сеансов между HAProxy и сервером.
Если параметр включён в секции “defaults”, для отдельного экземпляра его можно отключить, добавив перед ним ключевое слово “no”.
См. также: “option clitcpka”, “option tcpka”
option ssl-hello-chk
Использует проверки работоспособности с сообщением client hello SSLv3 для проверки серверов
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы: отсутствуют
При передаче некоторых протоколов на основе SSL через HAProxy в режиме TCP можно проверить, правильно ли сервер работает с SSL, вместо простой проверки принятия соединения TCP. При “option ssl-hello-chk” после установления соединения серверу отправляются чистые сообщения client hello SSLv3, затем ответ анализируется на наличие сообщения server hello SSL. Сервер считается пригодным только при наличии этого сообщения server hello в ответе.
Все проверенные до сих пор серверы правильно отвечают на сообщения client hello SSLv3. Большинство проверенных серверов даже не журналируют запросы, содержащие только сообщения hello, что удобно.
Проверка работает даже при сборке HAProxy без поддержки SSL, поскольку сама формирует сообщение SSL. Если поддержка SSL доступна, лучше использовать собственные проверки работоспособности SSL вместо этой.
См. также: “option httpchk”, “check-ssl”
option tcp-check
Выполняет проверки работоспособности последовательностями tcp-check send/expect
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Этот способ проверки работоспособности предназначен для сочетания со списками команд “tcp-check”, чтобы поддерживать последовательности проверок типа send/expect.
Проверки TCP сейчас поддерживают 4 режима работы: - без директивы “tcp-check” проверка состоит только из попытки соединения; это по-прежнему режим по умолчанию.
- Указаны только "tcp-check send" или "tcp-check send-binary": при открытии соединения отправляется строка. В некоторых протоколах это позволяет, например, отправить "QUIT", чтобы сервер не журналировал ошибку соединения при каждой проверке работоспособности. Результат проверки по-прежнему основан только на возможности открыть соединение.
- Указан только "tcp-check expect": проверяется приветствие сервера. Соединение открывается, и HAProxy ждёт содержимого от сервера, которое должно удовлетворять правилам. Результат проверки основан на совпадении содержимого с правилами. Подходит для POP, IMAP, SMTP, FTP, SSH, TELNET.
- Указаны и "tcp-check send", и "tcp-check expect": проверяется протокол с обменом приветствиями. HAProxy отправляет сообщение, сервер отвечает, затем ответ анализируется. Результат проверки основан на совпадении содержимого ответа с правилами. Часто подходит для протоколов, требующих привязки или модели запрос/ответ. Примеры — LDAP, MySQL, Redis и SSL, хотя для каждого уже есть специальные проверки с более глубоким пониманием соответствующего протокола. В этом режиме можно отправлять много запросов и анализировать много ответов.
Пятый режим позволяет вставлять комментарии на разных шагах сценария.
В каждое создаваемое правило tcp-check можно добавить директиву “comment” со строкой. Эта строка выводится в журнал и stderr в режиме отладки, что помогает делать сообщения об ошибках понятными пользователю. Разумеется, “comment” необязателен.
Во время проверки работоспособности доступна область видимости переменных для хранения образцов данных с помощью операции “tcp-check set-var”. Освобождать эти переменные можно через “tcp-check unset-var”.
Примеры:
См. также: “tcp-check connect”, “tcp-check expect” и “tcp-check send”.
option tcp-smart-accept
Включает или отключает экономию одного пакета ACK при принятии соединения
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | нет
Аргументы: отсутствуют
Когда приходит запрос на соединение HTTP, система подтверждает его от имени HAProxy. Затем клиент сразу отправляет запрос, который система также подтверждает, уведомляя HAProxy о новом соединении. HAProxy читает запрос и отвечает. Таким образом, система отправляет один лишний пакет ACK TCP: запрос мог бы быть подтверждён ответом HAProxy.
Поэтому в режиме HTTP HAProxy автоматически просит систему не отправлять этот бесполезный ACK на поддерживающих это платформах (сейчас по крайней мере Linux). Это не должно создавать проблем: если ответ задерживается дольше ожидаемого, система всё равно отправит ACK через 40 ms.
При сложной отладке сети может быть желательно отключить эту оптимизацию: задержанные ACK усложняют поиск мест задержки пакетов. Чтобы вернуться к обычному поведению, можно указать “no option tcp-smart-accept”.
Можно также принудительно включить её для прокси, работающих не с HTTP, просто указав “option tcp-smart-accept”. Например, это может быть полезно для некоторых служб, таких как SMTP, где сервер начинает обмен первым.
Рекомендуется не включать этот параметр принудительно в секции defaults. При сомнениях можно вернуть автоматическое значение, добавив перед ним ключевое слово “default”, либо отключить его ключевым словом “no”.
См. также: “option tcp-smart-connect”
option tcp-smart-connect
Включает или отключает экономию одного пакета ACK при установлении соединения
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы: отсутствуют
В некоторых системах (по крайней мере Linux) HAProxy может попросить ядро не отправлять сразу пустой ACK при запросе на соединение, а непосредственно отправить буферизованный запрос. Это экономит один сетевой пакет и повышает производительность. Может быть полезно и некоторым серверам: они сразу получают запрос вместе с входящим соединением.
Возможность включается при заданном “option tcp-smart-connect” в бэкенде. По умолчанию она выключена, поскольку усложняет отладку сети.
Её имеет смысл включать только для протоколов, где клиент начинает обмен первым, например HTTP. В остальных случаях при отсутствии данных для отправки вместо ACK отправляется обычный ACK.
Если параметр включён в секции “defaults”, для отдельного экземпляра его можно отключить, добавив перед ним ключевое слово “no”.
См. также: “option tcp-smart-accept”
option tcpka
Включает или отключает отправку пакетов TCP для поддержания соединения с обеих сторон
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы: отсутствуют
Если между клиентом и сервером находится межсетевой экран или другой компонент, учитывающий состояние сеанса, а протокол предполагает очень долгие сеансы с длительными периодами простоя (например, удалённые рабочие столы), один из промежуточных компонентов может решить, что слишком долго простаивавший сеанс истёк.
Включение поддержания соединений TCP на уровне сокета заставляет систему регулярно отправлять пакеты на другой конец соединения, сохраняя его активным. Интервал между проверочными пакетами задаётся только системой и зависит от операционной системы и её настроек.
Важно понимать, что пакеты поддержания соединения не отправляются и не принимаются на уровне приложения: их видят только сетевые стеки. Поэтому даже если одна сторона прокси уже использует такие пакеты для сохранения соединения, они не пересылаются на другую сторону прокси.
Это никак не связано с постоянными соединениями HTTP.
Параметр “tcpka” включает отправку проверочных пакетов TCP для поддержания соединения на клиентской и серверной сторонах. Это имеет смысл только в секциях “defaults” или “listen”. Во фронтенде такие пакеты получает только клиентская сторона, в бэкенде — только серверная. Поэтому при разделении конфигурации на фронтенды и бэкенды настоятельно рекомендуется явно использовать “option clitcpka” и “option srvtcpka”.
См. также: “option clitcpka”, “option srvtcpka”
option tcplog [clf]
Включает подробное журналирование соединений TCP с состоянием потока и таймерами
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | нет
Аргументы:
По умолчанию формат журнала очень беден: он содержит только исходный адрес, адрес назначения и имя экземпляра. “option tcplog” делает каждую строку гораздо богаче: она включает, помимо прочего, таймеры соединения, состояние потока, число соединений, имена фронтенда, бэкенда и сервера, а также, конечно, исходный адрес и порты. Параметр полезен для чистых прокси TCP, чтобы определить, кто — клиент или сервер — разрывает соединение либо достигает тайм-аута. Для обычных прокси HTTP лучше использовать ещё более полный “option httplog”.
“option tcplog” переопределяет любую предыдущую директиву “log-format”.
См. также: “option httplog” и раздел 8 о журналировании.
option transparent (deprecated)
Включает прозрачное проксирование на стороне клиента
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы: отсутствуют
Параметр появился для предоставления привязки сеанса уровня 7 балансировщикам нагрузки уровня 3. Идея — использовать способность операционной системы (OS) перенаправлять входящее соединение к удалённому адресу в локальный процесс (здесь HAProxy) и сообщать ему первоначально запрошенный адрес. При включённом параметре сеансы без cookie пересылаются на исходный адрес IP назначения входящего запроса (который, как ожидается, соответствует адресу другого оборудования), а запросы с cookie по-прежнему пересылаются подходящему серверу.
Вопреки распространённому мнению, этот параметр НЕ заставляет HAProxy представлять серверу адрес IP клиента при установлении соединения.
Начиная с 3.3 параметр устарел из-за ряда внутренних технических ограничений. Его использование вызывает предупреждение; при действительной необходимости его можно убрать глобальным ключевым словом “expose-deprecated-directives”.
Правильный подход — объявить сервер с адресом 0.0.0.0: он обеспечит соединение с ожидаемым адресом назначения. Сервер также правильно обрабатывает простаивающие соединения с целевыми серверами.
Пример:
См. также: аргумент “usesrc” ключевого слова “source” и параметр “transparent” ключевого слова “bind”.
option use-small-buffers [ queue | l7-retries | check ]*
Включает поддержку малых буферов для указанных категорий.
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Параметр позволяет включить поддержку малых буферов в разных местах для экономии памяти. По умолчанию, без параметров, малые буферы используются везде, где это возможно. Иначе их применение можно ограничить следующими местами:
- queue: При включении малые буферы хранят запросы, если те достаточно малы, пока соединение находится в очереди.
- l7-retries: При включении малые буферы сохраняют запросы при включённых повторных попытках L7.
- check: При включении малые буферы используются для запросов проверок работоспособности.
При включённой возможности малые буферы используются лишь там, где это возможно. Если данные слишком велики, автоматически используется обычный буфер. Размер малых буферов настраивается глобальным параметром “tune.bufsize.small”.
Если параметр включён в секции “defaults”, для отдельного экземпляра его можно отключить, добавив перед ним ключевое слово “no”.
См. также: tune.bufsize.small
persist rdp-cookie
Включает привязку сеанса на основе cookie RDP
Можно использовать в следующих контекстах: tcp
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
Эта директива включает привязку сеанса на основе cookie RDP. Cookie RDP содержит всю информацию, необходимую для поиска сервера в списке известных серверов. Поэтому при включённом параметре в бэкенде запрос анализируется; найденный cookie RDP декодируется. Если он соответствует известному серверу, который по-прежнему находится в состоянии UP (или включён “option persist”), соединение пересылается этому серверу.
Это имеет смысл только в бэкенде TCP, но для работы фронтенд должен ждать достаточно долго, чтобы cookie RDP присутствовал в буфере запроса. Такое же требование действует для метода балансировки “rdp-cookie”. Поэтому настоятельно рекомендуется поместить все директивы в одну секцию “listen”.
Также важно понимать, что терминальный сервер отправит cookie RDP только при настройке «режима перенаправления по токену», то есть при отключённом параметре «перенаправление по адресу IP».
Пример:
См. также: “balance rdp-cookie”, “tcp-request” и ACL “req.rdp_cookie”.
quic-initial <action> [ { if | unless } <condition> ]
Выполняет действие над входящим пакетом QUIC Initial. В отличие от “tcp-request connection”, оно выполняется до создания любого элемента соединения, а также до начала и завершения рукопожатия SSL. Это эффективнее при отклонении попыток соединения.
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да(!) | да | да | нет
Аргументы:
Действие выполняется в начале разбора пакета QUIC. Поэтому поддерживается лишь минимальный список действий: - accept - dgram-drop - reject - send-retry
rate-limit sessions <rate>
Ограничивает число новых сеансов, принимаемых фронтендом за секунду
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | нет
Аргументы:
Когда фронтенд достигает указанного числа новых сеансов в секунду, он перестаёт принимать новые соединения, пока частота снова не опустится ниже предела. В это время ожидающие сеансы остаются в очереди сокета backlog (в системных буферах), и HAProxy даже не знает об их ожидании. При очень низком пределе для сильно нагруженной службы может быть целесообразно увеличить очередь сокета ключевым словом “backlog”.
Возможность особенно эффективна против атак на основе соединений или злоупотребления службой на уязвимых серверах. Частота сеансов измеряется каждую миллисекунду, поэтому точность чрезвычайно высока. Ограничение также применяется немедленно: для обнаружения порога задержка вообще не нужна.
Пример: ограничить частоту соединений SMTP максимум 10 в секунду.
Примечание: при достижении максимальной частоты состояние фронтенда не меняется, но при включённом “socket-stats” его сокеты отображаются в статистике как “WAITING”.
См. также: ключевое слово “backlog” и критерий ACL “fe_sess_rate”.
redirect location <loc> [code <code>] <option> [{if | unless} <condition>]
Возвращает перенаправление HTTP при выполнении/невыполнении условия
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend нет | да | да | да
При выполнении/невыполнении условия запрос HTTP приводит к ответу с перенаправлением. Если условие не задано, перенаправление применяется безусловно.
Аргументы:
Пример: перевести только URL входа на HTTPS.
Пример: перенаправлять запросы статей без завершающего ‘/’.
Пример: перенаправлять весь трафик HTTP на HTTPS, когда HAProxy обрабатывает SSL.
Пример: добавлять префикс ‘www.’ перед всеми хостами, у которых его нет.
Пример: постоянно перенаправлять только старые URL на новые.
Об использовании ACL см. раздел 7 .
retries <value>
Задаёт число повторных попыток обращения к серверу после неудачи
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
По умолчанию повторяются только попытки установить новое соединение. Однако с директивой “retry-on” повторную попытку могут вызывать и другие условия, например пустой ответ или нежелательный код состояния. Каждое из них учитывается как одна попытка; когда общее число попыток достигает заданного здесь значения, возвращается ошибка.
Чтобы не устанавливать соединение повторно немедленно с перезапускающимся сервером, перед повторной попыткой обращения к тому же серверу вводится задержка min(“timeout connect”, одна секунда).
При “option redispatch” некоторые повторные попытки могут выполняться на другом сервере, даже если cookie указывает на иной сервер. По умолчанию это только последняя повторная попытка, если “option redispatch” не передан аргумент.
См. также: “option redispatch”
retry-on [space-delimited list of keywords]
Задаёт условия автоматического повторения неудачного запроса. Настройка действует только при “mode”, равном http; иначе молча игнорируется.
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
Эта директива заменяет предыдущие настройки новыми; они не накапливаются.
Любое значение, кроме “none” и “conn-failure”, требует выделить буфер и скопировать туда весь запрос, что влияет на память и производительность. Запросы, не помещающиеся в один буфер, никогда не повторяются (см. глобальный tune.bufsize).
Необходимо убедиться, что приложение защищено от повторного выполнения, например уникальными IDs транзакций, передаваемыми в запросах, либо что повторение того же запроса не имеет последствий. Иначе любое значение retry-on, кроме “conn-failure” и “none”, очень опасно. Серверы статических файлов и кеши обычно считаются безопасными для любых повторных попыток. Код состояния может помочь быстро уйти от сервера с ненормальным поведением, например нехваткой памяти или проблемами файловой системы. В таком случае может быть целесообразно немедленно перераспределить соединение на другой сервер (см. “option redispatch”). Наконец, большинство неудач вызвано самими запросами: повторение запроса, нарушающего работу сервера, часто ещё больше ухудшает состояние этого сервера, а при перераспределении — всей службы.
Если нет точного понимания того, как приложение обрабатывает повторяемые запросы, эту директиву не следует использовать.
Значение по умолчанию — “conn-failure”.
Пример:
См. также: “retries”, “option redispatch”, “tune.bufsize”
server <name> <address>[:[port]] [param*]
Объявляет сервер в бэкенде
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend нет | нет | да | да
Аргументы:
Примеры:
Примечание: для сокетов “abns” HAProxy в абстрактном пространстве имён Linux длина адреса равна полной длине sun_path. Некоторые другие программы, например socat, по умолчанию используют только длину строки. Чтобы определение абстрактного сокета в socat было совместимо с сокетами HAProxy, к нему нужно добавить параметр “,unix-tightsocklen=0”; другой вариант — использовать семейство сокетов “abnsz” HAProxy.
См. также: “default-server”, “http-send-name-header” и раздел 5 о параметрах серверов
server-state-file-name [ { use-backend-name | <file> } ]
Задаёт файл состояния серверов, который читается, загружается и применяется к серверам этого бэкенда.
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend нет | нет | да | да
Действует только при “load-server-state-from-file”, равном “local”. Если <file> отсутствует, указан “use-backend-name” либо директива не задана, используется имя бэкенда. <file>, начинающийся с ‘/’, считается абсолютным путём; иначе <file> присоединяется к глобальной директиве “server-state-base”.
Пример: приведённая ниже минимальная конфигурация заставит HAProxy искать файл состояния серверов ‘/etc/haproxy/states/bk’:
global
server-state-file-base /etc/haproxy/states
backend bk
load-server-state-from-file
См. также: “server-state-base”, “load-server-state-from-file” и “show servers state”
server-template <prefix> <num | range> <fqdn>[:<port>] [params*]
Задаёт шаблон инициализации серверов с общими параметрами. Имена серверов строятся из <prefix> и <num | range>.
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend нет | нет | да | да
Аргументы:
Примеры:
source <addr>[:<port>] [usesrc { <addr2>[:<port2>] | client | clientip } ]
Задаёт исходный адрес для исходящих соединений
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
Ключевое слово “source” полезно в сложных окружениях, где соединяться с серверами разрешено только с определённого адреса. Например, оно может понадобиться, когда через общедоступный шлюз необходимо использовать частный адрес и известно, что система не может сама определить подходящий исходный адрес.
Расширение, доступное в некоторых ядрах Linux с дополнительными исправлениями, можно использовать через необязательное ключевое слово “usesrc”. Оно позволяет соединяться с серверами с адресом IP, не принадлежащим самой системе. Это называется «режимом полностью прозрачного прокси». Для работы этого режима серверы назначения должны направлять ответный трафик к этому адресу через машину с HAProxy; на ней обычно необходимо включить пересылку IP.
В режиме «полностью прозрачного прокси» можно принудительно представлять серверам определённый адрес IP. На практике это используется редко. Чаще HAProxy поручают представлять адрес IP клиента. Для этого есть два способа:
- Представлять адрес IP и порт клиента. Это наиболее прозрачный режим, но при включённом отслеживании соединений IP на машине он может создавать проблемы: одно соединение может наблюдаться дважды с разными состояниями. Однако у этого решения есть большое преимущество: система не ограничена 64k исходящих пар «адрес + порт», поскольку можно использовать все диапазоны клиентов.
- Представлять только адрес IP клиента и выбирать свободный порт. Решение по-прежнему достаточно изящно, но чуть менее прозрачно: журналы нижестоящих межсетевых экранов не будут соответствовать журналам вышестоящих. Недостаток — число одновременных соединений ограничено обычными 64k портов. Однако поскольку порты до и после прокси различаются, повторное использование той же сессии не нарушает локальное отслеживание соединений IP на машине.
Этот параметр задаёт исходный адрес по умолчанию для всех серверов бэкенда. Его можно также указать в секции “defaults”. Для более точного задания исходного адреса на уровне сервера служит серверный параметр “source”. Подробнее см. раздел 5 .
Для работы “usesrc” нужны привилегии root либо, на поддерживающих это системах, специальное право “cap_net_raw”. См. также глобальную директиву “setcap”.
Примеры:
См. также: параметр сервера “source” в разделе 5 , патчи Tproxy для ядра Linux на www.balabit.com , ключевое слово “bind”.
srvtcpka-cnt <count>
Задаёт максимальное число проверочных пакетов для поддержания соединения, которые TCP должен отправить до разрыва соединения на стороне сервера.
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
Это ключевое слово соответствует параметру сокета TCP_KEEPCNT. Если оно не указано, используется общесистемный параметр TCP (tcp_keepalive_probes). Доступность этой настройки зависит от операционной системы. Известно, что она работает в Linux.
См. также: “option srvtcpka”, “srvtcpka-idle”, “srvtcpka-intvl”.
srvtcpka-idle <timeout>
Задаёт время простоя соединения, после которого TCP начинает отправлять проверочные пакеты для поддержания соединения, если отправка пакетов TCP для поддержания соединения на стороне сервера включена.
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
Это ключевое слово соответствует параметру сокета TCP_KEEPIDLE. Если оно не указано, используется общесистемный параметр TCP (tcp_keepalive_time). Доступность этой настройки зависит от операционной системы. Известно, что она работает в Linux.
См. также: “option srvtcpka”, “srvtcpka-cnt”, “srvtcpka-intvl”.
srvtcpka-intvl <timeout>
Задаёт интервал между отдельными проверочными пакетами для поддержания соединения на стороне сервера.
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
Это ключевое слово соответствует параметру сокета TCP_KEEPINTVL. Если оно не указано, используется общесистемный параметр TCP (tcp_keepalive_intvl). Доступность этой настройки зависит от операционной системы. Известно, что она работает в Linux.
См. также: “option srvtcpka”, “srvtcpka-cnt”, “srvtcpka-idle”.
stats admin { if | unless } <cond>
Включает административный уровень статистики при выполнении/невыполнении условия
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend нет | да | да | да
Эта директива включает административный уровень статистики при выполнении/невыполнении условия.
Административный уровень позволяет включать и отключать серверы через веб-интерфейс. По соображениям безопасности страница статистики по умолчанию доступна только для чтения. Если в секции заданы директивы “stats scope”, изменения состояния будут принимать только указанные ими прокси; доступ к остальным будет запрещён.
Сейчас размер запроса POST ограничен размером буфера за вычетом зарезервированного пространства. Поэтому при слишком длинном списке серверов запрос не будет обработан. Рекомендуется менять лишь несколько серверов за один раз.
Эти административные запросы POST уязвимы для атак CSRF. Риск частично снижается проверкой совпадения Origin (или Referer, если Origin отсутствует) с заголовком Host, но этого недостаточно для полного предотвращения атаки. Полностью защититься от таких атак невозможно. Рекомендуется не предоставлять этот интерфейс в публичный доступ и ограничивать круг тех, кто может им пользоваться.
Пример:
Пример:
Пример:
См. также: “stats enable”, “stats auth”, “stats http-request”, “stats scope”, раздел 12.2 о списках пользователей и раздел 7 об использовании ACL.
ssl-f-use [<sslbindconf> ...]*
Назначает сертификат текущему фронтенду.
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend нет | да | да | нет
Аргументы:
Назначает сертификат <crtname> автоматически созданному crt-list с именем фронтенда и префиксом @ (например, ‘@frontend1’).
Этот неявный crt-list назначается всем строкам bind с “ssl” в текущем фронтенде.
Команды crt-list, выполняемые через сокет статистики, действуют на этот crt-list, поэтому в нём можно заменять, удалять и добавлять сертификаты и параметры SSL.
Пример:
См. также: “crt-list” и “crt”.
stats auth <user>:<passwd>
Включает статистику с аутентификацией и предоставляет доступ учётной записи
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы:
Эта директива включает статистику с настройками по умолчанию и разрешает доступ только объявленным пользователям. Её можно повторить столько раз, сколько необходимо, чтобы добавить нужное число пользователей. При попытке доступа к статистике без действительной учётной записи возвращается ответ “401 Forbidden”, чтобы браузер запросил действительное имя пользователя и пароль. Область аутентификации, возвращаемая браузеру, настраивается через “stats realm”.
Поскольку используется базовая аутентификация HTTP (Basic Authentication), пароли передаются по сети в открытом виде. Поэтому было решено и в конфигурационном файле использовать открытые пароли: это напоминает пользователям, что здесь не следует использовать конфиденциальные пароли или пароли от других учётных записей.
Можно также ограничить набор прокси, отображаемых в отчёте, с помощью “stats scope”.
Хотя одной этой директивы достаточно для включения статистики, рекомендуется задать все остальные настройки, чтобы не полагаться на неочевидные параметры по умолчанию.
Пример:
См. также: “stats enable”, “stats realm”, “stats scope”, “stats uri”
stats enable
Включает статистику с настройками по умолчанию
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы: отсутствуют
Эта директива включает статистику с настройками по умолчанию, заданными при сборке. Если не указано иное, используются: - stats uri : /haproxy?stats - stats realm: “HAProxy Statistics” - stats auth : без аутентификации - stats scope: без ограничений
Хотя одной этой директивы достаточно для включения статистики, рекомендуется задать все остальные настройки, чтобы не полагаться на неочевидные параметры по умолчанию.
Пример:
См. также: “stats auth”, “stats realm”, “stats uri”
stats hide-version
Включает статистику и скрывает версию HAProxy
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы: отсутствуют
На странице статистики вместе со статистическими данными может отображаться полезная информация о состоянии, в том числе версия HAProxy. Однако сообщать точную версию любому посетителю обычно считается опасным: это может помочь подобрать атаки на известные уязвимости. Директива “stats hide-version” убирает версию из отчёта статистики. Это рекомендуется для публичных сайтов и сайтов со слабым логином/паролем и является настройкой по умолчанию.
Хотя одной этой директивы достаточно для включения статистики, рекомендуется задать все остальные настройки, чтобы не полагаться на неочевидные параметры по умолчанию.
Пример:
См. также: “stats auth”, “stats enable”, “stats realm”, “stats uri”, “stats show-version”
stats http-request { allow | deny | auth [realm <realm>] }
Управление доступом к статистике
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend нет | нет | да | да
Как и “http-request”, этот набор параметров позволяет точно управлять доступом к статистике. После каждого параметра могут идти if/unless и acl. Первый параметр с совпавшим условием (или без условия) определяет окончательное действие. При “deny” возвращается ошибка 403; при “allow” выполняется обычная обработка; при “auth” возвращается код ошибки 401/407, чтобы клиент запросил имя пользователя и пароль.
Число директив http-request на экземпляр не имеет фиксированного ограничения.
См. также: “http-request”, раздел 12.2 о списках пользователей и раздел 7 об использовании ACL.
stats realm <realm>
Включает статистику и задаёт область аутентификации
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы:
Область читается как одно слово, поэтому все пробелы в ней следует экранировать обратной косой чертой (’\’).
Эта директива полезна только в сочетании со “stats auth”, поскольку относится исключительно к аутентификации.
Хотя одной этой директивы достаточно для включения статистики, рекомендуется задать все остальные настройки, чтобы не полагаться на неочевидные параметры по умолчанию.
Пример:
См. также: “stats auth”, “stats enable”, “stats uri”
stats refresh <delay>
Включить статистику с автоматическим обновлением
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы:
Эта директива полезна для экранов мониторинга, на которых постоянно открыта страница с данными об активности балансировщика нагрузки. Если она задана, HTML страница отчёта будет содержать ссылку “refresh”/“stop refresh”, позволяющую пользователю включать или отключать автоматическое обновление страницы.
Хотя одной этой директивы достаточно для включения статистики, рекомендуется задать все остальные настройки, чтобы не полагаться на неочевидные параметры по умолчанию.
Пример:
См. также: “stats auth”, “stats enable”, “stats realm”, “stats uri”
stats scope { <name> | "." }
Включить статистику и ограничить область доступа
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы:
Если эта директива задана, в отчёте будут показаны только секции, перечисленные с её помощью. Все остальные будут скрыты, а попытки изменить их состояние в режиме администрирования будут отклонены. Если в отчёт нужно включить несколько секций, эту директиву можно повторять столько раз, сколько требуется. Имена проверяются простым сравнением строк; существование секции с указанным именем никогда не проверяется.
Хотя одной этой директивы достаточно для включения статистики, рекомендуется задать все остальные настройки, чтобы не полагаться на неочевидные параметры по умолчанию.
Пример:
См. также: “stats auth”, “stats enable”, “stats realm”, “stats uri” и “stats admin”
stats show-desc [ <desc> ]
Включить отображение описания на странице статистики.
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
`<desc>` — необязательное описание для отображения. Если оно не задано, автоматически
используется описание из секции global.
Эта директива полезна для пользователей, предлагающих своим клиентам общие сервисы, где узел или описание следует задавать разными для каждого клиента.
Хотя одной этой директивы достаточно для включения отчёта статистики, рекомендуется задать и все остальные настройки, чтобы не полагаться на неочевидные параметры по умолчанию. По умолчанию описание не отображается.
Пример:
См. также: “show-node”, “stats enable”, “stats uri” и “description” в секции global.
stats show-legends
Включить отображение дополнительной информации на странице статистики
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы: отсутствуют
Включить отображение дополнительной информации на странице статистики: - cap: возможности (прокси) - mode: один из режимов tcp, http или health (прокси) - id: SNMP ID (прокси, сокет, сервер) - IP (сокет, сервер) - cookie (бэкенд, сервер)
Хотя одной этой директивы достаточно для включения отчёта статистики, рекомендуется задать и все остальные настройки, чтобы не полагаться на неочевидные параметры по умолчанию. По умолчанию эта информация не отображается.
См. также: “stats enable”, “stats uri”.
stats show-modules
Включить отображение дополнительного модуля статистики на странице статистики
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы: отсутствуют
В конце строки добавляются новые столбцы, в которых дополнительные значения статистики представлены во всплывающей подсказке.
Хотя одной этой директивы достаточно для включения отчёта статистики, рекомендуется задать и все остальные настройки, чтобы не полагаться на неочевидные параметры по умолчанию. По умолчанию эта информация не отображается.
См. также: “stats enable”, “stats uri”.
stats show-node [ <name> ]
Включить отображение имени узла на странице статистики.
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы:
Эта директива полезна для пользователей, предлагающих своим клиентам общие сервисы, где узел или описание могут различаться на странице статистики для каждого клиента. По умолчанию имя узла не отображается.
Хотя одной этой директивы достаточно для включения статистики, рекомендуется задать все остальные настройки, чтобы не полагаться на неочевидные параметры по умолчанию.
Пример:
См. также: “show-desc”, “stats enable”, “stats uri” и “node” в секции global.
stats show-version
Включить статистику и отображение версии HAProxy
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы: отсутствуют
Страница статистики может отображать вместе со статистикой полезные сведения о состоянии, в том числе версию HAProxy. Однако обычно считается опасным сообщать точную версию всем: это может помочь проводить целевые атаки на известные уязвимости. Поэтому по умолчанию она не отображается. “stats show-version” включает отображение этих сведений. Это не рекомендуется для публичных сайтов или любых сайтов со слабыми учётными данными (именем пользователя и паролем).
См. также: “stats auth”, “stats enable”, “stats realm”, “stats uri”, “stats hide-version”
stats uri <prefix>
Включить статистику и задать префикс URI для доступа к ней
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы:
URI статистики перехватывается в ретранслируемом трафике, поэтому выглядит как страница обычного приложения. Настоятельно рекомендуется убедиться, что выбранный URI никогда не встретится в приложении, иначе обратиться к нему в приложении будет невозможно.
URI по умолчанию, встроенный в HAProxy, — “/haproxy?stats”, но его можно изменить при сборке, поэтому лучше всегда явно задавать его здесь. Обычно полезно включать в URI знак вопроса, чтобы промежуточные прокси воздерживались от кэширования результатов. Кроме того, поскольку любая строка с этим префиксом будет принята как запрос статистики, знак вопроса помогает гарантировать, что никакой корректный URI не начнётся с тех же слов.
Иногда очень удобно использовать “/” как префикс URI и поместить эту директиву в отдельный экземпляр “listen”. Так легко выделить адрес или порт исключительно для статистики.
Хотя одной этой директивы достаточно для включения статистики, рекомендуется задать все остальные настройки, чтобы не полагаться на неочевидные параметры по умолчанию.
Пример:
См. также: “stats auth”, “stats enable”, “stats realm”
stick match <pattern> [table <table>] [{if | unless} <cond>]
Задать условие сопоставления шаблона запроса для привязки пользователя к серверу
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend нет | нет | да | да
Аргументы:
Некоторые протоколы или приложения требуют сложных правил привязки и не всегда могут полагаться только на cookie или хэширование. Директива “stick match” описывает правило извлечения критерия привязки из входящего запроса или соединения. Полный список возможных шаблонов и правил преобразования см. в разделе 7 .
Таблицу нужно объявить директивой “stick-table”. Её тип должен быть совместим с шаблоном. По умолчанию используется таблица в том же бэкенде. Можно совместно использовать таблицу с другими бэкендами, сославшись на неё ключевым словом “table”. При ссылке на другую таблицу используются ID серверов в этих бэкендах. По умолчанию ID всех серверов в каждом бэкенде начинаются с 1, поэтому достаточно порядка серверов. Но при сомнениях настоятельно рекомендуется явно задать ID серверов с помощью их настройки “id”.
Условия применения директивы “stick match” можно ограничить с помощью “if” или “unless”, за которыми следует условие. Об условиях на основе ACL см. раздел 7 .
Количество директив “stick match” не ограничено. Первая применимая директива, для которой найдено совпадение, направит запрос на тот же сервер, что использовался для запроса, создавшего запись. Таким образом, несколько сопоставлений можно использовать как запасные варианты.
Правила stick проверяются после cookie привязки, поэтому не влияют на привязку, если cookie уже использовался для выбора сервера. Так очень легко вставлять cookie и сопоставлять IP адреса, сохраняя привязку между HTTP и HTTPS.
Пример:
См. также: “stick-table”, “stick on”, раздел 11 о таблицах привязок и раздел 7 об ACL и извлечении образцов.
stick on <pattern> [table <table>] [{if | unless} <condition>]
Задать шаблон запроса для связывания пользователя с сервером
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend нет | нет | да | да
Примечание: эта форма в точности эквивалентна “stick match”, за которой следует “stick store-request”, обе с одинаковыми аргументами. Подробности см. в описании обоих ключевых слов. Эта форма предоставлена лишь для удобства написания конфигураций, которые проще сопровождать.
Примеры:
См. также: “stick match”, “stick store-request” и раздел 11 о таблицах привязок.
stick store-request <pattern> [table <table>] [{if | unless} <condition>]
Задать шаблон запроса для создания записи в таблице привязок
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend нет | нет | да | да
Аргументы:
Некоторые протоколы или приложения требуют сложных правил привязки и не всегда могут полагаться только на cookie или хэширование. Директива “stick store-request” описывает правило, определяющее, что и когда извлекать из запроса для сохранения в таблице привязок, чтобы следующие запросы могли сопоставляться с записью с помощью “stick match”. Очевидно, извлечённая часть должна иметь смысл и допускать совпадение в последующем запросе. Например, сохранение IP адреса клиента часто имеет смысл. Сохранение ID из параметра URL тоже имеет смысл. Сохранение исходного порта почти никогда не имеет смысла, поскольку совпадения будут случайными. Полный список возможных шаблонов и правил преобразования см. в разделе 7 .
Таблицу нужно объявить директивой “stick-table”. Её тип должен быть совместим с шаблоном. По умолчанию используется таблица в том же бэкенде. Можно совместно использовать таблицу с другими бэкендами, сославшись на неё ключевым словом “table”. При ссылке на другую таблицу используются ID серверов в этих бэкендах. По умолчанию ID всех серверов в каждом бэкенде начинаются с 1, поэтому достаточно порядка серверов. Но при сомнениях настоятельно рекомендуется явно задать ID серверов с помощью их настройки “id”.
Условия применения директивы “stick store-request” можно ограничить с помощью “if” или “unless”, за которыми следует условие. Это условие проверяется при разборе запроса, поэтому можно использовать любые критерии. Об условиях на основе ACL см. раздел 7 .
Количество директив “stick store-request” не ограничено, но действует предел 8 одновременных сохранений на запрос или ответ. Это позволяет сохранить до 8 критериев, извлечённых из запроса или ответа, независимо от количества правил. Сохраняются только первые 8 совпавших критериев. Так можно заполнять несколько таблиц одновременно, чтобы увеличить вероятность распознавания пользователя при другом протоколе или способе доступа. Можно использовать несколько правил store-request с одной таблицей, располагая их в порядке убывания предпочтения, чтобы найти наиболее подходящий критерий. Для данной таблицы сохраняется только первый извлечённый критерий. Все последующие правила store-request, ссылающиеся на ту же таблицу, пропускаются, и их ACL не проверяются.
Правила “store-request” проверяются после установления соединения с сервером, чтобы таблица содержала настоящий сервер, обработавший запрос.
Пример:
См. также: “stick-table”, “stick on”, раздел 11 о таблицах привязок и раздел 7 об ACL и извлечении образцов.
stick store-response <pattern> [table <table>] [{if | unless} <condition>]
Задать шаблон ответа для создания записи в таблице привязок
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend нет | нет | да | да
Аргументы:
Некоторые протоколы или приложения требуют сложных правил привязки и не всегда могут полагаться только на cookie или хэширование. Директива “stick store-response” описывает правило, определяющее, что и когда извлекать из ответа для сохранения в таблице привязок, чтобы следующие запросы могли сопоставляться с записью с помощью “stick match”. Очевидно, извлечённая часть должна иметь смысл и допускать совпадение в последующем запросе. Сохранение ID из заголовка ответа имеет смысл. Полный список возможных шаблонов и правил преобразования см. в разделе 7 .
Таблицу нужно объявить директивой “stick-table”. Её тип должен быть совместим с шаблоном. По умолчанию используется таблица в том же бэкенде. Можно совместно использовать таблицу с другими бэкендами, сославшись на неё ключевым словом “table”. При ссылке на другую таблицу используются ID серверов в этих бэкендах. По умолчанию ID всех серверов в каждом бэкенде начинаются с 1, поэтому достаточно порядка серверов. Но при сомнениях настоятельно рекомендуется явно задать ID серверов с помощью их настройки “id”.
Условия применения директивы “stick store-response” можно ограничить с помощью “if” или “unless”, за которыми следует условие. Это условие проверяется при разборе ответа, поэтому можно использовать любые критерии. Об условиях на основе ACL см. раздел 7 .
Количество директив “stick store-response” не ограничено, но действует предел 8 одновременных сохранений на запрос или ответ. Это позволяет сохранить до 8 критериев, извлечённых из запроса или ответа, независимо от количества правил. Сохраняются только первые 8 совпавших критериев. Так можно заполнять несколько таблиц одновременно, чтобы увеличить вероятность распознавания пользователя при другом протоколе или способе доступа. Можно использовать несколько правил store-response с одной таблицей, располагая их в порядке убывания предпочтения, чтобы найти наиболее подходящий критерий. Для данной таблицы сохраняется только первый извлечённый критерий. Все последующие правила store-response, ссылающиеся на ту же таблицу, пропускаются, и их ACL не проверяются. Однако даже если правило store-request ссылается на таблицу, правило store-response тоже может использовать эту таблицу. Это означает, что каждая таблица может одновременно изучить ровно один элемент из запроса и один элемент из ответа.
Таблица будет содержать настоящий сервер, обработавший запрос.
Пример:
См. также: “stick-table”, “stick on”, раздел 11 о таблицах привязок и раздел 7 об ACL и извлечении шаблонов.
stick-table type <type> size <size> [expire <expire>] [args...]
Настроить таблицу привязок для текущей секции
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend нет | да | да | да
Используется для объявления и настройки stick-table. Полное описание и список поддерживаемых аргументов см. в разделе 11.1 . Обязательны только тип и размер.
tcp-check comment <string>
Задаёт комментарий для следующего правила tcp-check, который выводится в журнале при его неудаче.
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
Работает только для правил connect, send и expect. Позволяет делать сообщения об ошибках понятнее.
См. также: “option tcp-check”, “tcp-check connect”, “tcp-check send” и “tcp-check expect”.
tcp-check connect [default] [port <expr>] [addr <ip>] [send-proxy] [via-socks4]
Открывает новое соединение
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
Если приложение использует более одного TCP порта или HAProxy балансирует нагрузку между многими сервисами в одном бэкенде, имеет смысл отдельно проверять все сервисы, прежде чем считать сервер работоспособным.
Если TCP порт не настроен ни в строке server, ни директивой server port, первым шагом последовательности должен быть ’tcp-check connect port <port>’.
В наборе правил tcp-check требуется ‘connect’; также обязательно начинать набор правил с правила ‘connect’. Цель — обеспечить осознанность действий администратора.
Хотя набор правил должен начинаться с connect, перед ним всё же могут стоять правила set-var, unset-var или comment.
Примеры:
См. также: “option tcp-check”, “tcp-check send”, “tcp-check expect”
tcp-check expect [min-recv <int>] [comment <msg>]
Указать данные для сбора и анализа при общей проверке работоспособности
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
Доступные виды сопоставления намеренно похожи на соответствующие варианты http-check:
Ответы ограничены размером, заданным глобальным параметром “tune.bufsize”, по умолчанию 16384 байта. Поэтому слишком большие ответы могут не содержать обязательный шаблон при использовании “string”, “rstring” или binary. Если большой ответ совершенно необходим, можно изменить максимальный размер по умолчанию, задав глобальную переменную. Однако следует помнить, что разбор очень больших ответов может расходовать такты CPU впустую, особенно при использовании регулярных выражений; всегда лучше направлять проверки на меньшие ресурсы. Кроме того, в текущем состоянии проверка не найдёт ни строку, ни регулярное выражение после нулевого символа в ответе. Аналогично невозможно задать сопоставление с нулевым символом.
Примеры:
См. также: “option tcp-check”, “tcp-check connect”, “tcp-check send”, “tcp-check send-binary”, “http-check expect”, tune.bufsize
tcp-check send <data> [comment <msg>]
Указать строку или пользовательский формат журнала, отправляемые как запрос при общей проверке работоспособности
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
Примеры:
См. также: “option tcp-check”, “tcp-check connect”, “tcp-check expect”, “tcp-check send-binary”, tune.bufsize
tcp-check send-binary <hexstring> [comment <msg>]
Указать строку шестнадцатеричных цифр или пользовательский формат журнала с шестнадцатеричными цифрами, отправляемые как двоичный запрос при проверке работоспособности на уровне TCP
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
Примеры:
См. также: “option tcp-check”, “tcp-check connect”, “tcp-check expect”, “tcp-check send”, tune.bufsize
tcp-check set-var(<var-name>[,<cond>...]) <expr>
Эта операция устанавливает содержимое переменной. Переменная объявляется непосредственно при использовании.
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
Примеры:
tcp-check unset-var(<var-name>)
Освобождает ссылку на переменную в пределах её области видимости.
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
Примеры:
tcp-request connection <action> <options...> [ { if | unless } <condition> ]
Выполнить действие над входящим соединением в зависимости от условия уровня 4
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да(!) | да | да | нет
Аргументы:
Сразу после принятия нового входящего соединения можно проверить условия, чтобы решить, нужно ли принять или отбросить это соединение либо отслеживать его счётчики. Эти условия не могут использовать содержимое данных: чтение из соединения ещё не выполнялось, и буферы ещё не выделены. Это позволяет выборочно и очень быстро принимать или отбрасывать соединения от разных источников с очень небольшими накладными расходами. Если для принятия решения нужно проверить содержимое, необходимо использовать директивы “tcp-request content”.
Правила “tcp-request connection” проверяются строго в порядке их объявления. Если ни одно правило не совпало или правил нет, действие по умолчанию — принять входящее соединение. Особого ограничения на количество добавляемых правил нет. За любым правилом может следовать необязательное условие на основе ACL; в этом случае правило проверяется только тогда, когда условие истинно.
Условие проверяется непосредственно перед выполнением действия, а действие выполняется ровно один раз. Поэтому нет проблемы, если действие изменяет элемент, проверяемый в условии. Это также означает, что несколько действий могут зависеть от одного условия, и тогда первого действия, изменяющего результат проверки условия, достаточно для неявного отключения остальных действий. Например, это используется при попытке присвоить значение пустой переменной из разных источников.
Первое ключевое слово после “tcp-request connection” в синтаксисе задаёт действие правила; за ним может следовать различное количество аргументов этого действия. Поддерживаемые действия и их синтаксис перечислены в разделе 4.3 «Действия» (ищите действия с отметкой в столбце “TCP RqCon”).
Эта директива доступна только в именованных секциях defaults, а в анонимных недоступна. Правила секции defaults проверяются до правил связанной с ней секции прокси. Во избежание неоднозначности одну и ту же секцию defaults нельзя использовать одновременно для прокси с возможностями фронтенда и прокси с возможностями бэкенда. Поэтому секция listen не может использовать секцию defaults с такими правилами.
Условие “if/unless” необязательно. Если условие для действия не задано, оно просто выполняется безусловно. Это может быть полезно для действий “track-sc*”, а также для смены действия по умолчанию на отклонение.
Пример: принимать все соединения от узлов из белого списка, отклонять слишком часто поступающие соединения, не учитывая их, и отслеживать принятые соединения. В результате частота соединений от источников, злоупотребляющих подключениями, ограничивается.
tcp-request connection accept if { src -f /etc/haproxy/whitelist.lst }
tcp-request connection reject if { src_conn_rate gt 10 }
tcp-request connection track-sc0 src
Пример: принимать все соединения от узлов из белого списка, учитывать все остальные соединения и отклонять слишком часто поступающие. В результате нарушители остаются заблокированными, пока не снизят частоту.
tcp-request connection accept if { src -f /etc/haproxy/whitelist.lst }
tcp-request connection track-sc0 src
tcp-request connection reject if { sc0_conn_rate gt 10 }
Пример: включить протокол PROXY для трафика от всех известных прокси.
tcp-request connection expect-proxy layer4 if { src -f proxies.lst }
Об использовании ACL см. раздел 7 .
См. также: “tcp-request session”, “tcp-request content”, “stick-table”
tcp-request content <action> [{if | unless} <condition>]
Выполнить действие над новым сеансом в зависимости от условия уровней 4–7
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да(!) | да | да | да
Аргументы:
Содержимое запроса можно анализировать на раннем этапе обработки запроса, называемом «проверка содержимого TCP». На этом этапе правила на основе ACL проверяются при каждом обновлении содержимого запроса, пока не совпадёт правило “accept”, “reject” или “switch-mode” либо не истечёт задержка проверки TCP запроса без совпадения какого-либо правила.
Первое отличие этих правил от правил “tcp-request connection” состоит в том, что правила “tcp-request content” могут использовать содержимое для принятия решения. Чаще всего эти решения связаны с распознаванием протокола или проверкой его корректности. Второе отличие — правила на основе содержимого можно использовать и во фронтенде, и в бэкенде. При постоянном соединении HTTP с клиентом все правила tcp-request content проверяются заново. Поэтому HAProxy хранит сведения о том, какие счётчики привязки были назначены правилом “tcp-request connection”, а какие — правилом “tcp-request content”, и сбрасывает все связанные с содержимым счётчики после обработки HTTP запроса. Это позволяет назначить их снова при повторной проверке правил для следующего запроса. Это особенно важно, когда правило отслеживает некоторую информацию L7 или зависит от ACL на основе L7, поскольку отслеживание может меняться между запросами.
Правила, основанные на содержимом, проверяются строго в порядке их объявления. Если ни одно правило не совпало или правил нет, действие по умолчанию — принять содержимое. Особого ограничения на количество добавляемых правил нет.
Хотя это и не обязательно, рекомендуется использовать track-sc0 в правилах “tcp-request connection”, track-sc1 в правилах “tcp-request content” во фронтенде и track-sc2 в правилах “tcp-request content” в бэкенде: так конфигурацию легче читать и диагностировать. Но это лишь рекомендация, и все счётчики можно использовать где угодно.
Первое ключевое слово после “tcp-request content” в синтаксисе задаёт действие правила; за ним может следовать различное количество аргументов этого действия. Поддерживаемые действия и их синтаксис перечислены в разделе 4.3 «Действия» (ищите действия с отметкой в столбце “TCP RqCnt”).
Эта директива доступна только в именованных секциях defaults, а в анонимных недоступна. Правила секции defaults проверяются до правил связанной с ней секции прокси. Во избежание неоднозначности одну и ту же секцию defaults нельзя использовать одновременно для прокси с возможностями фронтенда и прокси с возможностями бэкенда. Поэтому секция listen не может использовать секцию defaults с такими правилами.
Условие “if/unless” необязательно. Если условие для действия не задано, оно просто выполняется безусловно. Это может быть полезно для действий “track-sc*”, а также для смены действия по умолчанию на отклонение.
Также рекомендуется использовать правило “tcp-request session” для отслеживания информации, которая не зависит от содержимого уровня 7, особенно для фронтендов HTTP. Некоторые операции обработки HTTP выполняются на уровне сеанса и могут привести к раннему отклонению запросов. В этом случае отслеживание на уровне содержимого может нарушиться. При запуске выдаётся предупреждение, чтобы по возможности предотвратить такое ненадёжное использование.
С помощью правил “tcp-request content” в TCP прокси вполне можно проверять содержимое уровня 7: HTTP-специфичные проверки ACL умеют предварительно разбирать содержимое буфера перед извлечением нужных данных. Если содержимое буфера не разбирается как корректное HTTP сообщение, ACL не совпадает. Здесь используется тот же парсер, что и при любой другой обработке HTTP, поэтому риска различий в разборе нет. Во фронтенде HTTP или бэкенде HTTP гарантируется, что при первой проверке правила HTTP содержимое уже будет доступно: разбор HTTP выполняется на ранних этапах обработки соединения, на уровне сеанса. Однако для таких прокси гораздо естественнее и рекомендуется использовать правила “http-request”.
Отслеживать информацию уровня 7 также можно, если она доступна в момент обработки правила. Если отслеживаемые данные ещё недоступны, механизм обработки правил умеет ждать до истечения задержки проверки.
Пример:
Пример:
Пример:
Пример:
Пример:
Пример:
Пример: отслеживать счётчики отдельно для фронтенда и бэкенда, блокировать нарушителей во фронтенде, когда бэкенд обнаруживает злоупотребление (и устанавливает gpc0).
frontend http
# Use General Purpose Counter 0 in SC0 as a global abuse counter
# protecting all our sites
stick-table type ip size 1m expire 5m store gpc0
tcp-request connection track-sc0 src
tcp-request connection reject if { sc0_get_gpc0 gt 0 }
...
use_backend http_dynamic if { path_end .php }
backend http_dynamic
# if a source makes too fast requests to this dynamic site (tracked
# by SC1), block it globally in the frontend.
stick-table type ip size 1m expire 5m store http_req_rate(10s)
acl click_too_fast sc1_http_req_rate gt 10
acl mark_as_abuser sc0_inc_gpc0(http) gt 0
tcp-request content track-sc1 src
tcp-request content reject if click_too_fast mark_as_abuser
Об использовании ACL см. раздел 7 .
См. также: “tcp-request connection”, “tcp-request session”, “tcp-request inspect-delay” и “http-request”.
tcp-request inspect-delay <timeout>
Установить максимально допустимое время ожидания данных при проверке содержимого
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да(!) | да | да | да
Аргументы:
Те, кто использует HAProxy главным образом для ретрансляции TCP, часто обеспокоены риском передачи серверу любого протокола без анализа. Чтобы анализировать содержимое запроса, нужно сначала задержать данные, а затем проанализировать их. Эта директива просто включает задержку данных на время не более указанного.
Проверка содержимого TCP выполняется на очень раннем этапе, когда соединение поступает во фронтенд, а затем на очень раннем этапе его передачи в бэкенд. Это означает, что соединение может сначала испытать задержку во фронтенде, а затем вторую задержку в бэкенде, если в обоих есть правила tcp-request.
При проверке содержимого HAProxy проверяет все правила для каждого нового поступившего фрагмента, учитывая, что данные неполны. Если до истечения указанной задержки ни одно правило не совпало, по её истечении выполняется последняя проверка: на этот раз содержимое считается окончательным. Если задержка не задана, HAProxy вообще не будет ждать и сразу вынесет решение по имеющейся информации. Очевидно, это вряд ли будет полезно и может даже привести к гонкам, поэтому такие настройки не рекомендуются.
Задержка проверки сокращается при ошибке соединения, его закрытии или заполнении буфера запроса.
Как только правило совпадает, запрос освобождается и продолжает обрабатываться обычным образом. Если тайм-аут истёк и ни одно правило не совпало, политика по умолчанию — пропустить запрос без изменений.
Для большинства протоколов достаточно установить несколько секунд: большинство клиентов отправляют весь запрос сразу после подключения. Добавьте 3 или более секунд для учёта повторных передач TCP; этого достаточно. Для некоторых протоколов имеет смысл задавать большие значения, например чтобы клиент никогда не начинал обмен раньше сервера (например, SMTP) или чтобы дождаться данных от клиента до передачи данных серверу (например, SSL). Тайм-аут клиента должен быть не меньше задержки проверки, иначе он истечёт первым. Если клиент закрывает соединение или буфер заполнен, задержка немедленно истекает, поскольку содержимое уже не сможет измениться.
Эта директива доступна только в именованных секциях defaults, но не в анонимных. Прокси наследуют это значение из своей секции defaults.
См. также: “tcp-request content accept”, “tcp-request content reject”, “timeout client”.
tcp-request session <action> [{if | unless} <condition>]
Выполнить действие над прошедшим проверку сеансом в зависимости от условия уровня 5
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да(!) | да | да | нет
Аргументы:
После проверки сеанса (то есть после завершения всех рукопожатий) можно проверить условия, чтобы решить, нужно ли принять или отбросить этот сеанс либо отслеживать его счётчики. Эти условия не могут использовать содержимое данных, поскольку буферы ещё не выделены и на этом этапе обработка не может ждать. Основное применение — скопировать некоторую раннюю информацию в переменные (переменные доступны в сеансе) или отслеживать сведения, полученные после рукопожатия, например элементы уровня SSL (SNI, шифры, CN сертификата клиента) или информацию из заголовка протокола PROXY (например, отслеживать переданный таким способом адрес источника). Таким образом, извлечённую информацию можно скопировать в переменную или отслеживать правилами “track-sc”. Разумеется, можно также решать, принимать или отклонять сеанс, как и в других наборах правил. Большинство операций, выполняемых здесь, можно выполнить и в правилах “tcp-request content”, но в HTTP эти правила проверяются для каждого нового запроса, что не всегда допустимо. Например, правило может увеличивать счётчик при каждой проверке. Можно также определить страну по геолокации исходного IP адреса, записать её в переменную уровня сеанса, а затем переписать исходный адрес из HTTP заголовка для всех запросов. Если для принятия решения нужно проверить содержимое, необходимо использовать директивы “tcp-request content”.
Правила “tcp-request session” проверяются строго в порядке их объявления. Если ни одно правило не совпало или правил нет, действие по умолчанию — принять входящий сеанс. Особого ограничения на количество добавляемых правил нет.
Первое ключевое слово после “tcp-request session” в синтаксисе задаёт действие правила; за ним может следовать различное количество аргументов этого действия. Поддерживаемые действия и их синтаксис перечислены в разделе 4.3 «Действия» (ищите действия с отметкой в столбце “TCP RqSes”).
Эта директива доступна только в именованных секциях defaults, а в анонимных недоступна. Правила секции defaults проверяются до правил связанной с ней секции прокси. Во избежание неоднозначности одну и ту же секцию defaults нельзя использовать одновременно для прокси с возможностями фронтенда и прокси с возможностями бэкенда. Поэтому секция listen не может использовать секцию defaults с такими правилами.
Условие “if/unless” необязательно. Если условие для действия не задано, оно просто выполняется безусловно. Это может быть полезно для действий “track-sc*”, а также для смены действия по умолчанию на отклонение.
Пример: по умолчанию отслеживать первоначальный адрес источника, а для соединений от локальных прокси — адрес, указанный в заголовке протокола PROXY. Первое правило уровня соединения включает для них приём протокола PROXY; второе правило отслеживает тот адрес, который мы решили сохранить после необязательного декодирования.
tcp-request connection expect-proxy layer4 if { src -f proxies.lst }
tcp-request session track-sc0 src
Пример: принимать все сеансы от узлов из белого списка, отклонять слишком часто поступающие сеансы, не учитывая их, и отслеживать принятые сеансы. В результате частота сеансов от источников, злоупотребляющих подключениями, ограничивается.
tcp-request session accept if { src -f /etc/haproxy/whitelist.lst }
tcp-request session reject if { src_sess_rate gt 10 }
tcp-request session track-sc0 src
Пример: принимать все сеансы от узлов из белого списка, учитывать все остальные сеансы и отклонять слишком часто поступающие. В результате нарушители остаются заблокированными, пока не снизят частоту.
tcp-request session accept if { src -f /etc/haproxy/whitelist.lst }
tcp-request session track-sc0 src
tcp-request session reject if { sc0_sess_rate gt 10 }
Об использовании ACL см. раздел 7 .
См. также: “tcp-request connection”, “tcp-request content”, “stick-table”
tcp-response content <action> [{if | unless} <condition>]
Выполнить действие над ответом в сеансе в зависимости от условия уровней 4–7
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да(!) | нет | да | да
Аргументы:
Содержимое ответа можно анализировать на раннем этапе обработки ответа, называемом «проверка содержимого TCP». На этом этапе правила на основе ACL проверяются при каждом обновлении содержимого ответа, пока не совпадёт окончательное правило либо не истечёт заданная задержка проверки TCP ответа без совпадения какого-либо правила.
Чаще всего эти решения связаны с распознаванием протокола или проверкой его корректности.
Правила, основанные на содержимом, проверяются строго в порядке их объявления. Если ни одно правило не совпало или правил нет, действие по умолчанию — принять содержимое. Особого ограничения на количество добавляемых правил нет.
Первое ключевое слово после “tcp-response content” в синтаксисе задаёт действие правила; за ним может следовать различное количество аргументов этого действия. Поддерживаемые действия и их синтаксис перечислены в разделе 4.3 «Действия» (ищите действия с отметкой в столбце “TCP RsCnt”).
Эта директива доступна только в именованных секциях defaults, а в анонимных недоступна. Правила секции defaults проверяются до правил связанной с ней секции прокси. Во избежание неоднозначности одну и ту же секцию defaults нельзя использовать одновременно для прокси с возможностями фронтенда и прокси с возможностями бэкенда. Поэтому секция listen не может использовать секцию defaults с такими правилами.
Условие “if/unless” необязательно. Если условие для действия не задано, оно просто выполняется безусловно. Это может быть полезно для смены действия по умолчанию на отклонение.
Поддерживаются несколько типов действий:
С помощью правил “tcp-response content” вполне можно проверять содержимое уровня 7, но тогда важно убедиться, что весь ответ помещён в буфер, иначе совпадений по содержимому не будет. Лучше всего для этого определять протокол HTTP в течение периода проверки.
Об использовании ACL см. раздел 7 .
См. также: “tcp-request content”, “tcp-response inspect-delay”
tcp-response inspect-delay <timeout>
Установить максимально допустимое время ожидания ответа при проверке содержимого
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да(!) | нет | да | да
Аргументы:
Эта директива доступна только в именованных секциях defaults, но не в анонимных. Прокси наследуют это значение из своей секции defaults.
См. также: “tcp-response content”, “tcp-request inspect-delay”.
timeout check <timeout>
Установить дополнительный тайм-аут проверки, применяемый только после установления соединения.
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
Если он задан, HAProxy использует min(“timeout connect”, “inter”) как тайм-аут подключения для проверки, а “timeout check” — как дополнительный тайм-аут чтения. “min” используется, чтобы очень большой “timeout connect” (например, у тех, кому он понадобился из-за очереди или ловушки соединений (tarpit)) не замедлял проверки. (Учтите также, что обоснованных причин для таких больших тайм-аутов подключения нет: чтобы избежать их, всегда можно использовать “timeout queue” и “timeout tarpit”.)
Если “timeout check” не задан, HAProxy использует “inter” как тайм-аут всей проверки (подключение + чтение), точно так же, как во всех версиях <1.3.15.
В большинстве случаев запрос проверки гораздо проще и обрабатывается быстрее обычных запросов, а пользователи могут хотеть исключить медленно отвечающие серверы, поэтому этот тайм-аут следует делать меньше “timeout server”.
Этот параметр относится к бэкенду, но его можно задать один раз для всех в секциях “defaults”. Это один из самых простых способов не забыть о нём.
См. также: “timeout connect”, “timeout queue”, “timeout server”, “timeout tarpit”.
timeout client <timeout>
Установить максимальное время бездействия на стороне клиента.
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | нет
Аргументы:
Тайм-аут бездействия применяется, когда от клиента ожидается подтверждение или отправка данных. В режиме HTTP его особенно важно учитывать на первом этапе, когда клиент отправляет запрос, и во время ответа, когда клиент читает данные, отправленные сервером. При этом для первого этапа предпочтительнее задать “timeout http-request”, чтобы лучше защитить HAProxy от атак типа Slowloris. Значение по умолчанию задаётся в миллисекундах, но можно использовать любую другую единицу, добавив её суффикс к числу, как описано в начале этого документа. В режиме TCP (и в меньшей степени в режиме HTTP) настоятельно рекомендуется сохранять тайм-аут клиента равным тайм-ауту сервера, чтобы избежать сложных для диагностики ситуаций. Полезно учитывать потерю одного или нескольких TCP пакетов, задавая тайм-ауты чуть больше значений, кратных 3 секундам (например, 4 или 5 секунд). Если долгоживущие потоки смешаны с короткоживущими (например, WebSocket и HTTP), имеет смысл рассмотреть “timeout tunnel”, который переопределяет “timeout client” и “timeout server” для туннелей, а также “timeout client-fin” для полузакрытых соединений.
Этот параметр относится к фронтенду, но его можно задать один раз для всех в секциях “defaults”. Это один из самых простых способов не забыть о нём. Если тайм-аут не задан, он считается бесконечным, что не рекомендуется. Такая настройка принимается и работает, но при запуске выдаётся предупреждение: если системные тайм-ауты тоже не настроены, в системе могут накапливаться просроченные сеансы.
См. также: “timeout server”, “timeout tunnel”, “timeout http-request”.
timeout client-fin <timeout>
Установить тайм-аут бездействия на стороне клиента для полузакрытых соединений.
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | нет
Аргументы:
Тайм-аут бездействия применяется, когда от клиента ожидается подтверждение или отправка данных, а одно направление уже закрыто. Этот тайм-аут отличается от “timeout client” тем, что применяется только к соединениям, закрытым в одном направлении. Это особенно полезно, чтобы соединения не оставались слишком долго в состоянии FIN_WAIT, когда клиенты завершают соединение некорректно. Эта проблема особенно распространена для длительных соединений, таких как RDP или WebSocket. Этот тайм-аут может переопределять “timeout tunnel”, когда соединение закрывается в одном направлении. Он применяется к бездействующим HTTP/2 соединениям после отправки кадра GOAWAY, который часто означает ожидание скорого завершения соединения.
Этот параметр относится к фронтенду, но его можно задать один раз для всех в секциях “defaults”. По умолчанию он не задан, поэтому полузакрытые соединения используют другие тайм-ауты (timeout.client или timeout.tunnel).
См. также: “timeout client”, “timeout server-fin” и “timeout tunnel”.
timeout client-hs <timeout>
Установить максимальное время ожидания завершения TLS рукопожатия клиента. Применимо как к TCP, так и к QUIC соединениям.
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | нет
Аргументы:
Если этот тайм-аут рукопожатия не задан, вместо него используется тайм-аут клиента.
timeout connect <timeout>
Установить максимальное время ожидания успешного завершения попытки подключения к серверу.
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
Если сервер находится в той же LAN, что и HAProxy, соединение должно устанавливаться немедленно (менее чем за несколько миллисекунд). В любом случае полезно учитывать потерю одного или нескольких TCP пакетов, задавая тайм-ауты чуть больше значений, кратных 3 секундам (например, 4 или 5 секунд). По умолчанию тайм-аут подключения также задаёт такое же значение тайм-аутам очереди и tarpit, если они не указаны.
Этот параметр относится к бэкенду, но его можно задать один раз для всех в секциях “defaults”. Это один из самых простых способов не забыть о нём. Если тайм-аут не задан, он считается бесконечным, что не рекомендуется. Такая настройка принимается и работает, но при запуске выдаётся предупреждение: если системные тайм-ауты тоже не настроены, в системе могут накапливаться неудавшиеся сеансы.
См. также: “timeout check”, “timeout queue”, “timeout server”, “timeout tarpit”.
timeout http-keep-alive <timeout>
Установить максимально допустимое время ожидания появления нового HTTP запроса
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы:
По умолчанию время ожидания нового запроса при постоянном соединении задаётся параметром “timeout http-request”. Однако это не всегда удобно: некоторые пользователи хотят очень короткие тайм-ауты постоянных соединений, чтобы быстрее освобождать соединения, а другие предпочитают более длительные, сохраняя короткий тайм-аут после начала поступления запроса.
Тайм-аут “http-keep-alive” удовлетворяет этим потребностям. Он определяет, сколько ждать начала поступления нового HTTP запроса после отправки ответа. Как только получен первый байт запроса, для ожидания всего запроса используется тайм-аут “http-request”. Пустые строки перед новым запросом не обновляют тайм-аут и не считаются новым запросом.
Между этими двумя тайм-аутами есть ещё одно различие: при истечении timeout http-keep-alive ошибка не возвращается, соединение просто закрывается. Если тайм-аут соединения истекает в “http-request” во время ожидания завершения запроса, перед закрытием соединения клиенту возвращается ошибка HTTP 408, если во фронтенде не задана “option http-ignore-probes”.
Обычно “timeout http-keep-alive” лучше всего использовать для предотвращения слишком долгого удержания клиентами открытого, но бездействующего соединения на сайтах с большим количеством коротких соединений. Для HTTP/1.1 этого можно добиться, задав значение от нескольких десятков до сотен миллисекунд. Тогда соединение закроется после запроса страницы клиентом, и его не придётся держать открытым в ожидании дальнейшей активности клиента. В этом случае новая активность браузера вызовет новое рукопожатие на уровне TCP и/или SSL. Типичный пример — HTTP сайты, которые лишь перенаправляют на HTTPS страницу. Такие соединения лучше не оставлять бездействующими надолго: они не будут использоваться повторно, разве что для получения значка сайта.
Другой случай прямо противоположен: некоторые сайты хотят разрешить клиентам долго повторно использовать бездействующие соединения (например, от 30 секунд до одной минуты), но не хотят столько же ждать первого запроса, чтобы избежать очень дешёвого способа атаки. В этом случае тайм-аут http-keep-alive задаётся большим, а http-request остаётся маленьким (несколько секунд).
При очень маленьком значении дополнительные запросы, не передаваемые конвейерно, скорее всего будут обрабатываться через другое соединение — если только они действительно не передаются конвейерно, что в HTTP/1.1 бывает очень редко (запросы отправляются подряд, без ожидания ответа). Большинство реализаций HTTP/1.1 отправляют запрос, ждут ответа, затем отправляют следующий. Небольшое значение здесь для HTTP/1.1 может помочь снизить потребление памяти и сокетов на сайтах с сотнями тысяч клиентов ценой увеличения вычислительных затрат на рукопожатия.
При работе с HTTP/2 следует особенно осторожно задавать небольшие значения. HTTP/2 мультиплексирует запросы в одном соединении, чтобы сократить накладные расходы на повторное подключение на уровнях TCP и/или SSL. Протокол также использует управляющие кадры, которые плохо переносят раннее закрытие TCP соединения. В очень редких случаях это может привести к обрезанным ответам, когда данные уничтожаются в пути после выхода из HAProxy (который тогда даже не может записать ошибку в журнал). В качестве начального малого значения для HTTP/2 соединений предлагается около 4 секунд. Это не позволит большинству современных реализаций постоянных соединений бессмысленно удерживать устаревшие соединения открытыми и одновременно позволит последующим запросам использовать соединение повторно. Однако значение следует корректировать по необходимости: это лишь отправная точка.
Если этот параметр не задан, применяется тайм-аут “http-request”; если не заданы оба, на нижнем уровне по-прежнему применяется “timeout client”. Чтобы он действовал, его следует задать во фронтенде, кроме случая, когда фронтенд работает в режиме TCP: тогда используется тайм-аут бэкенда HTTP.
См. также: “timeout http-request”, “timeout client”.
timeout http-request <timeout>
Установить максимально допустимое время ожидания полного HTTP запроса
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы:
Для защиты от DoS может потребоваться сократить максимально допустимое время получения полного HTTP запроса, не меняя тайм-аут клиента. Это помогает защититься от установленных соединений, по которым ничего не отправляется. Тайм-аут клиента плохо защищает от такого злоупотребления: это тайм-аут бездействия, и если атакующий время от времени отправляет один символ, он не сработает. При тайм-ауте HTTP запроса скорость отправки клиентом не имеет значения: запрос будет прерван, если не завершится вовремя. Когда тайм-аут истекает, клиенту отправляется ответ HTTP 408 с уведомлением о проблеме, а соединение закрывается. В журнале будет указан код завершения “cR”. У некоторых современных браузеров возникают проблемы с этим стандартным, хорошо документированным поведением, поэтому может потребоваться скрыть код 408 с помощью “option http-ignore-probes” или “errorfile 408 /dev/null”. Подробнее см. объяснение кода завершения “cR” в разделе 8.5 .
По умолчанию этот тайм-аут применяется только к заголовкам запроса, а не к данным. После получения пустой строки он больше не используется. В сочетании с “option http-buffer-request” этот тайм-аут применяется также к телу запроса. На постоянных соединениях он снова используется для ожидания второго запроса, если “timeout http-keep-alive” не задан.
Обычно достаточно задать несколько секунд, поскольку большинство клиентов отправляют весь запрос сразу после подключения. Добавьте 3 или более секунд для учёта повторных передач TCP; этого достаточно. Очень маленькие значения (например, 50 ms) обычно работают в локальных сетях, пока нет потерь пакетов. Это не позволит отправлять HTTP запросы вручную с помощью telnet.
Если этот параметр не задан, тайм-аут клиента по-прежнему применяется между фрагментами входящего запроса. Чтобы он действовал, его следует задать во фронтенде, кроме случая, когда фронтенд работает в режиме TCP: тогда используется тайм-аут бэкенда HTTP.
См. также: “errorfile”, “http-ignore-probes”, “timeout http-keep-alive” и “timeout client”, “option http-buffer-request”.
timeout queue <timeout>
Установить максимальное время ожидания в очереди освобождения места для соединения
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
При достижении maxconn сервера соединения остаются ожидать в очереди, отдельной для сервера или общей для бэкенда. Чтобы ожидание не было бесконечным, к запросам в очереди применяется тайм-аут. Если он истёк, считается, что запрос почти наверняка не будет обслужен, поэтому его отбрасывают, а клиенту возвращают ошибку 503.
Директива “timeout queue” позволяет задать максимальное время ожидания запроса в очереди. Если она не указана, используется то же значение, что и для тайм-аута подключения к бэкенду (“timeout connect”), для обратной совместимости со старыми версиями, в которых параметра “timeout queue” не было.
См. также: “timeout connect”.
timeout server <timeout>
Установить максимальное время бездействия на стороне сервера.
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
Тайм-аут бездействия применяется, когда от сервера ожидается подтверждение или отправка данных. В режиме HTTP этот тайм-аут особенно важно учитывать на первом этапе ответа сервера, когда он должен отправить заголовки: он непосредственно отражает время обработки запроса сервером. Чтобы определить подходящее значение, часто полезно начать со времени ответа, которое считается неприемлемым, затем изучить распределение времени ответа в журналах и соответствующим образом скорректировать значение.
Значение по умолчанию задаётся в миллисекундах, но можно использовать любую другую единицу, добавив её суффикс к числу, как описано в начале этого документа. В режиме TCP (и в меньшей степени в режиме HTTP) настоятельно рекомендуется сохранять тайм-аут клиента равным тайм-ауту сервера, чтобы избежать сложных для диагностики ситуаций. Независимо от ожидаемого времени ответа сервера полезно учитывать потерю как минимум одного или нескольких TCP пакетов, задавая тайм-ауты чуть больше значений, кратных 3 секундам (например, не менее 4 или 5 секунд). Если долгоживущие потоки смешаны с короткоживущими (например, WebSocket и HTTP), имеет смысл рассмотреть “timeout tunnel”, который переопределяет “timeout client” и “timeout server” для туннелей.
Этот параметр относится к бэкенду, но его можно задать один раз для всех в секциях “defaults”. Это один из самых простых способов не забыть о нём. Если тайм-аут не задан, он считается бесконечным, что не рекомендуется. Такая настройка принимается и работает, но при запуске выдаётся предупреждение: если системные тайм-ауты тоже не настроены, в системе могут накапливаться просроченные сеансы.
См. также: “timeout client” и “timeout tunnel”.
timeout server-fin <timeout>
Установить тайм-аут бездействия на стороне сервера для полузакрытых соединений.
Можно использовать в следующих контекстах: tcp, http, log
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
Тайм-аут бездействия применяется, когда от сервера ожидается подтверждение или отправка данных, а одно направление уже закрыто. Этот тайм-аут отличается от “timeout server” тем, что применяется только к соединениям, закрытым в одном направлении. Это особенно полезно, чтобы соединения не оставались слишком долго в состоянии FIN_WAIT, когда удалённый сервер завершает соединение некорректно. Эта проблема особенно распространена для длительных соединений, таких как RDP или WebSocket. Этот тайм-аут может переопределять “timeout tunnel”, когда соединение закрывается в одном направлении. Эта настройка предусмотрена для полноты, но в большинстве ситуаций она не нужна.
Этот параметр относится к бэкенду, но его можно задать один раз для всех в секциях “defaults”. По умолчанию он не задан, поэтому полузакрытые соединения используют другие тайм-ауты (timeout.server или timeout.tunnel).
См. также: “timeout client-fin”, “timeout server” и “timeout tunnel”.
timeout tarpit <timeout>
Задаёт длительность удержания соединений в ловушке соединений (tarpit)
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы:
Соединение, помещённое в ловушку через “http-request tarpit”, некоторое время сохраняется открытым без активности, затем закрывается. “timeout tarpit” задаёт длительность сохранения его открытым.
Значение по умолчанию указывается в миллисекундах, но после числа можно добавить другую единицу, как описано в начале документа. Если значение не задано, для совместимости со старыми версиями без “timeout tarpit” используется тайм-аут соединения бэкенда (“timeout connect”).
См. также: “timeout connect”.
timeout tunnel <timeout>
Задаёт максимальное время бездействия на клиентской и серверной сторонах туннелей.
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы:
Тайм-аут туннеля применяется при установленном двунаправленном соединении клиента с сервером, которое неактивно в обоих направлениях. После превращения соединения в туннель он заменяет клиентский и серверный тайм-ауты. В TCP он применяется, как только к обоим соединениям перестают быть подключены анализаторы (например, приняты правила содержимого tcp). В HTTP он применяется при переходе соединения к другому протоколу (например, WebSocket или пересылке запроса CONNECT прокси) либо после первого ответа, когда не задан параметр постоянных соединений/закрытия.
Поскольку тайм-аут обычно применяется к долгоживущим соединениям, как правило, целесообразно также задать “timeout client-fin”. Он обрабатывает случаи, когда клиент внезапно исчезает из сети и не подтверждает закрытие либо посылает сообщение о закрытии и перестаёт подтверждать ожидающие данные. Это возможно в сетях с потерями пакетов и межсетевыми экранами; признак — большое число сеансов в состоянии FIN_WAIT.
Значение по умолчанию указывается в миллисекундах, но после числа можно добавить другую единицу, как описано в начале документа. Независимо от ожидаемого обычного простоя полезно предусмотреть потерю одного или нескольких пакетов TCP, задавая тайм-ауты чуть больше значений, кратных 3 секундам (например, минимум 4 или 5 секунд).
Этот параметр относится к бэкенду, но его можно задать один раз для всех в секциях “defaults”. Это один из самых простых способов не забыть о нём.
Пример:
См. также: “timeout client”, “timeout client-fin”, “timeout server”.
transparent (deprecated)
Включает прозрачное проксирование на стороне клиента
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | нет | да | да
Аргументы: отсутствуют
Это ключевое слово появилось для предоставления привязки сеанса уровня 7 балансировщикам нагрузки уровня 3. Идея — использовать способность операционной системы (OS) перенаправлять входящее соединение к удалённому адресу в локальный процесс (здесь HAProxy) и сообщать ему первоначально запрошенный адрес. При включённом параметре сеансы без cookie пересылаются на исходный адрес IP назначения входящего запроса (который, как ожидается, соответствует адресу другого оборудования), а запросы с cookie по-прежнему пересылаются подходящему серверу.
Ключевое слово “transparent” устарело; вместо него следует использовать “option transparent”.
Вопреки распространённому мнению, этот параметр НЕ заставляет HAProxy представлять серверу адрес IP клиента при установлении соединения.
См. также: “option transparent”
unique-id-format <fmt>
Создаёт уникальный ID для каждого запроса.
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | да
Аргументы:
Это ключевое слово создаёт ID для каждого запроса по пользовательскому формату журнала. Уникальный ID помогает отслеживать запрос через множество компонентов сложной инфраструктуры. Созданный ID можно также журналировать через псевдоним %ID в строке пользовательского формата журнала.
Формат следует составлять из элементов, гарантированно уникальных при совместном использовании. Например, при нескольких экземплярах HAProxy может быть важно включить имя узла. Часто нужно журналировать исходный адрес и адрес назначения входящего соединения, а также порты. Поскольку в одном соединении может быть несколько запросов, счётчик запросов может помочь их различать. Аналогично отметка времени может защитить от переполнения счётчика. Журналирование ID процесса предотвращает коллизии после перезапуска службы.
Для многих полей рекомендуется шестнадцатеричная запись: она компактнее и экономит место в журналах.
Для обычных соединений уникальный ID создаётся по формату, настроенному во фронтенде. Для проверок работоспособности используется формат бэкенда при использовании извлечения “unique-id” в наборе правил tcp-check или http-check.
Пример:
См. также: “unique-id-header”
unique-id-header <name>
Добавляет заголовок с уникальным ID в запрос HTTP.
Можно использовать в следующих контекстах: http
Можно использовать в секциях: defaults | frontend | listen | backend да | да | да | нет
Аргументы:
Добавляет в запрос HTTP, отправляемый серверу, заголовок unique-id на основе unique-id-format. Без unique-id-format этот параметр не работает.
Пример:
use_backend <backend> [{if | unless} <condition>]
Переключает на определённый бэкенд, если условие на основе ACL выполнено или не выполнено.
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend нет | да | да | нет
Аргументы:
При переключении по содержимому соединения поступают на фронтенд, а затем распределяются по бэкендам в зависимости от ряда условий. Соответствие условий и бэкендов задаётся ключевым словом “use_backend”. Обычно оно используется при обработке HTTP, но применимо и к чистому TCP: без анализа содержимого, с ACL без состояния (например, для проверки исходного адреса), либо вместе с правилом “tcp-request”, позволяющим дождаться данных.
Число правил “use_backend” не ограничено. Они проверяются в порядке объявления; первое совпавшее правило назначает бэкенд, даже если он считается неработоспособным. Однако совпавшее правило, указывающее на отключённый или неопубликованный бэкенд, игнорируется, и проверка правил продолжается.
В первой форме бэкенд используется при выполнении условия, во второй — при его невыполнении. Если ни одно условие не выполнено, используется бэкенд из “default_backend”, если он не отключён и не снят с публикации. Если бэкенда по умолчанию нет, в секции “listen” используются серверы той же секции, а во фронтенде сервер не выбирается и возвращается ответ 503 о недоступности сервиса.
Можно переключаться с фронтенда TCP на бэкенд HTTP. Если фронтенд уже проверил, что используется HTTP, обработка на бэкенде начинается сразу; иначе бэкенд ждёт поступления полного запроса HTTP. Это полезно, когда фронтенд должен распознавать несколько протоколов на одном порту, в том числе HTTP.
Если <backend> — обычное имя, оно разрешается при разборе конфигурации, и отсутствие указанного бэкенда вызывает ошибку. Если же <backend> задан пользовательским форматом журнала, проверить его при разборе конфигурации нельзя: имя бэкенда разрешается динамически во время работы. Если полученное имя не соответствует ни одному допустимому бэкенду, остальные правила не проверяются и применяется директива default_backend. При динамических именах настоятельно рекомендуется использовать префикс, не используемый другими бэкендами, чтобы запрос не мог принудительно выбрать неразрешённый бэкенд.
Правила “use_backend” с явно заданным именем также позволяют определить связи между фронтендами и бэкендами для расчёта параметра “fullconn” бэкенда. Для динамических имён это невозможно.
См. также: “default_backend”, “tcp-request”, “fullconn”, “log-format” и раздел 7 об ACL.
use-fcgi-app <name>
Определяет приложение FastCGI для бэкенда.
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend нет | нет | да | да
Аргументы:
Подробнее о настройке приложения FastCGI см. раздел 10.1 .
use-server <server> if <condition>
Использует только указанный сервер, если условие на основе ACL выполнено или не выполнено.
Можно использовать в следующих контекстах: tcp, http
Можно использовать в секциях: defaults | frontend | listen | backend нет | нет | да | да
Аргументы:
По умолчанию соединения, поступающие на бэкенд, распределяются между доступными серверами согласно настроенному алгоритму, если только не используется механизм привязки, например cookie, обнаруженный в запросе.
Иногда требуется направить определённый запрос на конкретный сервер, не объявляя для него отдельный бэкенд. Это позволяют правила “use-server”. Они проверяются после правил “redirect”, перед обработкой cookie и имеют приоритет над cookie. Число правил “use-server” не ограничено. Правила проверяются в порядке объявления; первое совпавшее правило назначает сервер.
Если правило указывает на неработоспособный сервер, а “option persist” не используется и ни одно правило force-persist не сработало, это правило игнорируется. Проверка последующих правил продолжается до первого совпадения.
В первой форме сервер используется при выполнении условия, во второй — при его невыполнении. Если ни одно условие не выполнено, обработка продолжается и сервер назначается другими механизмами привязки.
Даже при совпадении правила обработка cookie продолжается, но уже не назначает сервер. Это позволяет удалять префикс у cookie с префиксами.
Директива “use-server” работает в режимах HTTP и TCP, что позволяет использовать её при анализе содержимого. Например, при протоколах с неявным TLS сервер в группе можно выбрать по полю TLS SNI (см. также “req.ssl_sni”). Если вес этих серверов равен нулю, для остального трафика они использоваться не будут.
Пример:
Если <server> — обычное имя, оно проверяется по серверам, указанным в конфигурации; отсутствие сервера вызывает ошибку. Для пользовательского формата журнала при разборе конфигурации проверка не выполняется. Если во время работы не удалось получить допустимое имя сервера, но ACL в условии правила use-server вернул true, остальные правила use-server не применяются и используется балансировка нагрузки.
См. также: “use_backend”, раздел 5 о серверах и раздел 7 об ACL.
4.3. Матрица ключевых слов действий
На разных этапах обработки запроса или ответа проверяется несколько наборов правил. Действие каждого правила может выполняться при соблюдении необязательного условия.
По умолчанию доступно множество действий: изменение содержимого, разрешение или блокировка обработки, изменение внутреннего состояния и т. д. Новые действия можно определять на Lua; их имена всегда начинаются с “lua.”.
Раньше некоторые действия были доступны только в определённых наборах правил. Теперь многие из них применимы к разным наборам. В таблице этого раздела для каждого поддерживаемого действия отмечены сокращённые названия наборов правил, в которых его можно использовать:
- QUIC Ini: действие допустимо в правилах “quic-initial”
- TCP RqCon: действие допустимо в правилах “tcp-request connection”
- TCP RqSes: действие допустимо в правилах “tcp-request session”
- TCP RqCnt: действие допустимо в правилах “tcp-request content”
- TCP RsCnt: действие допустимо в правилах “tcp-response content”
- HTTP Req: действие допустимо в правилах “http-request”
- HTTP Res: действие допустимо в правилах “http-response”
- HTTP Aft: действие допустимо в правилах “http-after-response”
Те же сокращения используются ниже в справочном разделе 4.4 .
4.4. Алфавитный справочник действий
В этом разделе подробно описаны все действия и их применение. Обозначения наборов правил те же, что в разделе 4.3 выше.
accept
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft X | X | X | X | X | - | - | -
Прекращает проверку правил и пропускает запрос или ответ. Это завершающее действие: остальные правила того же набора в текущей секции не проверяются. Оно не отличается от “allow”, но для совместимости с прежними версиями в правилах TCP и QUIC используется “accept”, а в правилах HTTP — “allow”. См. также действие “allow” ниже.
add-acl(<file-name>) <key fmt>
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | -
Добавляет новую запись в ACL. ACL должен быть загружен из файла, пусть даже пустого. Имя файла обновляемого ACL указывается в круглых скобках. Действие принимает один аргумент: <key fmt>, задающий содержимое новой записи по правилам пользовательского формата журнала из раздела 8.2.6
. Перед вставкой выполняется поиск в ACL, чтобы не создавать повторяющиеся значения. Это эквивалент команды “add acl” сокета статистики, который может вызываться запросом HTTP.
add-header <name> <fmt>
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X
Добавляет поле заголовка HTTP с именем <name> и значением <fmt>, заданным по правилам пользовательского формата журнала (см. раздел 8.2.6
). Это особенно удобно для передачи серверу сведений о соединении, например сертификата SSL клиента, или для объединения нескольких заголовков в один. Правило не является завершающим: после него можно добавить другие подобные правила. Заголовок добавляется немедленно, поэтому следующее правило может использовать заголовок, полученный в результате предыдущего.
add-headers-bin <expr> [ prefix <str> ]
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X
Вариант действия “add-header”, в котором имена и значения заголовков передаются двоичной строкой с кодированием varint. О формате varint см. функцию извлечения образца “req.hdrs_bin”. Это удобно для одновременного задания нескольких заголовков, имена которых заранее неизвестны. Эти заголовки не проверялись анализатором HTTP, поэтому могут привести к отправке некорректных сообщений, а в худшем случае — к атакам с подменой границ запросов (request smuggling). Число добавляемых заголовков также имеет значение: оно ограничено tune.http.maxhdr. При заданном необязательном префиксе из закодированной строки добавляются только заголовки, имена которых начинаются с <str>.
Пример:
allow
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X
Прекращает проверку правил и пропускает запрос. Это завершающее действие: остальные правила того же набора в текущей секции не проверяются. Оно не отличается от “accept”, но для совместимости с прежними версиями в правилах TCP используется “accept”, а в правилах HTTP — “allow”. См. также действие “accept” выше.
attach-srv <srv> [name <expr>] [ EXPERIMENTAL ]
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | X | - | - | - | - | -
Перехватывает соединение после корректного установления HTTP/2. Направление соединения меняется на сторону бэкенда, и оно помещается в пул простаивающих соединений сервера <srv>. Действие допустимо только для серверов с адресом ‘rhttp@’.
Соединение помещается в пул простаивающих соединений сервера с именем, полученным при вычислении <expr>. С этим именем сопоставляются запросы, к которым применяется параметр “pool-conn-name” или “sni”. Подробнее см. “http-reuse”.
Reverse HTTP пока активно разрабатывается. Механизм конфигурации может измениться. Поэтому функция помечена как экспериментальная: перед этой директивой в отдельной строке необходимо указать “expose-experimental-directives”.
Также разрабатывается очень похожий, но независимый протокол. См. https://www.ietf.org/archive/id/draft-bt-httpbis-reverse-http-00.html .
auth [realm <realm>]
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
Прекращает проверку правил и немедленно возвращает код ошибки HTTP 401 или 407, предлагая пользователю предоставить действительные имя и пароль. Остальные правила “http-request” не проверяются. Необязательный параметр “realm” задаёт область аутентификации, возвращаемую в ответе, — обычно это имя приложения.
Используется сообщение об ошибке соответствующего прокси. Его можно настроить директивой “errorfile” или “http-error”. В ответах 401 все вхождения заголовка WWW-Authenticate удаляются и заменяются одним новым заголовком с запросом базовой аутентификации для области “<realm>”. В ответах 407 то же происходит с заголовком Proxy-Authenticate. Если сообщение об ошибке должно оставаться неизменным, можно вместо этого использовать правило “http-request return”.
Пример:
cache-store <name>
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | - | X | -
Сохраняет http-response в кеше. Заголовки ответа сохраняются на этом этапе, поэтому другие действия http-response могут изменять их до или после сохранения ответа. Это действие отвечает за настройку фильтра сохранения в кеше.
О настройке кеша см. раздел 6.2 .
cache-use <name>
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
Пытается выдать закешированный объект из кеша <name>. Эта директива обязательна и для сохранения в кеше, поскольку вычисляет хеш кеша. Если условие должно применяться и к сохранению, и к выдаче, его целесообразно поместить после этой директивы.
О настройке кеша см. раздел 6.2 .
capture <sample> [ len <length> | id <id> ]
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | - | X | X | X
Захватывает результат выражения образца <sample> из буфера запроса или ответа и преобразует его в строку длиной не более <len> символов. Строка сохраняется в следующем слоте “capture” для запроса или ответа, поэтому может оказаться рядом с захваченными заголовками HTTP. Затем она автоматически появляется в журналах; её также можно получить функциями извлечения образцов и поместить в заголовки или использовать иначе. Длину следует ограничивать, поскольку такой объём памяти выделяется для каждого захвата на всё время жизни потока. Длину можно задавать только в правилах “http-request”. Такой слот существует только в секции, где он объявлен. Поэтому если правило размещено в секции “listen”, которая также используется как бэкенд другого фронтенда, оно игнорируется для потоков, поступивших от этого фронтенда. Подробнее см. раздел 7.3
(«Извлечение образцов»), “capture request header” и “capture response header”.
Если вместо “len” указано ключевое слово “id”, действие пытается сохранить захваченную строку в ранее объявленном слоте захвата. Это удобно для захвата на бэкендах. Идентификатор слота может быть объявлен предшествующей директивой “http-request capture” или ключевым словом “declare capture”.
При использовании этого действия на бэкенде необходимо убедиться, что соответствующие фронтенды имеют требуемые слоты захвата, иначе правило будет игнорироваться во время работы. Обнаружить это при разборе конфигурации невозможно: HAProxy может динамически разрешать имя бэкенда во время работы.
close
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | X | - | - | -
Немедленно закрывает соединение с сервером. Остальные правила “tcp-response content” не проверяются. Основное назначение — принудительно завершить соединение между клиентом и сервером после обмена данными, когда протокол приложения предполагает сначала дождаться длительных тайм-аутов. Это позволяет устранить простаивающие соединения, которые при некоторых протоколах занимают значительные ресурсы сервера.
del-acl(<file-name>) <key fmt>
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | -
Удаляет запись из ACL. ACL должен быть загружен из файла, пусть даже пустого. Имя файла обновляемого ACL указывается в круглых скобках. Действие принимает один аргумент: <key fmt>, задающий содержимое удаляемой записи по правилам пользовательского формата журнала из раздела 8.2.6
. Это эквивалент команды “del acl” сокета статистики, который может вызываться запросом или ответом HTTP.
del-header <name> [ -m <meth> ]
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X
Удаляет все поля заголовка HTTP с именем, указанным в <name>. <meth> задаёт метод сопоставления имени заголовка. Поддерживаются “str” (точное совпадение), “beg” (совпадение префикса), “end” (совпадение суффикса), “sub” (совпадение подстроки) и “reg” (сопоставление с регулярным выражением). Если метод не указан, используется точное совпадение.
del-headers-bin <expr> [ -m <meth> ]
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X
Удаляет все поля заголовка HTTP, имена которых заданы в <expr>. <expr> должно возвращать двоичную строку с кодированием varint, содержащую все имена удаляемых заголовков. Описание кодирования и примеры приведены в “add-headers-bin” и “set-headers-bin”. <meth> задаёт метод сопоставления для всех имён заголовков. Поддерживаются “str” (точное совпадение), “beg” (совпадение префикса), “end” (совпадение суффикса) и “sub” (совпадение подстроки). Метод “reg” (сопоставление с регулярным выражением) не поддерживается из-за непредсказуемой производительности во время работы. Если метод не указан, используется точное совпадение.
del-map(<map-name>) <key fmt>
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X
Удаляет запись из MAP. <map-name> должно соответствовать формату имён карт отображения и ACL из раздела 2.7. Имя обновляемой MAP указывается в круглых скобках. Действие принимает один аргумент: <key fmt>, задающий содержимое удаляемой записи по правилам пользовательского формата журнала из раздела 8.2.6
. Оно принимает один аргумент: “имя файла”. Это эквивалент команды “del map” сокета статистики, который может вызываться запросом или ответом HTTP.
deny [ { status | deny_status } <code> ] [ content-type <type> ]
file `<file>` | lf-file `<file>` | string `<str>` | lf-string `<fmt>` } ]
[ hdr `<name>` `<fmt>` ]*
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | -
Прекращает обработку правил и немедленно отклоняет запрос или ответ. По умолчанию для запросов возвращается ошибка HTTP 403, а для ответов — 502, но возвращаемый ответ можно настроить с тем же синтаксисом, что и у действия “return”. Подробности см. ниже в описании “return”. Для совместимости, если аргументы не заданы либо указан только “deny_status”, подразумевается аргумент “default-errorfiles”. Таким образом, “deny [deny_status <status>]” — псевдоним “deny [status <status>] default-errorfiles”. Это завершающее действие: дальнейшие правила из того же набора для текущей секции не обрабатываются. Расширенный синтаксис также описан в действии “return”.
dgram-drop
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft X | - | - | - | - | - | - | -
Без уведомления игнорирует получение начального пакета QUIC, который иначе привёл бы к созданию нового соединения QUIC и выполнению его рукопожатия SSL.
disable-l7-retry
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
Отключает все попытки повторить запрос, если он завершился неудачей по любой причине, кроме ошибки соединения. Это может быть полезно, например, чтобы исключить повтор POST-запросов после неудачи.
do-log [profile <log_profile>]
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft X | X | X | X | X | X | X | X
Это действие вручную запускает формирование записи журнала на прокси. Учитываются параметры ведения журнала прокси, включая параметры форматирования, например “log-format”, но действие не влияет на записи, автоматически формируемые прокси при обработке транзакций.
С помощью “log-profile” можно точно описать, как следует формировать запись журнала в каждом из доступных контекстов, где применимо действие. Для этого служит ключевое слово ‘on’, за которым следует одно из значений: ‘quic-init’, ’tcp-req-conn’, ’tcp-req-sess’, ’tcp-req-cont’, ’tcp-res-cont’, ‘http-req’, ‘http-res’, ‘http-after-res’.
Они также корректно отображаются при использовании псевдонима формата журнала “%OG”.
Необязательный аргумент “profile” позволяет указать имя секции log-profile, которую следует использовать именно для этого действия do-log вместо секции, связанной с текущим средством записи журнала и применяемой по умолчанию.
Пример:
do-resolve(<var>,<resolvers>[,ipv4|ipv6]) <expr>
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | - | X | - | -
Выполняет разрешение DNS для результата <expr> и сохраняет результат в переменной <var>. Используется секция резолверов DNS, указанная в <resolvers>. Необязательные аргументы ‘ipv4’ и ‘ipv6’ позволяют выбрать предпочтительное семейство адресов. См. также глобальное ключевое слово “dns-accept-family”, которое обеспечивает строгое использование определённого семейства.
Во время разрешения DNS клиентское соединение приостанавливается до завершения разрешения. Если найден IP-адрес, он сохраняется в <var>. При любой ошибке <var> не устанавливается. Это действие позволяет определять IP-адрес сервера во время выполнения на основании информации из запроса, например заголовка Host. Если действие используется для поиска IP-адреса сервера с последующим действием “set-dst”, IP-адрес сервера в бэкенде должен быть задан как 0.0.0.0. Действие do-resolve принимает параметр, содержащий только имя узла; любой порт необходимо удалить из строки.
Пример:
ПРИМЕЧАНИЕ: Следует задать защитные правила, чтобы HAProxy не использовался для сканирования сети или, что ещё хуже, не обращался циклически к самому себе…
early-hint <name> <fmt>
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
Формирует ответ HTTP 103 Early Hints перед любым другим ответом. Добавляет к нему поле заголовка HTTP с именем <name> и значением <fmt>, которое следует правилам пользовательского формата журнала (см. пользовательский формат журнала в разделе 8.2.6
). Это особенно полезно для передачи клиенту заголовков Link с целью предварительной загрузки ресурсов, необходимых для отображения документов HTML.
Дополнительную информацию см. в RFC 8297.
expect-netscaler-cip layer4
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | - | - | - | - | - | -
Настраивает клиентское соединение на получение заголовка протокола NetScaler Client IP insertion до чтения хотя бы одного байта из сокета. Это эквивалентно ключевому слову “accept-netscaler-cip” в строке “bind”, однако правило TCP позволяет принимать протокол PROXY только от определённых диапазонов IP-адресов с помощью ACL. Это удобно, когда трафик от общедоступных узлов проходит через несколько уровней балансировщиков нагрузки.
expect-proxy layer4
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | - | - | - | - | - | -
Настраивает клиентское соединение на получение заголовка протокола PROXY до чтения хотя бы одного байта из сокета. Это эквивалентно ключевому слову “accept-proxy” в строке “bind”, однако правило TCP позволяет принимать протокол PROXY только от определённых диапазонов IP-адресов с помощью ACL. Это удобно, когда трафик от общедоступных узлов проходит через несколько уровней балансировщиков нагрузки.
normalize-uri <normalizer>
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
Выполняет нормализацию URI запроса.
Нормализация URI в HAProxy 2.4 пока доступна в качестве экспериментальной предварительной реализации. Поэтому для её использования сначала необходимо задать глобальную директиву ’expose-experimental-directives’. Следует быть готовым к тому, что поведение нормализаторов может измениться для устранения возможных проблем, что способно нарушить корректную обработку запросов в инфраструктуре.
Каждый нормализатор выполняет один вид нормализации, что позволяет точно выбрать уровень нормализации, подходящий для поддерживаемого бэкенда.
Например, нормализатор “path-strip-dotdot” может быть полезен для сервера статических файлов, который напрямую сопоставляет запрошенный URI с путём в локальной файловой системе. Однако он может нарушить маршрутизацию API, ожидающего определённое число сегментов в пути.
Некоторые нормализаторы могут приводить к небезопасным преобразованиям некорректных URI. Кроме того, нормализаторы, безопасные по отдельности, при неправильном сочетании тоже могут приводить к небезопасным преобразованиям.
Например, нормализатор “percent-decode-unreserved” может давать неожиданные результаты, если некорректный URI содержит символы процента без кодирования. Такой URI — “/%%36%36”: он декодируется в “/%66”, что, в свою очередь, эквивалентно “/f”. Параметр “strict” позволяет безопасно отклонять запросы к таким некорректным URI.
Доступны следующие нормализаторы:
-
fragment-encode: Кодирует “#” как “%23”.
Следует предпочесть нормализатор “fragment-strip”, если только не известно, что некорректные клиенты неправильно кодируют ‘#’ в компоненте пути.
Пример:
- /#foo -> /%23foo
-
fragment-strip: Удаляет компонент “fragment” из URI.
Согласно RFC 3986#3.5 компонент “fragment” URI не следует отправлять; пользовательскому агенту следует обрабатывать его после получения ресурса.
Этот нормализатор следует применять первым, чтобы фрагмент не интерпретировался как часть компонента пути запроса.
Пример:
- /#foo -> /
-
path-strip-dot: Удаляет сегменты “/./” в компоненте “path” (RFC 3986#6.2.2.3).
Сегменты с точками в процентном кодировании ("%2E”) не обнаруживаются. Если такое поведение нежелательно, сначала следует использовать нормализатор “percent-decode-unreserved”.
Пример:
- /. -> /
- /./bar/ -> /bar/
- /a/./a -> /a/a
- /.well-known/ -> /.well-known/ (без изменений)
-
path-strip-dotdot: Нормализует сегменты “/../” в компоненте “path” (RFC 3986#6.2.2.3).
Объединяет сегменты, пытающиеся обратиться к родительскому каталогу, с предшествующим им сегментом.
Пустые сегменты не обрабатываются особым образом. Если такое поведение нежелательно, сначала следует использовать нормализатор “merge-slashes”.
Сегменты с точками в процентном кодировании ("%2E") не обнаруживаются. Если такое поведение нежелательно, сначала следует использовать нормализатор “percent-decode-unreserved”.
Пример:
- /foo/../ -> /
- /foo/../bar/ -> /bar/
- /foo/bar/../ -> /foo/
- /../bar/ -> /../bar/
- /bar/../../ -> /../
- /foo//../ -> /foo/
- /foo/%2E%2E/ -> /foo/%2E%2E/
Если указан параметр “full”, начальные “../” также удаляются:
Пример:
- /../bar/ -> /bar/
- /bar/../../ -> /
-
path-merge-slashes: Объединяет соседние косые черты в компоненте “path” в одну косую черту.
Пример:
- // -> /
- /foo//bar -> /foo/bar
-
percent-decode-unreserved: Декодирует незарезервированные символы в процентном кодировании в обычные символы (RFC 3986#6.2.2.2).
Набор незарезервированных символов включает все буквы, все цифры, “-”, “.”, “_” и “~”.
Пример:
- /%61dmin -> /admin
- /foo%3Fbar=baz -> /foo%3Fbar=baz (без изменений)
- /%%36%36 -> /%66 (небезопасно)
- /%ZZ -> /%ZZ
Если указан параметр “strict”, при недопустимых последовательностях возвращается HTTP 400 Bad Request.
Пример:
- /%%36%36 -> HTTP 400
- /%ZZ -> HTTP 400
-
percent-to-uppercase: Переводит буквы в процентно-кодированных последовательностях в верхний регистр (RFC 3986#6.2.2.1).
Пример:
- /%6f -> /%6F
- /%zz -> /%zz
Если указан параметр “strict”, при недопустимых последовательностях возвращается HTTP 400 Bad Request.
Пример:
- /%zz -> HTTP 400
-
query-sort-by-name: Сортирует параметры строки запроса по имени. Предполагается, что разделитель параметров — ‘&’. Короткие имена располагаются перед длинными, а параметры с одинаковыми именами сохраняют взаимный порядок.
Пример:
- /?c=3&a=1&b=2 -> /?a=1&b=2&c=3
- /?aaa=3&a=1&aa=2 -> /?a=1&aa=2&aaa=3
- /?a=3&b=4&a=1&b=5&a=2 -> /?a=3&a=1&a=2&b=4&b=5
pause { <timeout> | <expr> }
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | -
Приостанавливает анализ сообщения на указанное число миллисекунд. Тайм-аут можно задать в миллисекундах или в любой другой единице, добавив её обозначение после числа, как описано в начале документа. Также можно задать выражение, которое должно вернуть число, интерпретируемое как тайм-аут в миллисекундах. Если вычисление выражения завершается неудачей или возвращает недопустимое значение, действие игнорируется, а обработка продолжается.
Это действие может использоваться для отладки. Оно также позволяет замедлять обслуживание некоторых клиентов по определённым критериям. Например, можно замедлять клиентов с чрезмерной интенсивностью запросов, отслеживая их правилом “track-sc”.
redirect <rule>
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | -
Выполняет перенаправление HTTP по правилу перенаправления. Оно полностью соответствует директиве “redirect”, но вставляет правило, которое обрабатывается среди других правил “http-request” или “http-response” и использует пользовательский формат журнала. Для ответов разрешён только тип перенаправления “location”. Кроме того, при перенаправлении во время обработки ответа передача от сервера к HAProxy прерывается, поэтому клиенту нельзя переслать полезную нагрузку. В HTTP/1 это может привести к закрытию некоторых соединений. Это завершающее действие: дальнейшие правила из того же набора для текущей секции не обрабатываются. Синтаксис правила см. в описании ключевого слова “redirect”.
reject
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft X | X | X | X | X | X | - | -
Прекращает обработку правил и немедленно закрывает соединение без отправки ответа. В правилах HTTP действует аналогично правилам “tcp-request content reject”. Может быть полезно для принудительного немедленного закрытия соединений HTTP/2.
В правилах “tcp-request connection” отклонённые соединения даже не становятся сеансами, поэтому в статистике они учитываются отдельно как «отклонённые соединения». Они не учитываются при ограничении интенсивности сеансов и не записываются в журнал. Эти правила следует использовать только для фильтрации чрезвычайно высокой интенсивности соединений, например при массовой DDoS-атаке. В таких экстремальных условиях запись каждого события в журнал привела бы к отказу системы и существенно снизила бы возможности фильтрации. Если ведение журнала необходимо, следует использовать правила “tcp-request content”, поскольку правила “tcp-request session” также не формируют записи журнала.
При использовании в правилах “tcp-response content” соединение с сервером закрывается, а передача ответа прерывается. Обычно это служит для предотвращения утечки конфиденциальной информации, как правило после проверки содержимого совместно с действием “wait-for-body”.
Это действие можно использовать и в правилах “quic-initial”. Только что открытое соединение QUIC немедленно закрывается без обработки рукопожатия SSL, а клиент уведомляется кодом ошибки CONNECTION_REFUSED.
replace-header <name> <match-regex> <replace-fmt>
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X
Сопоставляет значения всех вхождений поля заголовка <name> с <match-regex>. Сопоставление учитывает регистр. Совпавшие значения полностью заменяются на <replace-fmt>. В <replace-fmt> разрешены символы форматирования; они работают так же, как аргументы <fmt> в “http-request add-header”. Поддерживаются стандартные обратные ссылки: обратная косая черта (’\’), за которой следует число.
Это действие обрабатывает строки заголовков целиком независимо от количества содержащихся в них значений. Поэтому оно хорошо подходит для заголовков, чьи значения естественным образом содержат запятые, например If-Modified-Since или Set-Cookie. Для заголовков со списком значений, разделённых запятыми, например Accept или Cache-Control, следует использовать действие “replace-value”. См. также действие “replace-value”.
Пример:
Пример:
replace-path <match-regex> <replace-fmt>
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
Работает как “replace-header”, но обрабатывает компонент пути запроса вместо заголовка. Компонент пути начинается с первой ‘/’ после необязательных схемы и полномочного компонента и заканчивается перед вопросительным знаком. Таким образом, замена не изменяет схему, полномочный компонент и строку запроса.
Вычисление регулярных выражений может обходиться дороже, чем проверка некоторых ACL. Поэтому для редко выполняемых замен может быть полезно условие, позволяющее вообще не вычислять выражение, если условие не выполняется.
Пример:
replace-pathq <match-regex> <replace-fmt>
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
Работает так же, как “http-request replace-path”, но путь включает строку запроса, если она присутствует. Таким образом, заменяются и путь, и строка запроса.
Пример:
replace-uri <match-regex> <replace-fmt>
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
Работает как “replace-header”, но обрабатывает URI запроса вместо заголовка. URI может включать необязательные схему, полномочный компонент или строку запроса. Они считаются частью сопоставляемого значения.
Вычисление регулярных выражений может обходиться дороже, чем проверка некоторых ACL. Поэтому для редко выполняемых замен может быть полезно условие, позволяющее вообще не вычислять выражение, если условие не выполняется.
ВАЖНОЕ ПРИМЕЧАНИЕ: Исторически в HTTP/1.x подавляющее большинство запросов браузеров использует исходную форму URI, которая отличается от абсолютной формы отсутствием схемы и компонента authority в URI. Абсолютную форму в основном используют лишь запросы к прокси, запросы, составленные вручную, и некоторые запросы отдельных приложений. Поэтому в HTTP/1.x “replace-uri” обычно работает корректно с правилами, начинающимися с “/”. Однако в HTTP/2 клиентам рекомендуется отправлять только абсолютные URI, похожие на URI, используемые клиентами HTTP/1 при обращении к прокси. Такие частичные правила replace-uri могут не работать в HTTP/2, хотя работают в HTTP/1. Следует либо адаптировать правила для необязательного сопоставления схемы и компонента authority, либо использовать replace-path.
Пример:
replace-value <name> <match-regex> <replace-fmt>
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X
Работает как “replace-header”, но сопоставляет регулярное выражение с каждым значением поля заголовка <name>, разделённым запятыми, вместо заголовка целиком. Подходит для всех заголовков, допускающих несколько значений, например заголовка запроса Accept или заголовка Cache-Control в запросах и ответах.
Пример:
Пример:
return [ status <code> ] [ content-type <type> ]
file `<file>` | lf-file `<file>` | string `<str>` | lf-string `<fmt>` } ]
[ hdr `<name>` `<fmt>` ]*
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | -
Прекращает обработку правил и немедленно возвращает ответ. По умолчанию ответ использует код состояния 200. Его можно изменить аргументом “status”. Тип содержимого ответа также можно задать аргументом “content-type”. Наконец, можно задать сам ответ: либо полный ответ HTTP с указанием используемого файла ошибки, либо полезную нагрузку ответа с указанием файла или строки. Ответ создаётся по следующим правилам:
-
Если не задан ни файл ошибки, ни полезная нагрузка, возвращается ответ-заглушка. Учитывается только аргумент “status”. Допустим любой код в диапазоне [200, 599]. Аргумент “content-type”, если он есть, игнорируется.
-
Если задан аргумент “default-errorfiles”, используются файлы ошибок прокси. Если задан аргумент “status”, он должен содержать один из кодов состояния, обрабатываемых HAProxy (200, 400, 403, 404, 405, 408, 410, 413, 414, 425, 429, 431, 500, 501, 502, 503 и 504). Аргумент “content-type”, если он есть, игнорируется.
-
Если аргументом “errorfile” задан конкретный файл ошибки, возвращается этот файл, содержащий полный ответ HTTP. Учитывается только аргумент “status”. Он должен содержать один из кодов состояния, обрабатываемых HAProxy (200, 400, 403, 404, 405, 408, 410, 413, 414, 425, 429, 431, 500, 501, 502, 503 и 504). Аргумент “content-type”, если он есть, игнорируется.
-
Если аргументом “errorfiles” задана секция http-errors, возвращается соответствующий файл из этой секции http-errors, содержащий полный ответ HTTP. Учитывается только аргумент “status”. Он должен содержать один из кодов состояния, обрабатываемых HAProxy (200, 400, 403, 404, 405, 408, 410, 413, 414, 425, 429, 431, 500, 501, 502, 503 и 504). Аргумент “content-type”, если он есть, игнорируется.
-
Если задан аргумент “file” или “lf-file”, содержимое файла используется как полезная нагрузка ответа. Если файл не пуст, тип его содержимого должен быть задан аргументом “content-type”. В противном случае любой аргумент “content-type” игнорируется. При аргументе “lf-file” содержимое файла вычисляется как пользовательский формат журнала (см. раздел 8.2.6 ). При аргументе “file” оно рассматривается как необработанное содержимое.
-
Если задан аргумент “string” или “lf-string”, указанная строка используется как полезная нагрузка ответа. Тип содержимого всегда должен быть задан аргументом “content-type”. При аргументе “lf-string” строка вычисляется как пользовательский формат журнала (см. раздел 8.2.6 ). При аргументе “string” она рассматривается как необработанная строка.
Если ответ не основан на файле ошибки, аргументы “hdr” позволяют добавить в него поля заголовков HTTP. В противном случае все аргументы “hdr” игнорируются. Для каждого заголовка имя задаётся в <name>, а значение — в <fmt> по правилам пользовательского формата журнала, описанным в разделе 8.2.6
.
Создаваемый ответ должен быть меньше буфера. Чтобы избежать предупреждений при загрузке файла ошибки или необработанного файла, также следует оставлять свободным пространство буфера, зарезервированное для перезаписи заголовков.
Это завершающее действие: дальнейшие правила из того же набора для текущей секции не обрабатываются.
Пример:
sc-add-gpc(<idx>,<sc-id>) { <int> | <expr> }
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | X
Увеличивает счётчик общего назначения с индексом <idx> в массиве, связанном со счётчиком привязки, заданным в <sc-id>, на целое число <int> или результат вычисления выражения <expr> как целого числа. Целые числа и результаты выражений ограничены беззнаковыми 32-битными значениями. При ошибке действие завершается неудачей без уведомления, а обработка действий продолжается. <idx> — целое число от 0 до 99, а <sc-id> — целое число от 0 до 2. Действие также завершается неудачей без уведомления, если по этому индексу не хранится GPC. Запись таблицы обновляется, даже если значение равно нулю. ‘gpc_rate’ автоматически корректируется, отражая среднюю скорость роста значения gpc.
Это действие применимо только к типам данных ‘gpc’ и ‘gpc_rate’, представляющим массивы (data_types), но не к устаревшим типам данных (data_types) ‘gpc0’, ‘gpc1’, ‘gpc0_rate’ и ‘gpc1_rate’. Эквивалентной функции для устаревших типов данных нет, но если значение всегда равно 1, см. ‘sc-inc-gpc()’, ‘sc-inc-gpc0()’ и ‘sc-inc-gpc1()’. Уменьшать значение также нельзя; однако точные значения можно хранить в метке общего назначения, используя вместо этого ‘sc-set-gpt()’.
Главное назначение этого действия — подсчёт баллов или суммарных объёмов, например оценки опасности исходного IP-адреса, сообщённой сервером или WAF, суммарного количества отправленных на сервер байтов и т. п.
sc-inc-gpc(<idx>,<sc-id>)
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | X
Увеличивает счётчик общего назначения с индексом <idx> в массиве, связанном со счётчиком привязки, заданным в <sc-id>. При ошибке действие завершается неудачей без уведомления, а обработка действий продолжается. <idx> — целое число от 0 до 99, а <sc-id> — целое число от 0 до 2. Действие также завершается неудачей без уведомления, если по этому индексу не хранится GPC. Применимо только к типам данных (data_types) в виде массивов ‘gpc’ и ‘gpc_rate’, но не к устаревшим типам данных (data_types) ‘gpc0’, ‘gpc1’, ‘gpc0_rate’ и ‘gpc1_rate’.
sc-inc-gpc0(<sc-id>)
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | X
Увеличивает счётчик GPC0 или GPC1 в соответствии со счётчиком привязки, заданным в <sc-id>. При ошибке действие завершается неудачей без уведомления, а обработка действий продолжается.
sc-set-gpt(<idx>,<sc-id>) { <int> | <expr> }
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | X
Устанавливает беззнаковую 32-битную метку GPT с индексом <idx> в массиве, связанном со счётчиком привязки, заданным в <sc-id>, в значение <int>/<expr>. Ожидаемый результат — логическое значение.
При ошибке действие завершается неудачей без уведомления, а обработка действий продолжается. <idx> — целое число от 0 до 99, а <sc-id> — целое число от 0 до 2. Действие также завершается неудачей без уведомления, если по этому индексу не хранится GPT.
Это действие применимо только к типу данных ‘gpt’, представляющему массив (data_type), но не к устаревшему типу ‘gpt0’.
sc-set-gpt0(<sc-id>) { <int> | <expr> }
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | X
Устанавливает беззнаковую 32-битную метку GPT0 в соответствии со счётчиком привязки, заданным в <sc-id>, и значением <int>/<expr>. Ожидаемый результат — логическое значение. При ошибке действие завершается неудачей без уведомления, а обработка действий продолжается. Это действие — псевдоним “sc-set-gpt(0,<sc-id>)”. См. также действие “sc-set-gpt”.
send-retry
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft X | - | - | - | - | - | - | -
Принудительно отправляет пакет Retry в ответ на клиентский пакет Initial без токена. Это позволяет проверить адрес клиента до создания любых элементов соединения и начала рукопожатия.
send-spoe-group <engine-name> <group-name>
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | X | X | X | -
Это действие запускает отправку группы сообщений SPOE. Необходимо задать движок SPOE, используемый для отправки сообщений, и отправляемую группу SPOE. Движок SPOE должен ссылаться на существующий фильтр SPOE. Если в строке фильтра SPOE не задано имя движка, необходимо использовать имя агента SPOE.
Аргументы:
set-bandwidth-limit <name> [limit {<expr> | <size>}] [period {<expr> | <time>}]
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | X | X | X | -
Включает фильтр ограничения пропускной способности <name> в направлении загрузки на сервер или с сервера в зависимости от типа фильтра. Собственные предел и период можно задать тогда и только тогда, когда <name> ссылается на фильтр ограничения пропускной способности отдельного потока. При выполнении правило set-bandwidth-limit сначала сбрасывает все параметры фильтра к значениям по умолчанию и лишь затем включает его. Поэтому, если для одного фильтра выполняется несколько действий “set-bandwidth-limit”, учитывается только последнее. Для одного потока можно включить несколько фильтров ограничения пропускной способности.
Это действие нельзя использовать в секции defaults, поскольку в секциях defaults нельзя определять фильтры ограничения пропускной способности. Кроме того, ограничивается только передача полезной нагрузки HTTP. Заголовки HTTP не учитываются.
Аргументы:
Пример:
О настройке фильтра ограничения пропускной способности см. раздел 9.7 .
set-bc-mark { <mark> | <expr> }
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | - | X | - | -
Устанавливает метку Netfilter/IPFW MARK для соединения с бэкендом, то есть для всех пакетов, отправляемых серверу, в значение <mark> или <expr> на платформах, которые это поддерживают. Это беззнаковое 32-битное значение может сопоставляться средствами netfilter/ipfw и таблицей маршрутизации либо использоваться при наблюдении за пакетами через DTrace. <mark> можно задавать в десятичном или шестнадцатеричном формате с префиксом “0x”. Вместо него можно использовать <expr> — стандартное выражение HAProxy, состоящее из извлечения образца и последующих преобразователей, которое должно возвращать целое число. Это действие может быть полезно для направления определённых пакетов по другому маршруту, например более дешёвому сетевому пути для массовых загрузок. Работает в ядрах Linux 2.6.32 и новее и требует административных привилегий, а также работает в FreeBSD и OpenBSD. Метка устанавливается на всё время существования соединения с бэкендом или сервером: от установления до закрытия.
set-bc-tos { <tos> | <expr> }
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | - | X | - | -
Устанавливает значение поля TOS или DSCP для соединения с бэкендом, то есть для всех пакетов, отправляемых серверу, в значение <tos> или <expr> на платформах, которые это поддерживают. Это значение представляет все 8 бит поля IP TOS. В DSCP или TOS используются только 6 старших бит, а два младших всегда равны 0. Вместо него можно использовать <expr> — стандартное выражение HAProxy, состоящее из извлечения образца и последующих преобразователей, которое должно возвращать целое число. Действие позволяет влиять на маршрутизацию во внутренних маршрутизаторах на основании информации из запроса. Значение tos устанавливается на всё время существования соединения с бэкендом или сервером: от установления до закрытия.
Дополнительную информацию см. в RFC 2474, 2597, 3260 и 4594.
set-dst <expr>
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | - | X | - | -
Устанавливает IP-адрес назначения в значение указанного выражения. Полезно, если прокси перед HAProxy переписывает IP-адрес назначения, но передаёт правильный IP-адрес в заголовке HTTP, либо если необходимо скрыть IP-адрес для защиты конфиденциальности. Для соединения с новым адресом и портом следует использовать ‘0.0.0.0:0’ как адрес сервера в бэкенде.
Аргументы:
Пример:
По возможности set-dst сохраняет исходный порт назначения, если семейство адресов это позволяет; иначе порт назначения устанавливается в 0.
set-dst-port <expr>
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | - | X | - | -
Устанавливает порт назначения в значение указанного выражения. Для соединения с новым адресом и портом следует использовать ‘0.0.0.0:0’ как адрес сервера в бэкенде.
Аргументы:
Пример:
По возможности set-dst-port сохраняет исходный адрес назначения, если семейство адресов поддерживает порт; иначе перед перезаписью порта принудительно устанавливает адрес назначения в IPv4 “0.0.0.0”.
set-fc-mark { <mark> | <expr> }
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | -
Устанавливает метку Netfilter/IPFW MARK для всех пакетов, отправляемых клиенту, в значение <mark> или <expr> на платформах, которые это поддерживают. Это беззнаковое 32-битное значение может сопоставляться средствами netfilter/ipfw и таблицей маршрутизации либо использоваться при наблюдении за пакетами через DTrace. <mark> можно задавать в десятичном или шестнадцатеричном формате с префиксом “0x”. Вместо него можно использовать <expr> — стандартное выражение HAProxy, состоящее из извлечения образца и последующих преобразователей, которое должно возвращать целое число. Это действие может быть полезно для направления определённых пакетов по другому маршруту, например более дешёвому сетевому пути для массовых загрузок. Работает в ядрах Linux 2.6.32 и новее и требует административных привилегий, а также работает в FreeBSD и OpenBSD.
set-fc-tos { <tos | <expr> }
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | -
Устанавливает значение поля TOS или DSCP в пакетах, отправляемых клиенту, в значение <tos> или <expr> на платформах, которые это поддерживают. Это значение представляет все 8 бит поля IP TOS. В DSCP или TOS используются только 6 старших бит, а два младших всегда равны 0. Вместо него можно использовать <expr> — стандартное выражение HAProxy, состоящее из извлечения образца и последующих преобразователей, которое должно возвращать целое число. Действие позволяет влиять на маршрутизацию в пограничных маршрутизаторах на основании информации из запроса.
Дополнительную информацию см. в RFC 2474, 2597, 3260 и 4594.
set-header <name> <fmt>
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X
Работает так же, как действие “add-header”, но сначала удаляет заголовок, если он существует. Полезно для передачи серверу информации безопасности в заголовке, которым не должны манипулировать внешние пользователи, либо для принудительной установки некоторых заголовков ответа, например “Server”, чтобы скрыть внешнюю информацию. Новое значение вычисляется до удаления, поэтому можно добавить значение к существующему заголовку.
Пример:
set-headers-bin <expr> [ prefix <str> ]
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X
Вариант действия “set-header”, в котором имена и значения заголовков передаются в двоичной строке с кодированием varint. Формат varint описан в извлечении образца “req.hdrs_bin”. Полезно для установки нескольких заголовков сразу, когда их имена заранее неизвестны. Эти заголовки не проверялись парсером HTTP, поэтому могут приводить к отправке некорректных сообщений, а в худших случаях — к атакам типа «контрабанда запросов». Количество вставляемых заголовков также важно: оно ограничено tune.http.maxhdr. Необязательный префикс позволяет устанавливать из кодированной строки только заголовки, начинающиеся с <str>.
Пример:
set-log-level <level>
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | X | X | X | X
Изменяет уровень журналирования текущего запроса при выполнении определённого условия. Допустимы 8 уровней syslog (см. ключевое слово “log”) и специальный уровень “silent”, отключающий ведение журнала для этого запроса. Это правило не является завершающим, поэтому действует последнее совпавшее правило. Оно может быть полезно для отключения проверок работоспособности, поступающих от другого оборудования.
set-map(<map-name>) <key fmt> <value fmt>
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X
Добавляет новую запись в таблицу соответствий. <map-name> должен соответствовать формату имён таблиц соответствий и ACL, описанному в 2.7. Имя обновляемой MAP передаётся в круглых скобках. Принимает 2 аргумента: <key fmt>, по правилам пользовательского формата журнала из раздела 8.2.6
, для получения ключа таблицы, и <value fmt>, также по правилам пользовательского формата журнала, для получения содержимого новой записи. Перед вставкой выполняется поиск в таблице, чтобы избежать появления двух или более одинаковых значений. Эквивалентно команде “set map” через сокет статистики, но может запускаться запросом HTTP.
set-mark <mark> (deprecated)
Псевдоним “set-fc-mark”, который следует использовать вместо него.
set-method <fmt>
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
Переписывает метод запроса результатом вычисления строки формата <fmt>. Обоснованных причин для этого должно быть очень мало, поскольку такое изменение скорее нарушит работу, чем исправит её.
set-nice <nice>
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | X | X | X | -
Устанавливает коэффициент “nice” обрабатываемого запроса или ответа. Он влияет только на соотношение с другими запросами, обрабатываемыми одновременно. Значение по умолчанию — 0, если оно не изменено параметром “nice” в строке “bind”. Допустимый диапазон — -1024..1024. Чем больше значение, тем «уступчивее» запрос; меньшие значения делают запрос важнее других. Это может ускорять некоторые запросы или снижать приоритет неважных запросов. Применение параметра без предварительных экспериментов может вызвать значительное замедление.
set-path <fmt>
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
Переписывает путь запроса результатом вычисления строки формата `<fmt>`. Строка запроса,
если она есть, остаётся неизменной. Схема и полномочный компонент перед путём, если они
есть, также остаются неизменными. Если у запроса нет пути ("*"), он заменяется строкой
формата. Это позволяет, например, добавить компонент каталога перед путём. См. также "http-request set-query"
и "http-request set-uri".
Пример:
set-pathq <fmt>
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
Работает так же, как “http-request set-path”, но также переписывает строку запроса. Позволяет удалить строку запроса вместе с вопросительным знаком, что невозможно с помощью “http-request set-query”.
set-priority-class <expr>
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | - | X | - | -
Устанавливает класс приоритета текущего запроса в очереди. Значение должно быть выражением извлечения образца, преобразуемым в целое число в диапазоне -2047..2047. Результаты за пределами диапазона ограничиваются его границами. Класс приоритета определяет порядок обработки запросов в очереди. Меньшие значения имеют более высокий приоритет.
set-priority-offset <expr>
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | - | X | - | -
Устанавливает смещение временной метки приоритета текущего запроса в очереди. Значение должно быть выражением извлечения образца, преобразуемым в целое число в диапазоне -524287..524287. Результаты за пределами диапазона ограничиваются его границами. При постановке в очередь запросы сначала упорядочиваются по классу приоритета, затем по текущей временной метке, скорректированной на заданное смещение в миллисекундах. Меньшие значения имеют более высокий приоритет. Результирующая временная метка отслеживается с точностью, достаточной лишь для 524,287ms (8m44s287ms). Если запрос остаётся в очереди так долго, что скорректированная временная метка превышает это значение, он ошибочно определяется как имеющий наивысший приоритет. Поэтому важно задать “timeout queue” так, чтобы его значение в сочетании со смещением не превышало этот предел.
set-query <fmt>
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
Переписывает строку запроса после первого вопросительного знака ("?") результатом вычисления строки формата <fmt>. Часть перед вопросительным знаком остаётся неизменной. Если запрос не содержит вопросительного знака, а новое значение не пусто, в конце URI добавляется вопросительный знак, за которым следует новое значение. Если вопросительный знак уже был, он никогда не удаляется, даже при пустом значении. Это позволяет добавлять и удалять параметры строки запроса.
См. также “http-request set-query” и “http-request set-uri”.
Пример:
set-retries <int> | <epxr>
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | - | X | - | -
Переопределяет указанное значение “retries” только для текущего потока. Можно задать целое число в диапазоне [0, 100] либо выражение, которое должно вернуть целое число в диапазоне [0, 100].
Это действие имеет смысл только на стороне бэкенда, поэтому правило доступно лишь прокси с возможностями бэкенда. В секциях “defaults” оно также запрещено. Для слушателя действие проверяется в контексте фронтенда, поэтому значение retries сохраняется только тогда, когда поток не направляется в другой бэкенд, например правилом use-backend. Иначе заранее задаётся значение retries по умолчанию выбранного бэкенда.
Пример:
set-src <expr>
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | - | X | - | -
Задаёт исходный адрес IP равным значению указанного выражения. Это удобно, когда прокси перед HAProxy подменяет исходный IP, но передаёт правильный IP в заголовке HTTP, либо когда исходный IP требуется скрыть для защиты конфиденциальности. Все последующие вызовы извлечения “src” возвращают это значение (см. пример).
Аргументы:
См. также “option forwardfor”.
Пример:
По возможности set-src сохраняет исходный порт, если семейство адресов это допускает; иначе исходный порт устанавливается равным 0.
set-src-port <expr>
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | - | X | - | -
Задаёт исходный порт равным значению указанного выражения.
Аргументы:
Пример:
По возможности set-src-port сохраняет исходный адрес, если семейство адресов поддерживает порт; иначе перед изменением порта принудительно задаёт исходный адрес IPv4 “0.0.0.0”.
set-status <status> [reason <str>]
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | - | X | X
Заменяет код состояния ответа значением <status>, которое должно быть целым числом от 100 до 999. Необязательный <str> задаёт собственный текст причины; иначе используется причина по умолчанию для указанного кода. Строка причины существует только в HTTP/1.x и игнорируется другими версиями протокола.
Пример:
set-timeout { client | connect | queue | server | tarpit | tunnel } { <timeout> | <expr> }
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | -
Переопределяет указанный тайм-аут “client”, “connect”, “queue”, “server”, “tarpit” или “tunnel” только для текущего потока. Изменение одного тайм-аута не влияет на остальные, даже если они наследуются друг от друга при разборе конфигурации (см. последний пример). Тайм-аут можно задать в миллисекундах или другой единице, добавив её суффикс к числу, как описано в начале документа. Можно также указать выражение, которое должно возвращать число, трактуемое как тайм-аут в миллисекундах.
Тайм-ауты connect, queue, server и tunnel имеют смысл только на стороне бэкенда, поэтому это правило доступно лишь прокси с возможностями бэкенда. Аналогично тайм-аут client имеет смысл только на стороне фронтенда. Тайм-аут tarpit доступен на обеих сторонах. Для ожидаемого результата тайм-аут должен быть ненулевым. Для слушателя действие проверяется в контексте фронтенда, поэтому собственные тайм-ауты стороны бэкенда сохраняются только тогда, когда поток не направляется в другой бэкенд, например правилом use-backend. Иначе заранее задаются значения по умолчанию выбранного бэкенда.
Пример:
Пример:
Пример:
set-tos <tos> (deprecated)
Это псевдоним “set-fc-tos” (следует использовать исходное действие).
set-uri <fmt>
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
Изменяет URI запроса на результат вычисления строки формата <fmt>. Схема, компонент authority, путь и строка запроса заменяются одновременно. Это позволяет менять имена хостов перед прокси или выполнять сложные изменения URI, например переносить части между путём и строкой запроса. Абсолютный URI передаётся серверам HTTP/1.1 без изменений. Если такое поведение нежелательно, следует задавать хост, путь и/или строку запроса отдельно. См. также “http-request set-path” и “http-request set-query”.
set-var(<var-name>[,<cond>...]) <expr>
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | X
Задаёт содержимое переменной. Переменная объявляется непосредственно в этом правиле.
Аргументы:
В правилах HTTP допустимы все области видимости. В наборах правил без доступа к содержимому, например “tcp-request connection” и “tcp-request session”, допустимы только “proc” и “sess”.
Пример:
silent-drop [ rst-ttl <ttl> ]
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | -
Прекращает проверку правил и резко удаляет соединение на стороне клиента способом, зависящим от системы и направленным на то, чтобы клиент не получил уведомления. Без аргумента rst-ttl с помощью TCP_REPAIR предпринимается попытка не отправлять клиенту пакеты FIN и RST. Если это не удаётся, главным образом из-за нехватки привилегий, отправляется пакет RST с TTL 1.
Клиент по-прежнему видит установленное соединение, хотя у HAProxy его уже нет, что экономит ресурсы. Однако оборудование с отслеживанием состояния между HAProxy и клиентом — межсетевые экраны, прокси и балансировщики нагрузки — также сохраняет установленное соединение в таблицах сеансов.
Необязательный rst-ttl меняет поведение: TCP_REPAIR не используется, а отправляется пакет RST с настраиваемым TTL. При разумном значении пакет проходит через локальную инфраструктуру, удаляя соединение из межсетевых экранов и других систем, но исчезает, не достигнув клиента. Последующие пакеты клиента отбрасываются уже входным оборудованием. Такие локальные RST защищают локальные ресурсы, но не ресурсы клиента. Это нельзя использовать без полного понимания последствий.
strict-mode { on | off }
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X
Включает или отключает строгий режим изменения для последующих правил. Не влияет на объявленные ранее правила и применим только к правилам изменения запросов. В строгом режиме любая неудача изменения вызывает внутреннюю ошибку; иначе такие ошибки молча игнорируются. Режим позволяет сделать некоторые изменения необязательными, а остальные — обязательными для продолжения обработки запроса.
По умолчанию строгий режим изменения включён. Его значение также сбрасывается после завершения проверки набора правил. Например, если изменить режим на фронтенде, при начале проверки правил бэкенда HAProxy восстанавливает режим по умолчанию.
switch-mode http [ proto <name> ]
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | - | - | - | -
Выполняет переход соединения к другому протоколу. Пока поддерживаются только переходы к HTTP. Протокол указывать необязательно. Действие доступно только прокси с возможностями фронтенда. Переход выполняется немедленно; следующие правила “tcp-request content” не проверяются. Этот способ следует предпочитать неявному переходу на основе режима бэкенда. Он позволяет задавать директивы HTTP во фронтенде без предупреждений; они проверяются условно, если переход к HTTP выполнен. Однако по-прежнему необходимо выбрать бэкенд HTTP. Направлять соединение HTTP — с переходом к протоколу или без него — на сервер TCP не поддерживается.
Подробнее о переходах к HTTP см. раздел 4 о прокси.
tarpit [ { status | deny_status } <code>] [content-type <type>]
file `<file>` | lf-file `<file>` | string `<str>` | lf-string `<fmt>` } ]
[ hdr `<name>` `<fmt>` ]*
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
Прекращает проверку правил и немедленно блокирует запрос, не отвечая в течение “timeout tarpit” либо “timeout connect”, если первый не задан. После задержки, если клиент ещё подключён, возвращается ответ, чтобы клиент не заподозрил попадание в ловушку соединений (tarpit). В журнале указываются флаги “PT”. Правило tarpit замедляет роботов во время атаки, если они ограничены числом одновременных запросов. Оно может быть очень эффективно против примитивных роботов и значительно снижает нагрузку на межсетевые экраны по сравнению с “deny”. Но против «правильно» разработанных роботов оно может ухудшить ситуацию, заставляя HAProxy и входной межсетевой экран поддерживать огромное число одновременных соединений. По умолчанию возвращается ошибка HTTP 500. Ответ можно настроить тем же синтаксисом, что и правила “http-request return”; подробности см. в “http-request return”.
Для совместимости при отсутствии аргументов либо только при “deny_status” подразумевается аргумент “default-errorfiles”. Поэтому “http-request tarpit [deny_status <status>]” — псевдоним “http-request tarpit [status <status>] default-errorfiles”. Остальные правила “http-request” не проверяются. См. также “http-request return” и “http-request silent-drop”.
track-sc0 <key> [table <table>]
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | - | X | X | -
Включает отслеживание счётчиков привязки для текущего запроса. Эти правила не прекращают проверку и не меняют действие по умолчанию. Число счётчиков, одновременно отслеживаемых для одного соединения, задаётся глобальным “tune.stick-counters”. По умолчанию используется MAX_SESS_STKCTR, если он задан при сборке (выводится в haproxy -vv); его значение по умолчанию — 3, поэтому номер track-sc лежит между 0 и (tune.stick-counters-1). Первое выполненное правило “track-sc0” включает отслеживание счётчиков указанной таблицы как первого набора. Первое выполненное правило “track-sc1” включает отслеживание счётчиков указанной таблицы как второго набора. Первое выполненное правило “track-sc2” включает отслеживание счётчиков указанной таблицы как третьего набора. Рекомендуется использовать первый набор для счётчиков фронтенда, а второй для счётчиков бэкенда. Это лишь рекомендация: все наборы можно использовать везде.
Аргументы:
После выполнения правила “track-sc*” ключ ищется в таблице; если его нет, для него выделяется запись. Указатель на запись сохраняется на всё время жизни сеанса. Её счётчики обновляются как можно чаще: при каждом обновлении счётчиков сеанса и обязательно при его завершении. Счётчики обновляются только для событий после начала отслеживания. Исключение — счётчики соединений и запросов: они обновляются обязательно, чтобы отражать полезную информацию.
Если запись отслеживает счётчики одновременных соединений, одно соединение учитывается всё время отслеживания записи, и в этот период срок её действия не истекает. Отслеживание счётчиков также быстрее простой проверки ключей: для всех проверок ACL, использующих запись, выполняется только один поиск в таблице.
unset-var(<var-name>)
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | X
Удаляет переменную. Подробнее о <var-name> см. действие “set-var”.
Пример:
use-service <service-name>
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | - | X | - | -
Запускает настроенную службу TCP или HTTP, отвечающую на запрос, в зависимости от набора правил. Правило завершающее: остальные правила того же набора не проверяются.
Служба может отправить любой допустимый ответ либо немедленно закрыть соединение, не отвечая. Для служб HTTP допустимым является корректный ответ HTTP. Помимо встроенных служб, например экспортера Prometheus для HTTP, можно писать собственные службы TCP и HTTP на Lua.
Аргументы:
Пример:
wait-for-body time <time> [ at-least <bytes> ] [use-large-buffer]
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | -
Задерживает обработку запроса или ответа до выполнения одного из следующих условий:
- Получено всё тело запроса; обработка продолжается обычным образом.
- Получено
<bytes>байтов, если указан аргумент “at-least”, а<bytes>не равен нулю; обработка продолжается обычным образом. - Буфер запроса заполнен; обработка продолжается обычным образом. Размер буфера задаётся параметром “tune.bufsize”.
- Запрос ожидал больше
<time>миллисекунд. В этом случае HAProxy отвечает клиенту ошибкой 408 “Request Timeout” и прекращает обработку запроса. Если раньше выполнено любое другое условие, этот тайм-аут не срабатывает, даже если получено ещё не всё тело.
Параметр “use-large-buffer” позволяет выделить большой буфер, если обычного недостаточно для тела сообщения. Для его использования должен быть задан глобальный параметр “tune.bufsize.large”.
Это действие можно использовать вместо “option http-buffer-request”.
Аргументы:
Пример:
См. также: “option http-buffer-request” и “tune.bufsize.large”
wait-for-handshake
Применимо в: QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -
Задерживает обработку запроса до завершения согласования SSL. Это особенно удобно, чтобы откладывать обработку ранних данных, пока не подтверждена их корректность.