-
Notifications
You must be signed in to change notification settings - Fork 0
/
replace_synology_ssl_certs.sh
161 lines (140 loc) · 6.44 KB
/
replace_synology_ssl_certs.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#!/bin/bash
# modified version of https://gist.github.com/catchdave/69854624a21ac75194706ec20ca61327
# from https://github.com/catchdave
#
# - Important:
# Before this script can run reliably, you must first manually import your LE certificates into DSM.
# Private Key ---------------> privkey.pem
# Certificate ---------------> cert.pem
# Intermediate Certificate --> fullchain.pem
#
# It's possible to initially import certs WITHOUT adding an Intermediate Cert, and while this works in most cases,
# it will cause OpenVPN on Synology to fail, as it requires the intermediate certs present in fullchain.pem
# You can also add fullchain.pem as the "Certificate" file, which works, but it's important to upload the correct files
# as above, so that the synology certificate sync tool will write the correct contents into the "info" files and associate
# the correct files with the "cert", "chain", and "key".
#
# *** For DSM v7.2 **
# Check for --force and --debug parameters
force=0
for arg in "$@"; do
if [ "$arg" == "--force" ]; then
force=1
fi
if [ "$arg" == "--debug" ]; then
set -x
fi
done
# CONSTANTS
NEW_CERTIFICATE_LOCATION="/volume1/docker/certbot/live/server-1.isol.sa" # location of your updated / generated certs
SYSTEM_CERTIFICATES_ROOT="/usr/syno/etc/certificate/" # location of the root certificates folder
CERTIFICATE_FILENAME=cert.pem # certificate file for comparing old / new
TARGET_FOLDERS=("/usr/syno/etc/certificate/smbftpd/ftpd"
"/usr/syno/etc/certificate/kmip/kmip") # any folders not otherwise covered by the script
SERVICES_TO_RESTART=("kmip" "ftpd") # a list of the synology services needing to be restarted
PACKAGES_TO_RESTART=() # a list of the synology packages needing to be restarted
# Functions
# ==========
# Function to call on errors
error_exit() {
echo "[ERROR] : $1" >&2
exit 1
}
# Function to check for unmatched certs
# this function takes an MD5 to compare found certs against.
function find_unmatched_certs() {
local updated_cert_md5=$1
declare -a allcerts
readarray -t allcerts < <(find ${SYSTEM_CERTIFICATES_ROOT} -type f -name "${CERTIFICATE_FILENAME}")
declare -a certs_unmatching
for cert in "${allcerts[@]}"; do
THIS_VERSION=$(md5sum < ${cert} | awk '{print $1}')
if [ $updated_cert_md5 != $THIS_VERSION ]; then
certs_unmatching+=("${cert}")
fi
done
if [ ! ${#certs_unmatching[@]} -eq 0 ]; then
echo
echo "Warning: Some unmatched certs still exist, in the following locations:"
echo "======================================================================"
for location in "${certs_unmatching[@]}"; do
echo " - ${location}"
done
echo
echo "...check the script and add these folders to TARGET_FOLDERS for syncing"
echo " this script can then be run again with the '--force' parameter to force push to new folders"
echo
fi
}
# Initialization
# ===============
if [[ "$EUID" -ne 0 ]]; then
error_exit "This script must be run as root. Try sudo $0" # Script only works as root
fi
# Discover the default directory
DEFAULT_CERTIFICATE_FOLDER_NAME=$(<$SYSTEM_CERTIFICATES_ROOT/_archive/DEFAULT)
if [[ -n "$DEFAULT_CERTIFICATE_FOLDER_NAME" ]]; then
DEFAULT_TARGET_FOLDER="${SYSTEM_CERTIFICATES_ROOT}_archive/${DEFAULT_CERTIFICATE_FOLDER_NAME}"
echo "Default cert directory found: ${DEFAULT_TARGET_FOLDER}"
else
error_exit "No default directory found. Probably unusual? Check: 'cat ${SYSTEM_CERTIFICATES_ROOT}_archive/DEFAULT'"
fi
# Only continue if the source certs and destination certs differ
# ==============================================================
UPDATED_CERT_MD5=`md5sum ${NEW_CERTIFICATE_LOCATION}/${CERTIFICATE_FILENAME} | awk '{ print $1 }'`
DEPLOYED_CERT_MD5=`md5sum ${DEFAULT_TARGET_FOLDER}/${CERTIFICATE_FILENAME} | awk '{ print $1 }'`
if [ $UPDATED_CERT_MD5 == $DEPLOYED_CERT_MD5 ]; then
echo "New certificates and current certificates do not differ. "
if [ ! "$force" -eq 1 ]; then
find_unmatched_certs $UPDATED_CERT_MD5
exit 0
else
echo "--force parameter passed to script. Redeploying certificates..."
fi
else
echo "New certificates differ from system certificates.. replacing..."
fi
# 2. Move and chown certificates from origin to destination directory
# ===================================================================
cp $NEW_CERTIFICATE_LOCATION/{cert,chain,fullchain,privkey}.pem "${DEFAULT_TARGET_FOLDER}/" || error_exit "Halting because of error moving files"
chown root:root "${DEFAULT_TARGET_FOLDER}/"{cert,chain,fullchain,privkey}.pem || error_exit "Halting because of error chowning files"
chmod 400 "${DEFAULT_TARGET_FOLDER}/"{cert,chain,fullchain,privkey}.pem || error_exit "Halting because of error chmoding files"
echo "Certs copied from $NEW_CERTIFICATE_LOCATION/ to "
echo " $DEFAULT_TARGET_FOLDER/ & chown, chmod complete."
# 3. Copy certificates to additional target directories if they exist
# ===================================================================
for target_dir in "${TARGET_FOLDERS[@]}"; do
if [[ ! -d "$target_dir" ]]; then
echo "Target cert directory '$target_dir' not found, skipping..."
continue
fi
echo "Copying certificates to '$target_dir'"
if ! cp "${DEFAULT_TARGET_FOLDER}/"{cert,chain,fullchain,privkey}.pem "$target_dir/" && \
chown root:root "$target_dir/"{cert,chain,fullchain,privkey}.pem &&\
chmod 400 "$target_dir/"{cert,chain,fullchain,privkey}.pem; then
echo "Error copying certs or with chmod, chown to ${target_dir}"
fi
done
# 4. Sync certs and Restart services & packages
# ==============================================
if ! /usr/syno/bin/synow3tool --gen-all ; then
echo "synow3tool --gen-all failed"
fi
for service in "${SERVICES_TO_RESTART[@]}"; do
echo "restarting ${service}"
/usr/syno/bin/synosystemctl restart "$service"
done
for package in "${PACKAGES_TO_RESTART[@]}"; do # Restart packages that are installed & turned on
/usr/syno/bin/synopkg is_onoff "$package" 1>/dev/null && \
echo "restarting ${package}" && \
/usr/syno/bin/synopkg restart "$package"
done
if ! /usr/syno/bin/synow3tool --nginx=reload ; then
echo "/usr/syno/bin/synow3tool --nginx=reload failed"
fi
if ! /usr/syno/bin/synow3tool --restart-dsm-service; then
echo "/usr/syno/bin/synow3tool --restart-dsm-service failed"
fi
# Always check for unmatched certs at successful conclusion of script
find_unmatched_certs $UPDATED_CERT_MD5
echo "Done"