Merge pull request #1933 from fraenki/haproxy_1925

net/haproxy: release 2.24
This commit is contained in:
Frank Wall
2020-08-20 01:03:40 +02:00
committed by GitHub
20 changed files with 1253 additions and 475 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
PLUGIN_NAME= haproxy
PLUGIN_VERSION= 2.23
PLUGIN_VERSION= 2.24
PLUGIN_COMMENT= Reliable, high performance TCP/HTTP load balancer
PLUGIN_DEPENDS= haproxy20
PLUGIN_MAINTAINER= opnsense@moov.de
+241 -1
View File
@@ -3,4 +3,244 @@ availability, load balancing, and proxying for TCP and HTTP-based
applications. It is particularly suited for web sites crawling under
very high loads while needing persistence or Layer7 processing.
WWW: https://haproxy.org/
Plugin Changelog
================
2.24
Added:
* add support for http-request set-var and http-response set-var (#1796)
* add group as userlist to HAProxy config to make it usable in rules/conditions (#1796)
* add support for resolvers to customize how HAProxy handles name resolution (#1787)
* add support for init-addr to allow HAProxy to start when DNS does not resolve (#1787)
Fixed:
* honor sort order of all rules, remove special handling of "use_[backend|server]" options (#1925)
Changed:
* add "Save & Test syntax" button to all "Settings" pages
* add "introduction" page for Settings tab
* streamine "Settings" subtabs
2.23
Fixed:
* add missing acl SNI regex text field (#1883)
2.22
Added:
* enable SSL verification for a server when "Force SSL" is enabled in the associated health check (#1761)
* use the systems local Root CA Certificates for SSL verification when no CA was selected (#1761)
Fixed:
* fix label of src_sess_cnt (#1780)
* fix invalid use of option httplog (resolves a warning in config test)
* fix invalid use of option forwardfor (resolves a warning in config test)
2.21
Fixed:
* override "graceful" restart if required (#1745)
2.20
Changed:
* update stats socket permission for easier (non-root) monitoring (#1232)
2.19
Added:
* switch to HAProxy 2.0 release series (#1089)
* add support for the "max-object-size" cache configuration option (#1458)
* add end-to-end HTTP/2 support (details)
* add support for the random balancing algorithm (details)
Fixed:
* fix IPv6 validation in frontends (#540)
Changed:
* add IPv6 example to listen address help text
* update URLs to HAProxy 2.0 documentation
* frontends: move HTTP/2 option to HTTP settings
* change order of frontend options
2.18
Added:
* add support for HAProxy cache (#1442)
Changed:
* change http-reuse default (align with HAProxy's default value, #1439)
2.17
Added:
* allow backends without servers (#1304)
* add support for deciphered SNI check in ACLs (#1365)
* allow to force SSL for health checks (#1282)
Changed:
* improve wording for SNI conditions to differentiate between deciphered vs. not deciphered
2.16
Fixed:
* allow hyphens in server, frontend and backend names (#1346)
2.15
Added:
* rules can finally be sorted by using drag'n'drop (#582)
* added "enabled" field to servers (#1208)
* TCP inspection delays are supported in rules (#1188)
Changed:
* server option "mode" is always visible, no longer requires "advanced mode" (#1208)
* most dropdown fields finally have alphanumeric sorting (#687, opnsense/core#3251)
* rules: align indentation of comments in haproxy.conf
2.14
Fixed:
* bulk deleting does not work (#1164)
Changed:
* migrate to mutable controller (required to fix #1164)
2.13
Added:
* support multiple CAs for SSL verification for servers
Fixed:
* fix export of CAs (#1074)
Changed:
* export a frontend's default SSL certificate (#1088)
* it is no longer required to add a default SSL certificate to a frontend's "certificates" list (#1088)
* avoid duplicate entry in certlist file if a default SSL certificate is specified
* always show "Default certificate" option in frontends, it's no longer an "advanced" option
2.12
Added:
* add support for HTTP/2 (#1047)
2.11
Fixed:
* fix warning: a 'http-request' rule placed after a 'use_backend' rule will still be processed before (#999)
* fix wrong parameter name when using tcp-request content lua (#999)
Changed:
* internal: trim whitespace, remove empty lines in haproxy.conf (#999)
2.10
Added:
* add support for multithreading (available as new option in Settings -> Global Parameters) (#1003)
* add support for client certificate authentication (#426)
* add support for HTTP Basic Auth to frontends/backends/ACLs (#300)
* add basic user/group management functionality (supports Basic Auth as well as stats users)
* add new CPU Affinity Rules feature (which is a combination of HAProxy's cpu-map, bind-process and process options) (see #1003 for a short explanation)
Fixed:
* function "http-request header-delete" generated a corrupted haproxy.conf (#882)
Changed:
* migrate all stats users from old (and cumbersome) username:password format to new user management feature
* internal: use /tmp for autogenerated files (now they are automatically cleaned up on boot)
* internal: change filename of cert lists from id.crtlist to id.certlist
2.9
Added:
* add "http-reuse" option (#836)
2.8
Added:
* support truly seamless reloads (#224)
* add support for the "map" feature (#180)
Fixed:
* fix reload of service template in "reconfigure" action (#690; introduced in 7381101)
* enabling "hard stop" mode resulted in an invalid "hardrestart" RC command
Changed:
* use "reload" instead of "restart" RC action
* if "reload" fails, also issue a "restart" command (required when enabling seamless reloads)
* start progress animation (spinner) earlier when applying settings
2.7
Added:
* support rise/fall parameters in backends and health checks
* support set-path in ACLs
* support for cookie-based persistence (#680)
Fixed:
* fix X-Forwarded-For option disappeared (#647)
* fix validation for source address fields (#695)
2.6
Added:
* add support for http-response set-status in ACLs to manipulate HTTP status codes
Fixed:
* fix invalid backend name when using nbsrv in ACLs
2.5
Added:
* add support for the PROXY protocol (i.e. in combination with postfix or dovecot)
* switch to HAProxy 1.8.4
2.4
Added:
* add support for "preload" and "includeSubDomains" HSTS options (#447)
* support session sync / HAProxy peers (#165)
* add new HTTP timeout options (to mitigate slowloris attacks) (#202)
* allow tracking additional values in stick-tables (#202)
* add stick-table config for frontends (optional, disabled by default) (#202)
* add support for many new conditions (#202)
* enable sticky counters for frontend stick-tables (required for new conditions) (#202)
Changed:
* relax validation masks for several "name" fields (to allow more "special" characters)
* switch to new mutable service controller
2.3
Added:
* new option to hide introduction pages (#340)
Fixed:
* fix wrong introduction for "Advanced" tab (regression introduced in 8cdcbda)
2.2
Fixed:
* fix for rules parameters (values could not be saved, leading to invalid rules)
2.1
Fixed:
* do not enable HSTS unconditionally (now works as described in #380)
* enable HSTS only for HTTP frontends
2.0
Added:
* new GUI to guide new users and improve general usability (#208)
* make server port optional (#341)
* new SSL settings for frontends (#380)
* new global SSL default values (#380)
* new option for HTTP Strict Transport Security (#380)
Fixed:
* rephrase text to make it clear that aliases cannot be used (#360)
* rephrase text to make it clear that "use_server" will only work for backends (#361)
@@ -379,4 +379,34 @@ class SettingsController extends ApiMutableModelControllerBase
{
return $this->searchBase('users.user', array('enabled', 'name', 'description'), 'name');
}
public function getresolverAction($uuid = null)
{
return $this->getBase('resolver', 'resolvers.resolver', $uuid);
}
public function setresolverAction($uuid)
{
return $this->setBase('resolver', 'resolvers.resolver', $uuid);
}
public function addresolverAction()
{
return $this->addBase('resolver', 'resolvers.resolver');
}
public function delresolverAction($uuid)
{
return $this->delBase('resolvers.resolver', $uuid);
}
public function toggleresolverAction($uuid, $enabled = null)
{
return $this->toggleBase('resolvers.resolver', $uuid);
}
public function searchresolversAction()
{
return $this->searchBase('resolvers.resolver', array('enabled', 'name', 'nameservers'), 'name');
}
}
@@ -44,19 +44,26 @@ class IndexController extends \OPNsense\Base\IndexController
public function indexAction()
{
// include form definitions
$this->view->mainForm = $this->getForm("main");
$this->view->formDialogFrontend = $this->getForm("dialogFrontend");
$this->view->formDialogBackend = $this->getForm("dialogBackend");
$this->view->formDialogServer = $this->getForm("dialogServer");
$this->view->formDialogHealthcheck = $this->getForm("dialogHealthcheck");
$this->view->formDialogAction = $this->getForm("dialogAction");
$this->view->formDialogAcl = $this->getForm("dialogAcl");
$this->view->formDialogUser = $this->getForm("dialogUser");
$this->view->formDialogGroup = $this->getForm("dialogGroup");
$this->view->formDialogLua = $this->getForm("dialogLua");
$this->view->formDialogErrorfile = $this->getForm("dialogErrorfile");
$this->view->formDialogMapfile = $this->getForm("dialogMapfile");
$this->view->formDialogAction = $this->getForm("dialogAction");
$this->view->formDialogBackend = $this->getForm("dialogBackend");
$this->view->formDialogCpu = $this->getForm("dialogCpu");
$this->view->formDialogErrorfile = $this->getForm("dialogErrorfile");
$this->view->formDialogFrontend = $this->getForm("dialogFrontend");
$this->view->formDialogGroup = $this->getForm("dialogGroup");
$this->view->formDialogHealthcheck = $this->getForm("dialogHealthcheck");
$this->view->formDialogLua = $this->getForm("dialogLua");
$this->view->formDialogMapfile = $this->getForm("dialogMapfile");
$this->view->formDialogResolver = $this->getForm("dialogResolver");
$this->view->formDialogServer = $this->getForm("dialogServer");
$this->view->formDialogUser = $this->getForm("dialogUser");
$this->view->generalCacheForm = $this->getForm("generalCache");
$this->view->generalDefaultsForm = $this->getForm("generalDefaults");
$this->view->generalLoggingForm = $this->getForm("generalLogging");
$this->view->generalPeersForm = $this->getForm("generalPeers");
$this->view->generalSettingsForm = $this->getForm("generalSettings");
$this->view->generalStatsForm = $this->getForm("generalStats");
$this->view->generalTuningForm = $this->getForm("generalTuning");
// set additional view parameters
$mdlHAProxy = new \OPNsense\HAProxy\HAProxy();
$this->view->showIntro = (string)$mdlHAProxy->general->showIntro;
@@ -203,6 +203,28 @@
<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>
@@ -310,6 +332,28 @@
<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>
@@ -54,6 +54,13 @@
<help><![CDATA[Add servers to this backend. Use TAB key to complete typing.]]></help>
<hint>Type server name or choose from list.</hint>
</field>
<field>
<id>backend.linkedResolver</id>
<label>Resolver</label>
<type>dropdown</type>
<help><![CDATA[Select the custom resolver configuration that should be used for all servers in this backend.]]></help>
<advanced>true</advanced>
</field>
<field>
<id>backend.source</id>
<label>Source address</label>
@@ -24,4 +24,10 @@
<allownew>true</allownew>
<hint>Type username or choose from list.</hint>
</field>
<field>
<id>group.add_userlist</id>
<label>Add userlist</label>
<type>checkbox</type>
<help>Usually HAproxy userlists are created automatically in a context sensitive way. This option adds this group as userlist, so that it can be referenced in rules/conditions. All special and non-alphanumeric characters will be removed from the userlist name.</help>
</field>
</form>
@@ -0,0 +1,54 @@
<form>
<field>
<id>resolver.enabled</id>
<label>Enabled</label>
<type>checkbox</type>
<help>Enable this resolver configuration.</help>
</field>
<field>
<id>resolver.name</id>
<label>Name</label>
<type>text</type>
<help>Choose a name for this resolver configuration.</help>
</field>
<field>
<id>resolver.description</id>
<label>Description</label>
<type>text</type>
<help>Choose a optional description for this resolver configuration.</help>
</field>
<field>
<id>resolver.nameservers</id>
<label>Nameservers</label>
<type>select_multiple</type>
<style>tokenize</style>
<allownew>true</allownew>
<sortable>true</sortable>
<help><![CDATA[Add nameservers to this resolver configuration, i.e. 127.0.0.1:53 or 192.168.1.1:53. Use TAB key to complete typing.]]></help>
<hint>Enter ip:port here. Finish with TAB.</hint>
</field>
<field>
<id>resolver.parse_resolv_conf</id>
<label>Use resolv.conf</label>
<type>checkbox</type>
<help>Add all nameservers found in /etc/resolv.conf to this resolver configuration.</help>
</field>
<field>
<id>resolver.resolve_retries</id>
<label>Resolve Retries</label>
<type>text</type>
<help><![CDATA[This configures the number of queries to send to resolve a server name before giving up.]]></help>
</field>
<field>
<id>resolver.timeout_resolve</id>
<label>Resolve Timeout</label>
<type>text</type>
<help><![CDATA[This configures the default time to trigger name resolutions when no other time applied. Enter a number followed by one of the supported suffixes "d" (days), "h" (hour), "m" (minute), "s" (seconds), "ms" (miliseconds).]]></help>
</field>
<field>
<id>resolver.timeout_retry</id>
<label>Retry Timeout</label>
<type>text</type>
<help><![CDATA[This configures the default time between two DNS queries, when no valid response has been received. Enter a number followed by one of the supported suffixes "d" (days), "h" (hour), "m" (minute), "s" (seconds), "ms" (miliseconds).]]></help>
</field>
</form>
@@ -0,0 +1,30 @@
<form>
<field>
<label>Cache</label>
<type>header</type>
</field>
<field>
<id>haproxy.general.cache.enabled</id>
<label>Cache enabled</label>
<type>checkbox</type>
<help><![CDATA[Enable HAProxy's cache which was designed to perform cache on small objects (favicon, css...). This is a minimalist low-maintenance cache which runs in RAM.]]></help>
</field>
<field>
<id>haproxy.general.cache.totalMaxSize</id>
<label>Maximum Size of Cache (MB)</label>
<type>text</type>
<help><![CDATA[Define the size in RAM of the cache in megabytes. This size is split in blocks of 1kB which are used by the cache entries. Its maximum value is 4095.]]></help>
</field>
<field>
<id>haproxy.general.cache.maxAge</id>
<label>Maximum Object Age (sec)</label>
<type>text</type>
<help><![CDATA[Define the maximum expiration duration. Cache-Control response headers will be respected if they are less than this value. The default value is 60 seconds.]]></help>
</field>
<field>
<id>haproxy.general.cache.maxObjectSize</id>
<label>Maximum Object Size (bytes)</label>
<type>text</type>
<help><![CDATA[Define the maximum size of the objects to be cached. Must not be greater than an half of the maximum size of the cache. If not set, it equals to a 256th of the cache size. All objects with sizes larger than this value will not be cached.]]></help>
</field>
</form>
@@ -0,0 +1,63 @@
<form>
<field>
<label>Default Parameters</label>
<type>header</type>
</field>
<field>
<id>haproxy.general.defaults.maxConnections</id>
<label>Max. Connections</label>
<type>text</type>
<help><![CDATA[Set the maximum number of concurrent connections for this frontend.]]></help>
</field>
<field>
<id>haproxy.general.defaults.timeoutClient</id>
<label>Client Timeout</label>
<type>text</type>
<help><![CDATA[Set the maximum inactivity time on the client side. Defaults to milliseconds. Optionally the unit may be specified as either "d", "h", "m", "s", "ms" or "us".]]></help>
</field>
<field>
<id>haproxy.general.defaults.timeoutConnect</id>
<label>Connection Timeout</label>
<type>text</type>
<help><![CDATA[Set the maximum time to wait for a connection attempt to a server to succeed. Defaults to milliseconds. Optionally the unit may be specified as either "d", "h", "m", "s", "ms" or "us".]]></help>
</field>
<field>
<id>haproxy.general.defaults.timeoutCheck</id>
<label>Check Timeout</label>
<type>text</type>
<help><![CDATA[Sets an additional read timeout for running health checks on a server. Defaults to milliseconds. Optionally the unit may be specified as either "d", "h", "m", "s", "ms" or "us".]]></help>
</field>
<field>
<id>haproxy.general.defaults.timeoutServer</id>
<label>Server Timeout</label>
<type>text</type>
<help><![CDATA[Set the maximum inactivity time on the server side. Defaults to milliseconds. Optionally the unit may be specified as either "d", "h", "m", "s", "ms" or "us".]]></help>
</field>
<field>
<id>haproxy.general.defaults.retries</id>
<label>Retries</label>
<type>text</type>
<help><![CDATA[Set the number of retries to perform on a server after a connection failure (default is 3).]]></help>
</field>
<field>
<id>haproxy.general.defaults.redispatch</id>
<label>Session redistribution</label>
<type>dropdown</type>
<help><![CDATA[Enable or disable session redistribution in case of connection failure.]]></help>
</field>
<field>
<id>haproxy.general.defaults.init_addr</id>
<label>DNS Resolve Order</label>
<type>select_multiple</type>
<style>tokenize</style>
<sortable>true</sortable>
<help><![CDATA[Indicates in which order server addresses should be resolved upon startup. Method "last" suggests to pick the address which appears in the state file. Method "libc" uses the libc's internal resolver. Method "none" specifically indicates that the server should start without any valid IP address in a down state. It can be useful to ignore some DNS issues upon startup, waiting for the situation to get fixed later. Defaults to "last,libc".]]></help>
</field>
<field>
<id>haproxy.general.defaults.customOptions</id>
<label>Custom options</label>
<type>textbox</type>
<help><![CDATA[These lines will be added to the defaults settings of to the HAProxy configuration file.<br/><div class="text-info"><b>NOTE:</b> The syntax will not be checked, use at your own risk!</div>]]></help>
<advanced>true</advanced>
</field>
</form>
@@ -0,0 +1,31 @@
<form>
<field>
<label>Logging</label>
<type>header</type>
</field>
<field>
<id>haproxy.general.logging.host</id>
<label>Log Host</label>
<type>text</type>
<help><![CDATA[Indicates where to send the logs. Takes an IPv4 or IPv6 address optionally followed by a colon (':') and a UDP port, i.e. 127.0.0.1 or 10.0.0.1:514]]></help>
</field>
<field>
<id>haproxy.general.logging.facility</id>
<label>Syslog facility</label>
<type>dropdown</type>
<help><![CDATA[Choose one of the 24 standard syslog facilities. The default value is local0.]]></help>
</field>
<field>
<id>haproxy.general.logging.level</id>
<label>Filter syslog level</label>
<type>dropdown</type>
<help><![CDATA[Can be specified to filter outgoing messages. By default, all messages are sent. If a level is specified, only messages with a severity at least as important as this level will be sent.]]></help>
</field>
<field>
<id>haproxy.general.logging.length</id>
<label>Max. line length</label>
<type>text</type>
<help><![CDATA[Specify an optional maximum line length in characters. Log lines larger than this value will be truncated before being sent. The reason is that syslog servers act differently on log line length. All servers support the default value of 1024 characters, but some servers simply drop larger lines while others do log them.]]></help>
<advanced>true</advanced>
</field>
</form>
@@ -0,0 +1,56 @@
<form>
<field>
<label>Peers</label>
<type>header</type>
</field>
<field>
<id>haproxy.general.peers.enabled</id>
<label>Enable peers</label>
<type>checkbox</type>
<help><![CDATA[Enable or disable HAProxy peers. This will propagate entries of any data-types in stick-tables between several HAProxy instances over TCP connections in a multi-master fashion.]]></help>
</field>
<field>
<label>Peer 1 (this host)</label>
<type>header</type>
</field>
<field>
<id>haproxy.general.peers.name1</id>
<label>Peer name (FQDN)</label>
<type>text</type>
<help><![CDATA[The name of the peer. This is usually the full hostname to make it possible for HAProxy to recognize the local peer. If HAProxy is unable to find the local peer it will fail to start.]]></help>
</field>
<field>
<id>haproxy.general.peers.listen1</id>
<label>Listen address (IP)</label>
<type>text</type>
<help><![CDATA[The listen address of the local peer or the address of the remote peer.]]></help>
</field>
<field>
<id>haproxy.general.peers.port1</id>
<label>TCP Port</label>
<type>text</type>
<help><![CDATA[The TCP port that should be used for connections to this peer. It must not be used by any other service.]]></help>
</field>
<field>
<label>Peer 2 (remote host)</label>
<type>header</type>
</field>
<field>
<id>haproxy.general.peers.name2</id>
<label>Peer name (FQDN)</label>
<type>text</type>
<help><![CDATA[The name of the peer. This is usually the full hostname to make it possible for HAProxy to recognize the local peer. If HAProxy is unable to find the local peer it will fail to start.]]></help>
</field>
<field>
<id>haproxy.general.peers.listen2</id>
<label>Listen address (IP)</label>
<type>text</type>
<help><![CDATA[The listen address of the local peer or the address of the remote peer.]]></help>
</field>
<field>
<id>haproxy.general.peers.port2</id>
<label>TCP Port</label>
<type>text</type>
<help><![CDATA[The TCP port that should be used for connections to this peer. It must not be used by any other service.]]></help>
</field>
</form>
@@ -0,0 +1,30 @@
<form>
<field>
<label>Service</label>
<type>header</type>
</field>
<field>
<id>haproxy.general.enabled</id>
<label>Enable HAProxy</label>
<type>checkbox</type>
<help>Enable or disable the HAProxy service.</help>
</field>
<field>
<id>haproxy.general.gracefulStop</id>
<label>Graceful stop</label>
<type>checkbox</type>
<help><![CDATA[Enable HAProxy's graceful stop mode. In this mode HAProxy will continue to process existing connections until they close. Note that this may severely slow down HAProxy's shutdown, depending on the configured timeout values. If graceful stop mode is not enabled, HAProxy will use the hard stop mode where it immediately quits and all established connections are closed. Hard stop mode is recommended.]]></help>
</field>
<field>
<id>haproxy.general.seamlessReload</id>
<label>Seamless reload</label>
<type>checkbox</type>
<help><![CDATA[HAProxy will handle service restarts in a way that no connections are dropped. This is the best restart mode, because it has no impact on user experience. That being said, there might be edge cases where seamless reloads lead to unexpected behaviour.]]></help>
</field>
<field>
<id>haproxy.general.showIntro</id>
<label>Show introduction pages</label>
<type>checkbox</type>
<help><![CDATA[Uncheck to hide all additional introduction pages. Requires a manual page reload for the change to take effect.]]></help>
</field>
</form>
@@ -0,0 +1,60 @@
<form>
<field>
<label>Statistics</label>
<type>header</type>
</field>
<field>
<id>haproxy.general.stats.enabled</id>
<label>Stats enabled</label>
<type>checkbox</type>
<help><![CDATA[Enable HAProxy's statistics page.]]></help>
</field>
<field>
<id>haproxy.general.stats.port</id>
<label>Local stats TCP port</label>
<type>text</type>
<help><![CDATA[Choose a TCP port to be used for the local statistics page. The default value is 8822.]]></help>
<advanced>true</advanced>
</field>
<field>
<id>haproxy.general.stats.remoteEnabled</id>
<label>Enable remote access</label>
<type>checkbox</type>
<help><![CDATA[Enable remote access to HAProxy's statistics page. <b>This may be a security risk if you do not enable authentication!</b> Note that you need to add appropiate firewall rules for this to work.]]></help>
</field>
<field>
<id>haproxy.general.stats.remoteBind</id>
<label>Remote listen addresses</label>
<type>select_multiple</type>
<style>tokenize</style>
<allownew>true</allownew>
<help><![CDATA[Configure listen addresses for the statistics page to enable remote access, i.e. 10.0.0.1:8080 or haproxy.example.com:8999. Use TAB key to complete typing a listen address.]]></help>
<hint>Enter address:port here. Finish with TAB.</hint>
</field>
<field>
<id>haproxy.general.stats.authEnabled</id>
<label>Enable authentication</label>
<type>checkbox</type>
</field>
<field>
<id>haproxy.general.stats.allowedUsers</id>
<label>Allowed Users</label>
<type>select_multiple</type>
<allownew>true</allownew>
<hint>Type username or choose from list.</hint>
</field>
<field>
<id>haproxy.general.stats.allowedGroups</id>
<label>Allowed Groups</label>
<type>select_multiple</type>
<allownew>true</allownew>
<hint>Type group or choose from list.</hint>
</field>
<field>
<id>haproxy.general.stats.customOptions</id>
<label>Custom options</label>
<type>textbox</type>
<help><![CDATA[These lines will be added to the statistics settings of to the HAProxy configuration file.<br/><div class="text-info"><b>NOTE:</b> The syntax will not be checked, use at your own risk!</div>]]></help>
<advanced>true</advanced>
</field>
</form>
@@ -0,0 +1,102 @@
<form>
<field>
<label>Global Parameters</label>
<type>header</type>
</field>
<field>
<id>haproxy.general.tuning.root</id>
<label>Run as root</label>
<type>checkbox</type>
<help><![CDATA[Enable or disable HAProxy running as root.<br/><div class="text-info"><b>NOTE:</b> Enabling root could be a security issue but it's required by some feature.</div>]]></help>
<advanced>true</advanced>
</field>
<field>
<id>haproxy.general.tuning.nbproc</id>
<label>HAProxy processes</label>
<type>text</type>
<help><![CDATA[Number of HAProxy processes to start.<br/><div class="text-info"><b>NOTE:</b> You may experience random issues in multi-process mode. For more information about the "nbproc" option please see the HAProxy Documentation.</div>]]></help>
<advanced>true</advanced>
</field>
<field>
<id>haproxy.general.tuning.nbthread</id>
<label>HAProxy threads</label>
<type>text</type>
<help><![CDATA[Number of threads to create for each HAProxy process.]]></help>
</field>
<field>
<id>haproxy.general.tuning.maxConnections</id>
<label>Maximum connections</label>
<type>text</type>
<help><![CDATA[Sets the maximum number of concurrent connections per HAProxy process.<br/><div class="text-info"><b>NOTE:</b> HAProxy will not be able to allocate enough memory if you set this value too high. Consider raising the settings for kern.maxfiles and kern.maxfilesperproc if you need to specify a non-default value.</div>]]></help>
</field>
<field>
<id>haproxy.general.tuning.sslServerVerify</id>
<label>Verify SSL Server Certificates</label>
<type>dropdown</type>
<help><![CDATA[This enforces a certain behavior for SSL verify on servers, ignoring per-server settings. If set to 'enforce verify', server certificates are verified. If set to 'disable verify', server certificates are not verified. The default is 'no preference' to only use per-server configurations and not enforce a global default for all servers.]]></help>
</field>
<field>
<id>haproxy.general.tuning.maxDHSize</id>
<label>Maximum SSL DH Size</label>
<type>text</type>
<help><![CDATA[Sets the maximum size of the Diffie-Hellman parameters used for generating the ephemeral/temporary Diffie-Hellman key in case of DHE key exchange (default is 1024).<br/><div class="text-info"><b>NOTE:</b> Higher values will increase the CPU load. For more information about the "tune.ssl.default-dh-param" option please see the HAProxy Documentation.</div>]]></help>
</field>
<field>
<id>haproxy.general.tuning.bufferSize</id>
<label>Buffer size</label>
<type>text</type>
<help><![CDATA[Change the buffer size (in bytes). Lower values allow more sessions to coexist in the same amount of RAM, and higher values allow some applications with very large cookies to work. The default value is 16384. <br/><div class="text-info"><b>NOTE:</b> It is strongly recommended not to change this from the default value, as very low values will break some services such as statistics, and values larger than default size will increase memory usage, possibly causing the system to run out of memory.</div>]]></help>
<advanced>true</advanced>
</field>
<field>
<id>haproxy.general.tuning.checkBufferSize</id>
<label>Health check buffer size</label>
<type>text</type>
<help><![CDATA[Change the check buffer size (in bytes). Higher values may help find string or regex patterns in very large pages, though doing so may imply more memory and CPU usage. The default value is 16384.]]></help>
<advanced>true</advanced>
</field>
<field>
<id>haproxy.general.tuning.luaMaxMem</id>
<label>Maximum RAM per LUA process</label>
<type>text</type>
<help><![CDATA[Sets the maximum amount of RAM in megabytes per process usable by Lua. By default it is zero which means unlimited. It is important to set a limit to ensure that a bug in a script will not result in the system running out of memory.]]></help>
<advanced>true</advanced>
</field>
<field>
<id>haproxy.general.tuning.spreadChecks</id>
<label>Spread checks</label>
<type>text</type>
<help><![CDATA[Add some randomness in the check interval between 0 and +/- 50%. A value between 2 and 5 seems to show good results. The default value is 0 (disabled).]]></help>
</field>
<field>
<id>haproxy.general.tuning.customOptions</id>
<label>Custom options</label>
<type>textbox</type>
<help><![CDATA[These lines will be added to the global settings of to the HAProxy configuration file.<br/><div class="text-info"><b>NOTE:</b> The syntax will not be checked, use at your own risk!</div>]]></help>
<advanced>true</advanced>
</field>
<field>
<label>SSL default settings</label>
<type>header</type>
</field>
<field>
<id>haproxy.general.tuning.ssl_defaultsEnabled</id>
<label>Enabled</label>
<type>checkbox</type>
<help><![CDATA[Enable global SSL default values.]]></help>
</field>
<field>
<id>haproxy.general.tuning.ssl_bindOptions</id>
<label>Bind options</label>
<type>select_multiple</type>
<style>tokenize</style>
<allownew>true</allownew>
<help><![CDATA[Used to enforce or disable certain SSL options.]]></help>
</field>
<field>
<id>haproxy.general.tuning.ssl_cipherList</id>
<label>Cipher List</label>
<type>text</type>
<help><![CDATA[It sets the default string describing the list of cipher algorithms ("cipher suite") that are negotiated during the SSL/TLS handshake.]]></help>
</field>
</form>
@@ -1,348 +0,0 @@
<form>
<tab id="haproxy-general" description="Settings">
<subtab id="haproxy-general-settings" description="Service Settings">
<field>
<id>haproxy.general.enabled</id>
<label>Enable HAProxy</label>
<type>checkbox</type>
<help>Enable or disable the HAProxy service.</help>
</field>
<field>
<id>haproxy.general.gracefulStop</id>
<label>Graceful stop</label>
<type>checkbox</type>
<help><![CDATA[Enable HAProxy's graceful stop mode. In this mode HAProxy will continue to process existing connections until they close. Note that this may severely slow down HAProxy's shutdown, depending on the configured timeout values. If graceful stop mode is not enabled, HAProxy will use the hard stop mode where it immediately quits and all established connections are closed. Hard stop mode is recommended.]]></help>
</field>
<field>
<id>haproxy.general.seamlessReload</id>
<label>Seamless reload</label>
<type>checkbox</type>
<help><![CDATA[HAProxy will handle service restarts in a way that no connections are dropped. This is the best restart mode, because it has no impact on user experience. That being said, there might be edge cases where seamless reloads lead to unexpected behaviour.]]></help>
</field>
<field>
<id>haproxy.general.showIntro</id>
<label>Show introduction pages</label>
<type>checkbox</type>
<help><![CDATA[Uncheck to hide all additional introduction pages. Requires a manual page reload for the change to take effect.]]></help>
</field>
</subtab>
<subtab id="haproxy-general-peers" description="Peers / Session Sync">
<field>
<id>haproxy.general.peers.enabled</id>
<label>Enable peers</label>
<type>checkbox</type>
<help><![CDATA[Enable or disable HAProxy peers. This will propagate entries of any data-types in stick-tables between several HAProxy instances over TCP connections in a multi-master fashion.]]></help>
</field>
<field>
<label>Peer 1</label>
<type>header</type>
</field>
<field>
<id>haproxy.general.peers.name1</id>
<label>Peer name (FQDN)</label>
<type>text</type>
<help><![CDATA[The name of the peer. This is usually the full hostname to make it possible for HAProxy to recognize the local peer. If HAProxy is unable to find the local peer it will fail to start.]]></help>
</field>
<field>
<id>haproxy.general.peers.listen1</id>
<label>Listen address (IP)</label>
<type>text</type>
<help><![CDATA[The listen address of the local peer or the address of the remote peer.]]></help>
</field>
<field>
<id>haproxy.general.peers.port1</id>
<label>TCP Port</label>
<type>text</type>
<help><![CDATA[The TCP port that should be used for connections to this peer. It must not be used by any other service.]]></help>
</field>
<field>
<label>Peer 2</label>
<type>header</type>
</field>
<field>
<id>haproxy.general.peers.name2</id>
<label>Peer name (FQDN)</label>
<type>text</type>
<help><![CDATA[The name of the peer. This is usually the full hostname to make it possible for HAProxy to recognize the local peer. If HAProxy is unable to find the local peer it will fail to start.]]></help>
</field>
<field>
<id>haproxy.general.peers.listen2</id>
<label>Listen address (IP)</label>
<type>text</type>
<help><![CDATA[The listen address of the local peer or the address of the remote peer.]]></help>
</field>
<field>
<id>haproxy.general.peers.port2</id>
<label>TCP Port</label>
<type>text</type>
<help><![CDATA[The TCP port that should be used for connections to this peer. It must not be used by any other service.]]></help>
</field>
</subtab>
<subtab id="haproxy-general-global" description="Global Parameters">
<field>
<label>NOTE: Define global parameters for the HAProxy service. They cannot be overriden.</label>
<type>info</type>
</field>
<field>
<id>haproxy.general.tuning.root</id>
<label>Run as root</label>
<type>checkbox</type>
<help><![CDATA[Enable or disable HAProxy running as root.<br/><div class="text-info"><b>NOTE:</b> Enabling root could be a security issue but it's required by some feature.</div>]]></help>
<advanced>true</advanced>
</field>
<field>
<id>haproxy.general.tuning.nbproc</id>
<label>HAProxy processes</label>
<type>text</type>
<help><![CDATA[Number of HAProxy processes to start.<br/><div class="text-info"><b>NOTE:</b> You may experience random issues in multi-process mode. For more information about the "nbproc" option please see the HAProxy Documentation.</div>]]></help>
<advanced>true</advanced>
</field>
<field>
<id>haproxy.general.tuning.nbthread</id>
<label>HAProxy threads</label>
<type>text</type>
<help><![CDATA[Number of threads to create for each HAProxy process.]]></help>
</field>
<field>
<id>haproxy.general.tuning.maxConnections</id>
<label>Maximum connections</label>
<type>text</type>
<help><![CDATA[Sets the maximum number of concurrent connections per HAProxy process.<br/><div class="text-info"><b>NOTE:</b> HAProxy will not be able to allocate enough memory if you set this value too high. Consider raising the settings for kern.maxfiles and kern.maxfilesperproc if you need to specify a non-default value.</div>]]></help>
</field>
<field>
<id>haproxy.general.tuning.sslServerVerify</id>
<label>Verify SSL Server Certificates</label>
<type>dropdown</type>
<help><![CDATA[This enforces a certain behavior for SSL verify on servers, ignoring per-server settings. If set to 'enforce verify', server certificates are verified. If set to 'disable verify', server certificates are not verified. The default is 'no preference' to only use per-server configurations and not enforce a global default for all servers.]]></help>
</field>
<field>
<id>haproxy.general.tuning.maxDHSize</id>
<label>Maximum SSL DH Size</label>
<type>text</type>
<help><![CDATA[Sets the maximum size of the Diffie-Hellman parameters used for generating the ephemeral/temporary Diffie-Hellman key in case of DHE key exchange (default is 1024).<br/><div class="text-info"><b>NOTE:</b> Higher values will increase the CPU load. For more information about the "tune.ssl.default-dh-param" option please see the HAProxy Documentation.</div>]]></help>
</field>
<field>
<id>haproxy.general.tuning.bufferSize</id>
<label>Buffer size</label>
<type>text</type>
<help><![CDATA[Change the buffer size (in bytes). Lower values allow more sessions to coexist in the same amount of RAM, and higher values allow some applications with very large cookies to work. The default value is 16384. <br/><div class="text-info"><b>NOTE:</b> It is strongly recommended not to change this from the default value, as very low values will break some services such as statistics, and values larger than default size will increase memory usage, possibly causing the system to run out of memory.</div>]]></help>
<advanced>true</advanced>
</field>
<field>
<id>haproxy.general.tuning.checkBufferSize</id>
<label>Health check buffer size</label>
<type>text</type>
<help><![CDATA[Change the check buffer size (in bytes). Higher values may help find string or regex patterns in very large pages, though doing so may imply more memory and CPU usage. The default value is 16384.]]></help>
<advanced>true</advanced>
</field>
<field>
<id>haproxy.general.tuning.luaMaxMem</id>
<label>Maximum RAM per LUA process</label>
<type>text</type>
<help><![CDATA[Sets the maximum amount of RAM in megabytes per process usable by Lua. By default it is zero which means unlimited. It is important to set a limit to ensure that a bug in a script will not result in the system running out of memory.]]></help>
<advanced>true</advanced>
</field>
<field>
<id>haproxy.general.tuning.spreadChecks</id>
<label>Spread checks</label>
<type>text</type>
<help><![CDATA[Add some randomness in the check interval between 0 and +/- 50%. A value between 2 and 5 seems to show good results. The default value is 0 (disabled).]]></help>
</field>
<field>
<id>haproxy.general.tuning.customOptions</id>
<label>Custom options</label>
<type>textbox</type>
<help><![CDATA[These lines will be added to the global settings of to the HAProxy configuration file.<br/><div class="text-info"><b>NOTE:</b> The syntax will not be checked, use at your own risk!</div>]]></help>
<advanced>true</advanced>
</field>
<field>
<label>SSL default settings</label>
<type>header</type>
</field>
<field>
<id>haproxy.general.tuning.ssl_defaultsEnabled</id>
<label>Enabled</label>
<type>checkbox</type>
<help><![CDATA[Enable global SSL default values.]]></help>
</field>
<field>
<id>haproxy.general.tuning.ssl_bindOptions</id>
<label>Bind options</label>
<type>select_multiple</type>
<style>tokenize</style>
<allownew>true</allownew>
<help><![CDATA[Used to enforce or disable certain SSL options.]]></help>
</field>
<field>
<id>haproxy.general.tuning.ssl_cipherList</id>
<label>Cipher List</label>
<type>text</type>
<help><![CDATA[It sets the default string describing the list of cipher algorithms ("cipher suite") that are negotiated during the SSL/TLS handshake.]]></help>
</field>
</subtab>
<subtab id="haproxy-general-defaults" description="Default Parameters">
<field>
<label>NOTE: Define default parameters for ALL Public Services, Backend Pools and Servers here. They may still be overriden elsewhere.</label>
<type>info</type>
</field>
<field>
<id>haproxy.general.defaults.maxConnections</id>
<label>Max. Connections</label>
<type>text</type>
<help><![CDATA[Set the maximum number of concurrent connections for this frontend.]]></help>
</field>
<field>
<id>haproxy.general.defaults.timeoutClient</id>
<label>Client Timeout</label>
<type>text</type>
<help><![CDATA[Set the maximum inactivity time on the client side. Defaults to milliseconds. Optionally the unit may be specified as either "d", "h", "m", "s", "ms" or "us".]]></help>
</field>
<field>
<id>haproxy.general.defaults.timeoutConnect</id>
<label>Connection Timeout</label>
<type>text</type>
<help><![CDATA[Set the maximum time to wait for a connection attempt to a server to succeed. Defaults to milliseconds. Optionally the unit may be specified as either "d", "h", "m", "s", "ms" or "us".]]></help>
</field>
<field>
<id>haproxy.general.defaults.timeoutCheck</id>
<label>Check Timeout</label>
<type>text</type>
<help><![CDATA[Sets an additional read timeout for running health checks on a server. Defaults to milliseconds. Optionally the unit may be specified as either "d", "h", "m", "s", "ms" or "us".]]></help>
</field>
<field>
<id>haproxy.general.defaults.timeoutServer</id>
<label>Server Timeout</label>
<type>text</type>
<help><![CDATA[Set the maximum inactivity time on the server side. Defaults to milliseconds. Optionally the unit may be specified as either "d", "h", "m", "s", "ms" or "us".]]></help>
</field>
<field>
<id>haproxy.general.defaults.retries</id>
<label>Retries</label>
<type>text</type>
<help><![CDATA[Set the number of retries to perform on a server after a connection failure (default is 3).]]></help>
</field>
<field>
<id>haproxy.general.defaults.redispatch</id>
<label>Session redistribution</label>
<type>dropdown</type>
<help><![CDATA[Enable or disable session redistribution in case of connection failure.]]></help>
</field>
<field>
<id>haproxy.general.defaults.customOptions</id>
<label>Custom options</label>
<type>textbox</type>
<help><![CDATA[These lines will be added to the defaults settings of to the HAProxy configuration file.<br/><div class="text-info"><b>NOTE:</b> The syntax will not be checked, use at your own risk!</div>]]></help>
<advanced>true</advanced>
</field>
</subtab>
<subtab id="haproxy-general-logging" description="Logging Configuration">
<field>
<id>haproxy.general.logging.host</id>
<label>Log Host</label>
<type>text</type>
<help><![CDATA[Indicates where to send the logs. Takes an IPv4 or IPv6 address optionally followed by a colon (':') and a UDP port, i.e. 127.0.0.1 or 10.0.0.1:514]]></help>
</field>
<field>
<id>haproxy.general.logging.facility</id>
<label>Syslog facility</label>
<type>dropdown</type>
<help><![CDATA[Choose one of the 24 standard syslog facilities. The default value is local0.]]></help>
</field>
<field>
<id>haproxy.general.logging.level</id>
<label>Filter syslog level</label>
<type>dropdown</type>
<help><![CDATA[Can be specified to filter outgoing messages. By default, all messages are sent. If a level is specified, only messages with a severity at least as important as this level will be sent.]]></help>
</field>
<field>
<id>haproxy.general.logging.length</id>
<label>Max. line length</label>
<type>text</type>
<help><![CDATA[Specify an optional maximum line length in characters. Log lines larger than this value will be truncated before being sent. The reason is that syslog servers act differently on log line length. All servers support the default value of 1024 characters, but some servers simply drop larger lines while others do log them.]]></help>
<advanced>true</advanced>
</field>
</subtab>
<subtab id="haproxy-general-statistics" description="Statistics Configuration">
<field>
<id>haproxy.general.stats.enabled</id>
<label>Stats enabled</label>
<type>checkbox</type>
<help><![CDATA[Enable HAProxy's statistics page.]]></help>
</field>
<field>
<id>haproxy.general.stats.port</id>
<label>Local stats TCP port</label>
<type>text</type>
<help><![CDATA[Choose a TCP port to be used for the local statistics page. The default value is 8822.]]></help>
<advanced>true</advanced>
</field>
<field>
<id>haproxy.general.stats.remoteEnabled</id>
<label>Enable remote access</label>
<type>checkbox</type>
<help><![CDATA[Enable remote access to HAProxy's statistics page. <b>This may be a security risk if you do not enable authentication!</b> Note that you need to add appropiate firewall rules for this to work.]]></help>
</field>
<field>
<id>haproxy.general.stats.remoteBind</id>
<label>Remote listen addresses</label>
<type>select_multiple</type>
<style>tokenize</style>
<allownew>true</allownew>
<help><![CDATA[Configure listen addresses for the statistics page to enable remote access, i.e. 10.0.0.1:8080 or haproxy.example.com:8999. Use TAB key to complete typing a listen address.]]></help>
<hint>Enter address:port here. Finish with TAB.</hint>
</field>
<field>
<id>haproxy.general.stats.authEnabled</id>
<label>Enable authentication</label>
<type>checkbox</type>
</field>
<field>
<id>haproxy.general.stats.allowedUsers</id>
<label>Allowed Users</label>
<type>select_multiple</type>
<allownew>true</allownew>
<hint>Type username or choose from list.</hint>
</field>
<field>
<id>haproxy.general.stats.allowedGroups</id>
<label>Allowed Groups</label>
<type>select_multiple</type>
<allownew>true</allownew>
<hint>Type group or choose from list.</hint>
</field>
<field>
<id>haproxy.general.stats.customOptions</id>
<label>Custom options</label>
<type>textbox</type>
<help><![CDATA[These lines will be added to the statistics settings of to the HAProxy configuration file.<br/><div class="text-info"><b>NOTE:</b> The syntax will not be checked, use at your own risk!</div>]]></help>
<advanced>true</advanced>
</field>
</subtab>
<subtab id="haproxy-general-cache" description="Cache">
<field>
<id>haproxy.general.cache.enabled</id>
<label>Cache enabled</label>
<type>checkbox</type>
<help><![CDATA[Enable HAProxy's cache which was designed to perform cache on small objects (favicon, css...). This is a minimalist low-maintenance cache which runs in RAM.]]></help>
</field>
<field>
<id>haproxy.general.cache.totalMaxSize</id>
<label>Maximum Size of Cache (MB)</label>
<type>text</type>
<help><![CDATA[Define the size in RAM of the cache in megabytes. This size is split in blocks of 1kB which are used by the cache entries. Its maximum value is 4095.]]></help>
</field>
<field>
<id>haproxy.general.cache.maxAge</id>
<label>Maximum Object Age (sec)</label>
<type>text</type>
<help><![CDATA[Define the maximum expiration duration. Cache-Control response headers will be respected if they are less than this value. The default value is 60 seconds.]]></help>
</field>
<field>
<id>haproxy.general.cache.maxObjectSize</id>
<label>Maximum Object Size (bytes)</label>
<type>text</type>
<help><![CDATA[Define the maximum size of the objects to be cached. Must not be greater than an half of the maximum size of the cache. If not set, it equals to a 256th of the cache size. All objects with sizes larger than this value will not be cached.]]></help>
</field>
</subtab>
</tab>
</form>
@@ -1,6 +1,6 @@
<model>
<mount>//OPNsense/HAProxy</mount>
<version>2.8.0</version>
<version>2.10.0</version>
<description>the HAProxy load balancer</description>
<items>
<general>
@@ -199,6 +199,17 @@
<x-3>redispatch on the 3rd retry prior to the last retry</x-3>
</OptionValues>
</redispatch>
<init_addr type="OptionField">
<Required>N</Required>
<default>last,libc</default>
<Multiple>Y</Multiple>
<Sorted>Y</Sorted>
<OptionValues>
<last>last</last>
<libc>libc</libc>
<none>none</none>
</OptionValues>
</init_addr>
<customOptions type="TextField">
<Required>N</Required>
</customOptions>
@@ -792,6 +803,18 @@
<Multiple>Y</Multiple>
<Required>N</Required>
</linkedServers>
<linkedResolver type="ModelRelationField">
<Model>
<template>
<source>OPNsense.HAProxy.HAProxy</source>
<items>resolvers.resolver</items>
<display>name</display>
</template>
</Model>
<ValidationMessage>Related resolver not found</ValidationMessage>
<multiple>N</multiple>
<Required>N</Required>
</linkedResolver>
<source type="TextField">
<mask>/^((([0-9a-zA-Z._\-\*:]+)))*/u</mask>
<ChangeCase>lower</ChangeCase>
@@ -1829,6 +1852,7 @@
<http-request_replace-header>http-request header replace</http-request_replace-header>
<http-request_replace-value>http-request header replace value</http-request_replace-value>
<http-request_set-path>http-request set-path</http-request_set-path>
<http-request_set-var>http-request set-var</http-request_set-var>
<http-response_allow>http-response allow</http-response_allow>
<http-response_deny>http-response deny</http-response_deny>
<http-response_lua>http-response lua script</http-response_lua>
@@ -1837,7 +1861,8 @@
<http-response_del-header>http-response header delete</http-response_del-header>
<http-response_replace-header>http-response header replace</http-response_replace-header>
<http-response_replace-value>http-response header replace value</http-response_replace-value>
<http-response_set-status>Set HTTP status code in response</http-response_set-status>
<http-response_set-status>http-response set-status</http-response_set-status>
<http-response_set-var>http-response set-var</http-response_set-var>
<tcp-request_connection_accept>tcp-request connection accept</tcp-request_connection_accept>
<tcp-request_connection_reject>tcp-request connection reject</tcp-request_connection_reject>
<tcp-request_content_accept>tcp-request content accept</tcp-request_content_accept>
@@ -1934,6 +1959,25 @@
<mask>/^.{1,4096}$/u</mask>
<Required>N</Required>
</http_request_set_path>
<http_request_set_var_scope type="OptionField">
<Required>N</Required>
<default>txn</default>
<OptionValues>
<proc>variable is shared with the whole process</proc>
<sess>variable is shared with the whole session</sess>
<txn>variable is shared with the transaction (request/response)</txn>
<req>variable is shared only during request processing</req>
<res>variable is shared only during response processing</res>
</OptionValues>
</http_request_set_var_scope>
<http_request_set_var_name type="TextField">
<mask>/^.{1,4096}$/u</mask>
<Required>N</Required>
</http_request_set_var_name>
<http_request_set_var_expr type="TextField">
<mask>/^.{1,4096}$/u</mask>
<Required>N</Required>
</http_request_set_var_expr>
<http_response_lua type="TextField">
<mask>/^.{1,4096}$/u</mask>
<Required>N</Required>
@@ -1984,6 +2028,25 @@
<mask>/^.{1,4096}$/u</mask>
<Required>N</Required>
</http_response_set_status_reason>
<http_response_set_var_scope type="OptionField">
<Required>N</Required>
<default>txn</default>
<OptionValues>
<proc>variable is shared with the whole process</proc>
<sess>variable is shared with the whole session</sess>
<txn>variable is shared with the transaction (request/response)</txn>
<req>variable is shared only during request processing</req>
<res>variable is shared only during response processing</res>
</OptionValues>
</http_response_set_var_scope>
<http_response_set_var_name type="TextField">
<mask>/^.{1,4096}$/u</mask>
<Required>N</Required>
</http_response_set_var_name>
<http_response_set_var_expr type="TextField">
<mask>/^.{1,4096}$/u</mask>
<Required>N</Required>
</http_response_set_var_expr>
<tcp_request_content_lua type="TextField">
<mask>/^.{1,4096}$/u</mask>
<Required>N</Required>
@@ -2179,6 +2242,10 @@
<Multiple>Y</Multiple>
<Required>N</Required>
</members>
<add_userlist type="BooleanField">
<default>0</default>
<Required>N</Required>
</add_userlist>
</group>
</groups>
<users>
@@ -2438,5 +2505,57 @@
</cpu_id>
</cpu>
</cpus>
<resolvers>
<resolver type="ArrayField">
<id type="UniqueIdField">
<Required>Y</Required>
</id>
<enabled type="BooleanField">
<default>1</default>
<Required>Y</Required>
</enabled>
<name type="TextField">
<mask>/^[^\t^,^;^\.^\[^\]^\{^\}]{1,255}$/u</mask>
<ValidationMessage>Should be a string between 1 and 255 characters.</ValidationMessage>
<Required>Y</Required>
</name>
<description type="TextField">
<Required>N</Required>
<mask>/^.{1,255}$/u</mask>
<ValidationMessage>Should be a string between 1 and 255 characters.</ValidationMessage>
</description>
<nameservers type="CSVListField">
<Required>N</Required>
<Sorted>Y</Sorted>
<multiple>Y</multiple>
<mask>/^((([0-9a-zA-Z._\-\*:\[\]]+:[0-9]+(-[0-9]+)?)([,]){0,1}))*/u</mask>
<ChangeCase>lower</ChangeCase>
<ValidationMessage>Please provide a valid nameserver address, i.e. 127.0.0.1:53, [::1]:53 or 192.168.1.1:53.</ValidationMessage>
</nameservers>
<parse_resolv_conf type="BooleanField">
<default>0</default>
<Required>Y</Required>
</parse_resolv_conf>
<resolve_retries type="IntegerField">
<default>3</default>
<MinimumValue>0</MinimumValue>
<MaximumValue>100000</MaximumValue>
<ValidationMessage>Please specify a value between 0 and 100000.</ValidationMessage>
<Required>N</Required>
</resolve_retries>
<timeout_resolve type="TextField">
<default>1s</default>
<mask>/^([0-9]{1,8}(?:us|ms|s|m|h|d)?)/u</mask>
<ValidationMessage>Should be a number between 1 and 8 characters, optionally followed by either "d", "h", "m", "s", "ms" or "us".</ValidationMessage>
<Required>N</Required>
</timeout_resolve>
<timeout_retry type="TextField">
<default>1s</default>
<mask>/^([0-9]{1,8}(?:us|ms|s|m|h|d)?)/u</mask>
<ValidationMessage>Should be a number between 1 and 8 characters, optionally followed by either "d", "h", "m", "s", "ms" or "us".</ValidationMessage>
<Required>N</Required>
</timeout_retry>
</resolver>
</resolvers>
</items>
</model>
@@ -20,6 +20,7 @@
<Luas VisibleName="Lua Scripts" url="/ui/haproxy#luas"/>
<Errorfiles VisibleName="Error Files" url="/ui/haproxy#errorfiles"/>
<Mapfiles VisibleName="Map Files" url="/ui/haproxy#mapfiles"/>
<Resolvers VisibleName="Resolvers" url="/ui/haproxy#resolvers"/>
</Settings>
<Statistics order="20" url="/ui/haproxy/statistics">
<Overview VisibleName="Overview" url="/ui/haproxy/statistics#info"/>
File diff suppressed because it is too large Load Diff
@@ -44,7 +44,6 @@
{# # remember all ACLs to avoid duplicate declarations #}
{% set acls_seen = [] %}
{% set global_action_options = [] %}
{% set global_use_options = [] %}
{% for action in linkedData.split(",") %}
{% set action_data = helpers.getUUID(action) %}
{# # collect ACLs for this action #}
@@ -307,11 +306,10 @@
{% if acl_errors|int == 0 %}
{% set action_enabled = '1' %}
{% set action_options = [] %}
{% set use_options = [] %}
{% if action_data.type == 'use_backend' %}
{% if action_data.use_backend|default("") != "" %}
{% set acl_backend_data = helpers.getUUID(action_data.use_backend) %}
{% do use_options.append('use_backend ' ~ acl_backend_data.name) %}
{% do action_options.append('use_backend ' ~ acl_backend_data.name) %}
{% else %}
{% set action_enabled = '0' %}
# ERROR: missing parameters
@@ -319,7 +317,7 @@
{% elif action_data.type == 'use_server' %}
{% if action_data.use_server|default("") != "" %}
{% set server_data = helpers.getUUID(action_data.use_server) %}
{% do use_options.append('use-server ' ~ server_data.name) %}
{% do action_options.append('use-server ' ~ server_data.name) %}
{% else %}
{% set action_enabled = '0' %}
# ERROR: missing parameters
@@ -337,7 +335,7 @@
{% set defaultbackend_option = '' %}
{% endif %}
{# # Finally add map file to config #}
{% do use_options.append('use_backend %[req.hdr(host),lower,map_dom(' ~ mapfile_path ~ defaultbackend_option ~ ')]') %}
{% do action_options.append('use_backend %[req.hdr(host),lower,map_dom(' ~ mapfile_path ~ defaultbackend_option ~ ')]') %}
{% else %}
{% set action_enabled = '0' %}
# ERROR: missing parameters
@@ -417,6 +415,13 @@
{% set action_enabled = '0' %}
# ERROR: missing parameters
{% endif %}
{% elif action_data.type == 'http-request_set-var' %}
{% if action_data.http_request_set_var_scope|default("") != "" and action_data.http_request_set_var_name|default("") != "" and action_data.http_request_set_var_expr|default("") != "" %}
{% do action_options.append('http-request set-var(' ~ action_data.http_request_set_var_scope ~ '.' ~ action_data.http_request_set_var_name ~ ') ' ~ action_data.http_request_set_var_expr) %}
{% else %}
{% set action_enabled = '0' %}
# ERROR: missing parameters
{% endif %}
{% elif action_data.type == 'http-response_allow' %}
{% do action_options.append('http-response allow') %}
{% elif action_data.type == 'http-response_deny' %}
@@ -475,6 +480,13 @@
{% set action_enabled = '0' %}
# ERROR: missing parameters
{% endif %}
{% elif action_data.type == 'http-response_set-var' %}
{% if action_data.http_response_set_var_scope|default("") != "" and action_data.http_response_set_var_name|default("") != "" and action_data.http_response_set_var_expr|default("") != "" %}
{% do action_options.append('http-response set-var(' ~ action_data.http_response_set_var_scope ~ '.' ~ action_data.http_response_set_var_name ~ ') ' ~ action_data.http_response_set_var_expr) %}
{% else %}
{% set action_enabled = '0' %}
# ERROR: missing parameters
{% endif %}
{% elif action_data.type == 'tcp-request_connection_accept' %}
{% do action_options.append('tcp-request connection accept') %}
{% elif action_data.type == 'tcp-request_connection_reject' %}
@@ -554,10 +566,6 @@
{% do global_action_options.append(comment_lines|join('\n')) %}
{% do global_action_options.append(([action_options|join(' '), acl_line]|join(' '))) %}
{% endif %}
{% if use_options|length > 0 %}
{% do global_use_options.append(comment_lines|join('\n')) %}
{% do global_use_options.append(([use_options|join(' '), acl_line]|join(' '))) %}
{% endif %}
{% else %}
# ACTION INVALID: {{action_data.name}}
{% endif %}
@@ -569,10 +577,6 @@
{% if global_action_options|length > 0 %}
{{global_action_options|join('\n' + ' ')}}
{% endif %}
{% if global_use_options|length > 0 %}
{{global_use_options|join('\n' + ' ')}}
{% endif %}
{% else %}
# ERROR: AclsAndActions called with empty data
@@ -725,7 +729,7 @@
{% endif %}
{% endfor %}
{% else %}
# WARNING: UserlistAddUsers called with empty user data
# NOTE: UserlistAddUsers called with empty user data
{% endif %}
{# # process all group members #}
{% if linkedGroupData is defined %}
@@ -754,20 +758,32 @@
{% endif %}
{% endfor %}
{% else %}
# WARNING: UserlistAddUsers called with empty group data
# NOTE: UserlistAddUsers called with empty group data
{% endif %}
{%- endmacro %}
{# Macro expects a backend or frontend object. #}
{% macro AddUserlist(proxy) -%}
{% if proxy is defined %}
{% if (proxy.enabled|default("") == '1' and proxy.mode|default("") == 'http' and proxy.basicAuthEnabled|default("") == '1') %}
{# Macro expects a backend/frontend (type 1) or group object (type 2). #}
{% macro AddUserlist(type,object) -%}
{% if (type == '1' and object is defined) %}
{# # frontend/backend object #}
{% if (object.enabled|default("") == '1' and object.mode|default("") == 'http' and object.basicAuthEnabled|default("") == '1') %}
{# # call macro to generate list of unique users #}
{% set userlist_result = UserlistAddUsers(proxy.basicAuthUsers,proxy.basicAuthGroups) %}
{% set userlist_result = UserlistAddUsers(object.basicAuthUsers,object.basicAuthGroups) %}
{# # check result, skip when empty #}
{% if (userlist_result is defined and userlist_result|default("") != "" )%}
userlist list_{{proxy.id}}
# Origin: {{proxy.name}}
userlist list_{{object.id}}
# Origin: {{object.name}}
{{userlist_result}}
{% endif %}
{% endif %}
{% elif (type == '2' and object is defined) %}
{# # group object #}
{% if (object.enabled|default("") == '1' and object.add_userlist|default("") == '1') %}
{# # call macro to generate list of unique users #}
{% set userlist_result = UserlistAddUsers(object.members) %}
{# # check result, skip when empty #}
{% if (userlist_result is defined and userlist_result|default("") != "" ) %}
userlist {{object.name | regex_replace ("[^A-Za-z0-9]","")}}
{{userlist_result}}
{% endif %}
{% endif %}
@@ -917,6 +933,9 @@ defaults
{% if OPNsense.HAProxy.general.defaults.retries|default("") != "" %}
retries {{OPNsense.HAProxy.general.defaults.retries}}
{% endif %}
{% if OPNsense.HAProxy.general.defaults.init_addr|default("") != "" %}
default-server init-addr {{OPNsense.HAProxy.general.defaults.init_addr}}
{% endif %}
{% if OPNsense.HAProxy.general.defaults.customOptions|default("") != "" %}
# WARNING: pass through options below this line
{% for customOpt in OPNsense.HAProxy.general.defaults.customOptions.split("\n") %}
@@ -947,17 +966,25 @@ userlist acl_{{acl.id}}
{% endfor %}
{% endif %}
{% if helpers.exists('OPNsense.HAProxy.groups') %}
# userlists generated from groups
{% for group in helpers.toList('OPNsense.HAProxy.groups.group') %}
{# # call macro to generate userlist #}
{{ AddUserlist('2',group) -}}
{% endfor %}
{% endif %}
# autogenerated entries for config in backends/frontends
{% if helpers.exists('OPNsense.HAProxy.frontends') %}
{% for frontend in helpers.toList('OPNsense.HAProxy.frontends.frontend') %}
{# # call macro to generate userlist #}
{{ AddUserlist(frontend) -}}
{{ AddUserlist('1',frontend) -}}
{% endfor %}
{% endif %}
{% if helpers.exists('OPNsense.HAProxy.backends') %}
{% for backend in helpers.toList('OPNsense.HAProxy.backends.backend') %}
{# # call macro to generate userlist #}
{{ AddUserlist(backend) -}}
{{ AddUserlist('1',backend) -}}
{% endfor %}
{% endif %}
@@ -974,6 +1001,40 @@ userlist stats_auth
{% endif %}
{% endif %}
{# ############################### #}
{# RESOLVERS #}
{# ############################### #}
{% if helpers.exists('OPNsense.HAProxy.resolvers') %}
{% for resolver in helpers.toList('OPNsense.HAProxy.resolvers.resolver') %}
{% if resolver.enabled == '1' %}
# Resolver: {{resolver.name}}
resolvers {{resolver.id}}
{% if resolver.nameservers|default("") != "" %}
{% for nameserver in resolver.nameservers.split(",") %}
nameserver {{nameserver}} {{nameserver}}
{% endfor %}
{% endif %}
{% if resolver.parse_resolv_conf|default("") == "1" %}
parse-resolv-conf
{% endif %}
{% if resolver.resolve_retries|default("") != "" %}
resolve_retries {{resolver.resolve_retries}}
{% endif %}
{% if resolver.timeout_resolve|default("") != "" %}
timeout resolve {{resolver.timeout_resolve}}
{% endif %}
{% if resolver.timeout_retry|default("") != "" %}
timeout retry {{resolver.timeout_retry}}
{% endif %}
{% else %}
# Resolver (DISABLED): {{resolver.name}}
{% endif %}
{% endfor %}
{%- endif -%}
{# ############################### #}
{# FRONTENDS #}
{# ############################### #}
@@ -1430,6 +1491,11 @@ backend {{backend.name}}
{% do server_options.append('verify none') %}
{% endif %}
{% endif %}
{# # resolver #}
{% if backend.linkedResolver|default("") != "" %}
{% set resolver_data = helpers.getUUID(backend.linkedResolver) %}
{% do server_options.append('resolvers ' ~ resolver_data.id) %}
{% endif %}
{# # source address #}
{% if backend.source|default("") != "" %}
{# # prefer backend configuration #}