Merge pull request #5101 from fraenki/haproxy_470

net/haproxy: release 5.0
This commit is contained in:
Frank Wall 2026-02-06 23:20:27 +01:00 committed by GitHub
commit 646f886f3b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 5123 additions and 1025 deletions

View file

@ -1,8 +1,7 @@
PLUGIN_NAME= haproxy
PLUGIN_VERSION= 4.6
PLUGIN_REVISION= 2
PLUGIN_VERSION= 5.0
PLUGIN_COMMENT= Reliable, high performance TCP/HTTP load balancer
PLUGIN_DEPENDS= haproxy30 py${PLUGIN_PYTHON}-haproxy-cli
PLUGIN_DEPENDS= haproxy py${PLUGIN_PYTHON}-haproxy-cli
PLUGIN_MAINTAINER= opnsense@moov.de
.include "../../Mk/plugins.mk"

View file

@ -6,6 +6,43 @@ very high loads while needing persistence or Layer7 processing.
Plugin Changelog
================
5.0
WARNING: This is a new major release, which may result in
incompatible changes for some users.
Added:
* add support for HTTP/3 over QUIC to frontends (#4341)
* add new rule: http-request silent-drop
* add new rule: http-after-response
* add new condition: HTTP method
* support custom HTTP status code in "http-request deny" rules
* add new backend option to control PROXY protocol for health checks (#2909)
* add support for new map file types: beg,end,int,ip,reg,str (#3641)
* add support for more sample fetches: quic_enabled, stopping, wait_end (#3702)
* add support for HTTP compression (#4867)
* add all action keywords for http-request/-response and tcp-request/-response rules
* add "enabled" field to rules
* add support for all stick-table data types
* add support for GPC/GPT/SC to conditions and rules (#1123, #5109)
* add support for SSL SNI expression to servers (#3756)
* add column "mode" to servers overview (#4632)
* add support for loading mapfiles in conditions
Fixed:
* Maintenance tab "SSL Certificates" not working with only one cert
Changed:
* upgrade to HAProxy 3.2 release series (#5147)
* refactor http/tcp rules to make extensions easier
* rename some labels in rules
* change LUA boolean conversion (see tune.lua.bool-sample-conversion)
* stick-table "size" and "expiration time" are no longer advanced options (now always visible)
* replace stick-table type "ip" with "ipv4" (#5147)
* show the actual HAProxy option name in conditions for clarity
* allow stick-table types "binary", "integer" and "string" in backends
* make mapfiles more useful in rules
4.6
Changed:

View file

@ -1,7 +1,7 @@
<?php
/**
* Copyright (C) 2016-2022 Frank Wall
* Copyright (C) 2016-2026 Frank Wall
* Copyright (C) 2015 Deciso B.V.
*
* All rights reserved.
@ -133,7 +133,7 @@ class SettingsController extends ApiMutableModelControllerBase
public function searchServersAction()
{
return $this->searchBase('servers.server', array('enabled', 'name', 'type', 'address', 'port', 'description'), 'name');
return $this->searchBase('servers.server', array('enabled', 'name', 'type', 'mode', 'address', 'port', 'description'), 'name');
}
public function getHealthcheckAction($uuid = null)
@ -206,9 +206,14 @@ class SettingsController extends ApiMutableModelControllerBase
return $this->delBase('actions.action', $uuid);
}
public function toggleActionAction($uuid, $enabled = null)
{
return $this->toggleBase('actions.action', $uuid);
}
public function searchActionsAction()
{
return $this->searchBase('actions.action', array('name', 'description'), 'name');
return $this->searchBase('actions.action', array('enabled', 'name', 'description'), 'name');
}
public function getLuaAction($uuid = null)

View file

@ -1,4 +1,10 @@
<form>
<field>
<id>action.enabled</id>
<label>Enabled</label>
<type>checkbox</type>
<help>Enable this rule.</help>
</field>
<field>
<id>action.name</id>
<label>Name</label>
@ -15,12 +21,6 @@
<label>Optional condition</label>
<type>header</type>
</field>
<field>
<id>action.testType</id>
<label>Test type</label>
<type>dropdown</type>
<help><![CDATA[Choose how to test. By using IF it tests if the condition evaluates to true. If you use UNLESS, the sense of the test is reversed.]]></help>
</field>
<field>
<id>action.linkedAcls</id>
<label>Select conditions</label>
@ -28,20 +28,26 @@
<help><![CDATA[Select one or more conditions to be used for this rule.]]></help>
</field>
<field>
<id>action.operator</id>
<label>Logical operator for conditions</label>
<id>action.testType</id>
<label>Match Mode</label>
<type>dropdown</type>
<help><![CDATA[Choose a logical operator.]]></help>
<help><![CDATA[Apply this rule when conditions are met (IF) or unmet (UNLESS).]]></help>
</field>
<field>
<label>HAProxy function</label>
<id>action.operator</id>
<label>Logic Operator</label>
<type>dropdown</type>
<help><![CDATA[Combine multiple conditions using AND (all must match) or OR (any must match).]]></help>
</field>
<field>
<label>Rule type</label>
<type>header</type>
</field>
<field>
<id>action.type</id>
<label>Execute function</label>
<label>Type</label>
<type>dropdown</type>
<help><![CDATA[Choose a HAProxy function that should be executed if the condition evaluates to true.]]></help>
<help><![CDATA[Choose a HAProxy action that should be used if the condition evaluates to true.]]></help>
</field>
<field>
<label>Parameters</label>
@ -69,291 +75,6 @@
<label>NOTE: The specified server must be present in the Backend Pool where this rule is applied.</label>
<type>info</type>
</field>
<field>
<label>Parameters</label>
<type>header</type>
<style>type_table table_http-request_auth</style>
</field>
<field>
<id>action.http_request_auth</id>
<label>Auth Realm</label>
<type>text</type>
<help><![CDATA[When HAProxy requests user name and password from the user, this optional authentication realm is returned with the response (typically the application's name).]]></help>
</field>
<field>
<label>Parameters</label>
<type>header</type>
<style>type_table table_http-request_redirect</style>
</field>
<field>
<id>action.http_request_redirect</id>
<label>Redirect Command</label>
<type>text</type>
<help><![CDATA[Use HAProxy's redirect function to return a HTTP redirection. A full redirect command is required, e.g. "location https://www.example.net/" or "scheme https code 301". See <a href="http://docs.haproxy.org/3.0/configuration.html#redirect">HAProxy's documentation</a> for further details and examples.]]></help>
</field>
<field>
<label>Parameters</label>
<type>header</type>
<style>type_table table_http-request_lua</style>
</field>
<field>
<id>action.http_request_lua</id>
<label>Lua function</label>
<type>text</type>
<help><![CDATA[Execute the specified Lua function. You will most likely need to include/load your Lua code first.]]></help>
</field>
<field>
<label>Parameters</label>
<type>header</type>
<style>type_table table_http-request_use-service</style>
</field>
<field>
<id>action.http_request_use_service</id>
<label>Lua service</label>
<type>text</type>
<help><![CDATA[Register the specified Lua service. You will most likely need to include/load your Lua code first.]]></help>
</field>
<field>
<label>Parameters</label>
<type>header</type>
<style>type_table table_http-request_add-header</style>
</field>
<field>
<id>action.http_request_add_header_name</id>
<label>HTTP Header</label>
<type>text</type>
<help><![CDATA[Append a HTTP header field with the specified name.]]></help>
</field>
<field>
<id>action.http_request_add_header_content</id>
<label>Header Content</label>
<type>text</type>
<help><![CDATA[The value that should be set for the specified HTTP header. Note that it is possible to use pre-defined variables, see <a href="http://docs.haproxy.org/3.0/configuration.html#8.2.4">HAProxy's documentation</a> for further details and examples.]]></help>
</field>
<field>
<label>Parameters</label>
<type>header</type>
<style>type_table table_http-request_set-header</style>
</field>
<field>
<id>action.http_request_set_header_name</id>
<label>HTTP Header</label>
<type>text</type>
<help><![CDATA[Remove the HTTP header field with the specified name and add a new one with the same name. This is useful when passing security information to the server, where the header must not be manipulated by external users.]]></help>
</field>
<field>
<id>action.http_request_set_header_content</id>
<label>Header Content</label>
<type>text</type>
<help><![CDATA[The value that should be set for the specified HTTP header. Note that it's possible to use pre-defined variables, see <a href="http://docs.haproxy.org/3.0/configuration.html#8.2.4">HAProxy's documentation</a> for further details and examples.]]></help>
</field>
<field>
<label>Parameters</label>
<type>header</type>
<style>type_table table_http-request_del-header</style>
</field>
<field>
<id>action.http_request_del_header_name</id>
<label>HTTP Header</label>
<type>text</type>
<help><![CDATA[Remove the HTTP header field with the specified name.]]></help>
</field>
<field>
<label>Parameters</label>
<type>header</type>
<style>type_table table_http-request_replace-header</style>
</field>
<field>
<id>action.http_request_replace_header_name</id>
<label>HTTP Header</label>
<type>text</type>
<help><![CDATA[The name of the HTTP header field.]]></help>
</field>
<field>
<id>action.http_request_replace_header_regex</id>
<label>Regular Expression</label>
<type>text</type>
<help><![CDATA[Matches the specified regular expression in all occurrences of the header field.]]></help>
</field>
<field>
<label>Parameters</label>
<type>header</type>
<style>type_table table_http-request_replace-value</style>
</field>
<field>
<id>action.http_request_replace_value_name</id>
<label>HTTP Header</label>
<type>text</type>
<help><![CDATA[The name of the HTTP header field.]]></help>
</field>
<field>
<id>action.http_request_replace_value_regex</id>
<label>Regular Expression</label>
<type>text</type>
<help><![CDATA[This is suited for all header fields which are allowed to carry more than one value: Matches the specified regular expression against every comma-delimited value of the header field.]]></help>
</field>
<field>
<label>Parameters</label>
<type>header</type>
<style>type_table table_http-request_set-path</style>
</field>
<field>
<id>action.http_request_set_path</id>
<label>Set Path</label>
<type>text</type>
<help><![CDATA[Rewrites the request path. The query string, if any, is left intact. If a scheme and authority is found before the path, they are left intact as well.]]></help>
</field>
<field>
<label>Parameters</label>
<type>header</type>
<style>type_table table_http-request_set-var</style>
</field>
<field>
<id>action.http_request_set_var_scope</id>
<label>Variable Scope</label>
<type>dropdown</type>
<help><![CDATA[The name of the variable starts with an indication about its scope.]]></help>
</field>
<field>
<id>action.http_request_set_var_name</id>
<label>Variable Name</label>
<type>text</type>
</field>
<field>
<id>action.http_request_set_var_expr</id>
<label>Expression</label>
<type>text</type>
<help><![CDATA[A standard HAProxy expression formed by a sample-fetch followed by some converters.]]></help>
</field>
<field>
<label>Parameters</label>
<type>header</type>
<style>type_table table_http-response_lua</style>
</field>
<field>
<id>action.http_response_lua</id>
<label>Lua function</label>
<type>text</type>
<help><![CDATA[Execute the specified Lua function. You will most likely need to include/load your Lua code first.]]></help>
</field>
<field>
<label>Parameters</label>
<type>header</type>
<style>type_table table_http-response_add-header</style>
</field>
<field>
<id>action.http_response_add_header_name</id>
<label>HTTP Header</label>
<type>text</type>
<help><![CDATA[Append a HTTP header field with the specified name.]]></help>
</field>
<field>
<id>action.http_response_add_header_content</id>
<label>Header Content</label>
<type>text</type>
<help><![CDATA[The value that should be set for the specified HTTP header. Note that it's possible to use pre-defined variables, see <a href="http://docs.haproxy.org/3.0/configuration.html#8.2.4">HAProxy's documentation</a> for further details and examples.]]></help>
</field>
<field>
<label>Parameters</label>
<type>header</type>
<style>type_table table_http-response_set-header</style>
</field>
<field>
<id>action.http_response_set_header_name</id>
<label>HTTP Header</label>
<type>text</type>
<help><![CDATA[Remove the HTTP header field with the specified name and add a new one with the same name. This is useful when passing security information to the server, where the header must not be manipulated by external users.]]></help>
</field>
<field>
<id>action.http_response_set_header_content</id>
<label>Header Content</label>
<type>text</type>
<help><![CDATA[The value that should be set for the specified HTTP header. Note that it's possible to use pre-defined variables, see <a href="http://docs.haproxy.org/3.0/configuration.html#8.2.4">HAProxy's documentation</a> for further details and examples.]]></help>
</field>
<field>
<label>Parameters</label>
<type>header</type>
<style>type_table table_http-response_del-header</style>
</field>
<field>
<id>action.http_response_del_header_name</id>
<label>HTTP Header</label>
<type>text</type>
<help><![CDATA[Remove the HTTP header field with the specified name.]]></help>
</field>
<field>
<label>Parameters</label>
<type>header</type>
<style>type_table table_http-response_replace-header</style>
</field>
<field>
<id>action.http_response_replace_header_name</id>
<label>HTTP Header</label>
<type>text</type>
<help><![CDATA[The name of the HTTP header field.]]></help>
</field>
<field>
<id>action.http_response_replace_header_regex</id>
<label>Regular Expression</label>
<type>text</type>
<help><![CDATA[Matches the specified regular expression in all occurrences of header field.]]></help>
</field>
<field>
<label>Parameters</label>
<type>header</type>
<style>type_table table_http-response_replace-value</style>
</field>
<field>
<id>action.http_response_replace_value_name</id>
<label>HTTP Header</label>
<type>text</type>
<help><![CDATA[The name of the HTTP header field.]]></help>
</field>
<field>
<id>action.http_response_replace_value_regex</id>
<label>Regular Expression</label>
<type>text</type>
<help><![CDATA[This is suited for all header fields which are allowed to carry more than one value: Matches the specified regular expression against every comma-delimited value of the header field.]]></help>
</field>
<field>
<label>Parameters</label>
<type>header</type>
<style>type_table table_http-response_set-status</style>
</field>
<field>
<id>action.http_response_set_status_code</id>
<label>HTTP Status Code</label>
<type>text</type>
<help><![CDATA[Replaces the response status code. Must be an integer between 100 and 999.]]></help>
</field>
<field>
<id>action.http_response_set_status_reason</id>
<label>HTTP Reason Text</label>
<type>text</type>
<help><![CDATA[An optional custom reason text for the HTTP status code. If empty the default reason for the specified code will be used.]]></help>
</field>
<field>
<label>Parameters</label>
<type>header</type>
<style>type_table table_http-response_set-var</style>
</field>
<field>
<id>action.http_response_set_var_scope</id>
<label>Variable Scope</label>
<type>dropdown</type>
<help><![CDATA[The name of the variable starts with an indication about its scope.]]></help>
</field>
<field>
<id>action.http_response_set_var_name</id>
<label>Variable Name</label>
<type>text</type>
</field>
<field>
<id>action.http_response_set_var_expr</id>
<label>Expression</label>
<type>text</type>
<help><![CDATA[A standard HAProxy expression formed by a sample-fetch followed by some converters.]]></help>
</field>
<field>
<label>Parameters</label>
<type>header</type>
@ -365,61 +86,6 @@
<type>text</type>
<help><![CDATA[Specifies a URI which will be intercepted to return HAProxy's health status instead of forwarding the request. When a HTTP request is received, HAProxy will return either "HTTP/1.0 200 OK" or "HTTP/1.0 503 Service unavailable", depending on the fined failure conditions.]]></help>
</field>
<field>
<label>Parameters</label>
<type>header</type>
<style>type_table table_tcp-request_content_lua</style>
</field>
<field>
<id>action.tcp_request_content_lua</id>
<label>Lua function</label>
<type>text</type>
<help><![CDATA[Execute the specified Lua function. You will most likely need to include/load your Lua code first.]]></help>
</field>
<field>
<label>Parameters</label>
<type>header</type>
<style>type_table table_tcp-request_content_use-service</style>
</field>
<field>
<id>action.tcp_request_content_use_service</id>
<label>Lua service</label>
<type>text</type>
<help><![CDATA[Register the specified Lua service. You will most likely need to include/load your Lua code first.]]></help>
</field>
<field>
<label>Parameters</label>
<type>header</type>
<style>type_table table_tcp-request_inspect-delay</style>
</field>
<field>
<id>action.tcp_request_inspect_delay</id>
<label>TCP inspection delay</label>
<type>text</type>
<help><![CDATA[Set the maximum allowed time to wait for data during content inspection. Defaults to milliseconds. You may also enter a number followed by one of the supported suffixes "d" (days), "h" (hour), "m" (minute), "s" (seconds), "ms" (miliseconds).]]></help>
</field>
<field>
<label>Parameters</label>
<type>header</type>
<style>type_table table_tcp-response_content_lua</style>
</field>
<field>
<id>action.tcp_response_content_lua</id>
<label>Lua function</label>
<type>text</type>
<help><![CDATA[Execute the specified Lua function. You will most likely need to include/load your Lua code first.]]></help>
</field>
<field>
<label>Parameters</label>
<type>header</type>
<style>type_table table_tcp-response_inspect-delay</style>
</field>
<field>
<id>action.tcp_response_inspect_delay</id>
<label>TCP inspection delay</label>
<type>text</type>
<help><![CDATA[Set the maximum allowed time to wait for a response during content inspection. Defaults to milliseconds. You may also enter a number followed by one of the supported suffixes "d" (days), "h" (hour), "m" (minute), "s" (seconds), "ms" (miliseconds).]]></help>
</field>
<field>
<label>Parameters</label>
<type>header</type>
@ -448,6 +114,29 @@
<type>dropdown</type>
<help><![CDATA[HAProxy will use this backend pool if no match is found in the map file.]]></help>
</field>
<field>
<label>Parameters</label>
<type>header</type>
<style>type_table table_map_data_use_backend</style>
</field>
<field>
<id>action.map_data_use_backend_file</id>
<label>Map file</label>
<type>dropdown</type>
<help><![CDATA[HAProxy will extract the Host header from the HTTP request and search the map file for a match. If a match is found, the backend pool from the map file will be used.]]></help>
</field>
<field>
<id>action.map_data_use_backend_input</id>
<label>Input Sample</label>
<type>textbox</type>
<help><![CDATA[The sample expression (e.g., path, req.ssl_sni, hdr(Host), str(active)) whose fetched value is used as the lookup key for the map file.]]></help>
</field>
<field>
<id>action.map_data_use_backend_default</id>
<label>Default backend pool</label>
<type>dropdown</type>
<help><![CDATA[HAProxy will use this backend pool if no match is found in the map file.]]></help>
</field>
<field>
<label>Parameters</label>
<type>header</type>
@ -468,6 +157,172 @@
<id>action.fcgi_set_param</id>
<label>Parameter</label>
<type>text</type>
<help><![CDATA[Set a FastCGI parameter that should be passed to the application. Its value must follow HAProxy's <a href="http://docs.haproxy.org/3.0/configuration.html#8.2.4">Custom Log format rules</a>. With this directive, it is possible to overwrite the value of default FastCGI parameters.]]></help>
<help><![CDATA[Set a FastCGI parameter that should be passed to the application. Its value must follow HAProxy's <a href="http://docs.haproxy.org/3.2/configuration.html#8.2.4">Custom Log format rules</a>. With this directive, it is possible to overwrite the value of default FastCGI parameters.]]></help>
</field>
<field>
<label>Parameters</label>
<type>header</type>
<style>type_table table_compression</style>
</field>
<field>
<id>action.compression_direction</id>
<label>Compression Direction</label>
<type>dropdown</type>
<help><![CDATA[Whether HAProxy uses compression for HTTP responses, HTTP requests, or both. Be aware that most servers will not support request body decompression. For safekeeping only enable compression for HTTP responses.]]></help>
</field>
<field>
<id>action.compression_algo_res</id>
<label>Response Algorithm</label>
<type>dropdown</type>
<help><![CDATA[The compression algorithm used for HTTP responses. Compression will only be used depending on the Accept-Encoding request header.]]></help>
</field>
<field>
<id>action.compression_algo_req</id>
<label>Request Algorithm</label>
<type>dropdown</type>
<help><![CDATA[The compression algorithm used for HTTP requests. Compression will only be used depending on the Accept-Encoding request header.]]></help>
</field>
<field>
<id>action.compression_mime_res</id>
<label>Response Mime Types</label>
<type>select_multiple</type>
<style>tokenize</style>
<allownew>true</allownew>
<help><![CDATA[HTTP responses will use compression for the specified mime types, i.e. text/css, text/html, application/javascript.]]></help>
<hint>Enter MIME types here. Finish with TAB.</hint>
</field>
<field>
<id>action.compression_mime_req</id>
<label>Request Mime Types</label>
<type>select_multiple</type>
<style>tokenize</style>
<allownew>true</allownew>
<help><![CDATA[HTTP requests will use compression for the specified mime types, i.e. text/css, text/html, application/javascript.]]></help>
<hint>Enter MIME types here. Finish with TAB.</hint>
</field>
<field>
<id>action.compression_minsize_res</id>
<label>Response Minimum Size</label>
<type>text</type>
<help><![CDATA[Specifies a minimum file size for HTTP response compression in bytes. By avoiding unnecessary compression work on very small files, this may reduce CPU overhead. Entering 0 disables this option.]]></help>
</field>
<field>
<id>action.compression_minsize_req</id>
<label>Request Minimum Size</label>
<type>text</type>
<help><![CDATA[Specifies a minimum file size for HTTP request compression in bytes. By avoiding unnecessary compression work on very small files, this may reduce CPU overhead. Entering 0 disables this option.]]></help>
</field>
<field>
<id>action.compression_offloading</id>
<label>Compression Offloading</label>
<type>checkbox</type>
<help><![CDATA[When enabled, the load balancer will remove the Accept-Encoding header before forwarding a request to backend servers. This prevents the servers from performing compression, offloading that work to the load balancer. This may impact HAProxy's performance.]]></help>
</field>
<field>
<label>Parameters</label>
<type>header</type>
<style>type_table table_http-after-response</style>
</field>
<field>
<id>action.http_after_response_action</id>
<label>Action</label>
<type>dropdown</type>
<help><![CDATA[A detailed explanation of each action and examples can be found in <a href="http://docs.haproxy.org/3.2/configuration.html#4.3">HAProxy's documentation</a>.]]></help>
</field>
<field>
<id>action.http_after_response_option</id>
<label>Options/Values</label>
<type>text</type>
<help><![CDATA[Some actions require additional parameters and specific syntax. Examples and explanations can be found in the <a href="http://docs.haproxy.org/3.2/configuration.html#http-after-response">HAProxy's documentation</a>.]]></help>
</field>
<field>
<label>Parameters</label>
<type>header</type>
<style>type_table table_http-request</style>
</field>
<field>
<id>action.http_request_action</id>
<label>Action</label>
<type>dropdown</type>
<help><![CDATA[A detailed explanation of each action and examples can be found in <a href="http://docs.haproxy.org/3.2/configuration.html#4.3">HAProxy's documentation</a>.]]></help>
</field>
<field>
<id>action.http_request_option</id>
<label>Options/Values</label>
<type>text</type>
<help><![CDATA[Some actions require additional parameters and specific syntax. Examples and explanations can be found in the <a href="http://docs.haproxy.org/3.2/configuration.html#http-request">HAProxy's documentation</a>.]]></help>
</field>
<field>
<label>Parameters</label>
<type>header</type>
<style>type_table table_http-response</style>
</field>
<field>
<id>action.http_response_action</id>
<label>Action</label>
<type>dropdown</type>
<help><![CDATA[A detailed explanation of each action and examples can be found in <a href="http://docs.haproxy.org/3.2/configuration.html#4.3">HAProxy's documentation</a>.]]></help>
</field>
<field>
<id>action.http_response_option</id>
<label>Options/Values</label>
<type>text</type>
<help><![CDATA[Some actions require additional parameters and specific syntax. Examples and explanations can be found in the <a href="http://docs.haproxy.org/3.2/configuration.html#http-response">HAProxy's documentation</a>.]]></help>
</field>
<field>
<label>Parameters</label>
<type>header</type>
<style>type_table table_tcp-request</style>
</field>
<field>
<id>action.tcp_request_action</id>
<label>Action</label>
<type>dropdown</type>
<help><![CDATA[A detailed explanation of each action and examples can be found in <a href="http://docs.haproxy.org/3.2/configuration.html#4.3">HAProxy's documentation</a>.]]></help>
</field>
<field>
<id>action.tcp_request_option</id>
<label>Options/Values</label>
<type>text</type>
<help><![CDATA[Some actions require additional parameters and specific syntax. Examples and explanations can be found in the <a href="http://docs.haproxy.org/3.2/configuration.html#tcp-request">HAProxy's documentation</a>.]]></help>
</field>
<field>
<label>Parameters</label>
<type>header</type>
<style>type_table table_tcp-response</style>
</field>
<field>
<id>action.tcp_response_action</id>
<label>Action</label>
<type>dropdown</type>
<help><![CDATA[A detailed explanation of each action and examples can be found in <a href="http://docs.haproxy.org/3.2/configuration.html#4.3">HAProxy's documentation</a>.]]></help>
</field>
<field>
<id>action.tcp_response_option</id>
<label>Options/Values</label>
<type>text</type>
<help><![CDATA[Some actions require additional parameters and specific syntax. Examples and explanations can be found in the <a href="http://docs.haproxy.org/3.2/configuration.html#tcp-response">HAProxy's documentation</a>.]]></help>
</field>
<field>
<label>Conditional parameters</label>
<type>header</type>
</field>
<field>
<id>action.gpc_number</id>
<label>GPC number</label>
<type>text</type>
<help><![CDATA[Refers to the number of the General Purpose Counter, e.g. 0 or 1 when using gpc0 or gpc1 respectively. This value will be ignored in rules that do not support GPC.]]></help>
</field>
<field>
<id>action.gpt_number</id>
<label>GPT number</label>
<type>text</type>
<help><![CDATA[Refers to the number of the General Purpose Tag, e.g. 0 or 1 when using gpt0 or gpt1 respectively. This value will be ignored in rules that do not support GPT.]]></help>
</field>
<field>
<id>action.sc_number</id>
<label>SC number</label>
<type>text</type>
<help><![CDATA[Refers to the number of the Stick Counter, e.g. 0 or 1 when using sc0 or sc1 respectively. This value will be ignored in rules that do not support SC.]]></help>
</field>
</form>

View file

@ -28,7 +28,7 @@
<id>backend.algorithm</id>
<label>Balancing Algorithm</label>
<type>dropdown</type>
<help><![CDATA[Define the load balancing algorithm to be used in a Backend Pool. See the <a target="_blank" href="http://docs.haproxy.org/3.0/configuration.html#balance">HAProxy documentation</a> for a full description.]]></help>
<help><![CDATA[Define the load balancing algorithm to be used in a Backend Pool. See the <a target="_blank" href="http://docs.haproxy.org/3.2/configuration.html#balance">HAProxy documentation</a> for a full description.]]></help>
<hint>Choose a load balancing algorithm.</hint>
</field>
<field>
@ -42,7 +42,7 @@
<id>backend.proxyProtocol</id>
<label>Proxy Protocol</label>
<type>dropdown</type>
<help><![CDATA[Enforces use of the PROXY protocol over any connection established to the configured servers. The PROXY protocol informs the other end about the layer 3/4 addresses of the incoming connection, so that it can know the client's address or the public address it accessed to, whatever the upper layer protocol. This setting must not be used if the servers are not aware of the PROXY protocol. See the <a target="_blank" href="http://docs.haproxy.org/3.0/configuration.html#send-proxy">HAProxy documentation</a> for a full description.]]></help>
<help><![CDATA[Enforces use of the PROXY protocol over any connection established to the configured servers. The PROXY protocol informs the other end about the layer 3/4 addresses of the incoming connection, so that it can know the client's address or the public address it accessed to, whatever the upper layer protocol. This setting must not be used if the servers are not aware of the PROXY protocol. See the <a target="_blank" href="http://docs.haproxy.org/3.2/configuration.html#send-proxy">HAProxy documentation</a> for a full description.]]></help>
<advanced>true</advanced>
</field>
<field>
@ -147,6 +147,13 @@
<type>dropdown</type>
<help><![CDATA[Select an e-mail alert configuration. An e-mail is sent when the state of a server changes.]]></help>
</field>
<field>
<id>backend.healthCheckProxyProto</id>
<label>Use Proxy Protocol</label>
<type>dropdown</type>
<help><![CDATA[This option controls the emission of a PROXY protocol line with outgoing health checks. The default value is good for most situations. However, if either the server or the health check does not support the PROXY protocol, this option may be useful.]]></help>
<advanced>true</advanced>
</field>
<field>
<label>HTTP(S) settings</label>
<type>header</type>
@ -186,7 +193,7 @@
<style>tokenize</style>
<allownew>true</allownew>
<sortable>true</sortable>
<help><![CDATA[This may be used to add more information to the forwarded header. Default behavior enables proto parameter and injects original client IP. See he <a target="_blank" href="http://docs.haproxy.org/3.0/configuration.html#option forwarded">HAProxy documentation</a> for a full description.]]></help>
<help><![CDATA[This may be used to add more information to the forwarded header. Default behavior enables proto parameter and injects original client IP. See he <a target="_blank" href="http://docs.haproxy.org/3.2/configuration.html#option forwarded">HAProxy documentation</a> for a full description.]]></help>
</field>
<field>
<id>backend.forwardFor</id>
@ -213,7 +220,7 @@
<id>backend.persistence_cookiemode</id>
<label>Cookie handling</label>
<type>dropdown</type>
<help><![CDATA[Usually it is better to reuse an existing cookie. In this case HAProxy prefixes the cookie with the required information. See the <a target="_blank" href="http://docs.haproxy.org/3.0/configuration.html#4.2-cookie">HAProxy documentation</a> for a full description.]]></help>
<help><![CDATA[Usually it is better to reuse an existing cookie. In this case HAProxy prefixes the cookie with the required information. See the <a target="_blank" href="http://docs.haproxy.org/3.2/configuration.html#4.2-cookie">HAProxy documentation</a> for a full description.]]></help>
</field>
<field>
<id>backend.persistence_cookiename</id>
@ -228,34 +235,52 @@
<help><![CDATA[Enable to automatically strip quotes from the cookie value. Some broken HTTP clients add quotes, which breaks persistence.]]></help>
</field>
<field>
<label>Stick-table persistence</label>
<label>Stick-table</label>
<type>header</type>
</field>
<field>
<id>backend.stickiness_pattern</id>
<label>Table type</label>
<type>dropdown</type>
<help><![CDATA[Choose a request pattern to associate a user to a server. See the <a target="_blank" href="http://docs.haproxy.org/3.0/configuration.html#stick on">HAProxy documentation</a> for a full description.<br/><div class="text-info"><b>NOTE:</b> Consider not using this feature in multi-process mode, it can result in random behaviours.</div>]]></help>
<hint>Choose a persistence type.</hint>
<help><![CDATA[Choose the type of data that should be stored in this stick-table. See the <a target="_blank" href="http://docs.haproxy.org/3.2/configuration.html#11.1">HAProxy documentation</a> for further information.]]></help>
</field>
<field>
<id>backend.stickiness_dataTypes</id>
<label>Stored data types</label>
<type>select_multiple</type>
<help><![CDATA[This is used to store additional information in the stick-table. It may be used by ACLs in order to control various criteria related to the activity of the client matching the stick-table. Note that this directly impacts memory usage. See the <a target="_blank" href="http://docs.haproxy.org/3.0/configuration.html#stick-table">HAProxy documentation</a> for a full description.]]></help>
<help><![CDATA[This is used to store additional information in the stick-table. It may be used by ACLs in order to control various criteria related to the activity of the client matching the stick-table. Note that this directly impacts memory usage. See the <a target="_blank" href="http://docs.haproxy.org/3.2/configuration.html#11.1">HAProxy documentation</a> for a full description.]]></help>
</field>
<field>
<id>backend.stickiness_expire</id>
<label>Expiration time</label>
<type>text</type>
<help><![CDATA[Enter a number followed by one of the supported suffixes "d" (days), "h" (hour), "m" (minute), "s" (seconds), "ms" (miliseconds). This configures the maximum duration of an entry in the stick-table since it was last created, refreshed or matched. The maximum duration is slightly above 24 days.]]></help>
<advanced>true</advanced>
</field>
<field>
<id>backend.stickiness_size</id>
<label>Size</label>
<label>Table size</label>
<type>text</type>
<help><![CDATA[Enter a number followed by one of the supported suffixes "k", "m", "g". This configures the maximum number of entries that can fit in the table. This value directly impacts memory usage. Count approximately 50 bytes per entry, plus the size of a string if any.]]></help>
</field>
<field>
<id>backend.stickiness_length</id>
<label>Max. data length</label>
<type>text</type>
<help><![CDATA[Specify the maximum length for a value in the stick-table. If the value is larger than this value it will be truncated before being stored. Depending on the stick-table type this repesents either characters or bytes.]]></help>
<advanced>true</advanced>
</field>
<field>
<id>backend.stickiness_bytesInRatePeriod</id>
<label>Bytes in rate period</label>
<type>text</type>
<help><![CDATA[The length of the period over which the average is measured. It reports the average incoming bytes rate over that period, in bytes per period. Defaults to milliseconds. Optionally the unit may be specified as either "d", "h", "m", "s", "ms" or "us".]]></help>
<advanced>true</advanced>
</field>
<field>
<id>backend.stickiness_bytesOutRatePeriod</id>
<label>Bytes out rate period</label>
<type>text</type>
<help><![CDATA[The length of the period over which the average is measured. It reports the average outgoing bytes rate over that period, in bytes per period. Defaults to milliseconds. Optionally the unit may be specified as either "d", "h", "m", "s", "ms" or "us".]]></help>
<advanced>true</advanced>
</field>
<field>
@ -278,10 +303,31 @@
<advanced>true</advanced>
</field>
<field>
<id>backend.stickiness_sessRatePeriod</id>
<label>Session rate period</label>
<id>backend.stickiness_glitchRatePeriod</id>
<label>Glitch rate period</label>
<type>text</type>
<help><![CDATA[The length of the period over which the average is measured. It reports the average incoming session rate over that period, in sessions per period. Defaults to milliseconds. Optionally the unit may be specified as either "d", "h", "m", "s", "ms" or "us".]]></help>
<help><![CDATA[The length of the period over which the average is measured. It reports the average front glitches rate over that period. Defaults to milliseconds. Optionally the unit may be specified as either "d", "h", "m", "s", "ms" or "us".]]></help>
<advanced>true</advanced>
</field>
<field>
<id>backend.stickiness_gpcElements</id>
<label>GPC elements</label>
<type>text</type>
<help><![CDATA[The number of array elements that will be used for the General Purpose Counter. This is limited to a maximum of 100 elements, ranging from 0 to 99.]]></help>
<advanced>true</advanced>
</field>
<field>
<id>backend.stickiness_gpcRatePeriod</id>
<label>GPC rate period</label>
<type>text</type>
<help><![CDATA[The length of the period over which the average is measured. Most of the time it will be used to measure the frequency of occurrence of certain events. Defaults to milliseconds. Optionally the unit may be specified as either "d", "h", "m", "s", "ms" or "us".]]></help>
<advanced>true</advanced>
</field>
<field>
<id>backend.stickiness_gptElements</id>
<label>GPT elements</label>
<type>text</type>
<help><![CDATA[The number of array elements that will be used for the General Purpose Tag. This is limited to a maximum of 100 elements, ranging from 0 to 99.]]></help>
<advanced>true</advanced>
</field>
<field>
@ -299,17 +345,17 @@
<advanced>true</advanced>
</field>
<field>
<id>backend.stickiness_bytesInRatePeriod</id>
<label>Bytes in rate period</label>
<id>backend.stickiness_httpFailRatePeriod</id>
<label>HTTP fail rate period</label>
<type>text</type>
<help><![CDATA[The length of the period over which the average is measured. It reports the average incoming bytes rate over that period, in bytes per period. Defaults to milliseconds. Optionally the unit may be specified as either "d", "h", "m", "s", "ms" or "us".]]></help>
<help><![CDATA[The length of the period over which the average is measured. It reports the average HTTP response fail error rate over that period, in requests per period. Defaults to milliseconds. Optionally the unit may be specified as either "d", "h", "m", "s", "ms" or "us".]]></help>
<advanced>true</advanced>
</field>
<field>
<id>backend.stickiness_bytesOutRatePeriod</id>
<label>Bytes out rate period</label>
<id>backend.stickiness_sessRatePeriod</id>
<label>Session rate period</label>
<type>text</type>
<help><![CDATA[The length of the period over which the average is measured. It reports the average outgoing bytes rate over that period, in bytes per period. Defaults to milliseconds. Optionally the unit may be specified as either "d", "h", "m", "s", "ms" or "us".]]></help>
<help><![CDATA[The length of the period over which the average is measured. It reports the average incoming session rate over that period, in sessions per period. Defaults to milliseconds. Optionally the unit may be specified as either "d", "h", "m", "s", "ms" or "us".]]></help>
<advanced>true</advanced>
</field>
<field>

View file

@ -33,7 +33,7 @@
<id>fcgi.path_info</id>
<label>Path Info</label>
<type>text</type>
<help><![CDATA[Define a regular expression to extract the script-name and the path-info from the URL-decoded path, see <a href="http://docs.haproxy.org/3.0/configuration.html#10.1.1-path-info">HAProxy's documentation</a> for further details and examples.]]></help>
<help><![CDATA[Define a regular expression to extract the script-name and the path-info from the URL-decoded path, see <a href="http://docs.haproxy.org/3.2/configuration.html#10.1.1-path-info">HAProxy's documentation</a> for further details and examples.]]></help>
</field>
<field>
<id>fcgi.log_stderr</id>

View file

@ -23,7 +23,7 @@
<type>select_multiple</type>
<style>tokenize</style>
<allownew>true</allownew>
<help><![CDATA[Configure listen addresses for this Public Service, i.e. 127.0.0.1:8080 or www.example.com:443 or unix@socket-name. Use TAB key to complete typing a listen address.]]></help>
<help><![CDATA[Configure listen addresses for this Public Service, i.e. 127.0.0.1:8080 or www.example.com:443 or unix@socket-name. Add quic4@ or quic6@ to enable QUIC for IPv4/IPv6, e.g. quic4@www.example.com:443. Use TAB key to complete typing a listen address.]]></help>
<hint>Enter address:port here. Finish with TAB.</hint>
</field>
<field>
@ -203,7 +203,7 @@
<style>tokenize</style>
<allownew>true</allownew>
<sortable>true</sortable>
<help><![CDATA[When using the TLS ALPN extension, HAProxy advertises the specified protocol list as supported on top of ALPN. SSL offloading must be enabled.]]></help>
<help><![CDATA[When using the TLS ALPN extension, HAProxy advertises the specified protocol list as supported on top of ALPN. SSL offloading must be enabled. Note that HTTP/3 will only be added to QUIC-compatible Listening Addresses.]]></help>
</field>
<field>
<id>frontend.forwardFor</id>
@ -343,35 +343,33 @@
<advanced>true</advanced>
</field>
<field>
<label>Stickiness table</label>
<label>Stick-table</label>
<type>header</type>
</field>
<field>
<id>frontend.stickiness_pattern</id>
<label>Table type</label>
<type>dropdown</type>
<help><![CDATA[Choose the type of data that should be stored in this stick-table. Note that this stick-table cannot be used for session persistence, it is only used to store additional per-connection data (select below). See the <a target="_blank" href="http://docs.haproxy.org/3.0/configuration.html#stick-table">HAProxy documentation</a> for further information.]]></help>
<help><![CDATA[Choose the type of data that should be stored in this stick-table. Note that this stick-table cannot be used for session persistence, it is only used to store additional per-connection data (select below). See the <a target="_blank" href="http://docs.haproxy.org/3.2/configuration.html#11.1">HAProxy documentation</a> for further information.]]></help>
<hint>Choose a stick-table type.</hint>
</field>
<field>
<id>frontend.stickiness_dataTypes</id>
<label>Stored data types</label>
<type>select_multiple</type>
<help><![CDATA[This is used to store additional information in the stick-table. It may be used by ACLs in order to control various criteria related to the activity of the client matching the stick-table. Note that this directly impacts memory usage. See the <a target="_blank" href="http://docs.haproxy.org/3.0/configuration.html#stick-table">HAProxy documentation</a> for a full description.]]></help>
<help><![CDATA[This is used to store additional information in the stick-table. It may be used by ACLs in order to control various criteria related to the activity of the client matching the stick-table. Note that this directly impacts memory usage. See the <a target="_blank" href="http://docs.haproxy.org/3.2/configuration.html#11.1">HAProxy documentation</a> for a full description.]]></help>
</field>
<field>
<id>frontend.stickiness_expire</id>
<label>Expiration time</label>
<type>text</type>
<help><![CDATA[Enter a number followed by one of the supported suffixes "d" (days), "h" (hour), "m" (minute), "s" (seconds), "ms" (miliseconds). This configures the maximum duration of an entry in the stick-table since it was last created, refreshed or matched. The maximum duration is slightly above 24 days.]]></help>
<advanced>true</advanced>
</field>
<field>
<id>frontend.stickiness_size</id>
<label>Size</label>
<label>Table size</label>
<type>text</type>
<help><![CDATA[Enter a number followed by one of the supported suffixes "k", "m", "g". This configures the maximum number of entries that can fit in the table. This value directly impacts memory usage. Count approximately 50 bytes per entry, plus the size of a string if any.]]></help>
<advanced>true</advanced>
</field>
<field>
<id>frontend.stickiness_counter</id>
@ -384,7 +382,7 @@
<id>frontend.stickiness_counter_key</id>
<label>Sticky counter key</label>
<type>text</type>
<help><![CDATA[It describes what elements of the incoming request or connection will be analyzed, extracted, combined, and used to select which table entry to update the counters. Defaults to "src" to track elements of the source IP. See the <a target="_blank" href="http://docs.haproxy.org/3.0/configuration.html#tcp-request connection">HAProxy documentation</a> for a full description.]]></help>
<help><![CDATA[It describes what elements of the incoming request or connection will be analyzed, extracted, combined, and used to select which table entry to update the counters. Defaults to "src" to track elements of the source IP. See the <a target="_blank" href="http://docs.haproxy.org/3.2/configuration.html#tcp-request connection">HAProxy documentation</a> for a full description.]]></help>
<advanced>true</advanced>
</field>
<field>
@ -394,6 +392,20 @@
<help><![CDATA[Specify the maximum length for a value in the stick-table. If the value is larger than this value it will be truncated before being stored. Depending on the stick-table type this repesents either characters or bytes.]]></help>
<advanced>true</advanced>
</field>
<field>
<id>frontend.stickiness_bytesInRatePeriod</id>
<label>Bytes in rate period</label>
<type>text</type>
<help><![CDATA[The length of the period over which the average is measured. It reports the average incoming bytes rate over that period, in bytes per period. Defaults to milliseconds. Optionally the unit may be specified as either "d", "h", "m", "s", "ms" or "us".]]></help>
<advanced>true</advanced>
</field>
<field>
<id>frontend.stickiness_bytesOutRatePeriod</id>
<label>Bytes out rate period</label>
<type>text</type>
<help><![CDATA[The length of the period over which the average is measured. It reports the average outgoing bytes rate over that period, in bytes per period. Defaults to milliseconds. Optionally the unit may be specified as either "d", "h", "m", "s", "ms" or "us".]]></help>
<advanced>true</advanced>
</field>
<field>
<id>frontend.stickiness_connRatePeriod</id>
<label>Connection rate period</label>
@ -402,10 +414,31 @@
<advanced>true</advanced>
</field>
<field>
<id>frontend.stickiness_sessRatePeriod</id>
<label>Session rate period</label>
<id>frontend.stickiness_glitchRatePeriod</id>
<label>Glitch rate period</label>
<type>text</type>
<help><![CDATA[The length of the period over which the average is measured. It reports the average incoming session rate over that period, in sessions per period. Defaults to milliseconds. Optionally the unit may be specified as either "d", "h", "m", "s", "ms" or "us".]]></help>
<help><![CDATA[The length of the period over which the average is measured. It reports the average front glitches rate over that period. Defaults to milliseconds. Optionally the unit may be specified as either "d", "h", "m", "s", "ms" or "us".]]></help>
<advanced>true</advanced>
</field>
<field>
<id>frontend.stickiness_gpcElements</id>
<label>GPC elements</label>
<type>text</type>
<help><![CDATA[The number of array elements that will be used for the General Purpose Counter. This is limited to a maximum of 100 elements, ranging from 0 to 99.]]></help>
<advanced>true</advanced>
</field>
<field>
<id>frontend.stickiness_gpcRatePeriod</id>
<label>GPC rate period</label>
<type>text</type>
<help><![CDATA[The length of the period over which the average is measured. Most of the time it will be used to measure the frequency of occurrence of certain events. Defaults to milliseconds. Optionally the unit may be specified as either "d", "h", "m", "s", "ms" or "us".]]></help>
<advanced>true</advanced>
</field>
<field>
<id>frontend.stickiness_gptElements</id>
<label>GPT elements</label>
<type>text</type>
<help><![CDATA[The number of array elements that will be used for the General Purpose Tag. This is limited to a maximum of 100 elements, ranging from 0 to 99.]]></help>
<advanced>true</advanced>
</field>
<field>
@ -423,17 +456,17 @@
<advanced>true</advanced>
</field>
<field>
<id>frontend.stickiness_bytesInRatePeriod</id>
<label>Bytes in rate period</label>
<id>frontend.stickiness_httpFailRatePeriod</id>
<label>HTTP fail rate period</label>
<type>text</type>
<help><![CDATA[The length of the period over which the average is measured. It reports the average incoming bytes rate over that period, in bytes per period. Defaults to milliseconds. Optionally the unit may be specified as either "d", "h", "m", "s", "ms" or "us".]]></help>
<help><![CDATA[The length of the period over which the average is measured. It reports the average HTTP response fail error rate over that period, in requests per period. Defaults to milliseconds. Optionally the unit may be specified as either "d", "h", "m", "s", "ms" or "us".]]></help>
<advanced>true</advanced>
</field>
<field>
<id>frontend.stickiness_bytesOutRatePeriod</id>
<label>Bytes out rate period</label>
<id>frontend.stickiness_sessRatePeriod</id>
<label>Session rate period</label>
<type>text</type>
<help><![CDATA[The length of the period over which the average is measured. It reports the average outgoing bytes rate over that period, in bytes per period. Defaults to milliseconds. Optionally the unit may be specified as either "d", "h", "m", "s", "ms" or "us".]]></help>
<help><![CDATA[The length of the period over which the average is measured. It reports the average incoming session rate over that period, in sessions per period. Defaults to milliseconds. Optionally the unit may be specified as either "d", "h", "m", "s", "ms" or "us".]]></help>
<advanced>true</advanced>
</field>
<field>

View file

@ -11,10 +11,16 @@
<type>text</type>
<help>Description for this map file.</help>
</field>
<field>
<id>mapfile.type</id>
<label>Type</label>
<type>dropdown</type>
<help>The type of the map data.</help>
</field>
<field>
<id>mapfile.content</id>
<label>Content</label>
<type>textbox</type>
<help><![CDATA[Paste the content of your map file here. See the <a target="_blank" href="http://docs.haproxy.org/3.0/configuration.html#map">HAProxy documentation</a> for a full description.]]></help>
<help><![CDATA[Paste the content of your map file here. See the <a target="_blank" href="http://docs.haproxy.org/3.2/configuration.html#map">HAProxy documentation</a> for a full description.]]></help>
</field>
</form>

View file

@ -117,9 +117,15 @@
</field>
<field>
<id>server.sslSNI</id>
<label>SSL SNI</label>
<label>SSL SNI Name</label>
<type>text</type>
<help><![CDATA[The host name sent in the SNI TLS extension to the server.]]></help>
<help><![CDATA[The host name sent in the SNI TLS extension to the server. When present it will be preferred over the SNI expression.]]></help>
</field>
<field>
<id>server.sslSNIExpr</id>
<label>SSL SNI Expression</label>
<type>text</type>
<help><![CDATA[A HAProxy <a target="_blank" href="http://docs.haproxy.org/3.2/configuration.html##sni">SNI expression</a> to specify the data that will be sent in the SNI TLS extension to the server, e.g. req.hdr(host). When a SNI name is present it will be used instead and this option will be ignored.]]></help>
</field>
<field>
<id>server.sslVerify</id>

View file

@ -0,0 +1,309 @@
<?php
/**
* Copyright (C) 2026 Frank Wall
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
namespace OPNsense\HAProxy\Migrations;
use OPNsense\Base\BaseModelMigration;
class M5_0_0 extends BaseModelMigration
{
public function run($model)
{
foreach ($model->getNodeByReference('actions.action')->iterateItems() as $action) {
// Rules have an 'enabled' field now
$action->enabled = '1';
// Migrate TCP/HTTP rules to new format
switch ((string)$action->type) {
case 'http-request_add-header':
$action->type = 'http-request';
$action->http_request_action = 'add-header';
if (!empty((string)$action->http_request_add_header_name)) {
$action->http_request_option = (string)$action->http_request_add_header_name . ' ' . (string)$action->http_request_add_header_content;
$action->http_request_add_header_name = null;
$action->http_request_add_header_content = null;
}
break;
case 'http-request_allow':
$action->type = 'http-request';
$action->http_request_action = 'allow';
break;
case 'http-request_auth':
$action->type = 'http-request';
$action->http_request_action = 'auth';
if (!empty((string)$action->http_request_auth)) {
$action->http_request_option = 'realm ' . (string)$action->http_request_auth;
$action->http_request_auth = null;
}
break;
case 'http-request_del-header':
$action->type = 'http-request';
$action->http_request_action = 'del-header';
if (!empty((string)$action->http_request_del_header_name)) {
$action->http_request_option = (string)$action->http_request_del_header_name;
$action->http_request_del_header_name = null;
}
break;
case 'http-request_deny':
$action->type = 'http-request';
$action->http_request_action = 'deny';
break;
case 'http-request_lua':
$action->type = 'http-request';
$action->http_request_action = 'lua';
if (!empty((string)$action->http_request_lua)) {
$action->http_request_option = (string)$action->http_request_lua;
$action->http_request_lua = null;
}
break;
case 'http-request_redirect':
$action->type = 'http-request';
$action->http_request_action = 'redirect';
if (!empty((string)$action->http_request_redirect)) {
$action->http_request_option = (string)$action->http_request_redirect;
$action->http_request_redirect = null;
}
break;
case 'http-request_replace-header':
$action->type = 'http-request';
$action->http_request_action = 'replace-header';
if (!empty((string)$action->http_request_replace_header_name)) {
$action->http_request_option = (string)$action->http_request_replace_header_name . ' ' . (string)$action->http_request_replace_header_regex;
$action->http_request_replace_header_name = null;
$action->http_request_replace_header_regex = null;
}
break;
case 'http-request_replace-value':
$action->type = 'http-request';
$action->http_request_action = 'replace-value';
if (!empty((string)$action->http_request_replace_value_name)) {
$action->http_request_option = (string)$action->http_request_replace_value_name . ' ' . (string)$action->http_request_replace_value_regex;
$action->http_request_replace_value_name = null;
$action->http_request_replace_value_regex = null;
}
break;
case 'http-request_set-header':
$action->type = 'http-request';
$action->http_request_action = 'set-header';
if (!empty((string)$action->http_request_set_header_name)) {
$action->http_request_option = (string)$action->http_request_set_header_name . ' ' . (string)$action->http_request_set_header_content;
$action->http_request_set_header_name = null;
$action->http_request_set_header_content = null;
}
break;
case 'http-request_set-path':
$action->type = 'http-request';
$action->http_request_action = 'set-path';
if (!empty((string)$action->http_request_set_path)) {
$action->http_request_option = (string)$action->http_request_set_path;
$action->http_request_set_path = null;
}
break;
case 'http-request_set-var':
$action->type = 'http-request';
$action->http_request_action = 'set-var';
if (!empty((string)$action->http_request_set_var_name)) {
$action->http_request_option = '(' . (string)$action->http_request_set_var_scope . '.' . (string)$action->http_request_set_var_name . ') ' . (string)$action->http_request_set_var_expr;
$action->http_request_set_var_scope = null;
$action->http_request_set_var_name = null;
$action->http_request_set_var_expr = null;
}
break;
case 'http-request_silent-drop':
$action->type = 'http-request';
$action->http_request_action = 'silent-drop';
break;
case 'http-request_tarpit':
$action->type = 'http-request';
$action->http_request_action = 'tarpit';
break;
case 'http-request_use-service':
$action->type = 'http-request';
$action->http_request_action = 'use-service';
if (!empty((string)$action->http_request_use_service)) {
$action->http_request_option = (string)$action->http_request_use_service;
$action->http_request_use_service = null;
}
break;
case 'http-response_add-header':
$action->type = 'http-response';
$action->http_response_action = 'add-header';
if (!empty((string)$action->http_response_add_header_name)) {
$action->http_response_option = (string)$action->http_response_add_header_name . ' ' . (string)$action->http_response_add_header_content;
$action->http_response_add_header_name = null;
$action->http_response_add_header_content = null;
}
break;
case 'http-response_allow':
$action->type = 'http-response';
$action->http_response_action = 'allow';
break;
case 'http-response_del-header':
$action->type = 'http-response';
$action->http_response_action = 'del-header';
if (!empty((string)$action->http_response_del_header_name)) {
$action->http_response_option = (string)$action->http_response_del_header_name;
$action->http_response_del_header_name = null;
}
break;
case 'http-response_deny':
$action->type = 'http-response';
$action->http_response_action = 'deny';
break;
case 'http-response_lua':
$action->type = 'http-response';
$action->http_response_action = 'lua';
if (!empty((string)$action->http_response_lua)) {
$action->http_response_option = (string)$action->http_response_lua;
$action->http_response_lua = null;
}
break;
case 'http-response_replace-header':
$action->type = 'http-response';
$action->http_response_action = 'replace-header';
if (!empty((string)$action->http_response_replace_header_name)) {
$action->http_response_option = (string)$action->http_response_replace_header_name . ' ' . (string)$action->http_response_replace_header_regex;
$action->http_response_replace_header_name = null;
$action->http_response_replace_header_regex = null;
}
break;
case 'http-response_replace-value':
$action->type = 'http-response';
$action->http_response_action = 'replace-value';
if (!empty((string)$action->http_response_replace_value_name)) {
$action->http_response_option = (string)$action->http_response_replace_value_name . ' ' . (string)$action->http_response_replace_value_regex;
$action->http_response_replace_value_name = null;
$action->http_response_replace_value_regex = null;
}
break;
case 'http-response_set-header':
$action->type = 'http-response';
$action->http_response_action = 'set-header';
if (!empty((string)$action->http_response_set_header_name)) {
$action->http_response_option = (string)$action->http_response_set_header_name . ' ' . (string)$action->http_response_set_header_content;
$action->http_response_set_header_name = null;
$action->http_response_set_header_content = null;
}
break;
case 'http-response_set-status':
$action->type = 'http-response';
$action->http_response_action = 'set-status';
if (!empty((string)$action->http_response_set_status_code)) {
if (!empty((string)$action->http_response_set_status_reason)) {
$status_reason = ' reason "' . (string)$action->http_response_set_status_reason . '"';
} else {
$status_reason = '';
}
$action->http_response_option = (string)$action->http_response_set_status_code . $status_reason;
$action->http_response_set_status_code = null;
$action->http_response_set_status_reason = null;
}
break;
case 'http-response_set-var':
$action->type = 'http-response';
$action->http_response_action = 'set-var';
if (!empty((string)$action->http_response_set_var_name)) {
$action->http_response_option = '(' . (string)$action->http_response_set_var_scope . '.' . (string)$action->http_response_set_var_name . ') ' . (string)$action->http_response_set_var_expr;
$action->http_response_set_var_scope = null;
$action->http_response_set_var_name = null;
$action->http_response_set_var_expr = null;
}
break;
case 'tcp-request_connection_accept':
$action->type = 'tcp-request';
$action->tcp_request_action = 'connection_accept';
break;
case 'tcp-request_connection_reject':
$action->type = 'tcp-request';
$action->tcp_request_action = 'connection_reject';
break;
case 'tcp-request_content_accept':
$action->type = 'tcp-request';
$action->tcp_request_action = 'content_accept';
break;
case 'tcp-request_content_lua':
$action->type = 'tcp-request';
$action->tcp_request_action = 'content_lua';
if (!empty((string)$action->tcp_request_content_lua)) {
$action->tcp_request_option = (string)$action->tcp_request_content_lua;
$action->tcp_request_content_lua = null;
}
break;
case 'tcp-request_content_reject':
$action->type = 'tcp-request';
$action->tcp_request_action = 'content_reject';
break;
case 'tcp-request_content_use-service':
$action->type = 'tcp-request';
$action->tcp_request_action = 'content_use-service';
if (!empty((string)$action->tcp_request_content_use_service)) {
$action->tcp_request_option = (string)$action->tcp_request_content_use_service;
$action->tcp_request_content_use_service = null;
}
break;
case 'tcp-request_inspect-delay':
$action->type = 'tcp-request';
$action->tcp_request_action = 'inspect-delay';
if (!empty((string)$action->tcp_request_inspect_delay)) {
$action->tcp_request_option = (string)$action->tcp_request_inspect_delay;
$action->tcp_request_inspect_delay = null;
}
break;
case 'tcp-response_content_accept':
$action->type = 'tcp-response';
$action->tcp_response_action = 'content_accept';
break;
case 'tcp-response_content_close':
$action->type = 'tcp-response';
$action->tcp_response_action = 'content_close';
break;
case 'tcp-response_content_lua':
$action->type = 'tcp-response';
$action->tcp_response_action = 'content_lua';
if (!empty((string)$action->tcp_response_content_lua)) {
$action->tcp_response_option = (string)$action->tcp_response_content_lua;
$action->tcp_response_content_lua = null;
}
break;
case 'tcp-response_content_reject':
$action->type = 'tcp-response';
$action->tcp_response_action = 'content_reject';
break;
case 'tcp-response_inspect-delay':
$action->type = 'tcp-response';
$action->tcp_response_action = 'inspect-delay';
if (!empty((string)$action->tcp_response_inspect_delay)) {
$action->tcp_response_option = (string)$action->tcp_response_inspect_delay;
$action->tcp_response_inspect_delay = null;
}
break;
}
}
}
}

View file

@ -101,6 +101,7 @@ POSSIBILITY OF SUCH DAMAGE.
set:'/api/haproxy/settings/set_action/',
add:'/api/haproxy/settings/add_action/',
del:'/api/haproxy/settings/del_action/',
toggle:'/api/haproxy/settings/toggle_action/',
options: {
}
}
@ -702,7 +703,7 @@ POSSIBILITY OF SUCH DAMAGE.
<li>{{ lang._('Lastly, enable HAProxy using the %sService%s settings page.') | format('<b>', '</b>') }}</li>
</ul>
<p>{{ lang._('Please be aware that you need to %smanually%s add the required firewall rules for all configured services.') | format('<b>', '</b>') }}</p>
<p>{{ lang._('Further information is available in the %sofficial HAProxy documentation%s. Be sure to report bugs and request features on our %sGitHub issue page%s. Code contributions are also very welcome!') | format('<a href="http://docs.haproxy.org/3.0/configuration.html" target="_blank">', '</a>', '<a href="https://github.com/opnsense/plugins/issues/" target="_blank">', '</a>') }}</p>
<p>{{ lang._('Further information is available in the %sofficial HAProxy documentation%s. Be sure to report bugs and request features on our %sGitHub issue page%s. Code contributions are also very welcome!') | format('<a href="http://docs.haproxy.org/3.2/configuration.html" target="_blank">', '</a>', '<a href="https://github.com/opnsense/plugins/issues/" target="_blank">', '</a>') }}</p>
<br/>
</div>
</div>
@ -744,7 +745,7 @@ POSSIBILITY OF SUCH DAMAGE.
<li>{{ lang._('%sConditions:%s HAProxy is capable of extracting data from requests, responses and other connection data and match it against predefined patterns. Use these powerful patterns to compose a condition that may be used in multiple Rules.') | format('<b>', '</b>') }}</li>
<li>{{ lang._('%sRules:%s Perform a large set of actions if one or more %sConditions%s match. These Rules may be used in %sBackend Pools%s as well as %sPublic Services%s.') | format('<b>', '</b>', '<b>', '</b>', '<b>', '</b>', '<b>', '</b>') }}</li>
</ul>
<p>{{ lang._("For more information on HAProxy's %sACL feature%s see the %sofficial documentation%s.") | format('<b>', '</b>', '<a href="http://docs.haproxy.org/3.0/configuration.html#7" target="_blank">', '</a>') }}</p>
<p>{{ lang._("For more information on HAProxy's %sACL feature%s see the %sofficial documentation%s.") | format('<b>', '</b>', '<a href="http://docs.haproxy.org/3.2/configuration.html#7" target="_blank">', '</a>') }}</p>
<p>{{ lang._('Note that it is possible to directly add options to the HAProxy configuration by using the "option pass-through", a setting that is available for several configuration items. It allows you to implement configurations that are currently not officially supported by this plugin. It is strongly discouraged to rely on this feature. Please report missing features on our GitHub page!') | format('<b>', '</b>') }}</p>
<br/>
</div>
@ -759,7 +760,7 @@ POSSIBILITY OF SUCH DAMAGE.
<li>{{ lang._('%sGroup:%s A optional list containing one or more users. Groups usually make it easier to manage permissions for a large number of users') | format('<b>', '</b>') }}</li>
</ul>
<p>{{ lang._('Note that users and groups must be selected from the Backend Pool or Public Service configuration in order to be used for authentication. In addition to this users and groups may also be used in Rules/Conditions.') }}</p>
<p>{{ lang._("For more information on HAProxy's %suser/group management%s see the %sofficial documentation%s.") | format('<b>', '</b>', '<a href="http://docs.haproxy.org/3.0/configuration.html#3.4" target="_blank">', '</a>') }}</p>
<p>{{ lang._("For more information on HAProxy's %suser/group management%s see the %sofficial documentation%s.") | format('<b>', '</b>', '<a href="http://docs.haproxy.org/3.2/configuration.html#3.4" target="_blank">', '</a>') }}</p>
<br/>
</div>
</div>
@ -777,7 +778,7 @@ POSSIBILITY OF SUCH DAMAGE.
<li>{{ lang._("%sCache:%s HAProxy's cache which was designed to perform cache on small objects (favicon, css, etc.). This is a minimalist low-maintenance cache which runs in RAM.") | format('<b>', '</b>', '<b>', '</b>') }}</li>
<li>{{ lang._("%sPeers:%s Configure a communication channel between two HAProxy instances. This will propagate entries of any data-types in stick-tables between these HAProxy instances over TCP connections in a multi-master fashion. Useful when aiming for a seamless failover in a HA setup.") | format('<b>', '</b>', '<b>', '</b>') }}</li>
</ul>
<p>{{ lang._("For more details visit HAProxy's official documentation regarding the %sStatistics%s, %sCache%s and %sPeers%s features.") | format('<a href="http://docs.haproxy.org/3.0/configuration.html#stats%20enable" target="_blank">', '</a>', '<a href="http://docs.haproxy.org/3.0/configuration.html#10" target="_blank">', '</a>', '<a href="http://docs.haproxy.org/3.0/configuration.html#3.5" target="_blank">', '</a>') }}</p>
<p>{{ lang._("For more details visit HAProxy's official documentation regarding the %sStatistics%s, %sCache%s and %sPeers%s features.") | format('<a href="http://docs.haproxy.org/3.2/configuration.html#stats%20enable" target="_blank">', '</a>', '<a href="http://docs.haproxy.org/3.2/configuration.html#10" target="_blank">', '</a>', '<a href="http://docs.haproxy.org/3.2/configuration.html#3.5" target="_blank">', '</a>') }}</p>
<br/>
</div>
</div>
@ -795,7 +796,7 @@ POSSIBILITY OF SUCH DAMAGE.
<li>{{ lang._("%sResolvers:%s This feature allows in-depth configuration of how HAProxy handles name resolution and interacts with name resolvers (DNS). Each resolver configuration can be used in %sBackend Pools%s to apply individual name resolution configurations.") | format('<b>', '</b>', '<b>', '</b>') }}</li>
<li>{{ lang._("%sE-Mail Alerts:%s It is possible to send email alerts when the state of servers changes. Each configuration can be used in %sBackend Pools%s to send e-mail alerts to the configured recipient.") | format('<b>', '</b>', '<b>', '</b>') }}</li>
</ul>
<p>{{ lang._("For more details visit HAProxy's official documentation regarding the %sError Messages%s, %sLua Script%s and the %sMap Files%s features. More information on HAProxy's CPU Affinity is also available %shere%s, %shere%s and %shere%s. A detailed explanation of the resolvers feature can be found %shere%s.") | format('<a href="http://docs.haproxy.org/3.0/configuration.html#4-errorfile" target="_blank">', '</a>', '<a href="http://docs.haproxy.org/3.0/configuration.html#lua-load" target="_blank">', '</a>', '<a href="http://docs.haproxy.org/3.0/configuration.html#map" target="_blank">', '</a>' ,'<a href="http://docs.haproxy.org/3.0/configuration.html#cpu-map" target="_blank">', '</a>' ,'<a href="http://docs.haproxy.org/3.0/configuration.html#bind-process" target="_blank">', '</a>' ,'<a href="http://docs.haproxy.org/3.0/configuration.html#process" target="_blank">', '</a>','<a href="http://docs.haproxy.org/3.0/configuration.html#5.3.2" target="_blank">', '</a>') }}</p>
<p>{{ lang._("For more details visit HAProxy's official documentation regarding the %sError Messages%s, %sLua Script%s and the %sMap Files%s features. More information on HAProxy's CPU Affinity is also available %shere%s, %shere%s and %shere%s. A detailed explanation of the resolvers feature can be found %shere%s.") | format('<a href="http://docs.haproxy.org/3.2/configuration.html#4-errorfile" target="_blank">', '</a>', '<a href="http://docs.haproxy.org/3.2/configuration.html#lua-load" target="_blank">', '</a>', '<a href="http://docs.haproxy.org/3.2/configuration.html#map" target="_blank">', '</a>' ,'<a href="http://docs.haproxy.org/3.2/configuration.html#cpu-map" target="_blank">', '</a>' ,'<a href="http://docs.haproxy.org/3.2/configuration.html#bind-process" target="_blank">', '</a>' ,'<a href="http://docs.haproxy.org/3.2/configuration.html#process" target="_blank">', '</a>','<a href="http://docs.haproxy.org/3.2/configuration.html#5.3.2" target="_blank">', '</a>') }}</p>
<br/>
</div>
</div>
@ -860,6 +861,7 @@ POSSIBILITY OF SUCH DAMAGE.
<th data-column-id="serverid" data-type="number" data-visible="false">{{ lang._('Server ID') }}</th>
<th data-column-id="name" data-type="string">{{ lang._('Server Name') }}</th>
<th data-column-id="type" data-type="string">{{ lang._('Type') }}</th>
<th data-column-id="mode" data-type="string">{{ lang._('Mode') }}</th>
<th data-column-id="address" data-type="string">{{ lang._('Server Address') }}</th>
<th data-column-id="port" data-type="string">{{ lang._('Server Port') }}</th>
<th data-column-id="description" data-type="string">{{ lang._('Description') }}</th>
@ -910,6 +912,7 @@ POSSIBILITY OF SUCH DAMAGE.
<table id="grid-actions" class="table table-condensed table-hover table-striped table-responsive" data-editDialog="DialogAction" data-editAlert="haproxyChangeMessage">
<thead>
<tr>
<th data-column-id="enabled" data-width="6em" data-type="string" data-formatter="rowtoggle">{{ lang._('Enabled') }}</th>
<th data-column-id="actionid" data-type="number" data-visible="false">{{ lang._('Rule ID') }}</th>
<th data-column-id="name" data-type="string">{{ lang._('Rule Name') }}</th>
<th data-column-id="description" data-type="string">{{ lang._('Description') }}</th>

View file

@ -8,14 +8,14 @@
{# ################## #}
{% macro getCA(refId) -%}
{% set result = '{}' %}
{% for data in helpers.getNodeByTag('ca') if data.refid == refId %}
{% for data in helpers.toList('ca') if data.refid == refId %}
{{ data.crt -}}
{% else %}
{{ "{}" }}
{% endfor %}
{%- endmacro %}
{% macro getCert(refId, indent=4) -%}
{% for data in helpers.getNodeByTag('cert') if data.refid == refId %}
{% for data in helpers.toList('cert') if data.refid == refId %}
{% if data.caref %}
{% do data.update({'ca': getCA(data.caref)}) %}
{% else %}