Last active
September 27, 2021 13:36
-
-
Save blood72/dce243aed9a673aa42bd8b88e0c20dd2 to your computer and use it in GitHub Desktop.
Synology DSM 7 wildcard certificate renewal script without restarting (DS920+)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/bin/python - <<EOF | |
import os | |
from sys import exit | |
from json import load as parse | |
from filecmp import cmp, clear_cache | |
# env | |
DOMAIN = '__YOUR_DOMAIN__' | |
DEFAULT_CERT_KEY = '__YOUR_CA_DIR__' | |
ACME_DIR = '__YOUR_ACME_DIR__' | |
WORK_DIR = '/usr/syno/etc/certificate/_archive' | |
CERT_DIR = os.path.join(WORK_DIR, DEFAULT_CERT_KEY) | |
CERT_ORIGIN_PATH = [ | |
'/usr/syno/etc/certificate', | |
'/usr/local/etc/certificate', | |
] | |
CERT_RUNNING_PATH = '/usr/syno/etc/www/certificate' | |
# copy file if it is different | |
def copy_file(file, target): | |
if cmp(file, target): | |
os.system('echo "already up-to-date: %s"' % target) | |
return | |
os.system('/bin/cp %s %s && echo "success to copy: %s"' % (file, target, target)) | |
clear_cache() | |
# run acme.sh | |
os.system(' '.join([os.path.join(ACME_DIR, 'acme.sh'), '--cron', '--home', ACME_DIR, '--force'])) | |
# copy renewed certificate | |
file_map = { | |
f'{DOMAIN}.key': 'privkey.pem', | |
f'{DOMAIN}.cer': 'cert.pem', | |
'ca.cer': 'chain.pem', | |
'fullchain.cer': 'fullchain.pem', | |
} | |
for new_file, old_file in file_map.items(): | |
copy_file(os.path.join(ACME_DIR, DOMAIN, new_file), os.path.join(CERT_DIR, old_file)) | |
# parse INFO | |
INFO_FILE = os.path.join(WORK_DIR, 'INFO') | |
if not os.path.isfile(INFO_FILE): | |
print(f"can't open {INFO_FILE}") | |
exit(-1) | |
with open(INFO_FILE) as f: | |
info = parse(f) | |
f.close() | |
if DEFAULT_CERT_KEY not in info: | |
print(f'{DEFAULT_CERT_KEY} was not found in your system. please check {INFO_FILE}') | |
exit(-1) | |
# check original certificate | |
def check_cert_origin(path): | |
for cert_dir in CERT_ORIGIN_PATH: | |
filepath = os.path.join(cert_dir, path) | |
if os.path.exists(filepath) is True: | |
return filepath | |
return False | |
# check running server certificate | |
def check_cert_running(path): | |
filepath = os.path.join(CERT_RUNNING_PATH, path, 'cert.conf') | |
if not os.path.isfile(filepath): | |
return [] | |
with open(filepath) as f: | |
str = f.read() | |
f.close() | |
l = str.split() | |
if len(l) == 0: | |
return [] | |
return dict(zip(l[::2], map(lambda x: x.rstrip(';'), l[1::2]))) | |
# copy file if it is different | |
def copy_file(file, target): | |
if cmp(file, target): | |
os.system(f'echo "already up-to-date: {target}"') | |
return | |
os.system(f'/bin/cp {file} {target} && echo "success to copy: {target}"') | |
clear_cache() | |
# get services cert path | |
dirs = list(map(lambda x: [x['subscriber'], x['service']], info[DEFAULT_CERT_KEY]['services'])) | |
# copy certificate to origin target | |
cert_files = file_map.values() | |
for path in map(lambda x: check_cert_origin(os.path.join(*x)), dirs): | |
for f in cert_files: | |
copy_file(os.path.join(CERT_DIR, f), os.path.join(path, f)) | |
# copy certificate to running server target | |
for path in map(lambda x: check_cert_running('_'.join(x)), dirs): | |
if 'ssl_certificate_key' in path: | |
copy_file(os.path.join(CERT_DIR, 'privkey.pem'), path.pop('ssl_certificate_key')) | |
if 'ssl_certificate' in path: | |
copy_file(os.path.join(CERT_DIR, 'fullchain.pem'), path.pop('ssl_certificate')) | |
# reload server configuration | |
os.system('nginx -s reload') | |
EOF | |
/usr/syno/bin/synosystemctl reload nginx |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Basically, manual renewal does not even replace reverse proxy certificates.
/usr/syno/bin/synosystemctl restart nginx
copies cert,but there is a problem that the service is stopped for several minutes by unloading all applications.
I added a function to copy the certificate by searching the SSL certificate path applied to the reverse proxy.