This allows users to quickly show the state of any configured application, as well as the state of their server. In doing so, we make it easy for them to provide information necessary for debugging in a single command.
209 lines
6.7 KiB
Bash
Executable File
209 lines
6.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
|
source "$PLUGIN_AVAILABLE_PATH/certs/functions"
|
|
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
|
|
|
cmd-certs-report() {
|
|
declare desc="displays an ssl report for one or more apps"
|
|
local cmd="certs:report"
|
|
local INSTALLED_APPS=$(dokku_apps)
|
|
local APP="$2" INFO_FLAG="$3"
|
|
|
|
if [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
|
|
INFO_FLAG="$APP"
|
|
APP=""
|
|
fi
|
|
|
|
if [[ -z "$APP" ]] && [[ -z "$INFO_FLAG" ]]; then
|
|
INFO_FLAG="true"
|
|
fi
|
|
|
|
if [[ -z "$APP" ]]; then
|
|
for app in $INSTALLED_APPS; do
|
|
cmd-certs-report-single "$app" "$INFO_FLAG" | tee || true
|
|
done
|
|
else
|
|
cmd-certs-report-single "$APP" "$INFO_FLAG"
|
|
fi
|
|
}
|
|
|
|
cmd-certs-report-single() {
|
|
declare APP="$1" INFO_FLAG="$2"
|
|
if [[ "$INFO_FLAG" == "true" ]]; then
|
|
INFO_FLAG=""
|
|
fi
|
|
verify_app_name "$APP"
|
|
local flag_map=(
|
|
"--ssl-dir: $DOKKU_ROOT/$APP/tls"
|
|
"--ssl-enabled: $(fn-ssl-enabled "$APP")"
|
|
"--ssl-hostnames: $(fn-ssl-hostnames "$APP")"
|
|
"--ssl-expires-at: $(fn-ssl-expires-at "$APP")"
|
|
"--ssl-issuer: $(fn-ssl-issuer "$APP")"
|
|
"--ssl-starts-at: $(fn-ssl-starts-at "$APP")"
|
|
"--ssl-subject: $(fn-ssl-subject "$APP")"
|
|
"--ssl-verified: $(fn-ssl-verified "$APP")"
|
|
)
|
|
|
|
if [[ -z "$INFO_FLAG" ]]; then
|
|
dokku_log_info2_quiet "$APP ssl information"
|
|
for flag in "${flag_map[@]}"; do
|
|
key="$(echo "${flag#--}" | cut -f1 -d' ' | tr - ' ')"
|
|
dokku_log_verbose "$(printf "%-30s %-25s" "${key^}" "${flag#*: }")"
|
|
done
|
|
else
|
|
local match=false; local value_exists=false
|
|
for flag in "${flag_map[@]}"; do
|
|
valid_flags="${valid_flags} $(echo "$flag" | cut -d':' -f1)"
|
|
if [[ "$flag" == "${INFO_FLAG}:"* ]]; then
|
|
value=${flag#*: }
|
|
size="${#value}"
|
|
if [[ "$size" -ne 0 ]]; then
|
|
echo "$value" && match=true && value_exists=true
|
|
else
|
|
match=true
|
|
fi
|
|
fi
|
|
done
|
|
[[ "$match" == "true" ]] || dokku_log_fail "Invalid flag passed, valid flags:${valid_flags}"
|
|
[[ "$value_exists" == "true" ]] || dokku_log_fail "not deployed"
|
|
fi
|
|
}
|
|
|
|
certs_help_content_func() {
|
|
declare desc="return certs plugin help content"
|
|
cat<<help_content
|
|
certs <app>, [DEPRECATED] Alternative for certs:report
|
|
certs:add <app> CRT KEY, Add an ssl endpoint to an app. Can also import from a tarball on stdin
|
|
certs:chain CRT [CRT ...], [NOT IMPLEMENTED] Print the ordered and complete chain for the given certificate
|
|
certs:generate <app> DOMAIN, Generate a key and certificate signing request (and self-signed certificate)
|
|
certs:info <app>, [DEPRECATED] Alternative for certs:report
|
|
certs:key <app> CRT KEY [KEY ...], [NOT IMPLEMENTED] Print the correct key for the given certificate
|
|
certs:remove <app>, Remove an SSL Endpoint from an app
|
|
certs:report [<app>] [<flag>], Displays an ssl report for one or more apps
|
|
certs:rollback <app>, [NOT IMPLEMENTED] Rollback an SSL Endpoint for an app
|
|
certs:update <app> CRT KEY, Update an SSL Endpoint on an app. Can also import from a tarball on stdin
|
|
help_content
|
|
}
|
|
|
|
certs_help_cmd() {
|
|
if [[ $1 = "certs:help" ]] ; then
|
|
echo -e 'Usage: dokku certs[:COMMAND]'
|
|
echo ''
|
|
echo 'Manage Dokku apps SSL (TLS) certs.'
|
|
echo ''
|
|
echo 'Additional commands:'
|
|
certs_help_content_func | sort | column -c2 -t -s,
|
|
elif [[ $(ps -o command= $PPID) == *"--all"* ]]; then
|
|
certs_help_content_func
|
|
else
|
|
cat<<help_desc
|
|
certs, Manage Dokku apps SSL (TLS) certs
|
|
help_desc
|
|
fi
|
|
}
|
|
|
|
certs_info_cmd() {
|
|
# This is here because it's used in both the info and the default
|
|
declare desc="prints SSL certificate info for app"
|
|
local cmd="certs:info"
|
|
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
|
|
verify_app_name "$2"
|
|
local APP="$2"
|
|
local APP_SSL_PATH="$DOKKU_ROOT/$APP/tls"
|
|
|
|
if is_ssl_enabled "$APP"; then
|
|
dokku_log_info1 "Fetching SSL Endpoint info for $APP..."
|
|
dokku_log_info1 "Certificate details:"
|
|
dokku_log_info2 "Common Name(s): "
|
|
|
|
for domain in $(get_ssl_hostnames "$APP" | xargs); do
|
|
dokku_log_info2 " $domain"
|
|
done
|
|
|
|
dokku_log_info2 "Expires At: $(openssl x509 -in "$APP_SSL_PATH/server.crt" -noout -text | grep "Not After :" | awk -F " : " '{ print $2 }')"
|
|
dokku_log_info2 "Issuer: $(openssl x509 -in "$APP_SSL_PATH/server.crt" -noout -text | grep "Issuer:" | xargs | sed -e "s/Issuer: //g")"
|
|
dokku_log_info2 "Starts At: $(openssl x509 -in "$APP_SSL_PATH/server.crt" -noout -text | grep "Not Before:" | awk -F ": " '{ print $2 }')"
|
|
dokku_log_info2 "Subject: $(openssl x509 -in "$APP_SSL_PATH/server.crt" -noout -subject | sed -e "s:subject= ::g"| sed -e "s:^/::g" | sed -e "s:/:; :g")"
|
|
local SSL_VERIFY_OUTPUT="$(openssl verify -verbose -purpose sslserver "$APP_SSL_PATH/server.crt" | awk -F ':' '{ print $2 }' | tail -1 | xargs || true)"
|
|
if [[ "$SSL_VERIFY_OUTPUT" == "OK" ]]; then
|
|
local SSL_SELF_SIGNED="verified by a certificate authority."
|
|
else
|
|
local SSL_SELF_SIGNED="self signed."
|
|
fi
|
|
dokku_log_info2 "SSL certificate is $SSL_SELF_SIGNED"
|
|
else
|
|
dokku_log_info1 "$APP does not have an SSL endpoint"
|
|
fi
|
|
}
|
|
|
|
fn-ssl-enabled() {
|
|
declare APP="$1"
|
|
local SSL_ENABLED=false
|
|
|
|
if is_ssl_enabled "$APP"; then
|
|
SSL_ENABLED=true
|
|
fi
|
|
echo "$SSL_ENABLED"
|
|
}
|
|
|
|
fn-ssl-expires-at() {
|
|
declare APP="$1"
|
|
local APP_SSL_PATH="$DOKKU_ROOT/$APP/tls"
|
|
|
|
if is_ssl_enabled "$APP"; then
|
|
openssl x509 -in "$APP_SSL_PATH/server.crt" -noout -text | grep "Not After :" | awk -F " : " '{ print $2 }'
|
|
fi
|
|
}
|
|
|
|
fn-ssl-hostnames() {
|
|
declare APP="$1"
|
|
|
|
if is_ssl_enabled "$APP"; then
|
|
get_ssl_hostnames "$APP" | xargs
|
|
fi
|
|
}
|
|
|
|
fn-ssl-issuer() {
|
|
declare APP="$1"
|
|
local APP_SSL_PATH="$DOKKU_ROOT/$APP/tls"
|
|
|
|
if is_ssl_enabled "$APP"; then
|
|
openssl x509 -in "$APP_SSL_PATH/server.crt" -noout -text | grep "Issuer:" | xargs | sed -e "s/Issuer: //g"
|
|
fi
|
|
}
|
|
|
|
fn-ssl-starts-at() {
|
|
declare APP="$1"
|
|
local APP_SSL_PATH="$DOKKU_ROOT/$APP/tls"
|
|
|
|
if is_ssl_enabled "$APP"; then
|
|
openssl x509 -in "$APP_SSL_PATH/server.crt" -noout -text | grep "Not Before:" | awk -F ": " '{ print $2 }'
|
|
fi
|
|
}
|
|
|
|
fn-ssl-subject() {
|
|
declare APP="$1"
|
|
local APP_SSL_PATH="$DOKKU_ROOT/$APP/tls"
|
|
|
|
if is_ssl_enabled "$APP"; then
|
|
openssl x509 -in "$APP_SSL_PATH/server.crt" -noout -subject | sed -e "s:subject= ::g"| sed -e "s:^/::g" | sed -e "s:/:; :g"
|
|
fi
|
|
}
|
|
|
|
fn-ssl-verified() {
|
|
declare APP="$1"
|
|
local APP_SSL_PATH="$DOKKU_ROOT/$APP/tls"
|
|
local SSL_VERIFY_OUTPUT=false SSL_SELF_SIGNED="self signed"
|
|
|
|
if ! is_ssl_enabled "$APP"; then
|
|
return
|
|
fi
|
|
|
|
SSL_VERIFY_OUTPUT="$(openssl verify -verbose -purpose sslserver "$APP_SSL_PATH/server.crt" | awk -F ':' '{ print $2 }' | tail -1 | xargs || true)"
|
|
if [[ "$SSL_VERIFY_OUTPUT" == "OK" ]]; then
|
|
SSL_SELF_SIGNED="verified by a certificate authority"
|
|
fi
|
|
|
|
echo "$SSL_SELF_SIGNED"
|
|
}
|