|
|
#!/usr/bin/env sh
# Here is a script to deploy cert to Synology DSM # # it requires the jq and curl are in the $PATH and the following # environment variables must be set: # # SYNO_Username - Synology Username to login (must be an administrator) # SYNO_Password - Synology Password to login # SYNO_Certificate - Certificate description to target for replacement # # The following environmental variables may be set if you don't like their # default values: # # SYNO_Scheme - defaults to http # SYNO_Hostname - defaults to localhost # SYNO_Port - defaults to 5000 # #returns 0 means success, otherwise error.
######## Public functions #####################
#domain keyfile certfile cafile fullchain synology_dsm_deploy() {
_cdomain="$1" _ckey="$2" _ccert="$3" _cca="$4"
_debug _cdomain "$_cdomain"
# Get Username and Password, but don't save until we successfully authenticate SYNO_Username="${SYNO_Username:-$(_readdomainconf SYNO_Username)}" SYNO_Password="${SYNO_Password:-$(_readdomainconf SYNO_Password)}" if [ -z "$SYNO_Username" ] || [ -z "$SYNO_Password" ]; then SYNO_Username="" SYNO_Password="" _err "SYNO_Username & SYNO_Password must be set" return 1 fi _debug2 SYNO_Username "$SYNO_Username" _secure_debug2 SYNO_Password "$SYNO_Password"
# Optional scheme, hostname, and port for Synology DSM SYNO_Scheme="${SYNO_Scheme:-$(_readdomainconf SYNO_Scheme)}" SYNO_Hostname="${SYNO_Hostname:-$(_readdomainconf SYNO_Hostname)}" SYNO_Port="${SYNO_Port:-$(_readdomainconf SYNO_Port)}" _savedomainconf SYNO_Scheme "$SYNO_Scheme" _savedomainconf SYNO_Hostname "$SYNO_Hostname" _savedomainconf SYNO_Port "$SYNO_Port"
# default vaules for scheme, hostname, and port # defaulting to localhost and http because it's localhost... [ -n "${SYNO_Scheme}" ] || SYNO_Scheme="http" [ -n "${SYNO_Hostname}" ] || SYNO_Hostname="localhost" [ -n "${SYNO_Port}" ] || SYNO_Port="5000"
_debug2 SYNO_Scheme "$SYNO_Scheme" _debug2 SYNO_Hostname "$SYNO_Hostname" _debug2 SYNO_Port "$SYNO_Port"
# Get the certificate description, but don't save it until we verfiy it's real _getdeployconf SYNO_Certificate # shellcheck disable=SC2154 if [ -z "${SYNO_Certificate}" ]; then _err "SYNO_Certificate needs to be defined (with the Certificate description name)" return 1 fi _debug SYNO_Certificate "$SYNO_Certificate"
# We can't use _get or _post because they lack support for cookies # use jq because I'm too lazy to figure out what is required to parse json # by hand. Also it seems to be in place for Synology DSM (6.2.1 at least) for x in curl jq; do if ! _exists "$x"; then _err "Please install $x first." _err "We need $x to work." return 1 fi done
_base_url="$SYNO_Scheme://$SYNO_Hostname:$SYNO_Port" _debug _base_url "$_base_url"
_cookie_jar="$(_mktemp)" _debug _cookie_jar "$_cookie_jar"
# Login, get the token from JSON and session id from cookie _debug "Logging into $SYNO_Hostname:$SYNO_Port" token=$(curl -sk -c "$_cookie_jar" "$_base_url/webman/login.cgi?username=$SYNO_Username&passwd=$SYNO_Password&enable_syno_token=yes" | jq -r .SynoToken) if [ "$token" = "null" ]; then _err "Unable to authenticate to $SYNO_Hostname:$SYNO_Port using $SYNO_Scheme." _err "Check your username and password." rm "$_cookie_jar" return 1 fi
# Now that we know the username and password are good, save them _savedomainconf SYNO_Username "$SYNO_Username" _savedomainconf SYNO_Password "$SYNO_Password" _secure_debug2 token "$token"
# Use token and session id to get the list of certificates response=$(curl -sk -b "$_cookie_jar" "$_base_url/webapi/entry.cgi" -H "X-SYNO-TOKEN: $token" -d api=SYNO.Core.Certificate.CRT -d method=list -d version=1) _debug3 response "$response" # select the first certificate matching our description cert=$(echo "$response" | jq -r ".data.certificates | map(select(.desc == \"$SYNO_Certificate\"))[0]") _debug3 cert "$cert"
if [ "$cert" = "null" ]; then _err "Unable to find certificate: $SYNO_Certificate" rm "$_cookie_jar" return 1 fi
# we've verified this certificate description is a thing, so save it _savedeployconf SYNO_Certificate "$SYNO_Certificate"
id=$(echo "$cert" | jq -r ".id") default=$(echo "$cert" | jq -r ".is_default") _debug2 id "$id" _debug2 default "$default"
# This is the heavy lifting, make the API call to update a certificate in place response=$(curl -sk -b "$_cookie_jar" "$_base_url/webapi/entry.cgi?api=SYNO.Core.Certificate&method=import&version=1&SynoToken=$token" -F "key=@$_ckey" -F "cert=@$_ccert" -F "inter_cert=@$_cca" -F "id=$id" -F "desc=$SYNO_Certificate" -F "as_default=$default") _debug3 response "$response" success=$(echo "$response" | jq -r ".success") _debug2 success "$success" rm "$_cookie_jar"
if [ "$success" = "true" ]; then restarted=$(echo "$response" | jq -r ".data.restart_httpd") if [ "$restarted" = "true" ]; then _info "http services were restarted" else _info "http services were NOT restarted" fi return 0 else code=$(echo "$response" | jq -r ".error.code") _err "Unable to update certificate, error code $code" return 1 fi }
|