99# Issues: https://github.com/acmesh-official/acme.sh/issues/2727
1010# ###############################################################################
1111# Usage:
12- # 1. export SYNO_Username="adminUser"
13- # 2. export SYNO_Password="adminPassword"
12+ # - Create temp admin user automatically:
13+ # export SYNO_USE_TEMP_ADMIN=1
14+ # - Or provide your own admin user credential:
15+ # 1. export SYNO_Username="adminUser"
16+ # 2. export SYNO_Password="adminPassword"
1417# Optional exports (shown values are the defaults):
15- # - export SYNO_Certificate="" to replace a specific certificate via description
18+ # - export SYNO_Certificate="" - to replace a specific certificate via description
1619# - export SYNO_Scheme="http"
1720# - export SYNO_Hostname="localhost"
1821# - export SYNO_Port="5000"
19- # - export SYNO_Device_Name="CertRenewal" - required for skipping 2FA-OTP
22+ # - export SYNO_Create=1 - to allow creating the certificate if it doesn't exist
23+ # - export SYNO_Device_Name="CertRenewal" - required if 2FA-OTP enabled
2024# - export SYNO_Device_ID="" - required for skipping 2FA-OTP
2125# 3. acme.sh --deploy --deploy-hook synology_dsm -d example.com
2226# ###############################################################################
2327# Dependencies:
2428# - jq & curl
29+ # - synouser & synogroup (When available and SYNO_USE_TEMP_ADMIN is set)
2530# ###############################################################################
2631# Return value:
2732# 0 means success, otherwise error.
@@ -38,19 +43,33 @@ synology_dsm_deploy() {
3843 _debug _cdomain " $_cdomain "
3944
4045 # Get username & password, but don't save until we authenticated successfully
46+ _getdeployconf SYNO_USE_TEMP_ADMIN
4147 _getdeployconf SYNO_Username
4248 _getdeployconf SYNO_Password
4349 _getdeployconf SYNO_Create
4450 _getdeployconf SYNO_DID
4551 _getdeployconf SYNO_TOTP_SECRET
4652 _getdeployconf SYNO_Device_Name
4753 _getdeployconf SYNO_Device_ID
48- if [ -z " ${SYNO_Username:- } " ] || [ -z " ${SYNO_Password:- } " ]; then
49- _err " SYNO_Username & SYNO_Password must be set"
50- return 1
54+
55+ # Prepare temp admin user info if SYNO_USE_TEMP_ADMIN is set
56+ if [ -n " ${SYNO_USE_TEMP_ADMIN:- } " ]; then
57+ if ! _exists synouser; then
58+ if ! _exists synogroup; then
59+ _err " Tools are missing for creating temp admin user, please set SYNO_Username & SYNO_Password instead."
60+ return 1
61+ fi
62+ fi
63+ _debug " Setting temp admin user credential..."
64+ SYNO_Username=sc-acmesh-tmp
65+ SYNO_Password=$( head /dev/urandom | tr -dc A-Za-z0-9 | head -c 16)
66+ # Ignore 2FA-OTP settings which won't be needed.
67+ SYNO_Device_Name=
68+ SYNO_Device_ID=
5169 fi
52- if [ -n " ${SYNO_Device_Name:- } " ] && [ -z " ${SYNO_Device_ID:- } " ]; then
53- _err " SYNO_Device_Name set, but SYNO_Device_ID is empty"
70+
71+ if [ -z " ${SYNO_Username:- } " ] || [ -z " ${SYNO_Password:- } " ]; then
72+ _err " You must set either SYNO_USE_TEMP_ADMIN, or set both SYNO_Username and SYNO_Password."
5473 return 1
5574 fi
5675 _debug2 SYNO_Username " $SYNO_Username "
@@ -69,6 +88,7 @@ synology_dsm_deploy() {
6988 [ -n " ${SYNO_Scheme} " ] || SYNO_Scheme=" http"
7089 [ -n " ${SYNO_Hostname} " ] || SYNO_Hostname=" localhost"
7190 [ -n " ${SYNO_Port} " ] || SYNO_Port=" 5000"
91+ _savedeployconf SYNO_USE_TEMP_ADMIN " $SYNO_USE_TEMP_ADMIN "
7292 _savedeployconf SYNO_Scheme " $SYNO_Scheme "
7393 _savedeployconf SYNO_Hostname " $SYNO_Hostname "
7494 _savedeployconf SYNO_Port " $SYNO_Port "
@@ -108,13 +128,11 @@ synology_dsm_deploy() {
108128 _info " WARNING: Usage of SYNO_TOTP_SECRET is deprecated!"
109129 _info " See synology_dsm.sh script or ACME.sh Wiki page for details:"
110130 _info " https://github.com/acmesh-official/acme.sh/wiki/Synology-NAS-Guide"
111- DEPRECATED_otp_code=" "
112- if _exists oathtool; then
113- DEPRECATED_otp_code=" $( oathtool --base32 --totp " ${SYNO_TOTP_SECRET} " 2> /dev/null) "
114- else
131+ if ! _exists oathtool; then
115132 _err " oathtool could not be found, install oathtool to use SYNO_TOTP_SECRET"
116133 return 1
117134 fi
135+ DEPRECATED_otp_code=" $( oathtool --base32 --totp " ${SYNO_TOTP_SECRET} " 2> /dev/null) "
118136
119137 if [ -n " $SYNO_DID " ]; then
120138 _H1=" Cookie: did=$SYNO_DID "
@@ -125,35 +143,49 @@ synology_dsm_deploy() {
125143 response=$( _post " method=login&account=$encoded_username &passwd=$encoded_password &api=SYNO.API.Auth&version=$api_version &enable_syno_token=yes&otp_code=$DEPRECATED_otp_code &device_name=certrenewal&device_id=$SYNO_DID " " $_base_url /webapi/auth.cgi?enable_syno_token=yes" )
126144 _debug3 response " $response "
127145 # END - DEPRECATED, only kept for legacy compatibility reasons
146+ # If SYNO_DeviceDevice_ID & SYNO_Device_Name both empty, just log in normally
147+ elif [ -z " ${SYNO_Device_ID:- } " ] && [ -z " ${SYNO_Device_Name:- } " ]; then
148+ if [ -n " $SYNO_USE_TEMP_ADMIN " ]; then
149+ _debug " Creating temp admin user in Synology DSM"
150+ synouser --del " $SYNO_Username " > /dev/null 2> /dev/null
151+ synouser --add " $SYNO_Username " " $SYNO_Password " " " 0 " " 0 > /dev/null
152+ synogroup --memberadd administrators " $SYNO_Username " > /dev/null
153+ fi
154+ response=$( _get " $_base_url /webapi/entry.cgi?api=SYNO.API.Auth&version=$api_version &method=login&format=sid&account=$encoded_username &passwd=$encoded_password &enable_syno_token=yes" )
155+ _debug3 response " $response "
128156 # Get device ID if still empty first, otherwise log in right away
129- elif [ -z " ${SYNO_Device_ID:- } " ]; then
157+ # If SYNO_Device_Name is set, we treat that account enabled two-factor authorization, consider SYNO_Device_ID is not set, so it won't be able to login without requiring the OTP code.
158+ elif [ -n " ${SYNO_Device_Name:- } " ] && [ -z " ${SYNO_Device_ID:- } " ]; then
130159 printf " Enter OTP code for user '%s': " " $SYNO_Username "
131160 read -r otp_code
132- if [ -z " ${SYNO_Device_Name:- } " ]; then
133- printf " Enter device name or leave empty for default (CertRenewal): "
134- read -r SYNO_Device_Name
135- [ -n " ${SYNO_Device_Name} " ] || SYNO_Device_Name=" CertRenewal"
136- fi
137-
138161 response=$( _get " $_base_url /webapi/$api_path ?api=SYNO.API.Auth&version=$api_version &method=login&format=sid&account=$encoded_username &passwd=$encoded_password &otp_code=$otp_code &enable_syno_token=yes&enable_device_token=yes&device_name=$SYNO_Device_Name " )
139162 _secure_debug3 response " $response "
140163
141164 id_property=' device_id'
142165 [ " ${api_version} " -gt ' 6' ] || id_property=' did'
143166 SYNO_Device_ID=$( echo " $response " | grep " $id_property " | sed -n ' s/.*"' $id_property ' " *: *"\([^"]*\).*/\1/p' )
144167 _secure_debug2 SYNO_Device_ID " $SYNO_Device_ID "
168+ # Otherwise, if SYNO_Device_ID is set, we can just use it to login.
145169 else
170+ if [ -z " ${SYNO_Device_Name:- } " ]; then
171+ printf " Enter device name or leave empty for default (CertRenewal): "
172+ read -r SYNO_Device_Name
173+ [ -n " ${SYNO_Device_Name} " ] || SYNO_Device_Name=" CertRenewal"
174+ fi
146175 response=$( _get " $_base_url /webapi/$api_path ?api=SYNO.API.Auth&version=$api_version &method=login&format=sid&account=$encoded_username &passwd=$encoded_password &enable_syno_token=yes&device_name=$SYNO_Device_Name &device_id=$SYNO_Device_ID " )
147- _debug3 response " $response "
176+ _secure_debug3 response " $response "
148177 fi
149178
150179 sid=$( echo " $response " | grep " sid" | sed -n ' s/.*"sid" *: *"\([^"]*\).*/\1/p' )
151180 token=$( echo " $response " | grep " synotoken" | sed -n ' s/.*"synotoken" *: *"\([^"]*\).*/\1/p' )
152181 _debug " Session ID" " $sid "
153182 _debug SynoToken " $token "
154- if [ -z " $SYNO_DID " ] && [ -z " $SYNO_Device_ID " ] || [ -z " $ sid" ] || [ -z " $token " ]; then
183+ if [ -z " $sid " ] || [ -z " $token " ]; then
155184 _err " Unable to authenticate to $_base_url - check your username & password."
156- _err " If two-factor authentication is enabled for the user, set SYNO_Device_ID."
185+ _err " If two-factor authentication is enabled for the user:"
186+ _err " - set SYNO_Device_Name then input *correct* OTP-code manually"
187+ _err " - get & set SYNO_Device_ID via your browser cookies"
188+ _remove_temp_admin " $SYNO_USE_TEMP_ADMIN " " $SYNO_Username "
157189 return 1
158190 fi
159191
@@ -164,8 +196,10 @@ synology_dsm_deploy() {
164196 # Now that we know the username & password are good, save them
165197 _savedeployconf SYNO_Username " $SYNO_Username "
166198 _savedeployconf SYNO_Password " $SYNO_Password "
167- _savedeployconf SYNO_Device_Name " $SYNO_Device_Name "
168- _savedeployconf SYNO_Device_ID " $SYNO_Device_ID "
199+ if [ -z " ${SYNO_USE_TEMP_ADMIN:- } " ]; then
200+ _savedeployconf SYNO_Device_Name " $SYNO_Device_Name "
201+ _savedeployconf SYNO_Device_ID " $SYNO_Device_ID "
202+ fi
169203
170204 _info " Getting certificates in Synology DSM"
171205 response=$( _post " api=SYNO.Core.Certificate.CRT&method=list&version=1&_sid=$sid " " $_base_url /webapi/entry.cgi" )
@@ -177,6 +211,7 @@ synology_dsm_deploy() {
177211
178212 if [ -z " $id " ] && [ -z " ${SYNO_Create:- } " ]; then
179213 _err " Unable to find certificate: $SYNO_Certificate & \$ SYNO_Create is not set"
214+ _remove_temp_admin " $SYNO_USE_TEMP_ADMIN " " $SYNO_Username "
180215 return 1
181216 fi
182217
@@ -211,10 +246,11 @@ synology_dsm_deploy() {
211246 else
212247 _info " Restarting HTTP services failed"
213248 fi
214-
249+ _remove_temp_admin " $SYNO_USE_TEMP_ADMIN " " $SYNO_Username "
215250 _logout
216251 return 0
217252 else
253+ _remove_temp_admin " $SYNO_USE_TEMP_ADMIN " " $SYNO_Username "
218254 _err " Unable to update certificate, error code $response "
219255 _logout
220256 return 1
@@ -227,3 +263,13 @@ _logout() {
227263 response=$( _get " $_base_url /webapi/$api_path ?api=SYNO.API.Auth&version=$api_version &method=logout&_sid=$sid " )
228264 _debug3 response " $response "
229265}
266+
267+ _remove_temp_admin () {
268+ flag=$1
269+ username=$2
270+
271+ if [ -n " ${flag} " ]; then
272+ _debug " Removing temp admin user in Synology DSM"
273+ synouser --del " $username " > /dev/null
274+ fi
275+ }
0 commit comments