From 339d6edd9fb2ab57d9aad222fa44b14a68f8a43f Mon Sep 17 00:00:00 2001 From: aptalca Date: Fri, 26 Aug 2022 12:11:06 -0400 Subject: [PATCH] switch to hybrid --- .../dependencies.d/init-mods | 0 .../init-mod-universal-cloudflared-setup/run | 142 ++++++++++++++++++ .../init-mod-universal-cloudflared-setup/type | 1 + .../init-mod-universal-cloudflared-setup/up | 1 + .../init-mod-universal-cloudflared-setup | 0 .../dependencies.d/init-services | 0 .../s6-rc.d/svc-mod-universal-cloudflared/run | 8 + .../svc-mod-universal-cloudflared/type | 1 + .../init-mod-universal-cloudflared-setup | 0 .../contents.d/svc-mod-universal-cloudflared | 0 root/etc/services.d/cloudflared/run | 0 11 files changed, 153 insertions(+) create mode 100644 root/etc/s6-overlay/s6-rc.d/init-mod-universal-cloudflared-setup/dependencies.d/init-mods create mode 100755 root/etc/s6-overlay/s6-rc.d/init-mod-universal-cloudflared-setup/run create mode 100644 root/etc/s6-overlay/s6-rc.d/init-mod-universal-cloudflared-setup/type create mode 100644 root/etc/s6-overlay/s6-rc.d/init-mod-universal-cloudflared-setup/up create mode 100644 root/etc/s6-overlay/s6-rc.d/init-mods-end/dependencies.d/init-mod-universal-cloudflared-setup create mode 100644 root/etc/s6-overlay/s6-rc.d/svc-mod-universal-cloudflared/dependencies.d/init-services create mode 100755 root/etc/s6-overlay/s6-rc.d/svc-mod-universal-cloudflared/run create mode 100644 root/etc/s6-overlay/s6-rc.d/svc-mod-universal-cloudflared/type create mode 100644 root/etc/s6-overlay/s6-rc.d/user/contents.d/init-mod-universal-cloudflared-setup create mode 100644 root/etc/s6-overlay/s6-rc.d/user/contents.d/svc-mod-universal-cloudflared mode change 100644 => 100755 root/etc/services.d/cloudflared/run diff --git a/root/etc/s6-overlay/s6-rc.d/init-mod-universal-cloudflared-setup/dependencies.d/init-mods b/root/etc/s6-overlay/s6-rc.d/init-mod-universal-cloudflared-setup/dependencies.d/init-mods new file mode 100644 index 0000000..e69de29 diff --git a/root/etc/s6-overlay/s6-rc.d/init-mod-universal-cloudflared-setup/run b/root/etc/s6-overlay/s6-rc.d/init-mod-universal-cloudflared-setup/run new file mode 100755 index 0000000..bc36274 --- /dev/null +++ b/root/etc/s6-overlay/s6-rc.d/init-mod-universal-cloudflared-setup/run @@ -0,0 +1,142 @@ +#!/usr/bin/with-contenv bash + +echo "**** Cloudflared setup script init... ****" + +echo "**** Checking cloudflared setup script requirements... ****" +ARCH="$(command arch)" +if [ "${ARCH}" = "x86_64" ]; then + ARCH="amd64" +elif [ "${ARCH}" = "aarch64" ]; then + ARCH="arm64" +elif [ "${ARCH}" = "armv7l" ]; then + ARCH="armhf" +else + echo "**** Unsupported Linux architecture ${ARCH} found, exiting... ****" + exit 1 +fi +echo "**** Linux architecture found: ${ARCH} ****" + +echo "**** Checking for cloudflared setup script dependencies... ****" +YQARCH="${ARCH}" +if [ "${YQ_ARCH}" = "armhf" ]; then + YQARCH="arm" +fi +echo "**** Temporarily installing /tmp/yq... ****" +curl -sLo /tmp/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_${YQARCH} +chmod +x /tmp/yq + +echo "**** Installing cloudflared...****" +if [ -d "/cloudflared/" ]; then + echo "**** Moving /cloudflared/cloudflared-${ARCH} to /usr/local/bin/cloudflared... ****" + mv /cloudflared/cloudflared-${ARCH} /usr/local/bin/cloudflared + + echo "**** Deleting tmp /cloudflared dir... ****" + rm -rf /cloudflared + + echo "**** Cloudflared installed ****" +elif [ -x "$(command -v cloudflared)" ]; then + echo "**** Cloudflared already installed, skipping... ****" +else + echo "**** Cloudflared missing, exiting... ****" + exit 1 +fi +cloudflared -v + +echo "**** Checking for cloudflare tunnel parameters... ****" +if [[ ${#CF_ZONE_ID} -gt 0 ]] && [[ ${#CF_ACCOUNT_ID} -gt 0 ]] && [[ ${#CF_API_TOKEN} -gt 0 ]] && [[ ${#CF_TUNNEL_NAME} -gt 0 ]] && [[ ${#CF_TUNNEL_CONFIG} -gt 0 ]]; then + if [[ ${#CF_TUNNEL_PASSWORD} -lt 32 ]]; then + echo "**** Cloudflare tunnel password must be at least 32 characters long, exiting... ****" + rm -rf /etc/services.d/cloudflared + exit 1 + else + echo "**** Cloudflare tunnel parameters found, starting cloudflare tunnel setup... ****" + echo "**** Creating cloudflare tunnel (${CF_TUNNEL_NAME}) via API... ****" + + CF_TUNNEL_SECRET="$(command echo ${CF_TUNNEL_PASSWORD} | base64 -w 0)" + JSON_RESULT=$(curl -sX \ + POST "https://api.cloudflare.com/client/v4/accounts/${CF_ACCOUNT_ID}/tunnels" \ + -H "Authorization: Bearer ${CF_API_TOKEN}" \ + -H "Content-Type: application/json" \ + --data "{\"name\":\"${CF_TUNNEL_NAME}\",\"tunnel_secret\":\"${CF_TUNNEL_SECRET}\"}") + echo ${JSON_RESULT} | jq + + JSON_CODE_VALUE=$(echo ${JSON_RESULT} | jq -rc ".code // .errors[].code") + if [[ ${JSON_CODE_VALUE} -eq 1013 ]]; then + echo "**** You already have a cloudflare tunnel named ${CF_TUNNEL_NAME} ****" + + echo "**** Searching existing cloudflare tunnels via API... ****" + JSON_RESULT=$(curl -sX \ + GET "https://api.cloudflare.com/client/v4/accounts/${CF_ACCOUNT_ID}/tunnels?name=${CF_TUNNEL_NAME}&is_deleted=false" \ + -H "Authorization: Bearer ${CF_API_TOKEN}" \ + -H "Content-Type: application/json") + echo ${JSON_RESULT} | jq + + echo "**** Fetching existing cloudflare tunnel (${CF_TUNNEL_NAME}) via API... ****" + CF_TUNNEL_ID=$(echo ${JSON_RESULT} | jq -rc ".[].id? // .result[].id") + JSON_RESULT=$(curl -sX \ + GET "https://api.cloudflare.com/client/v4/accounts/${CF_ACCOUNT_ID}/tunnels/${CF_TUNNEL_ID}?" \ + -H "Authorization: Bearer ${CF_API_TOKEN}" \ + -H "Content-Type: application/json") + + JSON_RESULT=$(echo ${JSON_RESULT} | jq -rc ". |= .+ {\"credentials_file\": {\"AccountTag\": \"${CF_ACCOUNT_ID}\",\"TunnelID\": \"${CF_TUNNEL_ID}\",\"TunnelName\": \"${CF_TUNNEL_NAME}\",\"TunnelSecret\": \"${CF_TUNNEL_SECRET}\"}}") + echo ${JSON_RESULT} | jq + fi + + CF_TUNNEL_ID=$(echo ${JSON_RESULT} | jq -rc ".id // .result.id") + CREDENTIALS_FILE=$(echo ${JSON_RESULT} | jq -rc ".credentials_file // .result.credentials_file") + echo "**** Saving cloudflare tunnel (${CF_TUNNEL_NAME}) credentials json... ****" + if [ ! -d "/etc/cloudflared/" ]; then + mkdir -p "/etc/cloudflared"; + fi + printf "${CREDENTIALS_FILE}" > "/etc/cloudflared/${CF_TUNNEL_ID}.json" + echo ${JSON_RESULT} | jq -r ".result.credentials_file" + echo "**** Cloudflare tunnel (${CF_TUNNEL_NAME}) credentials saved to /etc/cloudflared/${CF_TUNNEL_ID}.json ****" + + echo "**** Generating config.yml for cloudflare tunnel (${CF_TUNNEL_NAME})... ****" + printf "tunnel: ${CF_TUNNEL_ID}\n" > "/etc/cloudflared/config.yml" + printf "credentials-file: /etc/cloudflared/${CF_TUNNEL_ID}.json\n" >> "/etc/cloudflared/config.yml" + printf "no-autoupdate: true\n\n" >> "/etc/cloudflared/config.yml" + printf "${CF_TUNNEL_CONFIG}" >> "/etc/cloudflared/config.yml" + /tmp/yq e /etc/cloudflared/config.yml + echo "**** Config for cloudflare tunnel (${CF_TUNNEL_NAME}) saved to /etc/cloudflared/config.yml ****" + + echo "**** Validating cloudflared tunnel rules... ****" + cloudflared tunnel ingress validate + + echo "**** Updating cloudflare zone... ****" + for HOSTNAME in $(/tmp/yq e ".ingress.[].hostname" /etc/cloudflared/config.yml); do + if [ ! "${HOSTNAME}" = "null" ]; then + echo "**** Searching zone for hostname (${HOSTNAME}) via API... ****" + JSON_RESULT=$(curl -sX \ + GET "https://api.cloudflare.com/client/v4/zones/${CF_ZONE_ID}/dns_records?name=${HOSTNAME}&type=CNAME&match=all" \ + -H "Authorization: Bearer ${CF_API_TOKEN}" \ + -H "Content-Type: application/json") + + COUNT=$(echo ${JSON_RESULT} | jq -rc ".result_info.count") + if [[ ${COUNT} -eq 0 ]]; then + echo "**** Creating new CNAME for hostname (${HOSTNAME}) via API... ****" + JSON_RESULT=$(curl -sX \ + POST "https://api.cloudflare.com/client/v4/zones/${CF_ZONE_ID}/dns_records" \ + -H "Authorization: Bearer ${CF_API_TOKEN}" \ + -H "Content-Type: application/json" \ + --data "{\"type\":\"CNAME\",\"name\":\"${HOSTNAME}\",\"content\":\"${CF_TUNNEL_ID}.cfargotunnel.com\",\"ttl\":1,\"proxied\":true}") + echo ${JSON_RESULT} | jq + else + echo "**** Updating existing CNAME for hostname (${HOSTNAME}) via API... ****" + RECORD_ID=$(echo ${JSON_RESULT} | jq -rc ".result[].id") + JSON_RESULT=$(curl -sX \ + PUT "https://api.cloudflare.com/client/v4/zones/${CF_ZONE_ID}/dns_records/${RECORD_ID}" \ + -H "Authorization: Bearer ${CF_API_TOKEN}" \ + -H "Content-Type: application/json" \ + --data "{\"type\":\"CNAME\",\"name\":\"${HOSTNAME}\",\"content\":\"${CF_TUNNEL_ID}.cfargotunnel.com\",\"ttl\":1,\"proxied\":true}") + echo ${JSON_RESULT} | jq + fi + fi + done + fi +else + echo "**** Cloudflare parameters blank or missing, skipped cloudflare tunnel setup ****" + rm -rf /etc/services.d/cloudflared +fi + +echo "**** Cloudflared setup script done, exiting... ****" diff --git a/root/etc/s6-overlay/s6-rc.d/init-mod-universal-cloudflared-setup/type b/root/etc/s6-overlay/s6-rc.d/init-mod-universal-cloudflared-setup/type new file mode 100644 index 0000000..3d92b15 --- /dev/null +++ b/root/etc/s6-overlay/s6-rc.d/init-mod-universal-cloudflared-setup/type @@ -0,0 +1 @@ +oneshot \ No newline at end of file diff --git a/root/etc/s6-overlay/s6-rc.d/init-mod-universal-cloudflared-setup/up b/root/etc/s6-overlay/s6-rc.d/init-mod-universal-cloudflared-setup/up new file mode 100644 index 0000000..0d3e2d8 --- /dev/null +++ b/root/etc/s6-overlay/s6-rc.d/init-mod-universal-cloudflared-setup/up @@ -0,0 +1 @@ +/etc/s6-overlay/s6-rc.d/init-mod-universal-cloudflared-setup/run \ No newline at end of file diff --git a/root/etc/s6-overlay/s6-rc.d/init-mods-end/dependencies.d/init-mod-universal-cloudflared-setup b/root/etc/s6-overlay/s6-rc.d/init-mods-end/dependencies.d/init-mod-universal-cloudflared-setup new file mode 100644 index 0000000..e69de29 diff --git a/root/etc/s6-overlay/s6-rc.d/svc-mod-universal-cloudflared/dependencies.d/init-services b/root/etc/s6-overlay/s6-rc.d/svc-mod-universal-cloudflared/dependencies.d/init-services new file mode 100644 index 0000000..e69de29 diff --git a/root/etc/s6-overlay/s6-rc.d/svc-mod-universal-cloudflared/run b/root/etc/s6-overlay/s6-rc.d/svc-mod-universal-cloudflared/run new file mode 100755 index 0000000..3a358e9 --- /dev/null +++ b/root/etc/s6-overlay/s6-rc.d/svc-mod-universal-cloudflared/run @@ -0,0 +1,8 @@ +#!/usr/bin/with-contenv bash + +if [[ ${#CF_ZONE_ID} -gt 0 ]] && [[ ${#CF_ACCOUNT_ID} -gt 0 ]] && [[ ${#CF_API_TOKEN} -gt 0 ]] && [[ ${#CF_TUNNEL_NAME} -gt 0 ]] && [[ ${#CF_TUNNEL_CONFIG} -gt 0 ]] && [[ ${#CF_TUNNEL_PASSWORD} -gt 31 ]]; then + exec s6-setuidgid abc cloudflared tunnel --no-autoupdate --config /etc/cloudflared/config.yml run +else + echo "**** Issues with cloudflared settings, sleeping ****" + sleep infinity +fi diff --git a/root/etc/s6-overlay/s6-rc.d/svc-mod-universal-cloudflared/type b/root/etc/s6-overlay/s6-rc.d/svc-mod-universal-cloudflared/type new file mode 100644 index 0000000..1780f9f --- /dev/null +++ b/root/etc/s6-overlay/s6-rc.d/svc-mod-universal-cloudflared/type @@ -0,0 +1 @@ +longrun \ No newline at end of file diff --git a/root/etc/s6-overlay/s6-rc.d/user/contents.d/init-mod-universal-cloudflared-setup b/root/etc/s6-overlay/s6-rc.d/user/contents.d/init-mod-universal-cloudflared-setup new file mode 100644 index 0000000..e69de29 diff --git a/root/etc/s6-overlay/s6-rc.d/user/contents.d/svc-mod-universal-cloudflared b/root/etc/s6-overlay/s6-rc.d/user/contents.d/svc-mod-universal-cloudflared new file mode 100644 index 0000000..e69de29 diff --git a/root/etc/services.d/cloudflared/run b/root/etc/services.d/cloudflared/run old mode 100644 new mode 100755