diff --git a/plugins/certs/commands b/plugins/certs/commands new file mode 100755 index 000000000..a9918b038 --- /dev/null +++ b/plugins/certs/commands @@ -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< CRT KEY, Add an ssl endpoint to an app. + certs:generate DOMAIN, Generate a key and certificate signing request (or self-signed certificate) + certs:info , Show certificate information for an ssl endpoint. + certs:key CRT KEY [KEY ...], Print the correct key for the given certificate. + certs:remove , Remove an SSL Endpoint from an app. + certs:update CRT KEY, Update an SSL Endpoint on an app. +EOF + ;; + + *) + exit $DOKKU_NOT_IMPLEMENTED_EXIT + ;; + +esac diff --git a/plugins/certs/functions b/plugins/certs/functions new file mode 100755 index 000000000..0f6dbd05c --- /dev/null +++ b/plugins/certs/functions @@ -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 +} diff --git a/plugins/domains/commands b/plugins/domains/commands index 73acd648e..399ff15d4 100755 --- a/plugins/domains/commands +++ b/plugins/domains/commands @@ -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 diff --git a/plugins/domains/functions b/plugins/domains/functions new file mode 100755 index 000000000..f79e889ee --- /dev/null +++ b/plugins/domains/functions @@ -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" +} diff --git a/plugins/nginx-vhosts/commands b/plugins/nginx-vhosts/commands index d2f400402..67838480b 100755 --- a/plugins/nginx-vhosts/commands +++ b/plugins/nginx-vhosts/commands @@ -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 <> $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 diff --git a/tests/unit/core.bats b/tests/unit/core.bats index 99c545a99..0d2641f27 100644 --- a/tests/unit/core.bats +++ b/tests/unit/core.bats @@ -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)" { diff --git a/tests/unit/nginx-vhosts.bats b/tests/unit/nginx-vhosts.bats index d08e7701c..fe2cf114a 100644 --- a/tests/unit/nginx-vhosts.bats +++ b/tests/unit/nginx-vhosts.bats @@ -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"