87 lines
2.9 KiB
Python
87 lines
2.9 KiB
Python
import argparse
|
|
import os.path
|
|
import subprocess
|
|
import logging
|
|
import shutil
|
|
from datetime import datetime
|
|
|
|
from .config import read_config
|
|
|
|
logging.basicConfig(level=logging.INFO, format='[%(levelname)s] %(name)s: %(message)s')
|
|
log = logging.getLogger('nyacme')
|
|
|
|
|
|
def main() -> None:
|
|
parser = argparse.ArgumentParser(
|
|
prog='nyacme',
|
|
description='fun uacme wrapper'
|
|
)
|
|
parser.add_argument('-c', '--config', default='/etc/nyacme.toml')
|
|
parser.add_argument('-o', '--output', default='/etc/ssl/uacme')
|
|
args = parser.parse_args()
|
|
|
|
config = read_config(args.config)
|
|
|
|
acquired = False
|
|
|
|
for domain in config.certificates:
|
|
# arguments passed to uacme
|
|
uacme_domains = [domain]
|
|
if domain.startswith('*.'):
|
|
uacme_domains = [ domain[2:], domain ]
|
|
domain = domain[2:]
|
|
|
|
cert_path = f'{args.output}/{domain}/cert.pem'
|
|
if os.path.exists(cert_path):
|
|
out = subprocess.run([ 'openssl', 'x509', '-enddate', '-noout', '-in', cert_path ], stdout=subprocess.PIPE, check=True).stdout.decode('utf-8').strip()
|
|
date = datetime.strptime(out, 'notAfter=%b %d %H:%M:%S %Y %Z')
|
|
# if more than 1 month, skip
|
|
delta = date - datetime.now()
|
|
if delta.days > 30:
|
|
log.info(f'cert for {domain} expires in more than a month ({delta.days} days), skipping')
|
|
# continue
|
|
|
|
log.info(f'getting cert for {domain}')
|
|
env = os.environ.copy()
|
|
env['NYACME_CONFIG'] = args.config
|
|
|
|
hook_path = shutil.which('nyacme-hook')
|
|
if not hook_path:
|
|
log.warning('setting hook path to hook launcher from git repo')
|
|
hook_path = os.path.join(os.path.dirname(__file__), '..', 'hook_launcher.py')
|
|
|
|
res = subprocess.run([
|
|
'uacme', '-v',
|
|
'--hook', hook_path,
|
|
'--confdir', args.output,
|
|
'-b', '384',
|
|
'--type', 'EC',
|
|
# '--force',
|
|
'issue'
|
|
] + uacme_domains, env=env)
|
|
|
|
if res.returncode == 0:
|
|
acquired = True
|
|
private_key = os.path.join(args.output, f'private/{domain}/key.pem')
|
|
domain_key = os.path.join(args.output, f'{domain}/cert.pem.key')
|
|
domain_pem = os.path.join(args.output, f'{domain}/cert.pem')
|
|
|
|
shutil.copy2(private_key, domain_key)
|
|
# TODO: add user/group to config
|
|
shutil.chown(domain_key, 'acme', 'acme')
|
|
os.chmod(domain_key, 0o440)
|
|
|
|
all_pem = os.path.join(args.output, f'all/{domain}.pem')
|
|
all_key = os.path.join(args.output, f'all/{domain}.pem.key')
|
|
|
|
shutil.copy2(domain_pem, all_pem)
|
|
shutil.copy2(domain_key, all_key)
|
|
|
|
if acquired:
|
|
for cmd in config.post_acquire:
|
|
subprocess.run(cmd, shell=True, check=True)
|
|
|
|
if __name__ == '__main__':
|
|
main()
|
|
|