|
|
# -*- mode: shell-script -*-
ssl_get_plugin_fun() { local cfg="$1"
type="$(echo "$cfg" | shyaml -y get-type 2>/dev/null)" || return 1 case "$type" in bool) err "Option ${WHITE}ssl${NORMAL} value '$cfg' is not supported." return 1 ;; str) keys=("$cfg") ;; struct) keys=( $(echo "$cfg" | shyaml keys 2>/dev/null) ) ;; *) err "Invalid ${WHITE}ssl${NORMAL} value type '$type': please provide a string or a struct." return 1 ;; esac
for key in "${keys[@]}"; do target_relation="cert-provider" fun="ssl_plugin_${target_relation}" while read-0 relation_name target_service relation_config tech_dep; do [ "$relation_name" == "${target_relation}" ] || continue [ "$target_service" == "$key" ] || continue verb "Corresponding plugin ${DARKGREEN}found${NORMAL}" \ "in ${DARKBLUE}$relation_name${NORMAL}/${DARKYELLOW}$key${NORMAL}" ssl_cfg=$(printf "%s" "$cfg" | shyaml get-value "$key" 2>/dev/null) || true merged_config=$(merge_yaml_str "$relation_config" "$ssl_cfg") || return 1 printf "%s\0" "$fun" "$key" "$merged_config" return 0 done < <(get_service_relations "$SERVICE_NAME") || return 1 case "$key" in cert|ca-cert|key) : ;; *) err "Invalid key '$key' in ${WHITE}ssl${NORMAL}:" \ "no corresponding services declared in ${DARKBLUE}${target_relation}$NORMAL" return 1 ;; esac done }
ssl_fallback_vars() { local cfg="$1" DOMAIN="$2" cert key ca_cert
base_dir=/etc/ssl print "%s\0" \ "$base_dir"/certs/"${DOMAIN}".pem \ "$base_dir"/private/"${DOMAIN}".key \ "$base_dir"/certs/"${DOMAIN}"-ca.pem
print "%s\0" "$base_dir"/cert.pem "$base_dir"/privkey.pem "$base_dir"/chain.pem }
ssl_fallback_prepare() { local cfg="$1" service="$2" l_cert l_key l_ca_cert
shift 2 read-0 l_cert l_key l_ca_cert < <(ssl_fallback_vars "$cfg" "$@")
dst="$CONFIGSTORE/$BASE_SERVICE_NAME" volumes="" for label in cert key ca-cert; do if content=$(echo "$cfg" | shyaml get-value "$label" 2>/dev/null); then location="$(eval echo "\$l_${label//-/_}")" echo "$content" | file_put "$dst$location" config_hash=$(printf "%s\0" "$config_hash" "$label" "$content" | md5_compat) volumes="$volumes - $dst$location:$location:ro" fi done
if [ "$volumes" ]; then init-config-add "\ $MASTER_TARGET_SERVICE_NAME: volumes: $volumes " fi
}
ssl_plugin_cert-provider_vars() { local cfg="$1" DOMAIN="$2"
base_dir="/etc/letsencrypt/live/$DOMAIN"
print "%s\0" "$base_dir"/cert.pem "$base_dir"/privkey.pem "$base_dir"/chain.pem }
ssl_plugin_cert-provider_prepare() { local cfg="$1" service="$2" options shift 2
options=$(yaml_key_val_str "options" "$cfg") || return 1 service_config=$(yaml_key_val_str "$service" "$options") compose --debug --add-compose-content "$service_config" run --rm --service-ports "$service" \ crt create "$@" || { err "Failed to launch letsencrypt for certificate creation." return 1 } init-config-add "\ $MASTER_TARGET_SERVICE_NAME: volumes: - $DATASTORE/$service/etc/letsencrypt:/etc/letsencrypt:ro " || return 1 }
make_pasv_options() { local pasv="$1" if [[ "${pasv,,}" =~ ^(false|no|n|0|disable|disabled)$ ]]; then echo "pasv_enable=no" return 0 fi
ports="$(printf "%s" "$pasv" | shyaml get-value -q "ports")" if [ "$ports" ]; then if [[ "$ports" =~ ^[0-9]+-[0-9]+$ ]]; then port_min=${ports##*-} port_max=${ports%%-*} if [ "$port_min" -gt "$port_max" ]; then die "Invalid value for ${WHITE}ports${NORMAL}: first port in range has to be lesser than second." fi else die "Invalid value for ${WHITE}ports${NORMAL}: please specify a port range (ie: '123-345')." fi fi
port_min=${port_min:-21100} port_max=${port_max:-21110}
host_address="$(printf "%s" "$pasv" | shyaml get-value -q "address")" if [ -z "$host_address" ]; then if [[ "$SERVICE_NAME" =~ ^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$ ]]; then host_address="$SERVICE_NAME" fi fi
if [ -z "$host_address" ]; then echo "## Could not find appropriate host return address" echo "pasv_enable=no" return 0 fi
if ! str_is_ipv4 "$host_address"; then host_address="$(get_ip_from_hostname "$host_address")" || { err "Can't resolve given hostname '$host_address'" return 1 } else err "You should NOT provide a direct IP for ${WHITE}pasv.address${NORMAL}," \ "try a resolvable address." return 1 fi cat <<EOF pasv_address=$host_address pasv_enable=yes pasv_min_port=$port_min pasv_max_port=$port_max EOF
init-config-add " $SERVICE_NAME: ports: - \"$port_min-$port_max:$port_min-$port_max\" "
}
make_ssl_options() { local ssl="$1" if [ -z "$ssl" ]; then target_relation="cert-provider" ssl=no while read-0 rn ts rc td; do [ "$rn" == "${target_relation}" ] || continue info "A ${DARKBLUE}$target_relation${NORMAL} ${DARKYELLOW}$ts${NORMAL} declared as 'ssl' value" ssl="$ts" break done < <(get_service_relations "$SERVICE_NAME") fi if [[ "${ssl,,}" =~ false|no|n|0|disable|disabled ]]; then echo "ssl_enable=no" return 0 fi
cat <<EOF ## ## SSL conf ##
ssl_enable=yes ssl_tlsv1=yes ssl_sslv2=no ssl_sslv3=no ssl_ciphers=HIGH implicit_ssl=no
EOF read-0 SSL_PLUGIN_FUN SSL_CFG_VALUE SSL_CFG_OPTIONS < <(ssl_get_plugin_fun "$ssl") || return 1 read-0 cert key ca_cert < <("$SSL_PLUGIN_FUN"_vars "$SSL_CFG_OPTIONS" "$SSL_CFG_VALUE") || return 1 "$SSL_PLUGIN_FUN"_prepare "$SSL_CFG_OPTIONS" "$SSL_CFG_VALUE" || return 1
cat <<EOF
rsa_cert_file=$cert rsa_private_key_file=$key ca_certs_file=$ca_cert
EOF
}
make_build_script() { local users_def="$1" allow_writeable_chroot="$2"
if [ -z "$users_def" ]; then return 0 fi
fixed_groups_code="" groups_code=""
declare -A created_groups while read-0 user user_def; do first_group= groups=() first=1 while read-0 group; do [ "${created_groups[$group]}" ] && continue if [[ "$group" == *":"* ]]; then gid=${group##*:} group=${group%%:*} fixed_groups_code+="addgroup -g \"$gid\" \"$group\""$'\n' else groups_code+="addgroup \"$group\""$'\n' fi created_groups[$group]=1 echo "X" >&2 if [ "$first" ]; then first_group="$group" first= else remaining_groups+=("$group") fi groups+=("$group") done < <(echo "$user_def" | shyaml get-values-0 groups 2>/dev/null) password=$(echo "$user_def" | shyaml get-value password 2>/dev/null) || password=$(gen_password 14) uid=$(echo "$user_def" | shyaml get-value uid 2>/dev/null)
useradd_options=( "-D" ## don't assign a password "-s" "/bin/false" ## default shell ) if [ "$uid" ]; then useradd_options+=("-u" "$uid") ## force uid fi if [ "$first_group" ]; then useradd_options+=("-G" "$first_group") ## force main group fi
code+="adduser ${useradd_options[*]} \"$user\""$'\n' code+="mkdir -p \"/home/$user\""$'\n' if [ "$allow_writeable_chroot" ]; then code+="chown $user \"/home/$user\""$'\n' ## sanitize else code+="chown root:root \"/home/$user\""$'\n' ## sanitize fi code+="chmod 755 \"/home/$user\""$'\n' ## sanitize code+="echo '$user:$password' | chpasswd"$'\n' for group in "${remaining_groups[@]}"; do code+="adduser \"$user\" \"$group\""$'\n' done done < <(echo "$users_def" | shyaml key-values-0) echo -n "$fixed_groups_code" echo -n "$groups_code" echo -n "$code" }
|