-
-
Notifications
You must be signed in to change notification settings - Fork 5.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
deploy hook for Ruckus ZoneDirector / Unleashed #4832
Changes from 4 commits
ed72b09
b6a77e0
7178026
d7bafa6
0cc74b7
5f7ad72
e98e7a2
b665014
38c41b7
2bb5fbd
412e14a
4232923
4299c6a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
#!/usr/bin/env sh | ||
|
||
# Here is a script to deploy cert to Ruckus ZoneDirector / Unleashed. | ||
# | ||
# Public domain, 2024, Tony Rielly <https://github.com/ms264556> | ||
# | ||
# ```sh | ||
# acme.sh --deploy -d ruckus.example.com --deploy-hook ruckus | ||
# ``` | ||
# | ||
# Then you need to set the environment variables for the | ||
# deploy script to work. | ||
# | ||
# ```sh | ||
# export RUCKUS_HOST=myruckus.example.com | ||
# export RUCKUS_USER=myruckususername | ||
# export RUCKUS_PASS=myruckuspassword | ||
# | ||
# acme.sh --deploy -d myruckus.example.com --deploy-hook ruckus | ||
# ``` | ||
# | ||
# returns 0 means success, otherwise error. | ||
|
||
######## Public functions ##################### | ||
|
||
#domain keyfile certfile cafile fullchain | ||
ruckus_deploy() { | ||
_cdomain="$1" | ||
_ckey="$2" | ||
_ccert="$3" | ||
_cca="$4" | ||
_cfullchain="$5" | ||
_err_code=0 | ||
|
||
_debug _cdomain "$_cdomain" | ||
_debug _ckey "$_ckey" | ||
_debug _ccert "$_ccert" | ||
_debug _cca "$_cca" | ||
_debug _cfullchain "$_cfullchain" | ||
|
||
_getdeployconf RUCKUS_HOST | ||
_getdeployconf RUCKUS_USER | ||
_getdeployconf RUCKUS_PASS | ||
|
||
if [ -z "$RUCKUS_HOST" ]; then | ||
_debug "Using _cdomain as RUCKUS_HOST, please set if not correct." | ||
RUCKUS_HOST="$_cdomain" | ||
fi | ||
|
||
if [ -z "$RUCKUS_USER" ]; then | ||
_err "Need to set the env variable RUCKUS_USER" | ||
return 1 | ||
fi | ||
|
||
if [ -z "$RUCKUS_PASS" ]; then | ||
_err "Need to set the env variable RUCKUS_PASS" | ||
return 1 | ||
fi | ||
|
||
_savedeployconf RUCKUS_HOST "$RUCKUS_HOST" | ||
_savedeployconf RUCKUS_USER "$RUCKUS_USER" | ||
_savedeployconf RUCKUS_PASS "$RUCKUS_PASS" | ||
|
||
_debug RUCKUS_HOST "$RUCKUS_HOST" | ||
_debug RUCKUS_USER "$RUCKUS_USER" | ||
_debug RUCKUS_PASS "$RUCKUS_PASS" | ||
|
||
export HTTPS_INSECURE=1 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why do we need "insecure" here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ruckus devices ship with 1024 bit self-signed server certificates, so curl will fail with error 60 unless I set HTTPS_INSECURE=1. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Overriding There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No problem. That's fixed now. |
||
export ACME_HTTP_NO_REDIRECTS=1 | ||
|
||
_info Discovering the login URL | ||
_get "https://$RUCKUS_HOST" >/dev/null | ||
_login_url="$(_response_header 'Location')" | ||
if [ -n "$_login_url" ]; then | ||
_login_path=$(echo "$_login_url" | sed 's|https\?://[^/]\+||') | ||
if [ -z "$_login_path" ]; then | ||
# redirect was to a different host | ||
_get "$_login_url" >/dev/null | ||
_login_url="$(_response_header 'Location')" | ||
fi | ||
fi | ||
|
||
if [ -z "${_login_url}" ]; then | ||
_err "Connection failed: couldn't find login page." | ||
return 1 | ||
fi | ||
|
||
_base_url=$(dirname "$_login_url") | ||
_login_page=$(basename "$_login_url") | ||
|
||
if [ "$_login_page" = "index.html" ]; then | ||
_err "Connection temporarily unavailable: Unleashed Rebuilding." | ||
return 1 | ||
fi | ||
|
||
if [ "$_login_page" = "wizard.jsp" ]; then | ||
_err "Connection failed: Setup Wizard not complete." | ||
return 1 | ||
fi | ||
|
||
_info Login | ||
_username_encoded="$(printf "%s" "$RUCKUS_USER" | _url_encode)" | ||
_password_encoded="$(printf "%s" "$RUCKUS_PASS" | _url_encode)" | ||
_login_query="$(printf "%s" "username=${_username_encoded}&password=${_password_encoded}&ok=Log+In")" | ||
_post "$_login_query" "$_login_url" >/dev/null | ||
|
||
_login_code="$(_response_code)" | ||
if [ "$_login_code" = "200" ]; then | ||
_err "Login failed: incorrect credentials." | ||
return 1 | ||
fi | ||
|
||
_info Collect Session Cookie | ||
_H1="Cookie: $(_response_cookie)" | ||
export _H1 | ||
_info Collect CSRF Token | ||
_H2="X-CSRF-Token: $(_response_header 'HTTP_X_CSRF_TOKEN')" | ||
export _H2 | ||
|
||
_info "Uploading certificate" | ||
_post_upload "uploadcert" "$_cfullchain" | ||
|
||
_info "Uploading private key" | ||
_post_upload "uploadprivatekey" "$_ckey" | ||
|
||
_info "Replacing certificate" | ||
_replace_cert_ajax='<ajax-request action="docmd" comp="system" updater="rid.0.5" xcmd="replace-cert" checkAbility="6" timeout="-1"><xcmd cmd="replace-cert" cn="'$RUCKUS_HOST'"/></ajax-request>' | ||
_post "$_replace_cert_ajax" "$_base_url/_cmdstat.jsp" >/dev/null | ||
|
||
info "Rebooting" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed, and I also fixed the unquoted _info strings |
||
_cert_reboot_ajax='<ajax-request action="docmd" comp="worker" updater="rid.0.5" xcmd="cert-reboot" checkAbility="6"><xcmd cmd="cert-reboot" action="undefined"/></ajax-request>' | ||
_post "$_cert_reboot_ajax" "$_base_url/_cmdstat.jsp" >/dev/null | ||
|
||
return 0 | ||
} | ||
|
||
_response_code() { | ||
< "$HTTP_HEADER" _egrep_o "^HTTP[^ ]* .*$" | cut -d " " -f 2-100 | tr -d "\f\n" | _egrep_o "^[0-9]*" | ||
} | ||
|
||
_response_header() { | ||
< "$HTTP_HEADER" grep -i "^$1:" | cut -d ':' -f 2- | tr -d "\r\n\t " | ||
} | ||
|
||
_response_cookie() { | ||
_response_header 'Set-Cookie' | awk -F';' '{for(i=1;i<=NF;i++) if (tolower($i) !~ /(path|domain|expires|max-age|secure|httponly|samesite)/) printf "%s; ", $i}' | sed 's/; $//' | ||
} | ||
|
||
_post_upload() { | ||
_post_action="$1" | ||
_post_file="$2" | ||
|
||
_post_boundary="----FormBoundary$(date "+%s%N")" | ||
|
||
_post_data="$({ | ||
printf -- "--%s\r\n" "$_post_boundary" | ||
printf -- "Content-Disposition: form-data; name=\"u\"; filename=\"%s\"\r\n" "$_post_action" | ||
printf -- "Content-Type: application/octet-stream\r\n\r\n" | ||
printf -- "%s\r\n" "$(cat "$_post_file")" | ||
|
||
printf -- "--%s\r\n" "$_post_boundary" | ||
printf -- "Content-Disposition: form-data; name=\"action\"\r\n\r\n" | ||
printf -- "%s\r\n" "$_post_action" | ||
|
||
printf -- "--%s\r\n" "$_post_boundary" | ||
printf -- "Content-Disposition: form-data; name=\"callback\"\r\n\r\n" | ||
printf -- "%s\r\n" "uploader_$_post_action" | ||
|
||
printf -- "--%s--\r\n\r\n" "$_post_boundary" | ||
})" | ||
|
||
_post "$_post_data" "$_base_url/_upload.jsp?request_type=xhr" "" "" "multipart/form-data; boundary=$_post_boundary" >/dev/null | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use
_secure_debug
for password, so that you won't leak it.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed