From e201bd35511e1a000ffa21a4194d234634cfd76c Mon Sep 17 00:00:00 2001 From: Viacheslav Hletenko Date: Fri, 19 May 2023 09:57:11 +0000 Subject: T5222: Refactoring load-balancing reverse-proxy Improve and refactoring "load-balancing reverse-proxy" - replace 'reverse-proxy server ' => 'reverse-proxy service ' - replace 'reverse-proxy global-parameters tls ' => 'reverse-proxy global-parameters tls-version-min xxx' => 'reverse-proxy global-parameters ssl-bind-ciphers xxx' - replace 'reverse-proxy service https rule set server 'xxx' => 'reverse-proxy service https rule set backend 'xxx' 'service https rule domain-name xxx' set as multinode --- data/templates/load-balancing/haproxy.cfg.j2 | 22 ++-- .../include/haproxy/rule-backend.xml.i | 131 +++++++++++++++++++ .../include/haproxy/rule-frontend.xml.i | 131 +++++++++++++++++++ interface-definitions/include/haproxy/rule.xml.i | 130 ------------------- .../load-balancing-haproxy.xml.in | 141 ++++++++++----------- src/conf_mode/load-balancing-haproxy.py | 13 +- 6 files changed, 347 insertions(+), 221 deletions(-) create mode 100644 interface-definitions/include/haproxy/rule-backend.xml.i create mode 100644 interface-definitions/include/haproxy/rule-frontend.xml.i delete mode 100644 interface-definitions/include/haproxy/rule.xml.i diff --git a/data/templates/load-balancing/haproxy.cfg.j2 b/data/templates/load-balancing/haproxy.cfg.j2 index 3d98d78b7..1a8ce13f8 100644 --- a/data/templates/load-balancing/haproxy.cfg.j2 +++ b/data/templates/load-balancing/haproxy.cfg.j2 @@ -19,12 +19,12 @@ global ca-base /etc/ssl/certs crt-base /etc/ssl/private -{% if global_parameters.tls.ssl_bind_ciphers is vyos_defined %} +{% if global_parameters.ssl_bind_ciphers is vyos_defined %} # https://ssl-config.mozilla.org/#server=haproxy&version=2.6.12-1&config=intermediate&openssl=3.0.8-1&guideline=5.6 - ssl-default-bind-ciphers {{ global_parameters.tls.ssl_bind_ciphers | join(':') | upper }} + ssl-default-bind-ciphers {{ global_parameters.ssl_bind_ciphers | join(':') | upper }} {% endif %} ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256 -{% if global_parameters.tls.tls_version_min is vyos_defined('1.3') %} +{% if global_parameters.tls_version_min is vyos_defined('1.3') %} ssl-default-bind-options force-tlsv13 {% else %} ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets @@ -47,8 +47,8 @@ defaults errorfile 504 /etc/haproxy/errors/504.http # Frontend -{% if server is vyos_defined %} -{% for front, front_config in server.items() %} +{% if service is vyos_defined %} +{% for front, front_config in service.items() %} frontend {{ front }} {% set ssl_front = 'ssl crt /run/haproxy/' ~ front_config.ssl.certificate ~ '.pem' if front_config.ssl.certificate is vyos_defined else '' %} bind {{ front_config.listen_address if front_config.listen_address if vyos_defined else '*' }}:{{ front_config.port }} {{ ssl_front }} @@ -61,14 +61,16 @@ frontend {{ front }} {% if front_config.rule is vyos_defined %} {% for rule, rule_config in front_config.rule.items() %} # rule {{ rule }} -{% if rule_config.domain_name is vyos_defined and rule_config.set.server is vyos_defined %} +{% if rule_config.domain_name is vyos_defined and rule_config.set.backend is vyos_defined %} {% set rule_options = 'hdr(host)' %} {% if rule_config.ssl is vyos_defined %} {% set ssl_rule_translate = {'req-ssl-sni': 'req_ssl_sni', 'ssl-fc-sni': 'ssl_fc_sni', 'ssl-fc-sni-end': 'ssl_fc_sni_end'} %} {% set rule_options = ssl_rule_translate[rule_config.ssl] %} {% endif %} - acl {{ rule }} {{ rule_options }} -i {{ rule_config.domain_name }} - use_backend {{ rule_config.set.server }} if {{ rule }} +{% for domain in rule_config.domain_name %} + acl {{ rule }} {{ rule_options }} -i {{ domain }} +{% endfor %} + use_backend {{ rule_config.set.backend }} if {{ rule }} {% endif %} {# path url #} {% if rule_config.url_path is vyos_defined and rule_config.set.redirect_location is vyos_defined %} @@ -117,7 +119,9 @@ backend {{ back }} {% set ssl_rule_translate = {'req-ssl-sni': 'req_ssl_sni', 'ssl-fc-sni': 'ssl_fc_sni', 'ssl-fc-sni-end': 'ssl_fc_sni_end'} %} {% set rule_options = ssl_rule_translate[rule_config.ssl] %} {% endif %} - acl {{ rule }} {{ rule_options }} -i {{ rule_config.domain_name }} +{% for domain in rule_config.domain_name %} + acl {{ rule }} {{ rule_options }} -i {{ domain }} +{% endfor %} use-server {{ rule_config.set.server }} if {{ rule }} {% endif %} {# path url #} diff --git a/interface-definitions/include/haproxy/rule-backend.xml.i b/interface-definitions/include/haproxy/rule-backend.xml.i new file mode 100644 index 000000000..a6832d693 --- /dev/null +++ b/interface-definitions/include/haproxy/rule-backend.xml.i @@ -0,0 +1,131 @@ + + + + Proxy rule number + + u32:1-10000 + Number for this proxy rule + + + + + Proxy rule number must be between 1 and 10000 + + + + + Domain name to match + + txt + Domain address to match + + + + + + + + + + Proxy modifications + + + + + Set URL location + + url + Set URL location + + + ^\/[\w\-.\/]+$ + + Incorrect URL format + + + + + Server name + + [-_a-zA-Z0-9]+ + + Server name must be alphanumeric and can contain hyphen and underscores + + + + + + + SSL match options + + req-ssl-sni ssl-fc-sni + + + req-ssl-sni + SSL Server Name Indication (SNI) request match + + + ssl-fc-sni + SSL frontend connection Server Name Indication match + + + ssl-fc-sni-end + SSL frontend match end of connection Server Name Indication + + + (req-ssl-sni|ssl-fc-sni|ssl-fc-sni-end) + + + + + + URL path match + + + + + Begin URL match + + url + Begin URL + + + ^\/[\w\-.\/]+$ + + Incorrect URL format + + + + + + End URL match + + url + End URL + + + ^\/[\w\-.\/]+$ + + Incorrect URL format + + + + + + Exactly URL match + + url + Exactly URL + + + ^\/[\w\-.\/]+$ + + Incorrect URL format + + + + + + + + diff --git a/interface-definitions/include/haproxy/rule-frontend.xml.i b/interface-definitions/include/haproxy/rule-frontend.xml.i new file mode 100644 index 000000000..001ae2d80 --- /dev/null +++ b/interface-definitions/include/haproxy/rule-frontend.xml.i @@ -0,0 +1,131 @@ + + + + Proxy rule number + + u32:1-10000 + Number for this proxy rule + + + + + Proxy rule number must be between 1 and 10000 + + + + + Domain name to match + + txt + Domain address to match + + + + + + + + + + Proxy modifications + + + + + Set URL location + + url + Set URL location + + + ^\/[\w\-.\/]+$ + + Incorrect URL format + + + + + Backend name + + [-_a-zA-Z0-9]+ + + Server name must be alphanumeric and can contain hyphen and underscores + + + + + + + SSL match options + + req-ssl-sni ssl-fc-sni + + + req-ssl-sni + SSL Server Name Indication (SNI) request match + + + ssl-fc-sni + SSL frontend connection Server Name Indication match + + + ssl-fc-sni-end + SSL frontend match end of connection Server Name Indication + + + (req-ssl-sni|ssl-fc-sni|ssl-fc-sni-end) + + + + + + URL path match + + + + + Begin URL match + + url + Begin URL + + + ^\/[\w\-.\/]+$ + + Incorrect URL format + + + + + + End URL match + + url + End URL + + + ^\/[\w\-.\/]+$ + + Incorrect URL format + + + + + + Exactly URL match + + url + Exactly URL + + + ^\/[\w\-.\/]+$ + + Incorrect URL format + + + + + + + + diff --git a/interface-definitions/include/haproxy/rule.xml.i b/interface-definitions/include/haproxy/rule.xml.i deleted file mode 100644 index 9d9f63c9c..000000000 --- a/interface-definitions/include/haproxy/rule.xml.i +++ /dev/null @@ -1,130 +0,0 @@ - - - - Proxy rule number - - u32:1-10000 - Number for this proxy rule - - - - - Proxy rule number must be between 1 and 10000 - - - - - Domain name to match - - txt - Domain address to match - - - - - - - - - Proxy modifications - - - - - Set URL location - - url - Set URL location - - - ^\/[\w\-.\/]+$ - - Incorrect URL format - - - - - Server name - - [-_a-zA-Z0-9]+ - - Server name must be alphanumeric and can contain hyphen and underscores - - - - - - - SSL match options - - req-ssl-sni ssl-fc-sni - - - req-ssl-sni - SSL Server Name Indication (SNI) request match - - - ssl-fc-sni - SSL frontend connection Server Name Indication match - - - ssl-fc-sni-end - SSL frontend match end of connection Server Name Indication - - - (req-ssl-sni|ssl-fc-sni|ssl-fc-sni-end) - - - - - - URL path match - - - - - Begin URL match - - url - Begin URL - - - ^\/[\w\-.\/]+$ - - Incorrect URL format - - - - - - End URL match - - url - End URL - - - ^\/[\w\-.\/]+$ - - Incorrect URL format - - - - - - Exactly URL match - - url - Exactly URL - - - ^\/[\w\-.\/]+$ - - Incorrect URL format - - - - - - - - diff --git a/interface-definitions/load-balancing-haproxy.xml.in b/interface-definitions/load-balancing-haproxy.xml.in index f0c0ee8ce..e295dcb63 100644 --- a/interface-definitions/load-balancing-haproxy.xml.in +++ b/interface-definitions/load-balancing-haproxy.xml.in @@ -7,9 +7,9 @@ Configure reverse-proxy - + - Frontend server name + Frontend service name #include @@ -37,7 +37,7 @@ #include #include #include - #include + #include Redirect HTTP to HTTPS @@ -102,7 +102,7 @@ - #include + #include Backend server name @@ -161,78 +161,71 @@ - + - Transport Layer Security (TLS) options + Cipher algorithms ("cipher suite") used during SSL/TLS handshake for all frontend servers + + ecdhe-ecdsa-aes128-gcm-sha256 ecdhe-rsa-aes128-gcm-sha256 ecdhe-ecdsa-aes256-gcm-sha384 ecdhe-rsa-aes256-gcm-sha384 ecdhe-ecdsa-chacha20-poly1305 ecdhe-rsa-chacha20-poly1305 dhe-rsa-aes128-gcm-sha256 dhe-rsa-aes256-gcm-sha384 + + + ecdhe-ecdsa-aes128-gcm-sha256 + ecdhe-ecdsa-aes128-gcm-sha256 + + + ecdhe-rsa-aes128-gcm-sha256 + ecdhe-rsa-aes128-gcm-sha256 + + + ecdhe-ecdsa-aes256-gcm-sha384 + ecdhe-ecdsa-aes256-gcm-sha384 + + + ecdhe-rsa-aes256-gcm-sha384 + ecdhe-rsa-aes256-gcm-sha384 + + + ecdhe-ecdsa-chacha20-poly1305 + ecdhe-ecdsa-chacha20-poly1305 + + + ecdhe-rsa-chacha20-poly1305 + ecdhe-rsa-chacha20-poly1305 + + + dhe-rsa-aes128-gcm-sha256 + dhe-rsa-aes128-gcm-sha256 + + + dhe-rsa-aes256-gcm-sha384 + dhe-rsa-aes256-gcm-sha384 + + + (ecdhe-ecdsa-aes128-gcm-sha256|ecdhe-rsa-aes128-gcm-sha256|ecdhe-ecdsa-aes256-gcm-sha384|ecdhe-rsa-aes256-gcm-sha384|ecdhe-ecdsa-chacha20-poly1305|ecdhe-rsa-chacha20-poly1305|dhe-rsa-aes128-gcm-sha256|dhe-rsa-aes256-gcm-sha384) + + - - - - Cipher algorithms ("cipher suite") used during SSL/TLS handshake for all frontend servers - - ecdhe-ecdsa-aes128-gcm-sha256 ecdhe-rsa-aes128-gcm-sha256 ecdhe-ecdsa-aes256-gcm-sha384 ecdhe-rsa-aes256-gcm-sha384 ecdhe-ecdsa-chacha20-poly1305 ecdhe-rsa-chacha20-poly1305 dhe-rsa-aes128-gcm-sha256 dhe-rsa-aes256-gcm-sha384 - - - ecdhe-ecdsa-aes128-gcm-sha256 - ecdhe-ecdsa-aes128-gcm-sha256 - - - ecdhe-rsa-aes128-gcm-sha256 - ecdhe-rsa-aes128-gcm-sha256 - - - ecdhe-ecdsa-aes256-gcm-sha384 - ecdhe-ecdsa-aes256-gcm-sha384 - - - ecdhe-rsa-aes256-gcm-sha384 - ecdhe-rsa-aes256-gcm-sha384 - - - ecdhe-ecdsa-chacha20-poly1305 - ecdhe-ecdsa-chacha20-poly1305 - - - ecdhe-rsa-chacha20-poly1305 - ecdhe-rsa-chacha20-poly1305 - - - dhe-rsa-aes128-gcm-sha256 - dhe-rsa-aes128-gcm-sha256 - - - dhe-rsa-aes256-gcm-sha384 - dhe-rsa-aes256-gcm-sha384 - - - (ecdhe-ecdsa-aes128-gcm-sha256|ecdhe-rsa-aes128-gcm-sha256|ecdhe-ecdsa-aes256-gcm-sha384|ecdhe-rsa-aes256-gcm-sha384|ecdhe-ecdsa-chacha20-poly1305|ecdhe-rsa-chacha20-poly1305|dhe-rsa-aes128-gcm-sha256|dhe-rsa-aes256-gcm-sha384) - - - - ecdhe-ecdsa-aes128-gcm-sha256 ecdhe-rsa-aes128-gcm-sha256 ecdhe-ecdsa-aes256-gcm-sha384 ecdhe-rsa-aes256-gcm-sha384 ecdhe-ecdsa-chacha20-poly1305 ecdhe-rsa-chacha20-poly1305 dhe-rsa-aes128-gcm-sha256 dhe-rsa-aes256-gcm-sha384 - - - - Specify the minimum required TLS version - - 1.2 1.3 - - - 1.2 - TLS v1.2 - - - 1.3 - TLS v1.3 - - - (1.2|1.3) - - - 1.3 - - - + ecdhe-ecdsa-aes128-gcm-sha256 ecdhe-rsa-aes128-gcm-sha256 ecdhe-ecdsa-aes256-gcm-sha384 ecdhe-rsa-aes256-gcm-sha384 ecdhe-ecdsa-chacha20-poly1305 ecdhe-rsa-chacha20-poly1305 dhe-rsa-aes128-gcm-sha256 dhe-rsa-aes256-gcm-sha384 + + + + Specify the minimum required TLS version + + 1.2 1.3 + + + 1.2 + TLS v1.2 + + + 1.3 + TLS v1.3 + + + (1.2|1.3) + + + 1.3 + #include diff --git a/src/conf_mode/load-balancing-haproxy.py b/src/conf_mode/load-balancing-haproxy.py index d2b895fbe..938af6cda 100755 --- a/src/conf_mode/load-balancing-haproxy.py +++ b/src/conf_mode/load-balancing-haproxy.py @@ -74,15 +74,12 @@ def verify(lb): if not lb: return None - if 'backend' not in lb or 'server' not in lb: - raise ConfigError(f'"server" and "backend" must be configured!') + if 'backend' not in lb or 'service' not in lb: + raise ConfigError(f'"service" and "backend" must be configured!') - for front, front_config in lb['server'].items(): + for front, front_config in lb['service'].items(): if 'port' not in front_config: - raise ConfigError(f'"{front} server port" must be configured!') - # We can use redirect to HTTPS without backend section - if 'backend' not in front_config and 'redirect_http_to_https' not in front_config: - raise ConfigError(f'"{front} backend" must be configured!') + raise ConfigError(f'"{front} service port" must be configured!') # Check if bind address:port are used by another service tmp_address = front_config.get('address', '0.0.0.0') @@ -117,7 +114,7 @@ def generate(lb): os.mkdir(load_balancing_dir) # SSL Certificates for frontend - for front, front_config in lb['server'].items(): + for front, front_config in lb['service'].items(): if 'ssl' in front_config: cert_file_path = os.path.join(load_balancing_dir, 'cert.pem') cert_key_path = os.path.join(load_balancing_dir, 'cert.pem.key') -- cgit v1.2.3