diff options
author | Christian Breunig <christian@breunig.cc> | 2024-01-07 11:36:09 +0100 |
---|---|---|
committer | Christian Breunig <christian@breunig.cc> | 2024-01-08 21:12:57 +0100 |
commit | 4dfb14d509b962a437733406df225a55b4daf694 (patch) | |
tree | d55e45b949979997baca4ed22d62fea515302afc /src | |
parent | 1b85e7a9442aa71e2137df44747bd184c4a8b6de (diff) | |
download | vyos-1x-4dfb14d509b962a437733406df225a55b4daf694.tar.gz vyos-1x-4dfb14d509b962a437733406df225a55b4daf694.zip |
pki: T5905: do not use expand_nodes=Diff.ADD|Diff.DELETE) in node_changed()
This fixes a priority inversion when doing initial certificate commits.
* pki subsystem is executed with priority 300
* vti uses priority 381
* ipsec uses priority 901
On commit pki.py will be executed first, detecting a change in dependencies
for vpn_ipsec.py which will be executed second. The VTI interface was yet not
created leading to ConfigError('VTI interface XX for site-to-site peer YY does
not exist!')
The issue is caused by this new line of code in commit b8db1a9d7ba ("pki:
T5886: add support for ACME protocol (LetsEncrypt)") file src/conf_mode/pki.py
line 139 which triggers the dependency update even if a key is newly added.
This commit changes the "detection" based on the cerbot configuration on disk.
(cherry picked from commit 9162631f12ade65392ea2fa53642ea4af39627c7)
Diffstat (limited to 'src')
-rwxr-xr-x | src/conf_mode/pki.py | 31 |
1 files changed, 19 insertions, 12 deletions
diff --git a/src/conf_mode/pki.py b/src/conf_mode/pki.py index 310519abd..239e44c3b 100755 --- a/src/conf_mode/pki.py +++ b/src/conf_mode/pki.py @@ -104,10 +104,10 @@ def certbot_request(name: str, config: dict, dry_run: bool=True): return domains = '--domains ' + ' --domains '.join(config['domain_name']) - tmp = f'certbot certonly --config-dir {vyos_certbot_dir} --cert-name {name} '\ - f'--non-interactive --standalone --agree-tos --no-eff-email --expand '\ - f'--server {config["url"]} --email {config["email"]} '\ - f'--key-type rsa --rsa-key-size {config["rsa_key_size"]} {domains}' + tmp = f'certbot certonly --non-interactive --config-dir {vyos_certbot_dir} --cert-name {name} '\ + f'--standalone --agree-tos --no-eff-email --expand --server {config["url"]} '\ + f'--email {config["email"]} --key-type rsa --rsa-key-size {config["rsa_key_size"]} '\ + f'{domains}' if 'listen_address' in config: tmp += f' --http-01-address {config["listen_address"]}' # verify() does not need to actually request a cert but only test for plausability @@ -135,8 +135,7 @@ def get_config(config=None): if 'changed' not in pki: pki.update({'changed':{}}) pki['changed'].update({'ca' : tmp}) - tmp = node_changed(conf, base + ['certificate'], key_mangling=('-', '_'), - recursive=True, expand_nodes=Diff.ADD|Diff.DELETE) + tmp = node_changed(conf, base + ['certificate'], key_mangling=('-', '_'), recursive=True) if tmp: if 'changed' not in pki: pki.update({'changed':{}}) pki['changed'].update({'certificate' : tmp}) @@ -211,7 +210,7 @@ def get_config(config=None): if found_name == item_name: path = search['path'] path_str = ' '.join(path + found_path) - print(f'pki: Updating config: {path_str} {found_name}') + print(f'PKI: Updating config: {path_str} {found_name}') if path[0] == 'interfaces': ifname = found_path[0] @@ -371,21 +370,29 @@ def generate(pki): if 'certbot_renew' in pki: return None - # list of certificates issued via certbot certbot_list = [] + certbot_list_on_disk = [] + if os.path.exists(f'{vyos_certbot_dir}/live'): + certbot_list_on_disk = [f.path.split('/')[-1] for f in os.scandir(f'{vyos_certbot_dir}/live') if f.is_dir()] + if 'certificate' in pki: + changed_certificates = dict_search('changed.certificate', pki) for name, cert_conf in pki['certificate'].items(): if 'acme' in cert_conf: certbot_list.append(name) - # when something for the certificate changed, we should delete it - if name in dict_search('changed.certificate', pki): - certbot_delete(name) + # generate certificate if not found on disk + if name not in certbot_list_on_disk: + certbot_request(name, cert_conf['acme'], dry_run=False) + elif changed_certificates != None and name in changed_certificates: + # when something for the certificate changed, we should delete it + if name in certbot_list_on_disk: + certbot_delete(name) certbot_request(name, cert_conf['acme'], dry_run=False) # Cleanup certbot configuration and certificates if no longer in use by CLI # Get foldernames under vyos_certbot_dir which each represent a certbot cert if os.path.exists(f'{vyos_certbot_dir}/live'): - for cert in [f.path.split('/')[-1] for f in os.scandir(f'{vyos_certbot_dir}/live') if f.is_dir()]: + for cert in certbot_list_on_disk: if cert not in certbot_list: # certificate is no longer active on the CLI - remove it certbot_delete(cert) |