From 6b4680f58fb2c889a9e87a8c188b8b0ff78f3e0d Mon Sep 17 00:00:00 2001 From: Frank Wall Date: Tue, 5 Dec 2023 23:17:58 +0100 Subject: [PATCH 1/9] net/haproxy: fix typo in cert sync script --- net/haproxy/pkg-descr | 3 +++ net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/syncCerts.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/net/haproxy/pkg-descr b/net/haproxy/pkg-descr index 22d70bfae..def41ade0 100644 --- a/net/haproxy/pkg-descr +++ b/net/haproxy/pkg-descr @@ -6,6 +6,9 @@ very high loads while needing persistence or Layer7 processing. Plugin Changelog ================ +Fixed: +* fix typo in cert sync script + 4.1 Fixed: diff --git a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/syncCerts.py b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/syncCerts.py index cf8ac6797..f4932a0cd 100755 --- a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/syncCerts.py +++ b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/syncCerts.py @@ -357,7 +357,7 @@ class Diff(SyncWithTarget): for message in cert['messages']: print(" " + repr(message)) - for cert in sync['delete']: + for cert in sync['deleted']: print(f"\n DEL: {cert['cert']}") for message in cert['messages']: print(" " + repr(message)) From 13ab16cd96dda236c9e4c6481e6b09662e8f2179 Mon Sep 17 00:00:00 2001 From: Frank Wall Date: Tue, 5 Dec 2023 23:23:53 +0100 Subject: [PATCH 2/9] net/haproxy: replace bundled haproxyctl library The bundled library is a modified version of haproxyctl: https://github.com/neurogeek/haproxyctl Now a proper fork was created: https://github.com/markt-de/haproxy-cli The FreeBSD port is pending approval: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=275562 --- net/haproxy/Makefile | 2 +- net/haproxy/pkg-descr | 3 + .../OPNsense/HAProxy/lib/haproxy/__init__.py | 3 - .../OPNsense/HAProxy/lib/haproxy/cmds.py | 335 ------------------ .../OPNsense/HAProxy/lib/haproxy/conn.py | 83 ----- .../OPNsense/HAProxy/lib/haproxy/const.py | 7 - .../HAProxy/lib/haproxy/tests/__init__.py | 0 .../HAProxy/lib/haproxy/tests/test_cmds.py | 291 --------------- .../HAProxy/lib/haproxy/tests/test_conn.py | 59 --- .../scripts/OPNsense/HAProxy/socketCommand.py | 1 - .../scripts/OPNsense/HAProxy/syncCerts.py | 1 - 11 files changed, 4 insertions(+), 781 deletions(-) delete mode 100755 net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/lib/haproxy/__init__.py delete mode 100755 net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/lib/haproxy/cmds.py delete mode 100755 net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/lib/haproxy/conn.py delete mode 100755 net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/lib/haproxy/const.py delete mode 100755 net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/lib/haproxy/tests/__init__.py delete mode 100755 net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/lib/haproxy/tests/test_cmds.py delete mode 100755 net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/lib/haproxy/tests/test_conn.py diff --git a/net/haproxy/Makefile b/net/haproxy/Makefile index 49233c6f0..95013f8e1 100644 --- a/net/haproxy/Makefile +++ b/net/haproxy/Makefile @@ -2,7 +2,7 @@ PLUGIN_NAME= haproxy PLUGIN_VERSION= 4.1 PLUGIN_REVISION= 1 PLUGIN_COMMENT= Reliable, high performance TCP/HTTP load balancer -PLUGIN_DEPENDS= haproxy26 +PLUGIN_DEPENDS= haproxy26 py${PLUGIN_PYTHON}-haproxy-cli PLUGIN_MAINTAINER= opnsense@moov.de .include "../../Mk/plugins.mk" diff --git a/net/haproxy/pkg-descr b/net/haproxy/pkg-descr index def41ade0..2681b9f8d 100644 --- a/net/haproxy/pkg-descr +++ b/net/haproxy/pkg-descr @@ -9,6 +9,9 @@ Plugin Changelog Fixed: * fix typo in cert sync script +Changed: +* replace bundled haproxyctl library with haproxy-cli + 4.1 Fixed: diff --git a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/lib/haproxy/__init__.py b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/lib/haproxy/__init__.py deleted file mode 100755 index c7f37eafa..000000000 --- a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/lib/haproxy/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -"""haproxy lib for socket commands. -Based on: https://github.com/neurogeek/haproxyctl""" -__version__ = "1.0" diff --git a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/lib/haproxy/cmds.py b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/lib/haproxy/cmds.py deleted file mode 100755 index 733daf113..000000000 --- a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/lib/haproxy/cmds.py +++ /dev/null @@ -1,335 +0,0 @@ -"""cmds.py - Implementations of the different HAProxy commands""" -import re -import csv -import json -from collections import OrderedDict -from io import StringIO - -class Cmd(): - """Cmd - Command base class""" - req_args = [] - args = {} - cmdTxt = "" - helpTxt = "" - - # pylint: disable=unused-argument - def __init__(self, *args, **kwargs): - """Argument to the command are given in kwargs only. We ignore *args.""" - self.args = kwargs - valid_kwargs = [k for (k, v) in kwargs.items() if v is not None] - - if not all([a in valid_kwargs for a in self.req_args]): - raise Exception(f"Wrong number of arguments. Required arguments are: {self.WhatArgs()}") - - def WhatArgs(self): - """Returns a formatted string of arguments to this command.""" - return ",".join(self.req_args) - - @classmethod - def getHelp(cls): - """Get formatted help string for this command.""" - txtArgs = ",".join(cls.req_args) - - if not txtArgs: - txtArgs = "None" - return " ".join((cls.helpTxt, "Arguments: %s" % txtArgs)) - - def getCmd(self): - """Gets the command line for this command. - The default behavior is to apply the args dict to cmdTxt - """ - return self.cmdTxt % self.args - - def getBootstrapOutput(self, resObj): - """ Returns results gathered from HAProxy as jquery bootstrap output """ - args = { - "rows": resObj, - "page": int(self.args['page']) if self.args['page'] != None else 1, - "page_rows": int(self.args['page_rows']) if self.args['page_rows'] != None else len(rows), - "search": self.args['search'], - "sort_col": self.args['sort_col'] if self.args['sort_col'] else 'id', - "sort_dir": self.args['sort_dir'], - } - rows = args['rows'] - # search - if args['search']: - filtered_rows = [] - for row in rows: - def inner(row): - for k, v in row.items(): - if args['search'] in v: - return row - return None - - match = inner(row) - if match: - filtered_rows.append(match) - rows = filtered_rows - - # sort - rows.sort(key=lambda k: k[args['sort_col']], reverse=True if args['sort_dir'] == 'desc' else False) - - # pager - total = len(rows) - pages = [rows[i:i + args['page_rows']] for i in range(0, total, args['page_rows'])] - if pages and (args['page'] > len(pages) or args['page'] < 1): - raise KeyError(f"Current page {args['page']} does not exist. Available pages: {len(pages)}") - page = pages[args['page'] - 1] if pages else [] - - return json.dumps({ - "rows": page, - "total": total, - "rowCount": args['page_rows'], - "current": args['page'] - }) - - def getJsonOutput(self, resObj): - """Returns results gathered from HAProxy as json""" - return json.dumps(resObj) - - def getResult(self, res): - """Returns raw results gathered from HAProxy""" - if res == '\n': - res = None - - if self.args['output'] == 'json': - return self.getJsonOutput(self.getResultObj(res)) - - if self.args['output'] == 'bootstrap': - return self.getBootstrapOutput(self.getResultObj(res)) - - return res - - def getResultObj(self, res): - """Returns refined output from HAProxy, packed inside a Python obj i.e. a dict()""" - return res - -class setServerAgent(Cmd): - cmdTxt = "set server %(backend)s/%(server)s agent %(value)s\r\n" - req_args = ['backend', 'server', 'value'] - helpTxt = "Force a server's agent to a new state." - -class setServerHealth(Cmd): - cmdTxt = "set server %(backend)s/%(server)s health %(value)s\r\n" - req_args = ['backend', 'server', 'value'] - helpTxt = "Force a server's health to a new state." - -class setServerState(Cmd): - cmdTxt = "set server %(backend)s/%(server)s state %(value)s\r\n" - req_args = ['backend', 'server', 'value'] - helpTxt = "Force a server's administrative state to a new state." - -class setServerWeight(Cmd): - cmdTxt = "set server %(backend)s/%(server)s weight %(value)s\r\n" - req_args = ['backend', 'server', 'value'] - helpTxt = "Force a server's weight to a new state." - -class showSslCrtLists(Cmd): - cmdTxt = "show ssl crt-list\r\n" - helpTxt = "Show the list of crt-lists." - - def getResultObj(self, res): - result = { "crt_lists": []} - for line in res.split("\n"): - if line.startswith('/'): - result["crt_lists"].append(line) - return result - -class showSslCrtList(Cmd): - cmdTxt = "show ssl crt-list -n %(crt_list)s\r\n" - req_args = ['crt_list'] - helpTxt = "Show the the content of a crt-list." - - def getResultObj(self, res): - result = {} - list_id = None - for line in res.split("\n"): - if line.startswith('# '): - list_id = line.split("# ")[1] - result["certs"] = [] - - if list_id and line.startswith('/'): - result["certs"].append(line) - - if result: - return result - - return {"error": res.strip()} - -class showSslCerts(Cmd): - cmdTxt = "show ssl cert\r\n" - helpTxt = "Display the SSL certificates used in memory." - - def getResultObj(self, res): - result = { - "transaction": [], - "filename": [] - } - for line in res.split("\n"): - if line.startswith('*'): - result['transaction'].append(line) - elif line.startswith('/'): - result['filename'].append(line) - return result - -class showSslCert(Cmd): - cmdTxt = "show ssl cert %(certfile)s\r\n" - req_args = ['certfile'] - helpTxt = "Display the details of a SSL certificate used in memory." - - def getResultObj(self, res): - result = {} - cert_id = None - for line in res.split("\n"): - if line: - key = line.split(":")[0] - val = line.split(":")[1].strip() - - if key == 'Filename': - cert_id = val - - if cert_id: - result[key] = val - - if result: - return result - - return {"error": res.strip()} - -class addToSslCrtList(Cmd): - cmdTxt = "add ssl crt-list %(crt_list)s %(certfile)s\r\n" - req_args = ['crt_list', 'certfile'] - helpTxt = "Add a ssl cert to a crt-list." - -class delFromSslCrtList(Cmd): - cmdTxt = "del ssl crt-list %(crt_list)s %(certfile)s\r\n" - req_args = ['crt_list', 'certfile'] - helpTxt = "Delete a ssl cert from a crt-list." - -class newSslCrt(Cmd): - """" Create an empty slot for the certificate in HAProxy’s memory """ - cmdTxt = "new ssl cert %(certfile)s\r\n" - req_args = ['certfile'] - helpTxt = "Create a new certificate file to be used in a crt-list or a directory." - -class updateSslCrt(Cmd): - """" Begin a transaction to upload the certificate into a slot in HAProxy’s memory """ - cmdTxt = "set ssl cert %(certfile)s <<\n%(payload)s\r\n" - req_args = ['certfile', 'payload'] - helpTxt = "Replace a certificate file." - -class delSslCrt(Cmd): - """" Begin a transaction to remove the certificate from a slot in HAProxy’s memory """ - cmdTxt = "del ssl cert %(certfile)s\r\n" - req_args = ['certfile'] - helpTxt = "Delete delete an unused certificate file." - -class commitSslCrt(Cmd): - """ Commit the transaction so HAProxy detects the change. """ - cmdTxt = "commit ssl cert %(certfile)s\r\n" - req_args = ['certfile'] - helpTxt = "Commit a certificate file." - -class abortSslCrt(Cmd): - cmdTxt = "abort ssl cert %(certfile)s\r\n" - req_args = ['certfile'] - helpTxt = "Abort a transaction for a certificate file." - -class showFBEnds(Cmd): - """Base class for getting a listing Frontends and Backends""" - switch = "" - cmdTxt = "show stat\r\n" - - def getResult(self, res): - return "\n".join(self._getResult(res)) - - def getResultObj(self, res): - return self._getResult(res) - - def _getResult(self, res): - """Show Frontend/Backends. To do this, we extract info from - the stat command and filter out by a specific - switch (FRONTEND/BACKEND)""" - - if not self.switch: - raise Exception("No action specified") - - result = [] - lines = res.split('\n') - cl = re.compile("^[^,].+," + self.switch.upper() + ",.*$") - - for e in lines: - me = re.match(cl, e) - if me: - print(e) - result.append(e.split(",")[0]) - return result - -class showFrontends(showFBEnds): - """Show frontends command.""" - switch = "frontend" - helpTxt = "List all Frontends." - -class showBackends(showFBEnds): - """Show backends command.""" - switch = "backend" - helpTxt = "List all Backends." - -class showInfo(Cmd): - """Show info HAProxy command""" - cmdTxt = "show info\r\n" - helpTxt = "Show info on HAProxy instance." - - def getResultObj(self, res): - resDict = {} - for line in res.split('\n'): - k, v = line.split(':') - resDict[k] = v - - return resDict - -class showSessions(Cmd): - """Show sess HAProxy command""" - cmdTxt = "show sess\r\n" - helpTxt = "Show HAProxy sessions." - - def getResultObj(self, res): - return res.split('\n') - -class baseStat(Cmd): - """Base class for stats commands.""" - - def getDict(self, res): - # clean response - res = re.sub(r'^# ', '', res, re.MULTILINE) - res = re.sub(r',\n', '\n', res, re.MULTILINE) - res = re.sub(r',\n\n', '\n', res, re.MULTILINE) - - csv_string = StringIO(res) - return csv.DictReader(csv_string, delimiter=',') - -class showServers(baseStat): - """Show all servers. If backend is given, show only servers for this backend. """ - cmdTxt = "show stat\r\n" - helpTxt = "Lists all servers. Filter for servers in backend, if set." - - def getResultObj(self, res): - servers = [] - - reader = self.getDict(res) - for row in reader: - row = OrderedDict(row) - # show only server - if row['svname'] in ['BACKEND', 'FRONTEND']: - continue - - # filter server for given backend - if self.args['backend'] and row['pxname'] != self.args['backend']: - continue - - # add id - row['id'] = f"{row['pxname']}/{row['svname']}" - row.move_to_end('id', last=False) - servers.append(dict(row)) - - return servers diff --git a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/lib/haproxy/conn.py b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/lib/haproxy/conn.py deleted file mode 100755 index 0c38673c1..000000000 --- a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/lib/haproxy/conn.py +++ /dev/null @@ -1,83 +0,0 @@ -# pylint: disable=locally-disabled, too-few-public-methods, no-self-use, invalid-name -"""conn.py - Connection module.""" -import re -from socket import socket, AF_INET, AF_UNIX, SOCK_STREAM -from haproxy import const - -class HapError(Exception): - """Generic exception for haproxyctl.""" - pass - -class HaPConn(object): - """HAProxy Socket object. - This class abstract the socket interface so - commands can be sent to HAProxy and results received and - parse by the command objects""" - - def __init__(self, sfile, socket_module=socket): - """Initializes an HAProxy and opens a connection to it - (sfile, type) -> Path for the UNIX socket""" - - self.sock = None - sfile = sfile.strip() - stype = AF_UNIX - self.socket_module = socket_module - - mobj = re.match( - '(?Punix://|tcp://)(?P[^:]+):*(?P[0-9]*)$', sfile) - - if mobj: - proto = mobj.groupdict().get('proto', None) - addr = mobj.groupdict().get('addr', None) - port = mobj.groupdict().get('port', '') - - if not addr or not proto: - raise HapError('Could not determine type of socket.') - - if proto == const.HAP_TCP_PATH: - if not port: - raise HapError('When using a tcp socket, a port is needed.') - stype = AF_INET - sfile = (addr, int(port)) - - if proto == const.HAP_UNIX_PATH: - stype = AF_UNIX - sfile = addr - - # Fallback should be sfile/AF_UNIX by default - self.sfile = (sfile, stype) - self.open() - - def open(self): - """Opens a connection for the socket. - This function should only be called if - self.closed() method was called""" - - sfile, stype = self.sfile - self.sock = self.socket_module(stype, SOCK_STREAM) - self.sock.connect(sfile) - - def sendCmd(self, cmd, objectify=False): - """Receives a command obj and sends it to the socket. Receives the output and passes it - through the command to parse it. - objectify -> Return an object instead of plain text""" - - res = "" - try: - self.sock.send(cmd.getCmd()) - except TypeError: - self.sock.send(bytearray(cmd.getCmd(), 'ASCII')) - output = self.sock.recv(const.HAP_BUFSIZE) - - while output: - res += output.decode('UTF-8') - output = self.sock.recv(const.HAP_BUFSIZE) - - if objectify: - return cmd.getResultObj(res) - - return cmd.getResult(res) - - def close(self): - """Closes the socket""" - self.sock.close() diff --git a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/lib/haproxy/const.py b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/lib/haproxy/const.py deleted file mode 100755 index ebd60d8c8..000000000 --- a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/lib/haproxy/const.py +++ /dev/null @@ -1,7 +0,0 @@ -"""const.py - Constants for haproxyctl.""" -HAP_OK = 1 -HAP_ERR = 2 -HAP_SOCK_ERR = 3 -HAP_BUFSIZE = 8192 -HAP_UNIX_PATH = 'unix://' -HAP_TCP_PATH = 'tcp://' diff --git a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/lib/haproxy/tests/__init__.py b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/lib/haproxy/tests/__init__.py deleted file mode 100755 index e69de29bb..000000000 diff --git a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/lib/haproxy/tests/test_cmds.py b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/lib/haproxy/tests/test_cmds.py deleted file mode 100755 index 327787163..000000000 --- a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/lib/haproxy/tests/test_cmds.py +++ /dev/null @@ -1,291 +0,0 @@ -# pylint: disable=star-args, locally-disabled, too-few-public-methods, no-self-use, invalid-name -"""test_cmds.py - Unittests related to command implementations.""" -import sys, os, unittest - -sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..')) -from haproxy import cmds - - -class TestCommands(unittest.TestCase): - """Tests all of the commands.""" - - def setUp(self): - self.maxDiff = None - self.pem_cert_content = """ - -----BEGIN CERTIFICATE----- - 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 - +VCAIWMkC36Dvg== - -----END CERTIFICATE----- - - -----BEGIN RSA PRIVATE KEY----- - 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 - -----END RSA PRIVATE KEY----- - - -----BEGIN CERTIFICATE----- - MIIEqzCCApOgAwIBAgIRAIvhKg5ZRO08VGQx8JdhT+UwDQYJKoZIhvcNAQELBQAw - GjEYMBYGA1UEAwwPRmFrZSBMRSBSb290IFgxMB4XDTE2MDUyMzIyMDc1OVoXDTM2 - MDUyMzIyMDc1OVowIjEgMB4GA1UEAwwXRmFrZSBMRSBJbnRlcm1lZGlhdGUgWDEw - ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDtWKySDn7rWZc5ggjz3ZB0 - 8jO4xti3uzINfD5sQ7Lj7hzetUT+wQob+iXSZkhnvx+IvdbXF5/yt8aWPpUKnPym - oLxsYiI5gQBLxNDzIec0OIaflWqAr29m7J8+NNtApEN8nZFnf3bhehZW7AxmS1m0 - ZnSsdHw0Fw+bgixPg2MQ9k9oefFeqa+7Kqdlz5bbrUYV2volxhDFtnI4Mh8BiWCN - xDH1Hizq+GKCcHsinDZWurCqder/afJBnQs+SBSL6MVApHt+d35zjBD92fO2Je56 - dhMfzCgOKXeJ340WhW3TjD1zqLZXeaCyUNRnfOmWZV8nEhtHOFbUCU7r/KkjMZO9 - AgMBAAGjgeMwgeAwDgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQIMAYBAf8CAQAw - HQYDVR0OBBYEFMDMA0a5WCDMXHJw8+EuyyCm9Wg6MHoGCCsGAQUFBwEBBG4wbDA0 - BggrBgEFBQcwAYYoaHR0cDovL29jc3Auc3RnLXJvb3QteDEubGV0c2VuY3J5cHQu - b3JnLzA0BggrBgEFBQcwAoYoaHR0cDovL2NlcnQuc3RnLXJvb3QteDEubGV0c2Vu - Y3J5cHQub3JnLzAfBgNVHSMEGDAWgBTBJnSkikSg5vogKNhcI5pFiBh54DANBgkq - hkiG9w0BAQsFAAOCAgEABYSu4Il+fI0MYU42OTmEj+1HqQ5DvyAeyCA6sGuZdwjF - UGeVOv3NnLyfofuUOjEbY5irFCDtnv+0ckukUZN9lz4Q2YjWGUpW4TTu3ieTsaC9 - AFvCSgNHJyWSVtWvB5XDxsqawl1KzHzzwr132bF2rtGtazSqVqK9E07sGHMCf+zp - DQVDVVGtqZPHwX3KqUtefE621b8RI6VCl4oD30Olf8pjuzG4JKBFRFclzLRjo/h7 - IkkfjZ8wDa7faOjVXx6n+eUQ29cIMCzr8/rNWHS9pYGGQKJiY2xmVC9h12H99Xyf - zWE9vb5zKP3MVG6neX1hSdo7PEAb9fqRhHkqVsqUvJlIRmvXvVKTwNCP3eCjRCCI - PTAvjV+4ni786iXwwFYNz8l3PmPLCyQXWGohnJ8iBm+5nk7O2ynaPVW0U2W+pt2w - SVuvdDM5zGv2f9ltNWUiYZHJ1mmO97jSY/6YfdOUH66iRtQtDkHBRdkNBsMbD+Em - 2TgBldtHNSJBfB3pm9FblgOcJ0FSWcUDWJ7vO0+NTXlgrRofRT6pVywzxVo6dND0 - WzYlTWeUVsO40xJqhgUQRER9YLOLxJ0O6C8i0xFxAMKOtSdodMB3RIwt7RFQ0uyt - n5Z5MqkYhlMI3J1tPRTp1nEt9fyGspBOO05gi148Qasp+3N+svqKomoQglNoAxU= - -----END CERTIFICATE----- - """ - - self.Resp = { - "disable": "disable server redis-ro/redis-ro0", - "set-server-agent": "set server redis-ro/redis-ro0 agent up", - "set-server-health": "set server redis-ro/redis-ro0 health stopping", - "set-server-state": "set server redis-ro/redis-ro0 state drain", - "set-server-weight": "set server redis-ro/redis-ro0 weight 10", - "frontends": "show stat", - "info": "show info", - "sessions": "show sess", - "servers": "show stat", - "show-ssl-crt-lists": "show ssl crt-list", - "show-ssl-crt-list": "show ssl crt-list -n /tmp/haproxy/ssl/601a7392cc9984.99301413.certlist", - "show-ssl-certs": "show ssl cert", - "show-ssl-cert": "show ssl cert /tmp/haproxy/ssl/601a70e4844b0.pem", - "add-to-crt-list": "add ssl crt-list /tmp/haproxy/ssl/601a7392cc9984.99301413.certlist /tmp/haproxy/ssl/601a70e4844b0.pem", - "del-from-crt-list": "del ssl crt-list /tmp/haproxy/ssl/601a7392cc9984.99301413.certlist /tmp/haproxy/ssl/601a70e4844b0.pem", - "new-ssl-cert": "new ssl cert /tmp/haproxy/ssl/601a70e4844b0.pem", - "update-ssl-cert": "set ssl cert /tmp/haproxy/ssl/601a70e4844b0.pem <<\n%s" % self.pem_cert_content, - "del-ssl-cert": "del ssl cert /tmp/haproxy/ssl/601a70e4844b0.pem", - "commit-ssl-cert": "commit ssl cert /tmp/haproxy/ssl/601a70e4844b0.pem", - "abort-ssl-cert": "abort ssl cert /tmp/haproxy/ssl/601a70e4844b0.pem", - } - - self.Resp = dict([(k, v + "\r\n") for k, v in self.Resp.items()]) - - def test_setServerAgent(self): - """Test 'set server agent' command""" - args = {"backend": "redis-ro", "server": "redis-ro0", "value": "up"} - cmdOutput = cmds.setServerAgent(**args).getCmd() - self.assertEqual(cmdOutput, self.Resp["set-server-agent"]) - - def test_setServerHealth(self): - """Test 'set server health' command""" - args = {"backend": "redis-ro", "server": "redis-ro0", "value": "stopping"} - cmdOutput = cmds.setServerHealth(**args).getCmd() - self.assertEqual(cmdOutput, self.Resp["set-server-health"]) - - def test_setServerState(self): - """Test 'set server state' command""" - args = {"backend": "redis-ro", "server": "redis-ro0", "value": "drain"} - cmdOutput = cmds.setServerState(**args).getCmd() - self.assertEqual(cmdOutput, self.Resp["set-server-state"]) - - def test_setServerWeight(self): - """Test 'set server weight' command""" - args = {"backend": "redis-ro", "server": "redis-ro0", "value": "10"} - cmdOutput = cmds.setServerWeight(**args).getCmd() - self.assertEqual(cmdOutput, self.Resp["set-server-weight"]) - - def test_showFrontends(self): - """Test 'frontends/backends' commands""" - args = {} - cmdOutput = cmds.showFrontends(**args).getCmd() - self.assertEqual(cmdOutput, self.Resp["frontends"]) - - def test_showInfo(self): - """Test 'show info' command""" - cmdOutput = cmds.showInfo().getCmd() - self.assertEqual(cmdOutput, self.Resp["info"]) - - def test_showSessions(self): - """Test 'show sess' command""" - cmdOutput = cmds.showSessions().getCmd() - self.assertEqual(cmdOutput, self.Resp["sessions"]) - - def test_showServers(self): - """Test 'show stat' command""" - args = {"backend": "redis-ro"} - cmdOutput = cmds.showServers(**args).getCmd() - self.assertEqual(cmdOutput, self.Resp["servers"]) - - def test_showSslCrtLists(self): - """Test 'show ssl crt-list' command""" - cmdOutput = cmds.showSslCrtLists().getCmd() - self.assertEqual(cmdOutput, self.Resp["show-ssl-crt-lists"]) - - def test_showSslCrtList(self): - """Test 'show ssl crt-list ' command""" - args = { - "crt_list": "/tmp/haproxy/ssl/601a7392cc9984.99301413.certlist", - } - cmdOutput = cmds.showSslCrtList(**args).getCmd() - self.assertEqual(cmdOutput, self.Resp["show-ssl-crt-list"]) - - def test_showSslCerts(self): - """Test 'show ssl cert' command""" - cmdOutput = cmds.showSslCerts().getCmd() - self.assertEqual(cmdOutput, self.Resp["show-ssl-certs"]) - - def test_showSslCert(self): - """Test 'show ssl cert ' command""" - args = { - "certfile": "/tmp/haproxy/ssl/601a70e4844b0.pem" - } - cmdOutput = cmds.showSslCert(**args).getCmd() - self.assertEqual(cmdOutput, self.Resp["show-ssl-cert"]) - - def test_addToSslCrtList(self): - """Test 'add ssl crt-list ' command""" - args = { - "crt_list": "/tmp/haproxy/ssl/601a7392cc9984.99301413.certlist", - "certfile": "/tmp/haproxy/ssl/601a70e4844b0.pem" - } - cmdOutput = cmds.addToSslCrtList(**args).getCmd() - self.assertEqual(cmdOutput, self.Resp["add-to-crt-list"]) - - def test_delFromSslCrtList(self): - """Test 'del ssl crt-list ' command""" - args = { - "crt_list": "/tmp/haproxy/ssl/601a7392cc9984.99301413.certlist", - "certfile": "/tmp/haproxy/ssl/601a70e4844b0.pem" - } - cmdOutput = cmds.delFromSslCrtList(**args).getCmd() - self.assertEqual(cmdOutput, self.Resp["del-from-crt-list"]) - - def test_newSslCrt(self): - """Test 'new ssl cert ' command""" - args = { - "certfile": "/tmp/haproxy/ssl/601a70e4844b0.pem", - } - cmdOutput = cmds.newSslCrt(**args).getCmd() - self.assertEqual(cmdOutput, self.Resp["new-ssl-cert"]) - - def test_updateSslCrt(self): - """Test 'set ssl cert ' command""" - args = { - "certfile": "/tmp/haproxy/ssl/601a70e4844b0.pem", - "payload": "%s" % self.pem_cert_content - } - cmdOutput = cmds.updateSslCrt(**args).getCmd() - self.assertEqual(cmdOutput, self.Resp["update-ssl-cert"]) - - def test_delSslCrt(self): - """Test 'del ssl cert ' command""" - args = { - "certfile": "/tmp/haproxy/ssl/601a70e4844b0.pem", - } - cmdOutput = cmds.delSslCrt(**args).getCmd() - self.assertEqual(cmdOutput, self.Resp["del-ssl-cert"]) - - def test_commitSslCrt(self): - """Test 'commit ssl cert ' command""" - args = { - "certfile": "/tmp/haproxy/ssl/601a70e4844b0.pem", - } - cmdOutput = cmds.commitSslCrt(**args).getCmd() - self.assertEqual(cmdOutput, self.Resp["commit-ssl-cert"]) - - def test_abortSslCrt(self): - """Test 'abort ssl cert ' command""" - args = { - "certfile": "/tmp/haproxy/ssl/601a70e4844b0.pem", - } - cmdOutput = cmds.abortSslCrt(**args).getCmd() - self.assertEqual(cmdOutput, self.Resp["abort-ssl-cert"]) - - -if __name__ == '__main__': - unittest.main() diff --git a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/lib/haproxy/tests/test_conn.py b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/lib/haproxy/tests/test_conn.py deleted file mode 100755 index ea8c15f60..000000000 --- a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/lib/haproxy/tests/test_conn.py +++ /dev/null @@ -1,59 +0,0 @@ -# pylint: disable=locally-disabled, too-few-public-methods, no-self-use, invalid-name, broad-except -"""test_conn.py - Unittests related to connections to HAProxy.""" -import sys, os -sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..')) -from haproxy import conn -import unittest -from socket import AF_INET, AF_UNIX - -class SimpleConnMock(object): - """Simple socket mock.""" - def __init__(self, stype, stream): - self.stype = stype - self.stream = stream - - def connect(self, addr): - """Mocked socket.connect method.""" - pass - -class TestConnection(unittest.TestCase): - """Tests different aspects of haproxyctl's connections to HAProxy.""" - - def testConnSimple(self): - """Tests that connection to non-protocol path works and fallsback to UNIX socket.""" - sfile = "/some/path/to/socket.sock" - c = conn.HaPConn(sfile, socket_module=SimpleConnMock) - addr, stype = c.sfile - self.assertEqual(sfile, addr) - self.assertEqual(stype, AF_UNIX) - - def testConnUnixString(self): - """Tests that unix:// protocol works and connects to a socket.""" - sfile = "unix:///some/path/to/socket.socket" - c = conn.HaPConn(sfile, socket_module=SimpleConnMock) - addr, stype = c.sfile - self.assertEqual("/some/path/to/socket.socket", addr) - self.assertEqual(stype, AF_UNIX) - - def testConnTCPString(self): - """Tests that tcp:// protocol works and connects to an IP.""" - sfile = "tcp://1.2.3.4:8080" - c = conn.HaPConn(sfile, socket_module=SimpleConnMock) - addr, stype = c.sfile - ip, port = addr - self.assertEqual("1.2.3.4", ip) - self.assertEqual(8080, port) - self.assertEqual(stype, AF_INET) - - def testConnTCPStringNoPort(self): - """Tests that passing a tcp:// address with no port, raises an Exception.""" - sfile = "tcp://1.2.3.4" - # Not using assertRaises because we still support 2.6 - try: - conn.HaPConn(sfile, socket_module=SimpleConnMock) - raise Exception('Connection should have thrown an exception') - except conn.HapError: - pass - -if __name__ == '__main__': - unittest.main() diff --git a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/socketCommand.py b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/socketCommand.py index 554db684a..bcf407c36 100755 --- a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/socketCommand.py +++ b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/socketCommand.py @@ -4,7 +4,6 @@ import sys import argparse import traceback -sys.path.append(os.path.join(os.path.dirname(__file__), 'lib')) from haproxy.conn import HaPConn from haproxy import cmds diff --git a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/syncCerts.py b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/syncCerts.py index f4932a0cd..8df8543f3 100755 --- a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/syncCerts.py +++ b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/syncCerts.py @@ -9,7 +9,6 @@ import OpenSSL import json from typing import List -sys.path.append(os.path.join(os.path.dirname(__file__), 'lib')) from haproxy.conn import HaPConn from haproxy import cmds From ac824e3d02e631e05a646b99ab00ae5eb35cbbf9 Mon Sep 17 00:00:00 2001 From: Frank Wall Date: Sat, 16 Dec 2023 23:17:38 +0100 Subject: [PATCH 3/9] net/haproxy: add support for built-in OCSP update feature --- net/haproxy/pkg-descr | 7 ++ .../HAProxy/forms/generalSettings.xml | 6 -- .../OPNsense/HAProxy/forms/generalTuning.xml | 22 ++++++ .../HAProxy/forms/maintenanceCronjobs.xml | 11 --- .../app/models/OPNsense/HAProxy/HAProxy.xml | 22 +++++- .../OPNsense/HAProxy/Migrations/M4_1_0.php | 59 ++++++++++++++ .../scripts/OPNsense/HAProxy/exportCerts.php | 7 +- .../scripts/OPNsense/HAProxy/setup.sh | 5 -- .../scripts/OPNsense/HAProxy/updateOcsp.sh | 76 ------------------- .../conf/actions.d/actions_haproxy.conf | 7 -- .../templates/OPNsense/HAProxy/haproxy.conf | 9 +++ .../templates/OPNsense/HAProxy/rc.conf.d | 5 -- 12 files changed, 124 insertions(+), 112 deletions(-) create mode 100644 net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/Migrations/M4_1_0.php delete mode 100755 net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/updateOcsp.sh diff --git a/net/haproxy/pkg-descr b/net/haproxy/pkg-descr index 2681b9f8d..e0f6044fe 100644 --- a/net/haproxy/pkg-descr +++ b/net/haproxy/pkg-descr @@ -6,12 +6,19 @@ very high loads while needing persistence or Layer7 processing. Plugin Changelog ================ +Added: +* add support for built-in OCSP update feature + Fixed: * fix typo in cert sync script Changed: +* move OCSP settings from "Service" to "Global" section * replace bundled haproxyctl library with haproxy-cli +Removed: +* remove OSCP update cron job + 4.1 Fixed: diff --git a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/generalSettings.xml b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/generalSettings.xml index b9934dd6a..6c6a1a22e 100644 --- a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/generalSettings.xml +++ b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/generalSettings.xml @@ -33,12 +33,6 @@ checkbox - - haproxy.general.storeOcsp - - checkbox - - haproxy.general.showIntro diff --git a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/generalTuning.xml b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/generalTuning.xml index 0bef8a78b..364cf6032 100644 --- a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/generalTuning.xml +++ b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/generalTuning.xml @@ -67,6 +67,28 @@
NOTE: The syntax will not be checked, use at your own risk!
]]>
true
+ + + header + + + haproxy.general.tuning.ocspUpdateEnabled + + checkbox + + + + haproxy.general.tuning.ocspUpdateMinDelay + + text + + + + haproxy.general.tuning.ocspUpdateMaxDelay + + text + + header diff --git a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/maintenanceCronjobs.xml b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/maintenanceCronjobs.xml index f9c4edf83..1924980d2 100644 --- a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/maintenanceCronjobs.xml +++ b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/maintenanceCronjobs.xml @@ -10,17 +10,6 @@ checkbox Automation instead of this cron job.]]> - - - header - - - - haproxy.maintenance.cronjobs.updateOcsp - - checkbox - HAProxy service settings.]]> - header diff --git a/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml b/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml index baf4277b3..5c42f7c20 100644 --- a/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml +++ b/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml @@ -1,6 +1,6 @@ //OPNsense/HAProxy - 4.0.0 + 4.1.0 the HAProxy load balancer @@ -27,6 +27,7 @@ 0 Y + 0 N @@ -128,6 +129,24 @@ N + + 0 + Y + + + 300 + 1 + 86400 + Please specify a value between 1 and 86400. + N + + + 3600 + 1 + 86400 + Please specify a value between 1 and 86400. + N + 0 Y @@ -3027,6 +3046,7 @@ Related cron not found. N + 0 N diff --git a/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/Migrations/M4_1_0.php b/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/Migrations/M4_1_0.php new file mode 100644 index 000000000..22f91c8fe --- /dev/null +++ b/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/Migrations/M4_1_0.php @@ -0,0 +1,59 @@ +general->storeOcsp; + $model->general->tuning->ocspUpdateEnabled = $old_ocsp; + + // Remove obsolete OCSP cron job + if ((string)$model->maintenance->cronjobs->updateOcspCron != "") { + $cron_uuid = (string)$model->maintenance->cronjobs->updateOcspCron; + $model->maintenance->cronjobs->updateOcspCron = ""; + + // Delete the cronjob item + $mdlCron = new Cron(); + if ($mdlCron->jobs->job->del($cron_uuid)) { + $mdlCron->serializeToConfig(); + $model->serializeToConfig($validateFullModel = false, $disable_validation = true); + Config::getInstance()->save(); + } + } + } +} diff --git a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/exportCerts.php b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/exportCerts.php index 0dfa7bd26..c2e052f60 100755 --- a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/exportCerts.php +++ b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/exportCerts.php @@ -95,7 +95,12 @@ foreach ($configNodes as $key => $value) { file_put_contents($output_pem_filename, $pem_content); chmod($output_pem_filename, 0600); echo "exported $type to " . $output_pem_filename . "\n"; - $crtlist[] = $output_pem_filename; + // Check if automatic OCSP updates are enabled. + if (isset($configObj->OPNsense->HAProxy->general->tuning->ocspUpdateEnabled) and ($configObj->OPNsense->HAProxy->general->tuning->ocspUpdateEnabled == '1')) { + $crtlist[] = $output_pem_filename . " ocsp-update on"; + } else { + $crtlist[] = $output_pem_filename; + } } else { // In contrast to certificates, CA/CRL content needs to be put in a single file. // A list of individual files is not supported by HAproxy. diff --git a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/setup.sh b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/setup.sh index 0e07ab1ba..5c74fd279 100755 --- a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/setup.sh +++ b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/setup.sh @@ -22,11 +22,6 @@ find /var/haproxy -type d -exec chmod 550 {} \; /usr/local/opnsense/scripts/OPNsense/HAProxy/exportErrorFiles.php > /dev/null 2>&1 /usr/local/opnsense/scripts/OPNsense/HAProxy/exportMapFiles.php > /dev/null 2>&1 -# update OCSP data -if [ "${haproxy_ocsp}" == "YES" ]; then - /usr/local/opnsense/scripts/OPNsense/HAProxy/updateOcsp.sh > /dev/null 2>&1 -fi - # deploy new config case "$1" in deploy) diff --git a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/updateOcsp.sh b/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/updateOcsp.sh deleted file mode 100755 index 6bf8af928..000000000 --- a/net/haproxy/src/opnsense/scripts/OPNsense/HAProxy/updateOcsp.sh +++ /dev/null @@ -1,76 +0,0 @@ -#!/bin/sh -# This file is based on: -# https://github.com/acmesh-official/acme.sh/blob/master/deploy/haproxy.sh -# -# Copyright (C) 2021 Neil Pang -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -HAPROXY_DIR="/tmp/haproxy/ssl" -HAPROXY_SOCKET="/var/run/haproxy.socket" - -for _pem in "$HAPROXY_DIR"/*.pem; do - cert_file="$(basename "$_pem")" - _issuer="${HAPROXY_DIR}/${cert_file%.pem}.issuer" - _ocsp="${_pem}.ocsp" - cert_cn="$(openssl x509 -in "$_pem" -noout -text | sed -nE 's/.*Subject:.*CN = ([^,]*)(,.*)?$/\1/p')" - - if [ ! -f "$_issuer" ]; then - continue - fi - - if [ -r "${_issuer}" ]; then - _ocsp_url="$(openssl x509 -noout -ocsp_uri -in "$_pem")" - if [ -n "$_ocsp_url" ]; then - _ocsp_host="$(echo "$_ocsp_url" | cut -d/ -f3)" - subjectdn="$(openssl x509 -in "$_issuer" -subject -noout | cut -d'/' -f2,3,4,5,6,7,8,9,10)" - issuerdn="$(openssl x509 -in "$_issuer" -issuer -noout | cut -d'/' -f2,3,4,5,6,7,8,9,10)" - if [ "$subjectdn" = "$issuerdn" ]; then - _cafile_argument="-CAfile \"${_issuer}\"" - else - _cafile_argument="" - fi - _openssl_version=$(openssl version | cut -d' ' -f2) - _openssl_major=$(echo "${_openssl_version}" | cut -d '.' -f1) - _openssl_minor=$(echo "${_openssl_version}" | cut -d '.' -f2) - if [ "${_openssl_major}" -eq "1" ] && [ "${_openssl_minor}" -ge "1" ] || [ "${_openssl_major}" -ge "2" ]; then - _header_sep="=" - else - _header_sep=" " - fi - - _openssl_ocsp_cmd="openssl ocsp \ - -issuer \"${_issuer}\" \ - -cert \"${_pem}\" \ - -url \"${_ocsp_url}\" \ - -header Host${_header_sep}\"${_ocsp_host}\" \ - -respout \"${_ocsp}\" \ - -verify_other \"${_issuer}\" \ - ${_cafile_argument} \ - | grep -q \"${_pem}: good\"" - - eval "${_openssl_ocsp_cmd}" - _ret=$? - - if [ "${_ret}" != "0" ]; then - echo "Updating OCSP stapling failed with return code ${_ret}" - else - _update="$(openssl enc -base64 -A -in "${_ocsp}")" - if ! echo "set ssl ocsp-response ${_update}" | socat stdio $HAPROXY_SOCKET; then - echo "Updating haproxy OCSP stapling via socket failed" - fi - fi - fi - fi -done diff --git a/net/haproxy/src/opnsense/service/conf/actions.d/actions_haproxy.conf b/net/haproxy/src/opnsense/service/conf/actions.d/actions_haproxy.conf index 9ca6d13dd..ab181dd8a 100644 --- a/net/haproxy/src/opnsense/service/conf/actions.d/actions_haproxy.conf +++ b/net/haproxy/src/opnsense/service/conf/actions.d/actions_haproxy.conf @@ -126,10 +126,3 @@ command:/usr/bin/diff -Naur /usr/local/etc/haproxy.conf /usr/local/etc/haproxy.c parameters: type:script_output message:diff haproxy config - -[update_ocsp] -command:/usr/local/opnsense/scripts/OPNsense/HAProxy/updateOcsp.sh -parameters: -type:script_output -description:Update HAProxy OCSP data -message:update haproxy ocsp data diff --git a/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf b/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf index ab08e8f3a..bcfc4c6e2 100644 --- a/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf +++ b/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf @@ -982,6 +982,15 @@ global {% if helpers.exists('OPNsense.HAProxy.general.tuning.maxConnections') %} maxconn {{OPNsense.HAProxy.general.tuning.maxConnections}} {% endif %} +{# # check if OCSP is enabled #} +{% if OPNsense.HAProxy.general.tuning.ocspUpdateEnabled|default('') == '1' %} +{% if helpers.exists('OPNsense.HAProxy.general.tuning.ocspUpdateMinDelay') %} + tune.ssl.ocsp-update.mindelay {{OPNsense.HAProxy.general.tuning.ocspUpdateMinDelay}} +{% endif %} +{% if helpers.exists('OPNsense.HAProxy.general.tuning.ocspUpdateMaxDelay') %} + tune.ssl.ocsp-update.maxdelay {{OPNsense.HAProxy.general.tuning.ocspUpdateMaxDelay}} +{% endif %} +{% endif %} {% if helpers.exists('OPNsense.HAProxy.general.tuning.maxDHSize') %} tune.ssl.default-dh-param {{OPNsense.HAProxy.general.tuning.maxDHSize}} {% endif %} diff --git a/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/rc.conf.d b/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/rc.conf.d index 2e2090670..1aa2b759c 100644 --- a/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/rc.conf.d +++ b/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/rc.conf.d @@ -3,11 +3,6 @@ haproxy_enable=YES haproxy_setup="/usr/local/opnsense/scripts/OPNsense/HAProxy/setup.sh" haproxy_pidfile="/var/run/haproxy.pid" haproxy_config="/usr/local/etc/haproxy.conf" -{% if helpers.exists('OPNsense.HAProxy.general.storeOcsp') and OPNsense.HAProxy.general.storeOcsp|default("0") == "1" %} -haproxy_ocsp=YES -{% else %} -haproxy_ocsp=NO -{% endif %} {% if helpers.exists('OPNsense.HAProxy.general.gracefulStop') and OPNsense.HAProxy.general.gracefulStop|default("0") == "1" %} haproxy_hardstop=NO {% else %} From 1a1630b875af10a7f928470acc6df1ae022e9851 Mon Sep 17 00:00:00 2001 From: Frank Wall Date: Wed, 20 Dec 2023 15:28:04 +0100 Subject: [PATCH 4/9] net/haproxy: add support for forwarded header (RFC7239) --- net/haproxy/pkg-descr | 1 + .../OPNsense/HAProxy/forms/dialogBackend.xml | 15 +++++++++++++++ .../mvc/app/models/OPNsense/HAProxy/HAProxy.xml | 17 +++++++++++++++++ .../templates/OPNsense/HAProxy/haproxy.conf | 9 +++++++++ 4 files changed, 42 insertions(+) diff --git a/net/haproxy/pkg-descr b/net/haproxy/pkg-descr index e0f6044fe..056cc01d9 100644 --- a/net/haproxy/pkg-descr +++ b/net/haproxy/pkg-descr @@ -8,6 +8,7 @@ Plugin Changelog Added: * add support for built-in OCSP update feature +* add support for forwarded header (RFC7239) Fixed: * fix typo in cert sync script diff --git a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogBackend.xml b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogBackend.xml index c7babd3a7..5895c1013 100644 --- a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogBackend.xml +++ b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogBackend.xml @@ -173,6 +173,21 @@ true + + backend.forwardedHeader + + checkbox + + + + backend.forwardedHeaderParameters + + select_multiple + + true + true + HAProxy documentation for a full description.]]> + header diff --git a/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml b/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml index 5c42f7c20..c4eff76bc 100644 --- a/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml +++ b/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml @@ -1053,6 +1053,23 @@ HTTP/1.0 + + 0 + N + + + N + Y + Y + + proto + host + by + by_port + for + for_port + + N sticktable diff --git a/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf b/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf index bcfc4c6e2..19b5c50ea 100644 --- a/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf +++ b/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf @@ -1686,6 +1686,15 @@ backend {{backend.name}} {% if backend.tuning_httpreuse|default("") != "" and backend.mode == "http" %} http-reuse {{backend.tuning_httpreuse}} {% endif %} +{% if backend.forwardedHeader == '1' and backend.mode == 'http' %} +{% set forwarded_params = [] %} +{% if backend.forwardedHeaderParameters|default("") != "" %} +{% for fwd_param in backend.forwardedHeaderParameters.split(",") %} +{% do forwarded_params.append(fwd_param) %} +{% endfor %} +{% endif %} + option forwarded {{forwarded_params|join(' ')}} +{% endif %} {% if helpers.exists('OPNsense.HAProxy.general.cache') and OPNsense.HAProxy.general.cache.enabled|default("") == "1" and backend.tuning_caching|default("") == "1" and backend.mode == "http" %} http-request cache-use opnsense-haproxy-cache http-response cache-store opnsense-haproxy-cache From 79aec1ccb4b02227e2d32625802adfb95b426d8a Mon Sep 17 00:00:00 2001 From: Frank Wall Date: Wed, 20 Dec 2023 15:46:16 +0100 Subject: [PATCH 5/9] net/haproxy: add forwardfor option to backend settings --- net/haproxy/pkg-descr | 4 ++++ .../controllers/OPNsense/HAProxy/forms/dialogBackend.xml | 6 ++++++ .../controllers/OPNsense/HAProxy/forms/dialogFrontend.xml | 4 ++-- .../opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml | 5 +++++ .../service/templates/OPNsense/HAProxy/haproxy.conf | 3 +++ 5 files changed, 20 insertions(+), 2 deletions(-) diff --git a/net/haproxy/pkg-descr b/net/haproxy/pkg-descr index 056cc01d9..da3d9d987 100644 --- a/net/haproxy/pkg-descr +++ b/net/haproxy/pkg-descr @@ -9,6 +9,7 @@ Plugin Changelog Added: * add support for built-in OCSP update feature * add support for forwarded header (RFC7239) +* add option "X-Forwarded-For Header" to backend settings Fixed: * fix typo in cert sync script @@ -17,6 +18,9 @@ Changed: * move OCSP settings from "Service" to "Global" section * replace bundled haproxyctl library with haproxy-cli +Deprecated: +* frontend option "X-Forwarded-For Header" (the backend option should be used) + Removed: * remove OSCP update cron job diff --git a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogBackend.xml b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogBackend.xml index 5895c1013..73bb33ce6 100644 --- a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogBackend.xml +++ b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogBackend.xml @@ -188,6 +188,12 @@ true HAProxy documentation for a full description.]]> + + backend.forwardFor + + checkbox + + header diff --git a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogFrontend.xml b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogFrontend.xml index 2a4c492a5..d21e258f9 100644 --- a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogFrontend.xml +++ b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogFrontend.xml @@ -207,9 +207,9 @@ frontend.forwardFor - + checkbox - + frontend.prometheus_enabled diff --git a/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml b/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml index c4eff76bc..01e1eb4de 100644 --- a/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml +++ b/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml @@ -814,6 +814,7 @@ HTTP/1.0 + 0 Y @@ -1053,6 +1054,10 @@ HTTP/1.0 + + 0 + N + 0 N diff --git a/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf b/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf index 19b5c50ea..13754b111 100644 --- a/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf +++ b/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf @@ -1695,6 +1695,9 @@ backend {{backend.name}} {% endif %} option forwarded {{forwarded_params|join(' ')}} {% endif %} +{% if backend.forwardFor == '1' and backend.mode == 'http' %} + option forwardfor +{% endif %} {% if helpers.exists('OPNsense.HAProxy.general.cache') and OPNsense.HAProxy.general.cache.enabled|default("") == "1" and backend.tuning_caching|default("") == "1" and backend.mode == "http" %} http-request cache-use opnsense-haproxy-cache http-response cache-store opnsense-haproxy-cache From a57e2a3ccd00f721401d1b3cc7890c3493bf0502 Mon Sep 17 00:00:00 2001 From: Frank Wall Date: Thu, 28 Dec 2023 22:00:04 +0100 Subject: [PATCH 6/9] net/haproxy: adjust HTTP/2 settings to adopt HAProxy 2.8 defaults --- net/haproxy/pkg-descr | 2 ++ .../src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml | 4 ++-- .../opnsense/service/templates/OPNsense/HAProxy/haproxy.conf | 3 +++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/net/haproxy/pkg-descr b/net/haproxy/pkg-descr index da3d9d987..18eeccaba 100644 --- a/net/haproxy/pkg-descr +++ b/net/haproxy/pkg-descr @@ -15,6 +15,8 @@ Fixed: * fix typo in cert sync script Changed: +* change default for HTTP/2 to enabled (only new frontends/backends) +* add "no-alpn" option if HTTP/2 is not enabled (TLS-enabled frontends) * move OCSP settings from "Service" to "Global" section * replace bundled haproxyctl library with haproxy-cli diff --git a/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml b/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml index 01e1eb4de..ed8670c42 100644 --- a/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml +++ b/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml @@ -796,7 +796,7 @@ N - 0 + 1 N @@ -1036,7 +1036,7 @@ N - 0 + 1 N diff --git a/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf b/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf index 13754b111..571562c8d 100644 --- a/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf +++ b/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf @@ -1369,6 +1369,9 @@ frontend {{frontend.name}} {# # convert protocols to HAProxy-compatible format #} {% set alpn_options = frontend.advertised_protocols|replace('http10', 'http/1.0')|replace('http11', 'http/1.1') %} {% do ssl_options.append('alpn ' ~ alpn_options) %} +{% else %} +{# # disable ALPN to enforce the GUI settings #} +{% do ssl_options.append('no-alpn') %} {% endif %} {# # HTTP/2 without TLS #} {% elif frontend.http2Enabled|default("") == '1' and frontend.http2Enabled_nontls|default("") == '1' %} From 557f02a684ee0c92929172e0452a1841eeb94d13 Mon Sep 17 00:00:00 2001 From: Frank Wall Date: Thu, 28 Dec 2023 22:36:55 +0100 Subject: [PATCH 7/9] net/haproxy: add HTTP/2 performance settings --- net/haproxy/pkg-descr | 1 + .../OPNsense/HAProxy/forms/generalTuning.xml | 40 +++++++++++++++++++ .../app/models/OPNsense/HAProxy/HAProxy.xml | 36 +++++++++++++++++ .../templates/OPNsense/HAProxy/haproxy.conf | 18 +++++++++ 4 files changed, 95 insertions(+) diff --git a/net/haproxy/pkg-descr b/net/haproxy/pkg-descr index 18eeccaba..44cb5c952 100644 --- a/net/haproxy/pkg-descr +++ b/net/haproxy/pkg-descr @@ -10,6 +10,7 @@ Added: * add support for built-in OCSP update feature * add support for forwarded header (RFC7239) * add option "X-Forwarded-For Header" to backend settings +* add options for HTTP/2 performance tuning Fixed: * fix typo in cert sync script diff --git a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/generalTuning.xml b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/generalTuning.xml index 364cf6032..f20d662dc 100644 --- a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/generalTuning.xml +++ b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/generalTuning.xml @@ -132,4 +132,44 @@ true + + + header + + + haproxy.general.tuning.h2_initialWindowSize + + text + + + + haproxy.general.tuning.h2_initialWindowSizeOutgoing + + text + + + + haproxy.general.tuning.h2_initialWindowSizeIncoming + + text + + + + haproxy.general.tuning.h2_maxConcurrentStreams + + text + + + + haproxy.general.tuning.h2_maxConcurrentStreamsOutgoing + + text + + + + haproxy.general.tuning.h2_maxConcurrentStreamsIncoming + + text + + diff --git a/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml b/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml index ed8670c42..3e90be2f2 100644 --- a/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml +++ b/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml @@ -201,6 +201,42 @@ TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256 N + + 0 + 10000000 + Please specify a value between 0 and 10000000. + N + + + 0 + 10000000 + Please specify a value between 0 and 10000000. + N + + + 0 + 10000000 + Please specify a value between 0 and 10000000. + N + + + 0 + 10000000 + Please specify a value between 0 and 10000000. + N + + + 0 + 10000000 + Please specify a value between 0 and 10000000. + N + + + 0 + 10000000 + Please specify a value between 0 and 10000000. + N + diff --git a/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf b/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf index 571562c8d..4ee933700 100644 --- a/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf +++ b/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf @@ -1011,6 +1011,24 @@ global {% if OPNsense.HAProxy.general.tuning.luaMaxMem|default("") != "" %} tune.lua.maxmem {{OPNsense.HAProxy.general.tuning.luaMaxMem}} {% endif %} +{% if OPNsense.HAProxy.general.tuning.h2_initialWindowSize|default("") != "" %} + tune.h2.initial-window-size {{OPNsense.HAProxy.general.tuning.h2_initialWindowSize}} +{% endif %} +{% if OPNsense.HAProxy.general.tuning.h2_initialWindowSizeOutgoing|default("") != "" %} + tune.h2.be.initial-window-size {{OPNsense.HAProxy.general.tuning.h2_initialWindowSizeOutgoing}} +{% endif %} +{% if OPNsense.HAProxy.general.tuning.h2_initialWindowSizeIncoming|default("") != "" %} + tune.h2.fe.initial-window-size {{OPNsense.HAProxy.general.tuning.h2_initialWindowSizeIncoming}} +{% endif %} +{% if OPNsense.HAProxy.general.tuning.h2_maxConcurrentStreams|default("") != "" %} + tune.h2.max-concurrent-streams {{OPNsense.HAProxy.general.tuning.h2_maxConcurrentStreams}} +{% endif %} +{% if OPNsense.HAProxy.general.tuning.h2_maxConcurrentStreamsOutgoing|default("") != "" %} + tune.h2.be.max-concurrent-streams {{OPNsense.HAProxy.general.tuning.h2_maxConcurrentStreamsOutgoing}} +{% endif %} +{% if OPNsense.HAProxy.general.tuning.h2_maxConcurrentStreamsIncoming|default("") != "" %} + tune.h2.fe.max-concurrent-streams {{OPNsense.HAProxy.general.tuning.h2_maxConcurrentStreamsIncoming}} +{% endif %} {# # logging configuration #} {% set logging = [] %} {% if OPNsense.HAProxy.general.logging.host != '127.0.0.1' %} From 3d42eb6a9956d98836838baa8d15936b684535b9 Mon Sep 17 00:00:00 2001 From: Frank Wall Date: Thu, 28 Dec 2023 22:51:37 +0100 Subject: [PATCH 8/9] net/haproxy: switch to HAProxy 2.8, refs #3459 --- net/haproxy/Makefile | 2 +- net/haproxy/pkg-descr | 1 + .../OPNsense/HAProxy/forms/dialogAction.xml | 12 ++++++------ .../OPNsense/HAProxy/forms/dialogBackend.xml | 10 +++++----- .../OPNsense/HAProxy/forms/dialogFcgi.xml | 2 +- .../OPNsense/HAProxy/forms/dialogFrontend.xml | 6 +++--- .../OPNsense/HAProxy/forms/dialogMapfile.xml | 2 +- .../mvc/app/views/OPNsense/HAProxy/index.volt | 10 +++++----- 8 files changed, 23 insertions(+), 22 deletions(-) diff --git a/net/haproxy/Makefile b/net/haproxy/Makefile index 95013f8e1..14dccc7af 100644 --- a/net/haproxy/Makefile +++ b/net/haproxy/Makefile @@ -2,7 +2,7 @@ PLUGIN_NAME= haproxy PLUGIN_VERSION= 4.1 PLUGIN_REVISION= 1 PLUGIN_COMMENT= Reliable, high performance TCP/HTTP load balancer -PLUGIN_DEPENDS= haproxy26 py${PLUGIN_PYTHON}-haproxy-cli +PLUGIN_DEPENDS= haproxy py${PLUGIN_PYTHON}-haproxy-cli PLUGIN_MAINTAINER= opnsense@moov.de .include "../../Mk/plugins.mk" diff --git a/net/haproxy/pkg-descr b/net/haproxy/pkg-descr index 44cb5c952..8eb91e61d 100644 --- a/net/haproxy/pkg-descr +++ b/net/haproxy/pkg-descr @@ -16,6 +16,7 @@ Fixed: * fix typo in cert sync script Changed: +* upgrade to HAProxy 2.8 release series (#3459) * change default for HTTP/2 to enabled (only new frontends/backends) * add "no-alpn" option if HTTP/2 is not enabled (TLS-enabled frontends) * move OCSP settings from "Service" to "Global" section diff --git a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogAction.xml b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogAction.xml index e03c3632b..7945ded64 100644 --- a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogAction.xml +++ b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogAction.xml @@ -89,7 +89,7 @@ action.http_request_redirect text - HAProxy's documentation for further details and examples.]]> + HAProxy's documentation for further details and examples.]]> @@ -128,7 +128,7 @@ action.http_request_add_header_content text - HAProxy's documentation for further details and examples.]]> + HAProxy's documentation for further details and examples.]]> @@ -145,7 +145,7 @@ action.http_request_set_header_content text - HAProxy's documentation for further details and examples.]]> + HAProxy's documentation for further details and examples.]]> @@ -251,7 +251,7 @@ action.http_response_add_header_content text - HAProxy's documentation for further details and examples.]]> + HAProxy's documentation for further details and examples.]]> @@ -268,7 +268,7 @@ action.http_response_set_header_content text - HAProxy's documentation for further details and examples.]]> + HAProxy's documentation for further details and examples.]]> @@ -468,6 +468,6 @@ action.fcgi_set_param text - Custom Log format rules. With this directive, it is possible to overwrite the value of default FastCGI parameters.]]> + Custom Log format rules. With this directive, it is possible to overwrite the value of default FastCGI parameters.]]> diff --git a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogBackend.xml b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogBackend.xml index 73bb33ce6..8411a6ad9 100644 --- a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogBackend.xml +++ b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogBackend.xml @@ -28,7 +28,7 @@ backend.algorithm dropdown - HAProxy documentation for a full description.]]> + HAProxy documentation for a full description.]]> Choose a load balancing algorithm. @@ -42,7 +42,7 @@ backend.proxyProtocol dropdown - HAProxy documentation for a full description.]]> + HAProxy documentation for a full description.]]> true @@ -213,7 +213,7 @@ backend.persistence_cookiemode dropdown - HAProxy documentation for a full description.]]> + HAProxy documentation for a full description.]]> backend.persistence_cookiename @@ -235,14 +235,14 @@ backend.stickiness_pattern dropdown - HAProxy documentation for a full description.
NOTE: Consider not using this feature in multi-process mode, it can result in random behaviours.
]]>
+ HAProxy documentation for a full description.
NOTE: Consider not using this feature in multi-process mode, it can result in random behaviours.
]]>
Choose a persistence type.
backend.stickiness_dataTypes select_multiple - HAProxy documentation for a full description.]]> + HAProxy documentation for a full description.]]> backend.stickiness_expire diff --git a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogFcgi.xml b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogFcgi.xml index fd6e48bfd..c02327bce 100644 --- a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogFcgi.xml +++ b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogFcgi.xml @@ -33,7 +33,7 @@ fcgi.path_info text - HAProxy's documentation for further details and examples.]]> + HAProxy's documentation for further details and examples.]]> fcgi.log_stderr diff --git a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogFrontend.xml b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogFrontend.xml index d21e258f9..2268abe72 100644 --- a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogFrontend.xml +++ b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogFrontend.xml @@ -350,14 +350,14 @@ frontend.stickiness_pattern dropdown - HAProxy documentation for further information.]]> + HAProxy documentation for further information.]]> Choose a stick-table type. frontend.stickiness_dataTypes select_multiple - HAProxy documentation for a full description.]]> + HAProxy documentation for a full description.]]> frontend.stickiness_expire @@ -384,7 +384,7 @@ frontend.stickiness_counter_key text - HAProxy documentation for a full description.]]> + HAProxy documentation for a full description.]]> true diff --git a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogMapfile.xml b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogMapfile.xml index 6b8e712a3..4955c8519 100644 --- a/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogMapfile.xml +++ b/net/haproxy/src/opnsense/mvc/app/controllers/OPNsense/HAProxy/forms/dialogMapfile.xml @@ -15,6 +15,6 @@ mapfile.content textbox - HAProxy documentation for a full description.]]> + HAProxy documentation for a full description.]]> diff --git a/net/haproxy/src/opnsense/mvc/app/views/OPNsense/HAProxy/index.volt b/net/haproxy/src/opnsense/mvc/app/views/OPNsense/HAProxy/index.volt index c831ef9c8..932c8814f 100644 --- a/net/haproxy/src/opnsense/mvc/app/views/OPNsense/HAProxy/index.volt +++ b/net/haproxy/src/opnsense/mvc/app/views/OPNsense/HAProxy/index.volt @@ -717,7 +717,7 @@ POSSIBILITY OF SUCH DAMAGE.
  • {{ lang._('Lastly, enable HAProxy using the %sService%s settings page.') | format('', '') }}
  • {{ lang._('Please be aware that you need to %smanually%s add the required firewall rules for all configured services.') | format('', '') }}

    -

    {{ 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('', '', '', '') }}

    +

    {{ 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('', '', '', '') }}


    @@ -759,7 +759,7 @@ POSSIBILITY OF SUCH DAMAGE.
  • {{ 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('', '') }}
  • {{ 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('', '', '', '', '', '', '', '') }}
  • -

    {{ lang._("For more information on HAProxy's %sACL feature%s see the %sofficial documentation%s.") | format('', '', '', '') }}

    +

    {{ lang._("For more information on HAProxy's %sACL feature%s see the %sofficial documentation%s.") | format('', '', '', '') }}

    {{ 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('', '') }}


    @@ -774,7 +774,7 @@ POSSIBILITY OF SUCH DAMAGE.
  • {{ 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('', '') }}
  • {{ 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.') }}

    -

    {{ lang._("For more information on HAProxy's %suser/group management%s see the %sofficial documentation%s.") | format('', '', '', '') }}

    +

    {{ lang._("For more information on HAProxy's %suser/group management%s see the %sofficial documentation%s.") | format('', '', '', '') }}


    @@ -792,7 +792,7 @@ POSSIBILITY OF SUCH DAMAGE.
  • {{ 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('', '', '', '') }}
  • {{ 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('', '', '', '') }}
  • -

    {{ lang._("For more details visit HAProxy's official documentation regarding the %sStatistics%s, %sCache%s and %sPeers%s features.") | format('', '', '', '', '', '') }}

    +

    {{ lang._("For more details visit HAProxy's official documentation regarding the %sStatistics%s, %sCache%s and %sPeers%s features.") | format('', '', '', '', '', '') }}


    @@ -810,7 +810,7 @@ POSSIBILITY OF SUCH DAMAGE.
  • {{ 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('', '', '', '') }}
  • {{ 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('', '', '', '') }}
  • -

    {{ 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('', '', '', '', '', '' ,'', '' ,'', '' ,'', '','', '') }}

    +

    {{ 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('', '', '', '', '', '' ,'', '' ,'', '' ,'', '','', '') }}


    From ab0d4a95848b170ab7d524d3fd8ee7d0f436f750 Mon Sep 17 00:00:00 2001 From: Frank Wall Date: Thu, 28 Dec 2023 22:58:14 +0100 Subject: [PATCH 9/9] net/haproxy: bump version --- net/haproxy/Makefile | 5 ++--- net/haproxy/pkg-descr | 6 ++++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/net/haproxy/Makefile b/net/haproxy/Makefile index 14dccc7af..7ea41d936 100644 --- a/net/haproxy/Makefile +++ b/net/haproxy/Makefile @@ -1,8 +1,7 @@ PLUGIN_NAME= haproxy -PLUGIN_VERSION= 4.1 -PLUGIN_REVISION= 1 +PLUGIN_VERSION= 4.2 PLUGIN_COMMENT= Reliable, high performance TCP/HTTP load balancer -PLUGIN_DEPENDS= haproxy py${PLUGIN_PYTHON}-haproxy-cli +PLUGIN_DEPENDS= haproxy28 py${PLUGIN_PYTHON}-haproxy-cli PLUGIN_MAINTAINER= opnsense@moov.de .include "../../Mk/plugins.mk" diff --git a/net/haproxy/pkg-descr b/net/haproxy/pkg-descr index 8eb91e61d..f692d8110 100644 --- a/net/haproxy/pkg-descr +++ b/net/haproxy/pkg-descr @@ -6,6 +6,8 @@ very high loads while needing persistence or Layer7 processing. Plugin Changelog ================ +4.2 + Added: * add support for built-in OCSP update feature * add support for forwarded header (RFC7239) @@ -13,12 +15,12 @@ Added: * add options for HTTP/2 performance tuning Fixed: -* fix typo in cert sync script +* fix SSL sync cron job (bulk sync was never working properly) Changed: * upgrade to HAProxy 2.8 release series (#3459) * change default for HTTP/2 to enabled (only new frontends/backends) -* add "no-alpn" option if HTTP/2 is not enabled (TLS-enabled frontends) +* add "no-alpn" option if HTTP/2 is not enabled (only TLS-enabled frontends) * move OCSP settings from "Service" to "Global" section * replace bundled haproxyctl library with haproxy-cli