mirror of
https://github.com/moepman/acertmgr.git
synced 2025-01-01 04:21:51 +01:00
acertmgr: Add option to supersede previous cert on renewal
Add option to automatically revoke the previous certificate with reason superseded after deployment and all actions have been successful.
This commit is contained in:
parent
39aa7db24c
commit
f01140e89b
@ -72,6 +72,7 @@ By default the directory (work_dir) containing the working data (csr,certificate
|
|||||||
| csr_file | **d**,g | Path to store (and load) the certificate CSR file | {cert_dir}/{cert_id}.csr |
|
| csr_file | **d**,g | Path to store (and load) the certificate CSR file | {cert_dir}/{cert_id}.csr |
|
||||||
| ca_file | **d**,g | Path to store (and load) the certificate authority file | {cert_dir}/{cert_id}.ca |
|
| ca_file | **d**,g | Path to store (and load) the certificate authority file | {cert_dir}/{cert_id}.ca |
|
||||||
| cert_file | **d** | Path to store (and load) the certificate file | {cert_dir}/{cert_id}.crt |
|
| cert_file | **d** | Path to store (and load) the certificate file | {cert_dir}/{cert_id}.crt |
|
||||||
|
| cert_revoke_superseded | **d**,g | Revoke the previous certificate with reason "superseded" after successful deployment | false |
|
||||||
| key_file | **d**,g | Path to store (and load) the private key file | {cert_dir}/{cert_id}.key |
|
| key_file | **d**,g | Path to store (and load) the private key file | {cert_dir}/{cert_id}.key |
|
||||||
| mode | **d**,g | Mode of challenge handling used | standalone |
|
| mode | **d**,g | Mode of challenge handling used | standalone |
|
||||||
| webdir | **d**,g | [webdir] Put acme challenges into this path | /var/www/acme-challenge/ |
|
| webdir | **d**,g | [webdir] Put acme challenges into this path | /var/www/acme-challenge/ |
|
||||||
|
@ -85,6 +85,7 @@ def cert_get(settings):
|
|||||||
|
|
||||||
# if resulting certificate is valid: store in final location
|
# if resulting certificate is valid: store in final location
|
||||||
if tools.is_cert_valid(crt, settings['ttl_days']):
|
if tools.is_cert_valid(crt, settings['ttl_days']):
|
||||||
|
print("Certificate '{}' renewed and valid until {}".format(crt, crt.not_valid_after))
|
||||||
tools.write_pem_file(crt, settings['cert_file'], stat.S_IREAD)
|
tools.write_pem_file(crt, settings['cert_file'], stat.S_IREAD)
|
||||||
if "static_ca" in settings and not settings['static_ca'] and ca is not None:
|
if "static_ca" in settings and not settings['static_ca'] and ca is not None:
|
||||||
tools.write_pem_file(ca, settings['ca_file'])
|
tools.write_pem_file(ca, settings['ca_file'])
|
||||||
@ -163,6 +164,7 @@ def main():
|
|||||||
# Mode: issue certificates (implicit)
|
# Mode: issue certificates (implicit)
|
||||||
# post-update actions (run only once)
|
# post-update actions (run only once)
|
||||||
actions = set()
|
actions = set()
|
||||||
|
superseded = set()
|
||||||
# check certificate validity and obtain/renew certificates if needed
|
# check certificate validity and obtain/renew certificates if needed
|
||||||
for config in domainconfigs:
|
for config in domainconfigs:
|
||||||
cert = None
|
cert = None
|
||||||
@ -172,6 +174,8 @@ def main():
|
|||||||
('force_renew' in runtimeconfig and re.search(r'(^| ){}( |$)'.format(
|
('force_renew' in runtimeconfig and re.search(r'(^| ){}( |$)'.format(
|
||||||
re.escape(runtimeconfig['force_renew'])), config['domains'])):
|
re.escape(runtimeconfig['force_renew'])), config['domains'])):
|
||||||
cert_get(config)
|
cert_get(config)
|
||||||
|
if str(config.get('cert_revoke_superseded')).lower() == 'true' and cert:
|
||||||
|
superseded.add(cert)
|
||||||
|
|
||||||
# deploy new certificates after all are renewed
|
# deploy new certificates after all are renewed
|
||||||
for config in domainconfigs:
|
for config in domainconfigs:
|
||||||
@ -181,6 +185,7 @@ def main():
|
|||||||
actions.add(cert_put(cfg))
|
actions.add(cert_put(cfg))
|
||||||
|
|
||||||
# run post-update actions
|
# run post-update actions
|
||||||
|
all_actions_success = True
|
||||||
for action in actions:
|
for action in actions:
|
||||||
if action is not None:
|
if action is not None:
|
||||||
try:
|
try:
|
||||||
@ -188,4 +193,13 @@ def main():
|
|||||||
output = subprocess.check_output(action, shell=True, stderr=subprocess.STDOUT)
|
output = subprocess.check_output(action, shell=True, stderr=subprocess.STDOUT)
|
||||||
print("Executed '{}' successfully: {}".format(action, output))
|
print("Executed '{}' successfully: {}".format(action, output))
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
print("Execution of '{}' failed with error '{}': {}".format(e.cmd, e.returncode, e.output))
|
print("Execution of '{}' failed with error '{}': {}".format(e.cmd, e.returncode, e.output))
|
||||||
|
all_actions_success = False
|
||||||
|
|
||||||
|
# revoke old certificates as superseded
|
||||||
|
if all_actions_success:
|
||||||
|
for superseded_cert in superseded:
|
||||||
|
print("Revoking previous certificate '{}' valid until {} as superseded".format(
|
||||||
|
superseded_cert,
|
||||||
|
superseded_cert.not_valid_after))
|
||||||
|
cert_revoke(superseded_cert, domainconfigs, reason=4) # reason=4 is superseded
|
||||||
|
@ -123,6 +123,9 @@ def parse_config_entry(entry, globalconfig, runtimeconfig):
|
|||||||
update_config_value(config, 'ttl_days', localconfig, globalconfig, DEFAULT_TTL)
|
update_config_value(config, 'ttl_days', localconfig, globalconfig, DEFAULT_TTL)
|
||||||
config['ttl_days'] = int(config['ttl_days'])
|
config['ttl_days'] = int(config['ttl_days'])
|
||||||
|
|
||||||
|
# Revoke old certificate with reason superseded after renewal
|
||||||
|
update_config_value(config, 'cert_revoke_superseded', localconfig, globalconfig, "false")
|
||||||
|
|
||||||
# Use a static cert request
|
# Use a static cert request
|
||||||
update_config_value(config, 'csr_static', localconfig, globalconfig, "false")
|
update_config_value(config, 'csr_static', localconfig, globalconfig, "false")
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user