From 16235b2037af1941b4bb808fde1399692a4eab12 Mon Sep 17 00:00:00 2001 From: Christian Breunig Date: Wed, 29 May 2024 22:47:22 +0200 Subject: op-mode: T5231: add command to restart reverse-proxy (cherry picked from commit 2980eb0ad527f0ef0f1527c0ea97842ca2a8ede5) --- op-mode-definitions/reverse-proxy.xml.in | 23 +++++++++++++++++++++++ op-mode-definitions/show-reverse-proxy.xml.in | 13 ------------- 2 files changed, 23 insertions(+), 13 deletions(-) create mode 100644 op-mode-definitions/reverse-proxy.xml.in delete mode 100644 op-mode-definitions/show-reverse-proxy.xml.in diff --git a/op-mode-definitions/reverse-proxy.xml.in b/op-mode-definitions/reverse-proxy.xml.in new file mode 100644 index 000000000..4af24880b --- /dev/null +++ b/op-mode-definitions/reverse-proxy.xml.in @@ -0,0 +1,23 @@ + + + + + + + Restart reverse-proxy service + + if cli-shell-api existsActive load-balancing reverse-proxy; then sudo systemctl restart haproxy.service; else echo "Reverse-Proxy not configured"; fi + + + + + + + + Show load-balancing reverse-proxy + + sudo ${vyos_op_scripts_dir}/reverseproxy.py show + + + + diff --git a/op-mode-definitions/show-reverse-proxy.xml.in b/op-mode-definitions/show-reverse-proxy.xml.in deleted file mode 100644 index ed0fee843..000000000 --- a/op-mode-definitions/show-reverse-proxy.xml.in +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - Show load-balancing reverse-proxy - - sudo ${vyos_op_scripts_dir}/reverseproxy.py show - - - - -- cgit v1.2.3 From 8754f486acf64b1b1bfa3901f36229b713d4d573 Mon Sep 17 00:00:00 2001 From: Christian Breunig Date: Wed, 29 May 2024 22:49:00 +0200 Subject: reverse-proxy: T5231: better mark v4v6 listen any address haproxy supports both ":::80 v4v6" and "[::]:80 v4v6" as listen statement, where the later one is more humand readable. Both act in the same way. (cherry picked from commit a2f0b25452c67528077f343d75de09d038e97fee) --- data/templates/load-balancing/haproxy.cfg.j2 | 2 +- smoketest/scripts/cli/test_load-balancing_reverse-proxy.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/data/templates/load-balancing/haproxy.cfg.j2 b/data/templates/load-balancing/haproxy.cfg.j2 index 797bf17e7..b786a58f8 100644 --- a/data/templates/load-balancing/haproxy.cfg.j2 +++ b/data/templates/load-balancing/haproxy.cfg.j2 @@ -62,7 +62,7 @@ frontend {{ front }} bind {{ address | bracketize_ipv6 }}:{{ front_config.port }} {{ ssl_directive }} {{ ssl_front | join(' ') }} {% endfor %} {% else %} - bind :::{{ front_config.port }} v4v6 {{ ssl_directive }} {{ ssl_front | join(' ') }} + bind [::]:{{ front_config.port }} v4v6 {{ ssl_directive }} {{ ssl_front | join(' ') }} {% endif %} {% if front_config.redirect_http_to_https is vyos_defined %} http-request redirect scheme https unless { ssl_fc } diff --git a/smoketest/scripts/cli/test_load-balancing_reverse-proxy.py b/smoketest/scripts/cli/test_load-balancing_reverse-proxy.py index 370a9276a..2b2f93cdf 100755 --- a/smoketest/scripts/cli/test_load-balancing_reverse-proxy.py +++ b/smoketest/scripts/cli/test_load-balancing_reverse-proxy.py @@ -218,7 +218,7 @@ class TestLoadBalancingReverseProxy(VyOSUnitTestSHIM.TestCase): # Frontend self.assertIn(f'frontend {frontend}', config) - self.assertIn(f'bind :::{front_port} v4v6', config) + self.assertIn(f'bind [::]:{front_port} v4v6', config) self.assertIn(f'mode {mode}', config) for domain in domains_bk_first: self.assertIn(f'acl {rule_ten} hdr(host) -i {domain}', config) @@ -371,7 +371,7 @@ class TestLoadBalancingReverseProxy(VyOSUnitTestSHIM.TestCase): # Frontend self.assertIn(f'frontend {frontend}', config) - self.assertIn(f'bind :::{front_port} v4v6', config) + self.assertIn(f'bind [::]:{front_port} v4v6', config) self.assertIn(f'mode {mode}', config) self.assertIn(f'tcp-request inspect-delay {tcp_request_delay}', config) -- cgit v1.2.3 From aa3970cd922e8ff18e5b2500905ba0ce2cb14ed4 Mon Sep 17 00:00:00 2001 From: Christian Breunig Date: Wed, 29 May 2024 22:51:00 +0200 Subject: reverse-proxy: T5231: remove frontend ca-certificate code path The code path to handle the ca certificate used for the frontend service is removed, as there is no way on the XLI to define the CA certificate used for the frontend service. (cherry picked from commit 6000c47f068503522b0ccfe57c51f34ad9892e87) --- src/conf_mode/load-balancing_reverse-proxy.py | 33 +++++++++++---------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/src/conf_mode/load-balancing_reverse-proxy.py b/src/conf_mode/load-balancing_reverse-proxy.py index b6db110ae..16dcba852 100755 --- a/src/conf_mode/load-balancing_reverse-proxy.py +++ b/src/conf_mode/load-balancing_reverse-proxy.py @@ -126,30 +126,23 @@ def generate(lb): # SSL Certificates for frontend for front, front_config in lb['service'].items(): - if 'ssl' in front_config: + if 'ssl' not in front_config: + continue - if 'certificate' in front_config['ssl']: - cert_names = front_config['ssl']['certificate'] + if 'certificate' in front_config['ssl']: + cert_names = front_config['ssl']['certificate'] - for cert_name in cert_names: - pki_cert = lb['pki']['certificate'][cert_name] - cert_file_path = os.path.join(load_balancing_dir, f'{cert_name}.pem') - cert_key_path = os.path.join(load_balancing_dir, f'{cert_name}.pem.key') + for cert_name in cert_names: + pki_cert = lb['pki']['certificate'][cert_name] + cert_file_path = os.path.join(load_balancing_dir, f'{cert_name}.pem') + cert_key_path = os.path.join(load_balancing_dir, f'{cert_name}.pem.key') - with open(cert_file_path, 'w') as f: - f.write(wrap_certificate(pki_cert['certificate'])) + with open(cert_file_path, 'w') as f: + f.write(wrap_certificate(pki_cert['certificate'])) - if 'private' in pki_cert and 'key' in pki_cert['private']: - with open(cert_key_path, 'w') as f: - f.write(wrap_private_key(pki_cert['private']['key'])) - - if 'ca_certificate' in front_config['ssl']: - ca_name = front_config['ssl']['ca_certificate'] - pki_ca_cert = lb['pki']['ca'][ca_name] - ca_cert_file_path = os.path.join(load_balancing_dir, f'{ca_name}.pem') - - with open(ca_cert_file_path, 'w') as f: - f.write(wrap_certificate(pki_ca_cert['certificate'])) + if 'private' in pki_cert and 'key' in pki_cert['private']: + with open(cert_key_path, 'w') as f: + f.write(wrap_private_key(pki_cert['private']['key'])) # SSL Certificates for backend for back, back_config in lb['backend'].items(): -- cgit v1.2.3 From 2ae1798316863299424a2ab83019c1efc77b6def Mon Sep 17 00:00:00 2001 From: Christian Breunig Date: Wed, 29 May 2024 22:52:08 +0200 Subject: reverse-proxy: T6419: build full CA chain when verifying backend server (cherry picked from commit d83a6e5c5dc7e97e773f08bec7ba377530baafc9) --- src/conf_mode/load-balancing_reverse-proxy.py | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/conf_mode/load-balancing_reverse-proxy.py b/src/conf_mode/load-balancing_reverse-proxy.py index 16dcba852..a6fc407b0 100755 --- a/src/conf_mode/load-balancing_reverse-proxy.py +++ b/src/conf_mode/load-balancing_reverse-proxy.py @@ -28,7 +28,11 @@ from vyos.utils.network import check_port_availability from vyos.utils.network import is_listen_port_bind_service from vyos.pki import wrap_certificate from vyos.pki import wrap_private_key +from vyos.pki import find_chain +from vyos.pki import load_certificate +from vyos.pki import encode_certificate from vyos.template import render +from vyos.utils.file import write_file from vyos import ConfigError from vyos import airbag airbag.enable() @@ -146,15 +150,22 @@ def generate(lb): # SSL Certificates for backend for back, back_config in lb['backend'].items(): - if 'ssl' in back_config: + if 'ssl' not in back_config: + continue + + if 'ca_certificate' in back_config['ssl']: + ca_name = back_config['ssl']['ca_certificate'] + ca_cert_file_path = os.path.join(load_balancing_dir, f'{ca_name}.pem') + ca_chains = [] - if 'ca_certificate' in back_config['ssl']: - ca_name = back_config['ssl']['ca_certificate'] - pki_ca_cert = lb['pki']['ca'][ca_name] - ca_cert_file_path = os.path.join(load_balancing_dir, f'{ca_name}.pem') + loaded_ca_certs = {load_certificate(c['certificate']) + for c in lb['pki']['ca'].values()} if 'ca' in lb['pki'] else {} - with open(ca_cert_file_path, 'w') as f: - f.write(wrap_certificate(pki_ca_cert['certificate'])) + pki_ca_cert = lb['pki']['ca'][ca_name] + loaded_ca_cert = load_certificate(pki_ca_cert['certificate']) + ca_full_chain = find_chain(loaded_ca_cert, loaded_ca_certs) + ca_chains.append('\n'.join(encode_certificate(c) for c in ca_full_chain)) + write_file(ca_cert_file_path, '\n'.join(ca_chains)) render(load_balancing_conf_file, 'load-balancing/haproxy.cfg.j2', lb) render(systemd_override, 'load-balancing/override_haproxy.conf.j2', lb) -- cgit v1.2.3 From 5cfca2850ddbd9e2b594de1250d0064c1461ab59 Mon Sep 17 00:00:00 2001 From: Christian Breunig Date: Wed, 29 May 2024 23:25:15 +0200 Subject: reverse-proxy: T6419: build full CA chain for frontend SSL certificate (cherry picked from commit 4b189a76c0a9a28504aab6715658840b929fc243) --- src/conf_mode/load-balancing_reverse-proxy.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/conf_mode/load-balancing_reverse-proxy.py b/src/conf_mode/load-balancing_reverse-proxy.py index a6fc407b0..1c1252df0 100755 --- a/src/conf_mode/load-balancing_reverse-proxy.py +++ b/src/conf_mode/load-balancing_reverse-proxy.py @@ -26,11 +26,11 @@ from vyos.utils.dict import dict_search from vyos.utils.process import call from vyos.utils.network import check_port_availability from vyos.utils.network import is_listen_port_bind_service -from vyos.pki import wrap_certificate -from vyos.pki import wrap_private_key from vyos.pki import find_chain from vyos.pki import load_certificate +from vyos.pki import load_private_key from vyos.pki import encode_certificate +from vyos.pki import encode_private_key from vyos.template import render from vyos.utils.file import write_file from vyos import ConfigError @@ -128,6 +128,9 @@ def generate(lb): if not os.path.isdir(load_balancing_dir): os.mkdir(load_balancing_dir) + loaded_ca_certs = {load_certificate(c['certificate']) + for c in lb['pki']['ca'].values()} if 'ca' in lb['pki'] else {} + # SSL Certificates for frontend for front, front_config in lb['service'].items(): if 'ssl' not in front_config: @@ -141,12 +144,16 @@ def generate(lb): cert_file_path = os.path.join(load_balancing_dir, f'{cert_name}.pem') cert_key_path = os.path.join(load_balancing_dir, f'{cert_name}.pem.key') - with open(cert_file_path, 'w') as f: - f.write(wrap_certificate(pki_cert['certificate'])) + loaded_pki_cert = load_certificate(pki_cert['certificate']) + cert_full_chain = find_chain(loaded_pki_cert, loaded_ca_certs) + + write_file(cert_file_path, + '\n'.join(encode_certificate(c) for c in cert_full_chain)) if 'private' in pki_cert and 'key' in pki_cert['private']: - with open(cert_key_path, 'w') as f: - f.write(wrap_private_key(pki_cert['private']['key'])) + loaded_key = load_private_key(pki_cert['private']['key'], passphrase=None, wrap_tags=True) + key_pem = encode_private_key(loaded_key, passphrase=None) + write_file(cert_key_path, key_pem) # SSL Certificates for backend for back, back_config in lb['backend'].items(): @@ -158,9 +165,6 @@ def generate(lb): ca_cert_file_path = os.path.join(load_balancing_dir, f'{ca_name}.pem') ca_chains = [] - loaded_ca_certs = {load_certificate(c['certificate']) - for c in lb['pki']['ca'].values()} if 'ca' in lb['pki'] else {} - pki_ca_cert = lb['pki']['ca'][ca_name] loaded_ca_cert = load_certificate(pki_ca_cert['certificate']) ca_full_chain = find_chain(loaded_ca_cert, loaded_ca_certs) @@ -172,7 +176,6 @@ def generate(lb): return None - def apply(lb): call('systemctl daemon-reload') if not lb: -- cgit v1.2.3