Skip to content

Commit ebaa39b

Browse files
authored
Merge pull request #5075 from acmesh-official/dev
sync
2 parents 6e14a07 + fa3d7ad commit ebaa39b

File tree

6 files changed

+282
-26
lines changed

6 files changed

+282
-26
lines changed

acme.sh

+12-7
Original file line numberDiff line numberDiff line change
@@ -2396,13 +2396,18 @@ _migratedomainconf() {
23962396
_old_key="$1"
23972397
_new_key="$2"
23982398
_b64encode="$3"
2399-
_value=$(_readdomainconf "$_old_key")
2400-
if [ -z "$_value" ]; then
2401-
return 1 # oldkey is not found
2402-
fi
2403-
_savedomainconf "$_new_key" "$_value" "$_b64encode"
2399+
_old_value=$(_readdomainconf "$_old_key")
24042400
_cleardomainconf "$_old_key"
2405-
_debug "Domain config $_old_key has been migrated to $_new_key"
2401+
if [ -z "$_old_value" ]; then
2402+
return 1 # migrated failed: old value is empty
2403+
fi
2404+
_new_value=$(_readdomainconf "$_new_key")
2405+
if [ -n "$_new_value" ]; then
2406+
_debug "Domain config new key exists, old key $_old_key='$_old_value' has been removed."
2407+
return 1 # migrated failed: old value replaced by new value
2408+
fi
2409+
_savedomainconf "$_new_key" "$_old_value" "$_b64encode"
2410+
_debug "Domain config $_old_key has been migrated to $_new_key."
24062411
}
24072412

