remove magic additions to VHOST based on SSL cert. fixes #1368

This commit is contained in:
Michael Hobbs
2015-08-24 14:15:05 -07:00
committed by Jose Diaz-Gonzalez
parent 0904c3d458
commit a983456030
7 changed files with 117 additions and 44 deletions

22
plugins/certs/commands Executable file
View File

@@ -0,0 +1,22 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$(dirname $0)/../common/functions"
source "$(dirname $0)/functions"
case "$1" in
help | certs:help)
cat && cat<<EOF
certs:add <app> CRT KEY, Add an ssl endpoint to an app.
certs:generate <app> DOMAIN, Generate a key and certificate signing request (or self-signed certificate)
certs:info <app>, Show certificate information for an ssl endpoint.
certs:key <app> CRT KEY [KEY ...], Print the correct key for the given certificate.
certs:remove <app>, Remove an SSL Endpoint from an app.
certs:update <app> CRT KEY, Update an SSL Endpoint on an app.
EOF
;;
*)
exit $DOKKU_NOT_IMPLEMENTED_EXIT
;;
esac

45
plugins/certs/functions Executable file
View File

@@ -0,0 +1,45 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_PATH/common/functions"
# returns 'global', 'app', 'false'
# if both are configured, app trumps global
is_ssl_enabled() {
local APP=$1; verify_app_name $APP
APP_SSL_PATH="$DOKKU_ROOT/$APP/tls"
WILDCARD_SSL_PATH="$DOKKU_ROOT/tls"
if [[ -e "$APP_SSL_PATH/server.crt" ]] && [[ -e "$APP_SSL_PATH/server.key" ]]; then
echo app
return 0
elif [[ -e "$WILDCARD_SSL_PATH/server.crt" ]] && [[ -e "$WILDCARD_SSL_PATH/server.key" ]]; then
echo global
return 0
else
echo false
return 1
fi
}
get_ssl_hostnames() {
local APP=$1; verify_app_name $APP
case "$(is_ssl_enabled $APP)" in
app)
SSL_PATH="$DOKKU_ROOT/$APP/tls"
;;
global)
SSL_PATH="$DOKKU_ROOT/tls"
;;
esac
SSL_HOSTNAME=$(openssl x509 -in $SSL_PATH/server.crt -noout -subject | tr '/' '\n' | grep CN= | cut -c4-)
SSL_HOSTNAME_ALT=$(openssl x509 -in $SSL_PATH/server.crt -noout -text | grep --after-context=1 '509v3 Subject Alternative Name:' | tail -n 1 | sed -e "s/[[:space:]]*DNS://g" | tr ',' '\n' || true)
if [[ -n "$SSL_HOSTNAME_ALT" ]]; then
SSL_HOSTNAMES="${SSL_HOSTNAME}\n${SSL_HOSTNAME_ALT}"
else
SSL_HOSTNAMES=$SSL_HOSTNAME
fi
echo -e $SSL_HOSTNAMES
return 0
}

View File

@@ -2,6 +2,7 @@
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_PATH/common/functions"
source "$PLUGIN_PATH/config/functions"
source "$PLUGIN_PATH/domains/functions"
RE_IPV4="([0-9]{1,3}[\.]){3}[0-9]{1,3}"
@@ -32,7 +33,7 @@ case "$1" in
dokku domains:setup $APP
if [[ -f "$DOKKU_ROOT/$APP/VHOST" ]]; then
dokku_log_info2_quiet "$APP Domain Names"
cat "$DOKKU_ROOT/$APP/VHOST"
get_app_domains "$APP"
else
dokku_log_fail "No domain names set for $APP"
fi

8
plugins/domains/functions Executable file
View File

@@ -0,0 +1,8 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$(dirname $0)/../common/functions"
get_app_domains() {
local APP=$1; verify_app_name $APP
cat "$DOKKU_ROOT/$APP/VHOST"
}

View File

