cont the remaining workflow even if the cert is too new to refresh
This commit is contained in:
parent
68497c4d10
commit
e31ec00d3d
146
ssl-update.py
146
ssl-update.py
@ -40,8 +40,8 @@ restart_delay = {
|
||||
}
|
||||
|
||||
pfx_key_path = {
|
||||
'plex': '/data/plex/certs/certificate.pfx',
|
||||
'jellyfin': '/data/jellyfin/ssl/jellyfin.pfx',
|
||||
'plex': pathlib.Path('/data/plex/certs/certificate.pfx'),
|
||||
'jellyfin': pathlib.Path('/data/jellyfin/ssl/jellyfin.pfx'),
|
||||
}
|
||||
|
||||
# Cert owning user if different than the name of the service
|
||||
@ -163,7 +163,7 @@ def pfx_gen(service):
|
||||
except KeyError:
|
||||
sys.exit(f'{service} has no defined private key path.')
|
||||
|
||||
cmd = ['/usr/bin/openssl', 'pkcs12', '-export', '-out', pkp,
|
||||
cmd = ['/usr/bin/openssl', 'pkcs12', '-export', '-out', str(pkp),
|
||||
'-inkey', f'/etc/letsencrypt/live/{service}.{domain}/privkey.pem',
|
||||
'-in', f'/etc/letsencrypt/live/{service}.{domain}/cert.pem',
|
||||
'-certfile', f'/etc/letsencrypt/live/{service}.{domain}/chain.pem']
|
||||
@ -234,15 +234,24 @@ def run_cert_bot(fqdn, service, challenge_path, decrypt_pp):
|
||||
log.info(f'certbot cmd: "{" ".join(cmd)}"')
|
||||
cb = pexpect.spawnu(' '.join(cmd))
|
||||
cb.logfile = sys.stderr
|
||||
do_update = True
|
||||
matches = [
|
||||
'Create a file containing just this data:\r\n\r\n([^\r]+)\r',
|
||||
('You have an existing certificate that has exactly the '
|
||||
"same domains or certificate name you requested and isn't "
|
||||
'close to expiry'),
|
||||
'(U)pdate key type/(K)eep existing key type:',
|
||||
'no action taken',
|
||||
pexpect.TIMEOUT,
|
||||
pexpect.EOF]
|
||||
while True:
|
||||
res = cb.expect(
|
||||
['Create a file containing just this data:\r\n\r\n([^\r]+)\r',
|
||||
('You have an existing certificate that has exactly the '
|
||||
"same domains or certificate name you requested and isn't "
|
||||
'close to expiry'),'(U)pdate key type/(K)eep existing key type:',
|
||||
pexpect.TIMEOUT, pexpect.EOF], timeout=20)
|
||||
if res > 2:
|
||||
res = cb.expect(matches, timeout=20)
|
||||
print(f'\nresult: {matches[res]}, {res}')
|
||||
if res > 3:
|
||||
sys.exit('Timed out')
|
||||
if res == 3:
|
||||
do_update = False
|
||||
break
|
||||
if res == 2:
|
||||
cb.sendline('U')
|
||||
continue
|
||||
@ -251,74 +260,76 @@ def run_cert_bot(fqdn, service, challenge_path, decrypt_pp):
|
||||
res = cb.expect_exact(['cancel):', pexpect.TIMEOUT, pexpect.EOF])
|
||||
if res > 0:
|
||||
sys.exit('Timed out in setup with existing cert')
|
||||
cb.sendline('2')
|
||||
res = cb.expect(
|
||||
['Create a file containing just this data:\r\n\r\n([^\r]+)\r',
|
||||
pexpect.TIMEOUT, pexpect.EOF], timeout=20)
|
||||
if res > 1:
|
||||
sys.exit('Timed out')
|
||||
cb.sendline('1')
|
||||
continue
|
||||
# res = cb.expect(
|
||||
# ['Create a file containing just this data:\r\n\r\n([^\r]+)\r',
|
||||
# pexpect.TIMEOUT, pexpect.EOF], timeout=20)
|
||||
# if res > 1:
|
||||
# sys.exit('Timed out')
|
||||
if res == 0:
|
||||
break
|
||||
|
||||
data = cb.match.group(1)
|
||||
log.info(f'secret data: {data}')
|
||||
log.info('the data string and location for the shared secret are known')
|
||||
long_match = ('And make it available on your web server at this URL:'
|
||||
'\r\n\r\nhttp://%s/.well-known/acme-challenge/([^\r]+)\r')
|
||||
res = cb.expect([long_match % (fqdn,), pexpect.TIMEOUT, pexpect.EOF])
|
||||
if res > 0:
|
||||
sys.exit('Timed out')
|
||||
filename = cb.match.group(1)
|
||||
log.info(f'filename of secret: {filename}')
|
||||
res = cb.expect(['Press Enter to Continue', pexpect.EOF], timeout=0)
|
||||
if do_update:
|
||||
data = cb.match.group(1)
|
||||
log.info(f'secret data: {data}')
|
||||
log.info('the data string and location for the shared secret are known')
|
||||
long_match = ('And make it available on your web server at this URL:'
|
||||
'\r\n\r\nhttp://%s/.well-known/acme-challenge/([^\r]+)\r')
|
||||
res = cb.expect([long_match % (fqdn,), pexpect.TIMEOUT, pexpect.EOF])
|
||||
if res > 0:
|
||||
sys.exit('Timed out')
|
||||
filename = cb.match.group(1)
|
||||
log.info(f'filename of secret: {filename}')
|
||||
res = cb.expect(['Press Enter to Continue', pexpect.EOF], timeout=0)
|
||||
|
||||
data_file = challenge_path / pathlib.Path(filename)
|
||||
try:
|
||||
with open(data_file, 'w') as f:
|
||||
f.write(data)
|
||||
except:
|
||||
sys.exit(f'Failed to write {data_file}')
|
||||
log.info('created secret file with secret data')
|
||||
data_file.chmod(0o644)
|
||||
log.info('and chmodded')
|
||||
data_file = challenge_path / pathlib.Path(filename)
|
||||
try:
|
||||
with open(data_file, 'w') as f:
|
||||
f.write(data)
|
||||
except:
|
||||
sys.exit(f'Failed to write {data_file}')
|
||||
log.info('created secret file with secret data')
|
||||
data_file.chmod(0o644)
|
||||
log.info('and chmodded')
|
||||
|
||||
symlink_name = pathlib.Path(f'{service}-le')
|
||||
log.info(f'nginx symlink: {symlink_name}')
|
||||
nx_conf = pathlib.Path('/etc/nginx')
|
||||
avail_path = nx_conf / pathlib.Path('sites-available')
|
||||
enabled_path = nx_conf / pathlib.Path('sites-enabled')
|
||||
symlink_name = pathlib.Path(f'{service}-le')
|
||||
log.info(f'nginx symlink: {symlink_name}')
|
||||
nx_conf = pathlib.Path('/etc/nginx')
|
||||
avail_path = nx_conf / pathlib.Path('sites-available')
|
||||
enabled_path = nx_conf / pathlib.Path('sites-enabled')
|
||||
|
||||
service_available_file = avail_path / symlink_name
|
||||
log.info(f'nginx service avail symlink: {service_available_file}')
|
||||
service_enabled_symlink = enabled_path / symlink_name
|
||||
log.info(f'nginx service enabled symlink: {service_enabled_symlink}')
|
||||
if not service_enabled_symlink.is_symlink():
|
||||
service_enabled_symlink.symlink_to(service_available_file)
|
||||
log.info('created symlink to enable service')
|
||||
service_available_file = avail_path / symlink_name
|
||||
log.info(f'nginx service avail symlink: {service_available_file}')
|
||||
service_enabled_symlink = enabled_path / symlink_name
|
||||
log.info(f'nginx service enabled symlink: {service_enabled_symlink}')
|
||||
if not service_enabled_symlink.is_symlink():
|
||||
service_enabled_symlink.symlink_to(service_available_file)
|
||||
log.info('created symlink to enable service')
|
||||
|
||||
log.info(f'open port 80 to {service}')
|
||||
firewall_mod('HTTP_UP', service, decrypt_pp)
|
||||
restart('nginx')
|
||||
log.info(f'open port 80 to {service}')
|
||||
firewall_mod('HTTP_UP', service, decrypt_pp)
|
||||
restart('nginx')
|
||||
|
||||
cb.sendline()
|
||||
log.info(f'sent <enter> to certbot to continue process')
|
||||
res = cb.expect([pexpect.EOF])
|
||||
log.info(f'cerbot completed. final output: {cb.before}')
|
||||
cb.sendline()
|
||||
log.info(f'sent <enter> to certbot to continue process')
|
||||
res = cb.expect([pexpect.EOF])
|
||||
log.info(f'cerbot completed. final output: {cb.before}')
|
||||
|
||||
output_text = str(cb.before)
|
||||
if 'failed' in output_text:
|
||||
sys.exit('Something went wrong')
|
||||
output_text = str(cb.before)
|
||||
if 'failed' in output_text:
|
||||
sys.exit('Something went wrong')
|
||||
|
||||
log.info(f'close port 80 to {service}')
|
||||
firewall_mod('HTTP_DOWN', service, decrypt_pp)
|
||||
log.info(f'close port 80 to {service}')
|
||||
firewall_mod('HTTP_DOWN', service, decrypt_pp)
|
||||
|
||||
service_enabled_symlink.unlink()
|
||||
if service_enabled_symlink.is_symlink():
|
||||
sys.exit(f'Could not unlink {service_enabled_symlink}')
|
||||
log.info('created symlink to enable service')
|
||||
log.info('removed symlink in nginx to disable HTTP')
|
||||
service_enabled_symlink.unlink()
|
||||
if service_enabled_symlink.is_symlink():
|
||||
sys.exit(f'Could not unlink {service_enabled_symlink}')
|
||||
log.info('created symlink to enable service')
|
||||
log.info('removed symlink in nginx to disable HTTP')
|
||||
|
||||
restart('nginx')
|
||||
restart('nginx')
|
||||
|
||||
key_path = pathlib.Path('/etc/letsencrypt')
|
||||
live = key_path / pathlib.Path(f'live/{service}.{domain}')
|
||||
@ -372,9 +383,6 @@ def main(args):
|
||||
|
||||
fqdn = f'{service}.{domain}'
|
||||
log.info(f'fqdn: {fqdn}')
|
||||
# Dry run:
|
||||
# cmd = ['/usr/bin/certbot', '--dry-run', 'certonly', '--manual', '-d', fqdn]
|
||||
# Real run:
|
||||
run_cert_bot(fqdn, service, challenge_path, decrypt_pp)
|
||||
restart(service)
|
||||
|
||||
|
@ -3,9 +3,9 @@
|
||||
declare -a services
|
||||
services+=('git')
|
||||
services+=('plex')
|
||||
# services+=('jellyfin')
|
||||
services+=('jellyfin')
|
||||
services+=('photoprism')
|
||||
services+=('nextcloud')
|
||||
# services+=('nextcloud')
|
||||
services+=('read')
|
||||
services+=('www')
|
||||
services+=('chat')
|
||||
|
Loading…
x
Reference in New Issue
Block a user