|
@ -36,6 +36,19 @@ |
|
|
# Note: This functionality requires HAProxy was compiled against |
|
|
# Note: This functionality requires HAProxy was compiled against |
|
|
# a version of OpenSSL that supports this. |
|
|
# a version of OpenSSL that supports this. |
|
|
# |
|
|
# |
|
|
|
|
|
# export DEPLOY_HAPROXY_HOT_UPDATE="yes" |
|
|
|
|
|
# export DEPLOY_HAPROXY_STATS_SOCKET="UNIX:/run/haproxy/admin.sock" |
|
|
|
|
|
# |
|
|
|
|
|
# OPTIONAL: Deploy the certificate over the HAProxy stats socket without |
|
|
|
|
|
# needing to reload HAProxy. Default is "no". |
|
|
|
|
|
# |
|
|
|
|
|
# Require the socat binary. DEPLOY_HAPROXY_STATS_SOCKET variable uses the socat |
|
|
|
|
|
# address format. |
|
|
|
|
|
# |
|
|
|
|
|
# export DEPLOY_HAPROXY_MASTER_CLI="UNIX:/run/haproxy-master.sock" |
|
|
|
|
|
# |
|
|
|
|
|
# OPTIONAL: To use the master CLI with DEPLOY_HAPROXY_HOT_UPDATE="yes" instead |
|
|
|
|
|
# of a stats socket, use this variable. |
|
|
|
|
|
|
|
|
######## Public functions ##################### |
|
|
######## Public functions ##################### |
|
|
|
|
|
|
|
@ -46,6 +59,7 @@ haproxy_deploy() { |
|
|
_ccert="$3" |
|
|
_ccert="$3" |
|
|
_cca="$4" |
|
|
_cca="$4" |
|
|
_cfullchain="$5" |
|
|
_cfullchain="$5" |
|
|
|
|
|
_cmdpfx="" |
|
|
|
|
|
|
|
|
# Some defaults |
|
|
# Some defaults |
|
|
DEPLOY_HAPROXY_PEM_PATH_DEFAULT="/etc/haproxy" |
|
|
DEPLOY_HAPROXY_PEM_PATH_DEFAULT="/etc/haproxy" |
|
@ -53,6 +67,8 @@ haproxy_deploy() { |
|
|
DEPLOY_HAPROXY_BUNDLE_DEFAULT="no" |
|
|
DEPLOY_HAPROXY_BUNDLE_DEFAULT="no" |
|
|
DEPLOY_HAPROXY_ISSUER_DEFAULT="no" |
|
|
DEPLOY_HAPROXY_ISSUER_DEFAULT="no" |
|
|
DEPLOY_HAPROXY_RELOAD_DEFAULT="true" |
|
|
DEPLOY_HAPROXY_RELOAD_DEFAULT="true" |
|
|
|
|
|
DEPLOY_HAPROXY_HOT_UPDATE_DEFAULT="no" |
|
|
|
|
|
DEPLOY_HAPROXY_STATS_SOCKET_DEFAULT="UNIX:/run/haproxy/admin.sock" |
|
|
|
|
|
|
|
|
_debug _cdomain "${_cdomain}" |
|
|
_debug _cdomain "${_cdomain}" |
|
|
_debug _ckey "${_ckey}" |
|
|
_debug _ckey "${_ckey}" |
|
@ -86,6 +102,11 @@ haproxy_deploy() { |
|
|
_savedomainconf Le_Deploy_haproxy_pem_name "${Le_Deploy_haproxy_pem_name}" |
|
|
_savedomainconf Le_Deploy_haproxy_pem_name "${Le_Deploy_haproxy_pem_name}" |
|
|
elif [ -z "${Le_Deploy_haproxy_pem_name}" ]; then |
|
|
elif [ -z "${Le_Deploy_haproxy_pem_name}" ]; then |
|
|
Le_Deploy_haproxy_pem_name="${DEPLOY_HAPROXY_PEM_NAME_DEFAULT}" |
|
|
Le_Deploy_haproxy_pem_name="${DEPLOY_HAPROXY_PEM_NAME_DEFAULT}" |
|
|
|
|
|
# We better not have '*' as the first character |
|
|
|
|
|
if [ "${Le_Deploy_haproxy_pem_name%%"${Le_Deploy_haproxy_pem_name#?}"}" = '*' ]; then |
|
|
|
|
|
# removes the first characters and add a _ instead |
|
|
|
|
|
Le_Deploy_haproxy_pem_name="_${Le_Deploy_haproxy_pem_name#?}" |
|
|
|
|
|
fi |
|
|
fi |
|
|
fi |
|
|
|
|
|
|
|
|
# BUNDLE is optional. If not provided then assume "${DEPLOY_HAPROXY_BUNDLE_DEFAULT}" |
|
|
# BUNDLE is optional. If not provided then assume "${DEPLOY_HAPROXY_BUNDLE_DEFAULT}" |
|
@ -118,6 +139,36 @@ haproxy_deploy() { |
|
|
Le_Deploy_haproxy_reload="${DEPLOY_HAPROXY_RELOAD_DEFAULT}" |
|
|
Le_Deploy_haproxy_reload="${DEPLOY_HAPROXY_RELOAD_DEFAULT}" |
|
|
fi |
|
|
fi |
|
|
|
|
|
|
|
|
|
|
|
# HOT_UPDATE is optional. If not provided then assume "${DEPLOY_HAPROXY_HOT_UPDATE_DEFAULT}" |
|
|
|
|
|
_getdeployconf DEPLOY_HAPROXY_HOT_UPDATE |
|
|
|
|
|
_debug2 DEPLOY_HAPROXY_HOT_UPDATE "${DEPLOY_HAPROXY_HOT_UPDATE}" |
|
|
|
|
|
if [ -n "${DEPLOY_HAPROXY_HOT_UPDATE}" ]; then |
|
|
|
|
|
Le_Deploy_haproxy_hot_update="${DEPLOY_HAPROXY_HOT_UPDATE}" |
|
|
|
|
|
_savedomainconf Le_Deploy_haproxy_hot_update "${Le_Deploy_haproxy_hot_update}" |
|
|
|
|
|
elif [ -z "${Le_Deploy_haproxy_hot_update}" ]; then |
|
|
|
|
|
Le_Deploy_haproxy_hot_update="${DEPLOY_HAPROXY_HOT_UPDATE_DEFAULT}" |
|
|
|
|
|
fi |
|
|
|
|
|
|
|
|
|
|
|
# STATS_SOCKET is optional. If not provided then assume "${DEPLOY_HAPROXY_STATS_SOCKET_DEFAULT}" |
|
|
|
|
|
_getdeployconf DEPLOY_HAPROXY_STATS_SOCKET |
|
|
|
|
|
_debug2 DEPLOY_HAPROXY_STATS_SOCKET "${DEPLOY_HAPROXY_STATS_SOCKET}" |
|
|
|
|
|
if [ -n "${DEPLOY_HAPROXY_STATS_SOCKET}" ]; then |
|
|
|
|
|
Le_Deploy_haproxy_stats_socket="${DEPLOY_HAPROXY_STATS_SOCKET}" |
|
|
|
|
|
_savedomainconf Le_Deploy_haproxy_stats_socket "${Le_Deploy_haproxy_stats_socket}" |
|
|
|
|
|
elif [ -z "${Le_Deploy_haproxy_stats_socket}" ]; then |
|
|
|
|
|
Le_Deploy_haproxy_stats_socket="${DEPLOY_HAPROXY_STATS_SOCKET_DEFAULT}" |
|
|
|
|
|
fi |
|
|
|
|
|
|
|
|
|
|
|
# MASTER_CLI is optional. No defaults are used. When the master CLI is used, |
|
|
|
|
|
# all commands are sent with a prefix. |
|
|
|
|
|
_getdeployconf DEPLOY_HAPROXY_MASTER_CLI |
|
|
|
|
|
_debug2 DEPLOY_HAPROXY_MASTER_CLI "${DEPLOY_HAPROXY_MASTER_CLI}" |
|
|
|
|
|
if [ -n "${DEPLOY_HAPROXY_MASTER_CLI}" ]; then |
|
|
|
|
|
Le_Deploy_haproxy_stats_socket="${DEPLOY_HAPROXY_MASTER_CLI}" |
|
|
|
|
|
_savedomainconf Le_Deploy_haproxy_stats_socket "${Le_Deploy_haproxy_stats_socket}" |
|
|
|
|
|
_cmdpfx="@1 " # command prefix used for master CLI only. |
|
|
|
|
|
fi |
|
|
|
|
|
|
|
|
# Set the suffix depending if we are creating a bundle or not |
|
|
# Set the suffix depending if we are creating a bundle or not |
|
|
if [ "${Le_Deploy_haproxy_bundle}" = "yes" ]; then |
|
|
if [ "${Le_Deploy_haproxy_bundle}" = "yes" ]; then |
|
|
_info "Bundle creation requested" |
|
|
_info "Bundle creation requested" |
|
@ -142,12 +193,13 @@ haproxy_deploy() { |
|
|
_issuer="${_pem}.issuer" |
|
|
_issuer="${_pem}.issuer" |
|
|
_ocsp="${_pem}.ocsp" |
|
|
_ocsp="${_pem}.ocsp" |
|
|
_reload="${Le_Deploy_haproxy_reload}" |
|
|
_reload="${Le_Deploy_haproxy_reload}" |
|
|
|
|
|
_statssock="${Le_Deploy_haproxy_stats_socket}" |
|
|
|
|
|
|
|
|
_info "Deploying PEM file" |
|
|
_info "Deploying PEM file" |
|
|
# Create a temporary PEM file |
|
|
# Create a temporary PEM file |
|
|
_temppem="$(_mktemp)" |
|
|
_temppem="$(_mktemp)" |
|
|
_debug _temppem "${_temppem}" |
|
|
_debug _temppem "${_temppem}" |
|
|
cat "${_ccert}" "${_cca}" "${_ckey}" >"${_temppem}" |
|
|
|
|
|
|
|
|
cat "${_ccert}" "${_cca}" "${_ckey}" | grep . >"${_temppem}" |
|
|
_ret="$?" |
|
|
_ret="$?" |
|
|
|
|
|
|
|
|
# Check that we could create the temporary file |
|
|
# Check that we could create the temporary file |
|
@ -265,6 +317,76 @@ haproxy_deploy() { |
|
|
fi |
|
|
fi |
|
|
fi |
|
|
fi |
|
|
|
|
|
|
|
|
|
|
|
if [ "${Le_Deploy_haproxy_hot_update}" = "yes" ]; then |
|
|
|
|
|
# set the socket name for messages |
|
|
|
|
|
if [ -n "${_cmdpfx}" ]; then |
|
|
|
|
|
_socketname="master CLI" |
|
|
|
|
|
else |
|
|
|
|
|
_socketname="stats socket" |
|
|
|
|
|
fi |
|
|
|
|
|
|
|
|
|
|
|
# Update certificate over HAProxy stats socket or master CLI. |
|
|
|
|
|
if _exists socat; then |
|
|
|
|
|
# look for the certificate on the stats socket, to chose between updating or creating one |
|
|
|
|
|
_socat_cert_cmd="echo '${_cmdpfx}show ssl cert' | socat '${_statssock}' - | grep -q '^${_pem}$'" |
|
|
|
|
|
_debug _socat_cert_cmd "${_socat_cert_cmd}" |
|
|
|
|
|
eval "${_socat_cert_cmd}" |
|
|
|
|
|
_ret=$? |
|
|
|
|
|
if [ "${_ret}" != "0" ]; then |
|
|
|
|
|
_newcert="1" |
|
|
|
|
|
_info "Creating new certificate '${_pem}' over HAProxy ${_socketname}." |
|
|
|
|
|
# certificate wasn't found, it's a new one. We should check if the crt-list exists and creates/inserts the certificate. |
|
|
|
|
|
_socat_crtlist_show_cmd="echo '${_cmdpfx}show ssl crt-list' | socat '${_statssock}' - | grep -q '^${Le_Deploy_haproxy_pem_path}$'" |
|
|
|
|
|
_debug _socat_crtlist_show_cmd "${_socat_crtlist_show_cmd}" |
|
|
|
|
|
eval "${_socat_crtlist_show_cmd}" |
|
|
|
|
|
_ret=$? |
|
|
|
|
|
if [ "${_ret}" != "0" ]; then |
|
|
|
|
|
_err "Couldn't find '${Le_Deploy_haproxy_pem_path}' in haproxy 'show ssl crt-list'" |
|
|
|
|
|
return "${_ret}" |
|
|
|
|
|
fi |
|
|
|
|
|
# create a new certificate |
|
|
|
|
|
_socat_new_cmd="echo '${_cmdpfx}new ssl cert ${_pem}' | socat '${_statssock}' - | grep -q 'New empty'" |
|
|
|
|
|
_debug _socat_new_cmd "${_socat_new_cmd}" |
|
|
|
|
|
eval "${_socat_new_cmd}" |
|
|
|
|
|
_ret=$? |
|
|
|
|
|
if [ "${_ret}" != "0" ]; then |
|
|
|
|
|
_err "Couldn't create '${_pem}' in haproxy" |
|
|
|
|
|
return "${_ret}" |
|
|
|
|
|
fi |
|
|
|
|
|
else |
|
|
|
|
|
_info "Update existing certificate '${_pem}' over HAProxy ${_socketname}." |
|
|
|
|
|
fi |
|
|
|
|
|
_socat_cert_set_cmd="echo -e '${_cmdpfx}set ssl cert ${_pem} <<\n$(cat "${_pem}")\n' | socat '${_statssock}' - | grep -q 'Transaction created'" |
|
|
|
|
|
_debug _socat_cert_set_cmd "${_socat_cert_set_cmd}" |
|
|
|
|
|
eval "${_socat_cert_set_cmd}" |
|
|
|
|
|
_ret=$? |
|
|
|
|
|
if [ "${_ret}" != "0" ]; then |
|
|
|
|
|
_err "Can't update '${_pem}' in haproxy" |
|
|
|
|
|
return "${_ret}" |
|
|
|
|
|
fi |
|
|
|
|
|
_socat_cert_commit_cmd="echo '${_cmdpfx}commit ssl cert ${_pem}' | socat '${_statssock}' - | grep -q '^Success!$'" |
|
|
|
|
|
_debug _socat_cert_commit_cmd "${_socat_cert_commit_cmd}" |
|
|
|
|
|
eval "${_socat_cert_commit_cmd}" |
|
|
|
|
|
_ret=$? |
|
|
|
|
|
if [ "${_ret}" != "0" ]; then |
|
|
|
|
|
_err "Can't commit '${_pem}' in haproxy" |
|
|
|
|
|
return ${_ret} |
|
|
|
|
|
fi |
|
|
|
|
|
if [ "${_newcert}" = "1" ]; then |
|
|
|
|
|
# if this is a new certificate, it needs to be inserted into the crt-list` |
|
|
|
|
|
_socat_cert_add_cmd="echo '${_cmdpfx}add ssl crt-list ${Le_Deploy_haproxy_pem_path} ${_pem}' | socat '${_statssock}' - | grep -q 'Success!'" |
|
|
|
|
|
_debug _socat_cert_add_cmd "${_socat_cert_add_cmd}" |
|
|
|
|
|
eval "${_socat_cert_add_cmd}" |
|
|
|
|
|
_ret=$? |
|
|
|
|
|
if [ "${_ret}" != "0" ]; then |
|
|
|
|
|
_err "Can't update '${_pem}' in haproxy" |
|
|
|
|
|
return "${_ret}" |
|
|
|
|
|
fi |
|
|
|
|
|
fi |
|
|
|
|
|
else |
|
|
|
|
|
_err "'socat' is not available, couldn't update over ${_socketname}" |
|
|
|
|
|
fi |
|
|
|
|
|
else |
|
|
# Reload HAProxy |
|
|
# Reload HAProxy |
|
|
_debug _reload "${_reload}" |
|
|
_debug _reload "${_reload}" |
|
|
eval "${_reload}" |
|
|
eval "${_reload}" |
|
@ -275,6 +397,7 @@ haproxy_deploy() { |
|
|
else |
|
|
else |
|
|
_info "Reload successful" |
|
|
_info "Reload successful" |
|
|
fi |
|
|
fi |
|
|
|
|
|
fi |
|
|
|
|
|
|
|
|
return 0 |
|
|
return 0 |
|
|
} |
|
|
} |