@@ -1,7 +1,9 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_PATH/common/functions"
source "$PLUGIN_PATH/certs/functions"
source "$PLUGIN_PATH/config/functions"
source "$PLUGIN_PATH/domains/functions"
validate_nginx () {
set +e
@@ -32,8 +34,8 @@ case "$1" in
verify_app_name "$APP"
VHOST_PATH="$DOKKU_ROOT/$APP/VHOST"
URLS_PATH="$DOKKU_ROOT/$APP/URLS"
WILDCARD_SSL="$DOKKU_ROOT/tls"
SSL="$DOKKU_ROOT/$APP/tls"
WILDCARD_SSL_PATH="$DOKKU_ROOT/tls"
APP_SSL_PATH="$DOKKU_ROOT/$APP/tls"
APP_NGINX_TEMPLATE="$DOKKU_ROOT/$APP/nginx.conf.template"
if [[ -z "$DOKKU_APP_LISTEN_PORT" ]] && [[ -z "$DOKKU_APP_LISTEN_IP" ]]; then
@@ -58,17 +60,34 @@ case "$1" in
[[ -f "$APP_NGINX_TEMPLATE" ]] && NGINX_TEMPLATE="$APP_NGINX_TEMPLATE" && NGINX_CUSTOM_TEMPLATE="true" && dokku_log_info1 'Overriding default nginx.conf with detected nginx.conf.template'
if [[ ! -n "$NO_VHOST" ]] && [[ -f "$DOKKU_ROOT/$APP/VHOST" ]]; then
NONSSL_VHOSTS=$(cat $VHOST_PATH)
if [[ -e "$SSL/server.crt" ]] && [[ -e "$SSL/server.key" ]]; then
SSL_INUSE="$SSL"
SSL_DIRECTIVES=$(cat <<EOF
ssl_certificate $SSL_INUSE/server.crt;
ssl_certificate_key $SSL_INUSE/server.key;
NONSSL_VHOSTS=$(get_app_domains $APP)
if [[ -n "$(is_ssl_enabled $APP)" ]];then
SSL_HOSTNAME=$(get_ssl_hostnames $APP)
[[ -n "$SSL_HOSTNAME" ]] && SSL_HOSTNAME_REGEX=$(echo "$SSL_HOSTNAME" | xargs | sed 's|\.|\\.|g' | sed 's/\*/\[^\.\]\*/g' | sed 's/ /|/g')
if (egrep -q "^${SSL_HOSTNAME_REGEX}$" $VHOST_PATH); then
SSL_INUSE=true
else
dokku_log_info1 "No matching configured domains for $APP found in SSL certificate. Your app will not be configured with an SSL endpoint"
dokku_log_info1 "Please add appropriate domains via the dokku domains command"
dokku_log_info1 "Configured domains for app:"
for domain in $(echo $NONSSL_VHOSTS| xargs); do
dokku_log_info2 "$domain"
done
dokku_log_info1 "Domains found in SSL certificate:"
for domain in $(echo $SSL_HOSTNAME | xargs); do
dokku_log_info2 "$domain"
done
fi
if [[ "$(is_ssl_enabled $APP)" == "app" ]]; then
SSL_DIRECTIVES=$(cat <<EOF
ssl_certificate $APP_SSL_PATH/server.crt;
ssl_certificate_key $APP_SSL_PATH/server.key;
EOF
)
elif [[ -e "$WILDCARD_SSL/server.crt" ]] && [[ -e "$WILDCARD_SSL/server.key" ]]; then
SSL_INUSE="$WILDCARD_SSL"
SSL_DIRECTIVES=""
elif [[ "$(is_ssl_enabled $APP)" == "global" ]]; then
SSL_DIRECTIVES=""
fi
fi
NGINX_CONF=$(mktemp -t "nginx.conf.XXXXXX")
@@ -77,20 +96,8 @@ EOF
SCHEME="https"
[[ -z "$NGINX_TEMPLATE" ]] && NGINX_TEMPLATE="$PLUGIN_PATH/nginx-vhosts/templates/nginx.ssl.conf.template"
SSL_HOSTNAME=$(openssl x509 -in $SSL_INUSE/server.crt -noout -subject | tr '/' '\n' | grep CN= | cut -c4-)
if [[ -n "$SSL_HOSTNAME" ]]; then
SSL_HOSTNAME_REGEX=$(echo "$SSL_HOSTNAME" | sed 's|\.|\\.|g' | sed 's/\*/\[^\.\]\*/g')
[[ -z "$(egrep "^${SSL_HOSTNAME_REGEX}$" $VHOST_PATH)" ]] && [[ ! "$SSL_HOSTNAME" =~ ^\*.* ]] && echo "$SSL_HOSTNAME" >> $VHOST_PATH
fi
SSL_HOSTNAME_ALT=$(openssl x509 -in $SSL_INUSE/server.crt -noout -text | grep --after-context=1 '509v3 Subject Alternative Name:' | tail -n 1 | sed -e "s/[[:space:]]*DNS://g" | tr ',' '\n' || true)
if [[ -n "$SSL_HOSTNAME_ALT" ]]; then
SSL_HOSTNAME_ALT_REGEX=$(echo "$SSL_HOSTNAME_ALT" | sed 's|\.|\\.|g' | sed 's/\*/\[^\.\]\*/g')
[[ -z "$(egrep "^${SSL_HOSTNAME_ALT_REGEX}$" $VHOST_PATH)" ]] && [[ ! "$SSL_HOSTNAME_ALT" =~ ^\*.* ]] && echo "$SSL_HOSTNAME_ALT" >> $VHOST_PATH
fi
SSL_VHOSTS=$(egrep "^${SSL_HOSTNAME_REGEX}$|^${SSL_HOSTNAME_ALT_REGEX}$" $VHOST_PATH || exit 0)
NONSSL_VHOSTS=$(egrep -v "^${SSL_HOSTNAME_REGEX}$|^${SSL_HOSTNAME_ALT_REGEX}$" $VHOST_PATH || exit 0)
SSL_VHOSTS=$(egrep "^${SSL_HOSTNAME_REGEX}$" $VHOST_PATH || true)
NONSSL_VHOSTS=$(egrep -v "^${SSL_HOSTNAME_REGEX}$" $VHOST_PATH || true)
while read line; do
[[ -z "$line" ]] && continue

View File

@@ -99,9 +99,9 @@ build_nginx_config() {
setup_test_tls
assert_urls "https://dokku.me"
build_nginx_config
assert_urls "https://node-js-app.dokku.me" "http://${TEST_APP}.dokku.me"
assert_urls "http://${TEST_APP}.dokku.me"
add_domain "test.dokku.me"
assert_urls "https://node-js-app.dokku.me" "http://${TEST_APP}.dokku.me" "http://test.dokku.me"
assert_urls "http://${TEST_APP}.dokku.me" "http://test.dokku.me"
}
@test "(core) urls (wildcard ssl)" {

View File

@@ -74,9 +74,9 @@ assert_error_log() {
}
@test "(nginx-vhosts) logging" {
deploy_app
assert_access_log ${TEST_APP}
assert_error_log ${TEST_APP}
deploy_app
assert_access_log ${TEST_APP}
assert_error_log ${TEST_APP}
}
@test "(nginx-vhosts) nginx:build-config (wildcard SSL)" {
@@ -109,21 +109,11 @@ assert_error_log() {
assert_output "0"
}
@test "(nginx-vhosts) nginx:build-config (with SSL CN mismatch)" {
setup_test_tls
deploy_app
assert_ssl_domain "node-js-app.dokku.me"
}
@test "(nginx-vhosts) nginx:build-config (with SSL CN mismatch & custom nginx template)" {
setup_test_tls
custom_ssl_nginx_template
deploy_app
assert_ssl_domain "node-js-app.dokku.me"
}
@test "(nginx-vhosts) nginx:build-config (with SSL and Multiple SANs)" {
setup_test_tls_with_sans
add_domain "test.dokku.me"
add_domain "www.test.dokku.me"
add_domain "www.test.app.dokku.me"
deploy_app
assert_ssl_domain "test.dokku.me"
assert_ssl_domain "www.test.dokku.me"