From 59957ad694043f41a7b1e9ee740b19c87f297867 Mon Sep 17 00:00:00 2001 From: Christian Breunig Date: Sun, 4 May 2025 11:35:33 +0200 Subject: haproxy: T7122: always reverse-proxy ACL for certbot Always enable the ACL entry to reverse-proxy requests to the path "/.well-known/acme-challenge/" when "redirect-http-to-https" is configured for a given HAProxy frontend service. This is an intentional design decision to simplify the implementation and reduce overall code complexity. It poses no risk: a missing path returns a 404, and an unavailable backend yields an error 503. This approach avoids a chicken-and-egg problem where certbot might try to request a certificate via reverse-proxy before the proxy config is actually generated and active. By always routing through HAProxy, we also eliminate downtime as port 80 does not need to be freed for certbot's standalone mode. --- src/conf_mode/load-balancing_haproxy.py | 9 --------- src/conf_mode/pki.py | 15 ++++++++------- 2 files changed, 8 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/conf_mode/load-balancing_haproxy.py b/src/conf_mode/load-balancing_haproxy.py index f176009a0..0e959480c 100644 --- a/src/conf_mode/load-balancing_haproxy.py +++ b/src/conf_mode/load-balancing_haproxy.py @@ -22,7 +22,6 @@ from shutil import rmtree from vyos.config import Config from vyos.configverify import verify_pki_certificate from vyos.configverify import verify_pki_ca_certificate -from vyos.defaults import internal_ports from vyos.utils.dict import dict_search from vyos.utils.process import call from vyos.utils.network import check_port_availability @@ -59,14 +58,6 @@ def get_config(config=None): with_recursive_defaults=True, with_pki=True) - lb['certbot_port'] = internal_ports['certbot_haproxy'] - - if 'service' in lb: - for front, front_config in lb['service'].items(): - for cert in dict_search('ssl.certificate', front_config) or []: - if dict_search(f'pki.certificate.{cert}.acme', lb): - lb['service'][front]['ssl'].update({'acme_certificate': {}}) - return lb def verify(lb): diff --git a/src/conf_mode/pki.py b/src/conf_mode/pki.py index c1ff80d8a..98922595c 100755 --- a/src/conf_mode/pki.py +++ b/src/conf_mode/pki.py @@ -231,7 +231,7 @@ def get_config(config=None): path = search['path'] path_str = ' '.join(path + found_path).replace('_','-') - #print(f'PKI: Updating config: {path_str} {item_name}') + print(f'PKI: Updating config: {path_str} {item_name}') if path[0] == 'interfaces': ifname = found_path[0] @@ -241,10 +241,10 @@ def get_config(config=None): if not D.node_changed_presence(path): set_dependents(path[1], conf) - # Check PKI certificates if they are generated by ACME. If they are, traverse - # the current configutration and determine the service where the certificate - # is used by. This is needed to check if we might need to start ACME behing - # a reverse proxy. + # Check PKI certificates if they are auto-generated by ACME. If they are, + # traverse the current configuration and determine the service where the + # certificate is used by. + # Required to check if we might need to run certbot behing a reverse proxy. if 'certificate' in pki: for name, cert_config in pki['certificate'].items(): if 'acme' not in cert_config: @@ -252,7 +252,7 @@ def get_config(config=None): if not dict_search('system.load_balancing.haproxy', pki): continue used_by = [] - for cert_list, cli_path in dict_search_recursive( + for cert_list, _ in dict_search_recursive( pki['system']['load_balancing']['haproxy'], 'certificate'): if name in cert_list: used_by.append('haproxy') @@ -356,7 +356,8 @@ def verify(pki): if 'used_by' not in cert_conf['acme']: if not check_port_availability(listen_address, 80): - raise ConfigError(f'Port 80 is not available for ACME challenge for certificate "{name}"!') + raise ConfigError('Port 80 is already in use and not available '\ + f'to provide ACME challenge for "{name}"!') if 'certbot_renew' not in pki: # Only run the ACME command if something on this entity changed, -- cgit v1.2.3