Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ruanhaishen
Acme.Sh
Commits
53ede7b0
Unverified
Commit
53ede7b0
authored
Jul 08, 2023
by
neil
Committed by
GitHub
Jul 08, 2023
Browse files
Merge pull request #4646 from Eagle3386/patch-1
Remove external OTP dependency from deploy hook Synology_DSM.sh
parents
cd13aee3
0d7b8316
Changes
2
Show whitespace changes
Inline
Side-by-side
README.md
View file @
53ede7b0
...
@@ -51,14 +51,12 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa)
...
@@ -51,14 +51,12 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa)
-
[
ruby-china.org
](
https://ruby-china.org/topics/31983
)
-
[
ruby-china.org
](
https://ruby-china.org/topics/31983
)
-
[
Proxmox
](
https://pve.proxmox.com/wiki/Certificate_Management
)
-
[
Proxmox
](
https://pve.proxmox.com/wiki/Certificate_Management
)
-
[
pfsense
](
https://github.com/pfsense/FreeBSD-ports/pull/89
)
-
[
pfsense
](
https://github.com/pfsense/FreeBSD-ports/pull/89
)
-
[
webfaction
](
https://community.webfaction.com/questions/19988/using-letsencrypt
)
-
[
Loadbalancer.org
](
https://www.loadbalancer.org/blog/loadbalancer-org-with-lets-encrypt-quick-and-dirty
)
-
[
Loadbalancer.org
](
https://www.loadbalancer.org/blog/loadbalancer-org-with-lets-encrypt-quick-and-dirty
)
-
[
discourse.org
](
https://meta.discourse.org/t/setting-up-lets-encrypt/40709
)
-
[
discourse.org
](
https://meta.discourse.org/t/setting-up-lets-encrypt/40709
)
-
[
Centminmod
](
https://centminmod.com/letsencrypt-acmetool-https.html
)
-
[
Centminmod
](
https://centminmod.com/letsencrypt-acmetool-https.html
)
-
[
splynx
](
https://forum.splynx.com/t/free-ssl-cert-for-splynx-lets-encrypt/297
)
-
[
splynx
](
https://forum.splynx.com/t/free-ssl-cert-for-splynx-lets-encrypt/297
)
-
[
archlinux
](
https://www.archlinux.org/packages/community/any/acme.sh
)
-
[
opnsense.org
](
https://github.com/opnsense/plugins/tree/master/security/acme-client/src/opnsense/scripts/OPNsense/AcmeClient
)
-
[
opnsense.org
](
https://github.com/opnsense/plugins/tree/master/security/acme-client/src/opnsense/scripts/OPNsense/AcmeClient
)
-
[
CentOS Web Panel
](
http://c
e
nt
os
-webpanel.com
/
)
-
[
CentOS Web Panel
](
http
s
://c
o
nt
rol
-webpanel.com
)
-
[
lnmp.org
](
https://lnmp.org/
)
-
[
lnmp.org
](
https://lnmp.org/
)
-
[
more...
](
https://github.com/acmesh-official/acme.sh/wiki/Blogs-and-tutorials
)
-
[
more...
](
https://github.com/acmesh-official/acme.sh/wiki/Blogs-and-tutorials
)
...
...
deploy/synology_dsm.sh
View file @
53ede7b0
#!/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-07-03
# 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,39 +37,46 @@ synology_dsm_deploy() {
...
@@ -36,39 +37,46 @@ 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_DID
_getdeployconf SYNO_DID
_getdeployconf SYNO_TOTP_SECRET
_getdeployconf SYNO_TOTP_SECRET
_getdeployconf SYNO_Device_Name
_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
"
# Get the certificate description, but don't save it until we ver
f
iy it's real
# Get the certificate description, but don't save it until we veri
f
y it's real
_getdeployconf SYNO_Certificate
_getdeployconf SYNO_Certificate
_debug SYNO_Certificate
"
${
SYNO_Certificate
:-}
"
_debug SYNO_Certificate
"
${
SYNO_Certificate
:-}
"
...
@@ -87,20 +95,24 @@ synology_dsm_deploy() {
...
@@ -87,20 +95,24 @@ 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
=
""
otp_code
=
""
# START - DEPRECATED, only kept for legacy compatibility reasons
if
[
-n
"
$SYNO_TOTP_SECRET
"
]
;
then
if
[
-n
"
$SYNO_TOTP_SECRET
"
]
;
then
_info
"WARNING: Usage of SYNO_TOTP_SECRET is deprecated!"
_info
" See synology_dsm.sh script or ACME.sh Wiki page for details:"
_info
" https://github.com/acmesh-official/acme.sh/wiki/Synology-NAS-Guide"
DEPRECATED_otp_code
=
""
if
_exists oathtool
;
then
if
_exists oathtool
;
then
otp_code
=
"
$(
oathtool
--base32
--totp
"
${
SYNO_TOTP_SECRET
}
"
2>/dev/null
)
"
DEPRECATED_
otp_code
=
"
$(
oathtool
--base32
--totp
"
${
SYNO_TOTP_SECRET
}
"
2>/dev/null
)
"
else
else
_err
"oathtool could not be found, install oathtool to use SYNO_TOTP_SECRET"
_err
"oathtool could not be found, install oathtool to use SYNO_TOTP_SECRET"
return
1
return
1
fi
fi
fi
if
[
-n
"
$SYNO_DID
"
]
;
then
if
[
-n
"
$SYNO_DID
"
]
;
then
_H1
=
"Cookie: did=
$SYNO_DID
"
_H1
=
"Cookie: did=
$SYNO_DID
"
...
@@ -108,28 +120,47 @@ synology_dsm_deploy() {
...
@@ -108,28 +120,47 @@ synology_dsm_deploy() {
_debug3 H1
"
${
_H1
}
"
_debug3 H1
"
${
_H1
}
"
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"
)
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"
)
token
=
$(
echo
"
$response
"
|
grep
"synotoken"
|
sed
-n
's/.*"synotoken" *: *"\([^"]*\).*/\1/p'
)
_debug3 response
"
$response
"
_debug3 response
"
$response
"
_debug token
"
$token
"
# END - DEPRECATED, only kept for legacy compatibility reasons
# Get device ID if still empty first, otherwise log in right away
elif
[
-z
"
${
SYNO_Device_ID
:-}
"
]
;
then
printf
"Enter OTP code for user '%s': "
"
$SYNO_Username
"
read
-r
otp_code
if
[
-z
"
${
SYNO_Device_Name
:-}
"
]
;
then
printf
"Enter device name or leave empty for default (CertRenewal): "
read
-r
SYNO_Device_Name
[
-n
"
${
SYNO_Device_Name
}
"
]
||
SYNO_Device_Name
=
"CertRenewal"
fi
if
[
-z
"
$token
"
]
;
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
"
)
_err
"Unable to authenticate to
$SYNO_Hostname
:
$SYNO_Port
using
$SYNO_Scheme
."
_debug3 response
"
$response
"
_err
"Check your username and password."
SYNO_Device_ID
=
$(
echo
"
$response
"
|
grep
"device_id"
|
sed
-n
's/.*"device_id" *: *"\([^"]*\).*/\1/p'
)
_err
"If two-factor authentication is enabled for the user, set SYNO_TOTP_SECRET."
_secure_debug2 SYNO_Device_ID
"
$SYNO_Device_ID
"
return
1
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
sid
=
$(
echo
"
$response
"
|
grep
"sid"
|
sed
-n
's/.*"sid" *: *"\([^"]*\).*/\1/p'
)
sid
=
$(
echo
"
$response
"
|
grep
"sid"
|
sed
-n
's/.*"sid" *: *"\([^"]*\).*/\1/p'
)
token
=
$(
echo
"
$response
"
|
grep
"synotoken"
|
sed
-n
's/.*"synotoken" *: *"\([^"]*\).*/\1/p'
)
_debug
"Session ID"
"
$sid
"
_debug SynoToken
"
$token
"
if
[
-z
"
$SYNO_DID
"
]
&&
[
-z
"
$SYNO_Device_ID
"
]
||
[
-z
"
$sid
"
]
||
[
-z
"
$token
"
]
;
then
_err
"Unable to authenticate to
$_base_url
- check your username & password."
_err
"If two-factor authentication is enabled for the user, set SYNO_Device_ID."
return
1
fi
_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,11 +171,11 @@ synology_dsm_deploy() {
...
@@ -140,11 +171,11 @@ 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
#
w
e've verified this certificate description is a thing, so save it
#
W
e've verified this certificate description is a thing, so save it
_savedeployconf SYNO_Certificate
"
$SYNO_Certificate
"
"base64"
_savedeployconf SYNO_Certificate
"
$SYNO_Certificate
"
"base64"
_info
"Generate form POST request"
_info
"Generate form POST request"
...
@@ -156,10 +187,10 @@ synology_dsm_deploy() {
...
@@ -156,10 +187,10 @@ synology_dsm_deploy() {
content
=
"
$content
${
nl
}
--
$delim
${
nl
}
Content-Disposition: form-data; name=
\"
id
\"
${
nl
}${
nl
}
$id
"
content
=
"
$content
${
nl
}
--
$delim
${
nl
}
Content-Disposition: form-data; name=
\"
id
\"
${
nl
}${
nl
}
$id
"
content
=
"
$content
${
nl
}
--
$delim
${
nl
}
Content-Disposition: form-data; name=
\"
desc
\"
${
nl
}${
nl
}${
SYNO_Certificate
}
"
content
=
"
$content
${
nl
}
--
$delim
${
nl
}
Content-Disposition: form-data; name=
\"
desc
\"
${
nl
}${
nl
}${
SYNO_Certificate
}
"
if
echo
"
$response
"
|
sed
-n
"s/.*
\"
desc
\"
:
\"
$escaped_certificate
\"
,
\(
[^{]*
\)
.*/
\1
/p"
|
grep
--
'is_default":true'
>
/dev/null
;
then
if
echo
"
$response
"
|
sed
-n
"s/.*
\"
desc
\"
:
\"
$escaped_certificate
\"
,
\(
[^{]*
\)
.*/
\1
/p"
|
grep
--
'is_default":true'
>
/dev/null
;
then
_debug2 default
"
t
his is the default certificate"
_debug2 default
"
T
his is the default certificate"
content
=
"
$content
${
nl
}
--
$delim
${
nl
}
Content-Disposition: form-data; name=
\"
as_default
\"
${
nl
}${
nl
}
true"
content
=
"
$content
${
nl
}
--
$delim
${
nl
}
Content-Disposition: form-data; name=
\"
as_default
\"
${
nl
}${
nl
}
true"
else
else
_debug2 default
"
t
his is NOT the default certificate"
_debug2 default
"
T
his is NOT the default certificate"
fi
fi
content
=
"
$content
${
nl
}
--
$delim
--
${
nl
}
"
content
=
"
$content
${
nl
}
--
$delim
--
${
nl
}
"
content
=
"
$(
printf
"%b_"
"
$content
"
)
"
content
=
"
$(
printf
"%b_"
"
$content
"
)
"
...
@@ -171,13 +202,23 @@ synology_dsm_deploy() {
...
@@ -171,13 +202,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