24082413
#_migratedeployconf oldkey newkey base64encode
@@ -3768,7 +3773,7 @@ _regAccount() {
37683773
eab_sign_t="$eab_protected64.$eab_payload64"
37693774
_debug3 eab_sign_t "$eab_sign_t"
37703775

3771-
key_hex="$(_durl_replace_base64 "$_eab_hmac_key" | _dbase64 multi | _hex_dump | tr -d ' ')"
3776+
key_hex="$(_durl_replace_base64 "$_eab_hmac_key" | _dbase64 | _hex_dump | tr -d ' ')"
37723777
_debug3 key_hex "$key_hex"
37733778

37743779
eab_signature=$(printf "%s" "$eab_sign_t" | _hmac sha256 $key_hex | _base64 | _url_replace)

deploy/haproxy.sh

+132-9
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,19 @@
3636
# Note: This functionality requires HAProxy was compiled against
3737
# a version of OpenSSL that supports this.
3838
#
39+
# export DEPLOY_HAPROXY_HOT_UPDATE="yes"
40+
# export DEPLOY_HAPROXY_STATS_SOCKET="UNIX:/run/haproxy/admin.sock"
41+
#
42+
# OPTIONAL: Deploy the certificate over the HAProxy stats socket without
43+
# needing to reload HAProxy. Default is "no".
44+
#
45+
# Require the socat binary. DEPLOY_HAPROXY_STATS_SOCKET variable uses the socat
46+
# address format.
47+
#
48+
# export DEPLOY_HAPROXY_MASTER_CLI="UNIX:/run/haproxy-master.sock"
49+
#
50+
# OPTIONAL: To use the master CLI with DEPLOY_HAPROXY_HOT_UPDATE="yes" instead
51+
# of a stats socket, use this variable.
3952

4053
######## Public functions #####################
4154

@@ -46,13 +59,16 @@ haproxy_deploy() {
4659
_ccert="$3"
4760
_cca="$4"
4861
_cfullchain="$5"
62+
_cmdpfx=""
4963

5064
# Some defaults
5165
DEPLOY_HAPROXY_PEM_PATH_DEFAULT="/etc/haproxy"
5266
DEPLOY_HAPROXY_PEM_NAME_DEFAULT="${_cdomain}.pem"
5367
DEPLOY_HAPROXY_BUNDLE_DEFAULT="no"
5468
DEPLOY_HAPROXY_ISSUER_DEFAULT="no"
5569
DEPLOY_HAPROXY_RELOAD_DEFAULT="true"
70+
DEPLOY_HAPROXY_HOT_UPDATE_DEFAULT="no"
71+
DEPLOY_HAPROXY_STATS_SOCKET_DEFAULT="UNIX:/run/haproxy/admin.sock"
5672

5773
_debug _cdomain "${_cdomain}"
5874
_debug _ckey "${_ckey}"
@@ -86,6 +102,11 @@ haproxy_deploy() {
86102
_savedomainconf Le_Deploy_haproxy_pem_name "${Le_Deploy_haproxy_pem_name}"
87103
elif [ -z "${Le_Deploy_haproxy_pem_name}" ]; then
88104
Le_Deploy_haproxy_pem_name="${DEPLOY_HAPROXY_PEM_NAME_DEFAULT}"
105+
# We better not have '*' as the first character
106+
if [ "${Le_Deploy_haproxy_pem_name%%"${Le_Deploy_haproxy_pem_name#?}"}" = '*' ]; then
107+
# removes the first characters and add a _ instead
108+
Le_Deploy_haproxy_pem_name="_${Le_Deploy_haproxy_pem_name#?}"
109+
fi
89110
fi
90111

91112
# BUNDLE is optional. If not provided then assume "${DEPLOY_HAPROXY_BUNDLE_DEFAULT}"
@@ -118,6 +139,36 @@ haproxy_deploy() {
118139
Le_Deploy_haproxy_reload="${DEPLOY_HAPROXY_RELOAD_DEFAULT}"
119140
fi
120141

142+
# HOT_UPDATE is optional. If not provided then assume "${DEPLOY_HAPROXY_HOT_UPDATE_DEFAULT}"
143+
_getdeployconf DEPLOY_HAPROXY_HOT_UPDATE
144+
_debug2 DEPLOY_HAPROXY_HOT_UPDATE "${DEPLOY_HAPROXY_HOT_UPDATE}"
145+
if [ -n "${DEPLOY_HAPROXY_HOT_UPDATE}" ]; then
146+
Le_Deploy_haproxy_hot_update="${DEPLOY_HAPROXY_HOT_UPDATE}"
147+
_savedomainconf Le_Deploy_haproxy_hot_update "${Le_Deploy_haproxy_hot_update}"
148+
elif [ -z "${Le_Deploy_haproxy_hot_update}" ]; then
149+
Le_Deploy_haproxy_hot_update="${DEPLOY_HAPROXY_HOT_UPDATE_DEFAULT}"
150+
fi
151+
152+
# STATS_SOCKET is optional. If not provided then assume "${DEPLOY_HAPROXY_STATS_SOCKET_DEFAULT}"
153+
_getdeployconf DEPLOY_HAPROXY_STATS_SOCKET
154+
_debug2 DEPLOY_HAPROXY_STATS_SOCKET "${DEPLOY_HAPROXY_STATS_SOCKET}"
155+
if [ -n "${DEPLOY_HAPROXY_STATS_SOCKET}" ]; then
156+
Le_Deploy_haproxy_stats_socket="${DEPLOY_HAPROXY_STATS_SOCKET}"
157+
_savedomainconf Le_Deploy_haproxy_stats_socket "${Le_Deploy_haproxy_stats_socket}"
158+
elif [ -z "${Le_Deploy_haproxy_stats_socket}" ]; then
159+
Le_Deploy_haproxy_stats_socket="${DEPLOY_HAPROXY_STATS_SOCKET_DEFAULT}"
160+
fi
161+
162+
# MASTER_CLI is optional. No defaults are used. When the master CLI is used,
163+
# all commands are sent with a prefix.
164+
_getdeployconf DEPLOY_HAPROXY_MASTER_CLI
165+
_debug2 DEPLOY_HAPROXY_MASTER_CLI "${DEPLOY_HAPROXY_MASTER_CLI}"
166+
if [ -n "${DEPLOY_HAPROXY_MASTER_CLI}" ]; then
167+
Le_Deploy_haproxy_stats_socket="${DEPLOY_HAPROXY_MASTER_CLI}"
168+
_savedomainconf Le_Deploy_haproxy_stats_socket "${Le_Deploy_haproxy_stats_socket}"
169+
_cmdpfx="@1 " # command prefix used for master CLI only.
170+
fi
171+
121172
# Set the suffix depending if we are creating a bundle or not
122173
if [ "${Le_Deploy_haproxy_bundle}" = "yes" ]; then
123174
_info "Bundle creation requested"
@@ -142,12 +193,13 @@ haproxy_deploy() {
142193
_issuer="${_pem}.issuer"
143194
_ocsp="${_pem}.ocsp"
144195
_reload="${Le_Deploy_haproxy_reload}"
196+
_statssock="${Le_Deploy_haproxy_stats_socket}"
145197

146198
_info "Deploying PEM file"
147199
# Create a temporary PEM file
148200
_temppem="$(_mktemp)"
149201
_debug _temppem "${_temppem}"
150-
cat "${_ccert}" "${_cca}" "${_ckey}" >"${_temppem}"
202+
cat "${_ccert}" "${_cca}" "${_ckey}" | grep . >"${_temppem}"
151203
_ret="$?"
152204

153205
# Check that we could create the temporary file
@@ -265,15 +317,86 @@ haproxy_deploy() {
265317
fi
266318
fi
267319

268-
# Reload HAProxy
269-
_debug _reload "${_reload}"
270-
eval "${_reload}"
271-
_ret=$?
272-
if [ "${_ret}" != "0" ]; then
273-
_err "Error code ${_ret} during reload"
274-
return ${_ret}
320+
if [ "${Le_Deploy_haproxy_hot_update}" = "yes" ]; then
321+
# set the socket name for messages
322+
if [ -n "${_cmdpfx}" ]; then
323+
_socketname="master CLI"
324+
else
325+
_socketname="stats socket"
326+
fi
327+
328+
# Update certificate over HAProxy stats socket or master CLI.
329+
if _exists socat; then
330+
# look for the certificate on the stats socket, to chose between updating or creating one
331+
_socat_cert_cmd="echo '${_cmdpfx}show ssl cert' | socat '${_statssock}' - | grep -q '^${_pem}$'"
332+
_debug _socat_cert_cmd "${_socat_cert_cmd}"
333+
eval "${_socat_cert_cmd}"
334+
_ret=$?
335+
if [ "${_ret}" != "0" ]; then
336+
_newcert="1"
337+
_info "Creating new certificate '${_pem}' over HAProxy ${_socketname}."
338+
# certificate wasn't found, it's a new one. We should check if the crt-list exists and creates/inserts the certificate.
339+
_socat_crtlist_show_cmd="echo '${_cmdpfx}show ssl crt-list' | socat '${_statssock}' - | grep -q '^${Le_Deploy_haproxy_pem_path}$'"
340+
_debug _socat_crtlist_show_cmd "${_socat_crtlist_show_cmd}"
341+
eval "${_socat_crtlist_show_cmd}"
342+
_ret=$?
343+
if [ "${_ret}" != "0" ]; then
344+
_err "Couldn't find '${Le_Deploy_haproxy_pem_path}' in haproxy 'show ssl crt-list'"
345+
return "${_ret}"
346+
fi
347+
# create a new certificate
348+
_socat_new_cmd="echo '${_cmdpfx}new ssl cert ${_pem}' | socat '${_statssock}' - | grep -q 'New empty'"
349+
_debug _socat_new_cmd "${_socat_new_cmd}"
350+
eval "${_socat_new_cmd}"
351+
_ret=$?
352+
if [ "${_ret}" != "0" ]; then
353+
_err "Couldn't create '${_pem}' in haproxy"
354+
return "${_ret}"
355+
fi
356+
else
357+
_info "Update existing certificate '${_pem}' over HAProxy ${_socketname}."
358+
fi
359+
_socat_cert_set_cmd="echo -e '${_cmdpfx}set ssl cert ${_pem} <<\n$(cat "${_pem}")\n' | socat '${_statssock}' - | grep -q 'Transaction created'"
360+
_debug _socat_cert_set_cmd "${_socat_cert_set_cmd}"
361+
eval "${_socat_cert_set_cmd}"
362+
_ret=$?
363+
if [ "${_ret}" != "0" ]; then
364+
_err "Can't update '${_pem}' in haproxy"
365+
return "${_ret}"
366+
fi
367+
_socat_cert_commit_cmd="echo '${_cmdpfx}commit ssl cert ${_pem}' | socat '${_statssock}' - | grep -q '^Success!$'"
368+
_debug _socat_cert_commit_cmd "${_socat_cert_commit_cmd}"
369+
eval "${_socat_cert_commit_cmd}"
370+
_ret=$?
371+
if [ "${_ret}" != "0" ]; then
372+
_err "Can't commit '${_pem}' in haproxy"
373+
return ${_ret}
374+
fi
375+
if [ "${_newcert}" = "1" ]; then
376+
# if this is a new certificate, it needs to be inserted into the crt-list`
377+
_socat_cert_add_cmd="echo '${_cmdpfx}add ssl crt-list ${Le_Deploy_haproxy_pem_path} ${_pem}' | socat '${_statssock}' - | grep -q 'Success!'"
378+
_debug _socat_cert_add_cmd "${_socat_cert_add_cmd}"
379+
eval "${_socat_cert_add_cmd}"
380+
_ret=$?
381+
if [ "${_ret}" != "0" ]; then
382+
_err "Can't update '${_pem}' in haproxy"
383+
return "${_ret}"
384+
fi
385+
fi
386+
else
387+
_err "'socat' is not available, couldn't update over ${_socketname}"
388+
fi
275389
else
276-
_info "Reload successful"
390+
# Reload HAProxy
391+
_debug _reload "${_reload}"
392+
eval "${_reload}"
393+
_ret=$?
394+
if [ "${_ret}" != "0" ]; then
395+
_err "Error code ${_ret} during reload"
396+
return ${_ret}
397+
else
398+
_info "Reload successful"
399+
fi
277400
fi
278401

279402
return 0

deploy/panos.sh

+19
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
# export PANOS_USER="" #User *MUST* have Commit and Import Permissions in XML API for Admin Role
1313
# export PANOS_PASS=""
1414
#
15+
# OPTIONAL
16+
# export PANOS_TEMPLATE="" #Template Name of panorama managed devices
17+
#
1518
# The script will automatically generate a new API key if
1619
# no key is found, or if a saved key has expired or is invalid.
1720

@@ -78,6 +81,9 @@ deployer() {
7881
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"key\"\r\n\r\n$_panos_key"
7982
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"format\"\r\n\r\npem"
8083
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"file\"; filename=\"$(basename "$_cfullchain")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_cfullchain")"
84+
if [ "$_panos_template" ]; then
85+
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"target-tpl\"\r\n\r\n$_panos_template"
86+
fi
8187
fi
8288
if [ "$type" = 'key' ]; then
8389
panos_url="${panos_url}?type=import"
@@ -87,6 +93,9 @@ deployer() {
8793
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"format\"\r\n\r\npem"
8894
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"passphrase\"\r\n\r\n123456"
8995
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"file\"; filename=\"$(basename "$_cdomain.key")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ckey")"
96+
if [ "$_panos_template" ]; then
97+
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"target-tpl\"\r\n\r\n$_panos_template"
98+
fi
9099
fi
91100
#Close multipart
92101
content="$content${nl}--$delim--${nl}${nl}"
@@ -173,10 +182,20 @@ panos_deploy() {
173182
unset _panos_key
174183
fi
175184

185+
# PANOS_TEMPLATE
186+
if [ "$PANOS_TEMPLATE" ]; then
187+
_debug "Detected ENV variable PANOS_TEMPLATE. Saving to file."
188+
_savedeployconf PANOS_TEMPLATE "$PANOS_TEMPLATE" 1
189+
else
190+
_debug "Attempting to load variable PANOS_TEMPLATE from file."
191+
_getdeployconf PANOS_TEMPLATE
192+
fi
193+
176194
#Store variables
177195
_panos_host=$PANOS_HOST
178196
_panos_user=$PANOS_USER
179197
_panos_pass=$PANOS_PASS
198+
_panos_template=$PANOS_TEMPLATE
180199

181200
#Test API Key if found. If the key is invalid, the variable _panos_key will be unset.
182201
if [ "$_panos_host" ] && [ "$_panos_key" ]; then

dnsapi/dns_aws.sh

+23-8
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,6 @@ dns_aws_rm() {
145145
fi
146146
_sleep 1
147147
return 1
148-
149148
}
150149

151150
#################### Private functions below ##################################
@@ -207,24 +206,40 @@ _use_container_role() {
207206
}
208207

209208
_use_instance_role() {
210-
_url="http://169.254.169.254/latest/meta-data/iam/security-credentials/"
211-
_debug "_url" "$_url"
212-
if ! _get "$_url" true 1 | _head_n 1 | grep -Fq 200; then
209+
_instance_role_name_url="http://169.254.169.254/latest/meta-data/iam/security-credentials/"
210+
211+
if _get "$_instance_role_name_url" true 1 | _head_n 1 | grep -Fq 401; then
212+
_debug "Using IMDSv2"
213+
_token_url="http://169.254.169.254/latest/api/token"
214+
export _H1="X-aws-ec2-metadata-token-ttl-seconds: 21600"
215+
_token="$(_post "" "$_token_url" "" "PUT")"
216+
_secure_debug3 "_token" "$_token"
217+
if [ -z "$_token" ]; then
218+
_debug "Unable to fetch IMDSv2 token from instance metadata"
219+
return 1
220+
fi
221+
export _H1="X-aws-ec2-metadata-token: $_token"
222+
fi
223+
224+
if ! _get "$_instance_role_name_url" true 1 | _head_n 1 | grep -Fq 200; then
213225
_debug "Unable to fetch IAM role from instance metadata"
214226
return 1
215227
fi
216-
_aws_role=$(_get "$_url" "" 1)
217-
_debug "_aws_role" "$_aws_role"
218-
_use_metadata "$_url$_aws_role"
228+
229+
_instance_role_name=$(_get "$_instance_role_name_url" "" 1)
230+
_debug "_instance_role_name" "$_instance_role_name"
231+
_use_metadata "$_instance_role_name_url$_instance_role_name" "$_token"
232+
219233
}
220234

221235
_use_metadata() {
236+
export _H1="X-aws-ec2-metadata-token: $2"
222237
_aws_creds="$(
223238
_get "$1" "" 1 |
224239
_normalizeJson |
225240
tr '{,}' '\n' |
226241
while read -r _line; do
227-
_key="$(echo "${_line%%:*}" | tr -d '"')"
242+
_key="$(echo "${_line%%:*}" | tr -d '\"')"
228243
_value="${_line#*:}"
229244
_debug3 "_key" "$_key"
230245
_secure_debug3 "_value" "$_value"

dnsapi/dns_kappernet.sh

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ dns_kappernet_add() {
4141
_debug _domain "DOMAIN: $_domain"
4242

4343
_info "Trying to add TXT DNS Record"
44-
data="%7B%22name%22%3A%22$fullhostname%22%2C%22type%22%3A%22TXT%22%2C%22content%22%3A%22$txtvalue%22%2C%22ttl%22%3A%223600%22%2C%22prio%22%3A%22%22%7D"
44+
data="%7B%22name%22%3A%22$fullhostname%22%2C%22type%22%3A%22TXT%22%2C%22content%22%3A%22$txtvalue%22%2C%22ttl%22%3A%22300%22%2C%22prio%22%3A%22%22%7D"
4545
if _kappernet_api GET "action=new&subject=$_domain&data=$data"; then
4646

4747
if _contains "$response" "{\"OK\":true"; then
@@ -81,7 +81,7 @@ dns_kappernet_rm() {
8181
_saveaccountconf_mutable KAPPERNETDNS_Secret "$KAPPERNETDNS_Secret"
8282

8383
_info "Trying to remove the TXT Record: $fullhostname containing $txtvalue"
84-
data="%7B%22name%22%3A%22$fullhostname%22%2C%22type%22%3A%22TXT%22%2C%22content%22%3A%22$txtvalue%22%2C%22ttl%22%3A%223600%22%2C%22prio%22%3A%22%22%7D"
84+
data="%7B%22name%22%3A%22$fullhostname%22%2C%22type%22%3A%22TXT%22%2C%22content%22%3A%22$txtvalue%22%2C%22ttl%22%3A%22300%22%2C%22prio%22%3A%22%22%7D"
8585
if _kappernet_api GET "action=del&subject=$fullhostname&data=$data"; then
8686
if _contains "$response" "{\"OK\":true"; then
8787
return 0

0 commit comments

Comments
 (0)