Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
Acme.Sh
Commits
623d615c
Unverified
Commit
623d615c
authored
May 28, 2023
by
Martin Arndt
Committed by
GitHub
May 28, 2023
Browse files
Remove external OTP dependency from synology_dsm.sh
Also adapt to DSM 7's API improvements.
parent
0d25f761
Changes
1
Hide whitespace changes
Inline
Side-by-side
deploy/synology_dsm.sh
View file @
623d615c
#!/usr/bin/env sh
#!/bin/bash
# Here is a script to deploy cert to Synology DSM
################################################################################
#
# ACME.sh 3rd party deploy plugin for Synology DSM
# It requires following environment variables:
################################################################################
#
# Authors: Brian Hartvigsen (creator), https://github.com/tresni
# SYNO_Username - Synology Username to login (must be an administrator)
# Martin Arndt (contributor), https://troublezone.net/
# SYNO_Password - Synology Password to login
# Updated: 2023-05-28
# SYNO_Certificate - Certificate description to target for replacement
# Issues: https://github.com/acmesh-official/acme.sh/issues/2727
#
################################################################################
# The following environmental variables may be set if you don't like their
# Usage:
# default values:
# 1. export SYNO_Username="adminUser"
#
# 2. export SYNO_Password="adminPassword"
# SYNO_Scheme - defaults to http
# Optional exports (shown values are the defaults):
# SYNO_Hostname - defaults to localhost
# - export SYNO_Certificate="" to replace a specific certificate via description
# SYNO_Port - defaults to 5000
# - export SYNO_Scheme="http"
# SYNO_DID - device ID to skip OTP - defaults to empty
# - export SYNO_Hostname="localhost"
# SYNO_TOTP_SECRET - TOTP secret to generate OTP - defaults to empty
# - export SYNO_Port="5000"
#
# - export SYNO_Device_Name="CertRenewal" - required for skipping 2FA-OTP
# - export SYNO_Device_ID="" - required for skipping 2FA-OTP
# 3. acme.sh --deploy --deploy-hook synology_dsm -d example.com
################################################################################
# Dependencies:
# Dependencies:
# -------------
# - jq & curl
# - jq and curl
################################################################################
# - oathtool (When using 2 Factor Authentication and SYNO_TOTP_SECRET is set)
# Return value:
#
# 0 means success, otherwise error.
#returns 0 means success, otherwise error.
################################################################################
######## Public functions #####################
########## Public functions ####################################################
#domain keyfile certfile cafile fullchain
#domain keyfile certfile cafile fullchain
synology_dsm_deploy
()
{
synology_dsm_deploy
()
{
_cdomain
=
"
$1
"
_cdomain
=
"
$1
"
_ckey
=
"
$2
"
_ckey
=
"
$2
"
_ccert
=
"
$3
"
_ccert
=
"
$3
"
...
@@ -36,34 +37,39 @@ synology_dsm_deploy() {
...
@@ -36,34 +37,39 @@ synology_dsm_deploy() {
_debug _cdomain
"
$_cdomain
"
_debug _cdomain
"
$_cdomain
"
# Get
U
sername
and P
assword, but don't save until we
successfully authenticate
# Get
u
sername
& p
assword, but don't save until we
authenticated successfully
_getdeployconf SYNO_Username
_getdeployconf SYNO_Username
_getdeployconf SYNO_Password
_getdeployconf SYNO_Password
_getdeployconf SYNO_Create
_getdeployconf SYNO_Create
_getdeployconf SYNO_D
ID
_getdeployconf SYNO_D
evice_Name
_getdeployconf SYNO_
TOTP_SECRET
_getdeployconf SYNO_
Device_ID
if
[
-z
"
${
SYNO_Username
:-}
"
]
||
[
-z
"
${
SYNO_Password
:-}
"
]
;
then
if
[
-z
"
${
SYNO_Username
:-}
"
]
||
[
-z
"
${
SYNO_Password
:-}
"
]
;
then
_err
"SYNO_Username & SYNO_Password must be set"
_err
"SYNO_Username & SYNO_Password must be set"
return
1
return
1
fi
fi
if
[
-n
"
${
SYNO_Device_Name
:-}
"
]
&&
[
-z
"
${
SYNO_Device_ID
:-}
"
]
;
then
_err
"SYNO_Device_Name set, but SYNO_Device_ID is empty"
return
1
fi
_debug2 SYNO_Username
"
$SYNO_Username
"
_debug2 SYNO_Username
"
$SYNO_Username
"
_secure_debug2 SYNO_Password
"
$SYNO_Password
"
_secure_debug2 SYNO_Password
"
$SYNO_Password
"
_debug2 SYNO_Create
"
$SYNO_Create
"
_debug2 SYNO_Device_Name
"
$SYNO_Device_Name
"
_secure_debug2 SYNO_Device_ID
"
$SYNO_Device_ID
"
# Optional scheme, hostname
, and
port for Synology DSM
# Optional scheme, hostname
&
port for Synology DSM
_getdeployconf SYNO_Scheme
_getdeployconf SYNO_Scheme
_getdeployconf SYNO_Hostname
_getdeployconf SYNO_Hostname
_getdeployconf SYNO_Port
_getdeployconf SYNO_Port
#
d
efault va
u
les for scheme, hostname
, and
port
#
D
efault val
u
es for scheme, hostname
&
port
#
d
efaulting to localhost
and
http because it's localhost
...
#
D
efaulting to localhost
&
http
,
because it's localhost
…
[
-n
"
${
SYNO_Scheme
}
"
]
||
SYNO_Scheme
=
"http"
[
-n
"
${
SYNO_Scheme
}
"
]
||
SYNO_Scheme
=
"http"
[
-n
"
${
SYNO_Hostname
}
"
]
||
SYNO_Hostname
=
"localhost"
[
-n
"
${
SYNO_Hostname
}
"
]
||
SYNO_Hostname
=
"localhost"
[
-n
"
${
SYNO_Port
}
"
]
||
SYNO_Port
=
"5000"
[
-n
"
${
SYNO_Port
}
"
]
||
SYNO_Port
=
"5000"
_savedeployconf SYNO_Scheme
"
$SYNO_Scheme
"
_savedeployconf SYNO_Scheme
"
$SYNO_Scheme
"
_savedeployconf SYNO_Hostname
"
$SYNO_Hostname
"
_savedeployconf SYNO_Hostname
"
$SYNO_Hostname
"
_savedeployconf SYNO_Port
"
$SYNO_Port
"
_savedeployconf SYNO_Port
"
$SYNO_Port
"
_debug2 SYNO_Scheme
"
$SYNO_Scheme
"
_debug2 SYNO_Scheme
"
$SYNO_Scheme
"
_debug2 SYNO_Hostname
"
$SYNO_Hostname
"
_debug2 SYNO_Hostname
"
$SYNO_Hostname
"
_debug2 SYNO_Port
"
$SYNO_Port
"
_debug2 SYNO_Port
"
$SYNO_Port
"
...
@@ -87,49 +93,49 @@ synology_dsm_deploy() {
...
@@ -87,49 +93,49 @@ synology_dsm_deploy() {
_debug3 response
"
$response
"
_debug3 response
"
$response
"
_debug3 api_version
"
$api_version
"
_debug3 api_version
"
$api_version
"
# Login, get the
token from JSON and session id from cookie
# Login, get the
session ID & SynoToken from JSON
_info
"Logging into
$SYNO_Hostname
:
$SYNO_Port
"
_info
"Logging into
$SYNO_Hostname
:
$SYNO_Port
"
encoded_username
=
"
$(
printf
"%s"
"
$SYNO_Username
"
| _url_encode
)
"
encoded_username
=
"
$(
printf
"%s"
"
$SYNO_Username
"
| _url_encode
)
"
encoded_password
=
"
$(
printf
"%s"
"
$SYNO_Password
"
| _url_encode
)
"
encoded_password
=
"
$(
printf
"%s"
"
$SYNO_Password
"
| _url_encode
)
"
otp_code
=
""
# Get device ID if still empty first, otherwise log in right away
if
[
-n
"
$SYNO_TOTP_SECRET
"
]
;
then
if
[
-z
"
${
SYNO_Device_ID
:-}
"
]
;
then
if
_exists oathtool
;
then
printf
"Enter OTP code for user '%s': "
"
$SYNO_Username
"
otp_code
=
"
$(
oathtool
--base32
--totp
"
${
SYNO_TOTP_SECRET
}
"
2>/dev/null
)
"
read
-r
otp_code
else
if
[
-z
"
${
SYNO_Device_Name
:-}
"
]
;
then
_err
"oathtool could not be found, install oathtool to use SYNO_TOTP_SECRET"
printf
"Enter device name or leave empty for default (CertRenewal): "
return
1
read
-r
SYNO_Device_Name
[
-n
"
${
SYNO_Device_Name
}
"
]
||
SYNO_Device_Name
=
"CertRenewal"
fi
fi
fi
if
[
-n
"
$SYNO_DID
"
]
;
then
response
=
$(
_get
"
$_base_url
/webapi/entry.cgi?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
"
)
_H1
=
"Cookie: did=
$SYNO_DID
"
_debug3 response
"
$response
"
export
_H1
SYNO_Device_ID
=
$(
echo
"
$response
"
|
grep
"device_id"
|
sed
-n
's/.*"device_id" *: *"\([^"]*\).*/\1/p'
)
_debug3 H1
"
${
_H1
}
"
_secure_debug2 SYNO_Device_ID
"
$SYNO_Device_ID
"
else
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&device_name=
$SYNO_Device_Name
&device_id=
$SYNO_Device_ID
"
)
_debug3 response
"
$response
"
fi
fi
response
=
$(
_post
"method=login&account=
$encoded_username
&passwd=
$encoded_password
&api=SYNO.API.Auth&version=
$api_version
&enable_syno_token=yes&otp_code=
$otp_code
&device_name=certrenewal&device_id=
$SYNO_DID
"
"
$_base_url
/webapi/auth.cgi?enable_syno_token=yes"
)
sid
=
$(
echo
"
$response
"
|
grep
"sid"
|
sed
-n
's/.*"sid" *: *"\([^"]*\).*/\1/p'
)
token
=
$(
echo
"
$response
"
|
grep
"synotoken"
|
sed
-n
's/.*"synotoken" *: *"\([^"]*\).*/\1/p'
)
token
=
$(
echo
"
$response
"
|
grep
"synotoken"
|
sed
-n
's/.*"synotoken" *: *"\([^"]*\).*/\1/p'
)
_debug3 response
"
$response
"
_debug Session ID
"
$sid
"
_debug token
"
$token
"
_debug SynoToken
"
$token
"
if
[
-z
"
$SYNO_Device_ID
"
]
||
[
-z
"
$sid
"
]
||
[
-z
"
$token
"
]
;
then
if
[
-z
"
$token
"
]
;
then
_err
"Unable to authenticate to
$_base_url
- check your username & password."
_err
"Unable to authenticate to
$SYNO_Hostname
:
$SYNO_Port
using
$SYNO_Scheme
."
_err
"If two-factor authentication is enabled for the user, set SYNO_Device_ID."
_err
"Check your username and password."
_err
"If two-factor authentication is enabled for the user, set SYNO_TOTP_SECRET."
return
1
return
1
fi
fi
sid
=
$(
echo
"
$response
"
|
grep
"sid"
|
sed
-n
's/.*"sid" *: *"\([^"]*\).*/\1/p'
)
_H1
=
"X-SYNO-TOKEN:
$token
"
_H1
=
"X-SYNO-TOKEN:
$token
"
export
_H1
export
_H1
_debug2 H1
"
${
_H1
}
"
_debug2 H1
"
${
_H1
}
"
# Now that we know the username
and
password are good, save them
# Now that we know the username
&
password are good, save them
_savedeployconf SYNO_Username
"
$SYNO_Username
"
_savedeployconf SYNO_Username
"
$SYNO_Username
"
_savedeployconf SYNO_Password
"
$SYNO_Password
"
_savedeployconf SYNO_Password
"
$SYNO_Password
"
_savedeployconf SYNO_D
ID
"
$SYNO_DID
"
_savedeployconf SYNO_D
evice_Name
"
$SYNO_Device_Name
"
_savedeployconf SYNO_
TOTP_SECRET
"
$SYNO_TOTP_SECRET
"
_savedeployconf SYNO_
Device_ID
"
$SYNO_Device_ID
"
_info
"Getting certificates in Synology DSM"
_info
"Getting certificates in Synology DSM"
response
=
$(
_post
"api=SYNO.Core.Certificate.CRT&method=list&version=1&_sid=
$sid
"
"
$_base_url
/webapi/entry.cgi"
)
response
=
$(
_post
"api=SYNO.Core.Certificate.CRT&method=list&version=1&_sid=
$sid
"
"
$_base_url
/webapi/entry.cgi"
)
...
@@ -140,7 +146,7 @@ synology_dsm_deploy() {
...
@@ -140,7 +146,7 @@ synology_dsm_deploy() {
_debug2
id
"
$id
"
_debug2
id
"
$id
"
if
[
-z
"
$id
"
]
&&
[
-z
"
${
SYNO_Create
:-}
"
]
;
then
if
[
-z
"
$id
"
]
&&
[
-z
"
${
SYNO_Create
:-}
"
]
;
then
_err
"Unable to find certificate:
$SYNO_Certificate
and
\$
SYNO_Create is not set"
_err
"Unable to find certificate:
$SYNO_Certificate
&
\$
SYNO_Create is not set"
return
1
return
1
fi
fi
...
@@ -171,13 +177,23 @@ synology_dsm_deploy() {
...
@@ -171,13 +177,23 @@ synology_dsm_deploy() {
if
!
echo
"
$response
"
|
grep
'"error":'
>
/dev/null
;
then
if
!
echo
"
$response
"
|
grep
'"error":'
>
/dev/null
;
then
if
echo
"
$response
"
|
grep
'"restart_httpd":true'
>
/dev/null
;
then
if
echo
"
$response
"
|
grep
'"restart_httpd":true'
>
/dev/null
;
then
_info
"
http services were restart
ed"
_info
"
Restarting HTTP services succeed
ed"
else
else
_info
"
http services were NOT restart
ed"
_info
"
Restarting HTTP services fail
ed"
fi
fi
_logout
return
0
return
0
else
else
_err
"Unable to update certificate, error code
$response
"
_err
"Unable to update certificate, error code
$response
"
_logout
return
1
return
1
fi
fi
}
}
#################### Private functions below ##################################
_logout
()
{
# Logout to not occupy a permanent session, e. g. in DSM's "Connected Users" widget
response
=
$(
_get
"
$_base_url
/webapi/entry.cgi?api=SYNO.API.Auth&version=
$api_version
&method=logout"
)
_debug3 response
"
$response
"
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment