From ca3106c8205ebedf7306390b4a46deea9186b4d5 Mon Sep 17 00:00:00 2001 From: Valentin Lab Date: Fri, 3 Aug 2018 14:09:55 +0200 Subject: [PATCH] new: [apache] ssl plugin support, added letsencrypt ssl support. --- apache/lib/common | 117 ++++++++++++++++++++++++++++++++++------------ apache/test/vhost | 1 + 2 files changed, 89 insertions(+), 29 deletions(-) diff --git a/apache/lib/common b/apache/lib/common index 4c23791..1189237 100644 --- a/apache/lib/common +++ b/apache/lib/common @@ -32,9 +32,14 @@ export -f apache_publish_dir apache_vhost_create () { export APACHE_CONFIG_LOCATION="$SERVICE_CONFIGSTORE/etc/apache2/sites-enabled" + export SERVER_ALIAS=$(relation-get server-aliases 2>/dev/null) || true export PROTOCOLS=$(__vhost_cfg_normalize_protocol) || return 1 + export SSL_PLUGIN_FUN=$(ssl_get_plugin_fun) || return 1 + if is_protocol_enabled https; then + "$SSL_PLUGIN_FUN"_vars "$(relation-get ssl)" || return 1 + fi apache_vhost_statement "$PROTOCOLS" | file_put "$APACHE_CONFIG_LOCATION/$prefix$DOMAIN.conf" || return 1 @@ -43,9 +48,7 @@ apache_vhost_create () { apache_passwd_file || return 1 fi - if is_protocol_enabled https; then - apache_ssl_files - fi + "$SSL_PLUGIN_FUN"_prepare "$(relation-get ssl)" || return 1 } @@ -91,10 +94,55 @@ __vhost_cfg_normalize_protocol() { } -apache_ssl_files() { - local content - ## XXXvlab: called twice... no better way to do this ? - __vhost_ssl_statement > /dev/null +## ssl_plugin_* and ssl_fallback should : +## - do anything to ensure that +## - issue config-add to add volumes if necessary +## - output 3 vars of where to find the 3 files from within the docker apache + +ssl_get_plugin_fun() { + local cfg="$(relation-get ssl 2>/dev/null)" + if [[ "$(echo "$cfg" | shyaml get-type 2>/dev/null)" == "str" ]]; then + target_relation= + while read-0 relation_name target_service relation_config tech_dep; do + [ "$target_service" == "$cfg" ] || continue + verb "service ${DARKYELLOW}$target_service${NORMAL} matches" \ + "${WHITE}ssl${NORMAL} value: candidate relation is ${DARKBLUE}$relation_name${NORMAL}" + fun="ssl_plugin_${relation_name}" + if declare -F "${fun}_vars" >/dev/null 2>&1 && declare -F "${fun}_prepare" >/dev/null 2>&1; then + verb "Corresponding plugin ${DARKGREEN}found${NORMAL} for relation ${DARKBLUE}$relation_name${NORMAL}" + echo "$fun" + return 0 + else + verb "Corresponding plugin ${DARKRED}not found${NORMAL} for relation ${DARKBLUE}$relation_name${NORMAL}" + fi + done < <(get_compose_relations "$SERVICE_NAME") || return 1 + err "Invalid ${WHITE}ssl${NORMAL} value: '$cfg' is not a valid linked service through a support relation." + return 1 + else + echo ssl_fallback + fi +} + + +ssl_fallback_vars() { + local cfg="$1" cert key ca_cert + + if __vhost_cfg_ssl_cert=$(echo "$cfg" | shyaml get-value cert 2>/dev/null); then + __vhost_cfg_SSL_CERT_LOCATION=/etc/ssl/certs/${DOMAIN}.pem + fi + + if __vhost_cfg_ssl_key=$(echo "$cfg" | shyaml get-value key 2>/dev/null); then + __vhost_cfg_SSL_KEY_LOCATION=/etc/ssl/private/${DOMAIN}.key + fi + + if __vhost_cfg_ssl_ca_cert=$(echo "$cfg" | shyaml get-value ca-cert 2>/dev/null); then + __vhost_cfg_SSL_CA_CERT_LOCATION=/etc/ssl/certs/${DOMAIN}-ca.pem + fi +} + +ssl_fallback_prepare() { + local cfg="$1" cert key ca_cert + dst="$CONFIGSTORE/$BASE_CHARM_NAME" volumes="" for label in cert key ca_cert; do @@ -117,6 +165,31 @@ $volumes } +ssl_plugin_letsencrypt-dns_vars() { + + __vhost_cfg_SSL_CERT_LOCATION=/etc/letsencrypt/live/${DOMAIN}/cert.pem + __vhost_cfg_SSL_KEY_LOCATION=/etc/letsencrypt/live/${DOMAIN}/privkey.pem + __vhost_cfg_SSL_CHAIN=/etc/letsencrypt/live/${DOMAIN}/chain.pem +} + +ssl_plugin_letsencrypt-dns_prepare() { + local service="$1" letsencrypt_charm + shift + + export DEFAULT_COMPOSE_FILE="$COMPOSE_YML_FILE" + run_service_action "$service" add "$DOMAIN" $(echo "$SERVER_ALIAS" | shyaml get-values 2>/dev/null) || return 1 + letsencrypt_charm=$(get_service_charm "$service") || return 1 + + config-add "\ +services: + $MASTER_TARGET_CHARM_NAME: + volumes: + - $DATASTORE/${letsencrypt_charm}/etc/letsencrypt:/etc/letsencrypt:ro +" || return 1 + +} + + apache_passwd_file() { include parse || true @@ -142,12 +215,15 @@ apache_passwd_file() { ## Produce the full statements depending on relation-get informations apache_vhost_statement() { local vhost_statement + export SERVER_ALIAS=$(relation-get server-aliases 2>/dev/null) || true export PROTOCOLS="$1" if is_protocol_enabled http; then __vhost_full_vhost_statement http fi if is_protocol_enabled https; then + export SSL_PLUGIN_FUN=$(ssl_get_plugin_fun) || return 1 + "$SSL_PLUGIN_FUN"_vars "$(relation-get ssl 2>/dev/null)" cat < @@ -246,28 +322,11 @@ $MASTER_BASE_CHARM_NAME: __vhost_ssl_statement() { - local key cert ca_cert - __vhost_cfg_ssl="$(relation-get ssl 2>/dev/null)" - if __vhost_cfg_ssl_cert=$(echo "$__vhost_cfg_ssl" | shyaml get-value cert 2>/dev/null); then - __vhost_cfg_SSL_CERT_LOCATION=/etc/ssl/certs/${DOMAIN}.pem - fi + ## defaults - if __vhost_cfg_ssl_key=$(echo "$__vhost_cfg_ssl" | shyaml get-value key 2>/dev/null); then - __vhost_cfg_SSL_KEY_LOCATION=/etc/ssl/private/${DOMAIN}.key - fi - - if __vhost_cfg_ssl_ca_cert=$(echo "$__vhost_cfg_ssl" | shyaml get-value ca-cert 2>/dev/null); then - __vhost_cfg_SSL_CA_CERT_LOCATION=/etc/ssl/certs/${DOMAIN}-ca.pem - fi - - if [ -z "$__vhost_cfg_SSL_CERT_LOCATION" ]; then - __vhost_cfg_SSL_CERT_LOCATION=/etc/ssl/certs/ssl-cert-snakeoil.pem - fi - - if [ -z "$__vhost_cfg_SSL_KEY_LOCATION" ]; then - __vhost_cfg_SSL_KEY_LOCATION=/etc/ssl/private/ssl-cert-snakeoil.key - fi + __vhost_cfg_SSL_CERT_LOCATION=${__vhost_cfg_SSL_CERT_LOCATION:-/etc/ssl/certs/ssl-cert-snakeoil.pem} + __vhost_cfg_SSL_KEY_LOCATION=${__vhost_cfg_SSL_KEY_LOCATION:-/etc/ssl/private/ssl-cert-snakeoil.key} cat </dev/null); then echo "Allow from all" return 0 @@ -306,7 +366,6 @@ EOF __vhost_head_statement() { local protocol="$1" - SERVER_ALIAS=$(relation-get server-aliases 2>/dev/null) || true if [ "$protocol" == "https" ]; then prefix="s-" diff --git a/apache/test/vhost b/apache/test/vhost index 4086d36..35b1e8e 100644 --- a/apache/test/vhost +++ b/apache/test/vhost @@ -331,6 +331,7 @@ is out ' SSLCertificateFile /etc/ssl/certs/www.example.com.pem SSLCertificateKeyFile /etc/ssl/private/www.example.com.key SSLCACertificateFile /etc/ssl/certs/www.example.com-ca.pem + SSLVerifyClient None