From 2ff0072689247c1574b95ac5a0f292ae49bd7eb8 Mon Sep 17 00:00:00 2001 From: admin Date: Sun, 1 Jun 2025 12:58:12 -0600 Subject: [PATCH] Few mroe updates to prep for new deployment. Testing now --- add-cname-records.sh | 263 +++++++++++-------------------- config.md | 6 +- config.sh | 5 +- configs/homepage/services.yaml | 2 +- mkdocs/docs/javascripts/extra.js | 0 mkdocs/mkdocs.yml | 6 + 6 files changed, 108 insertions(+), 174 deletions(-) create mode 100644 mkdocs/docs/javascripts/extra.js diff --git a/add-cname-records.sh b/add-cname-records.sh index afecb05..a4cf6b4 100755 --- a/add-cname-records.sh +++ b/add-cname-records.sh @@ -1,11 +1,8 @@ #!/bin/bash echo "#############################################################" echo "# " -echo "# WARNING: This script will REPLACE ALL DNS records at " -echo "# the target domain ($CF_DOMAIN)! " -echo "# " -echo "# All existing DNS records for the listed subdomains will " -echo "# be deleted and replaced with new CNAME records. " +echo "# This script will ADD CNAME records for your services " +echo "# to point to your Cloudflare tunnel. " echo "# " echo "#############################################################" echo "" @@ -62,7 +59,7 @@ SUBDOMAINS=( "flatnotes" "code-server" "ollama" - "open-webui" + "chat" "gitea" "mini-qr" "ferdium" @@ -73,35 +70,12 @@ SUBDOMAINS=( "rocket" "live" "vw" + "docs" ) -# First, remove existing DNS records for these subdomains -echo "Removing existing DNS records..." - -for subdomain in "${SUBDOMAINS[@]}"; do - echo "Checking for existing records for $subdomain.$CF_DOMAIN..." - - # Get all DNS records for this subdomain - RECORDS=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records?name=$subdomain.$CF_DOMAIN" \ - -H "Authorization: Bearer $CF_API_TOKEN" \ - -H "Content-Type: application/json") - - # Extract record IDs - RECORD_IDS=$(echo $RECORDS | jq -r '.result[].id') - - # Delete each record - for record_id in $RECORD_IDS; do - echo "Deleting record $record_id for $subdomain.$CF_DOMAIN..." - - curl -s -X DELETE "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" - done -done - -echo "All existing records have been removed." - # Add CNAME records for each subdomain +echo "Adding CNAME records for services..." + for subdomain in "${SUBDOMAINS[@]}"; do echo "Adding CNAME record for $subdomain.$CF_DOMAIN..." @@ -146,33 +120,103 @@ if [[ ! "$ADMIN_EMAIL" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; t exit 1 fi -# Now create the Cloudflare Access applications -echo "Creating Cloudflare Access applications..." +# Get account ID (required for reusable policies) +echo "Getting Cloudflare account ID..." +ACCOUNT_RESPONSE=$(curl -s -X GET "https://api.cloudflare.com/client/v4/accounts" \ + -H "Authorization: Bearer $CF_API_TOKEN" \ + -H "Content-Type: application/json") -# Create access applications only for specific services -PROTECTED_SERVICES=("homepage" "live" "ferdium" "convertx" "mini-qr" "ollama") +ACCOUNT_ID=$(echo $ACCOUNT_RESPONSE | jq -r '.result[0].id') -# Services that should have bypass policies (no authentication) -BYPASS_SERVICES=("excalidraw" "rocket" "listmonk" "vw" "docs") +if [ -z "$ACCOUNT_ID" ] || [ "$ACCOUNT_ID" == "null" ]; then + echo "Error: Could not retrieve account ID. Response: $ACCOUNT_RESPONSE" + exit 1 +fi -# Function to create bypass policy for a service -create_bypass_policy() { - local service=$1 - echo "Creating access application for $service.$CF_DOMAIN with bypass policy..." +echo "Using account ID: $ACCOUNT_ID" + +# Create reusable Access policy +echo "Creating reusable Access policy for admin access..." + +REUSABLE_POLICY_RESPONSE=$(curl -s -X POST "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/access/policies" \ + -H "Authorization: Bearer $CF_API_TOKEN" \ + -H "Content-Type: application/json" \ + --data "{ + \"name\": \"Admin Access Policy for $CF_DOMAIN\", + \"decision\": \"allow\", + \"include\": [ + { + \"email\": { + \"email\": \"$ADMIN_EMAIL\" + } + }, + { + \"email_domain\": { + \"domain\": \"$CF_DOMAIN\" + } + } + ], + \"require\": [], + \"exclude\": [], + \"session_duration\": \"24h\" + }") + +# Extract the reusable policy ID +REUSABLE_POLICY_ID=$(echo $REUSABLE_POLICY_RESPONSE | jq -r '.result.id') + +if [ -z "$REUSABLE_POLICY_ID" ] || [ "$REUSABLE_POLICY_ID" == "null" ]; then + echo "Error creating reusable Access policy. Response: $REUSABLE_POLICY_RESPONSE" + exit 1 +else + echo "Successfully created reusable Access policy with ID: $REUSABLE_POLICY_ID" +fi + +# Create single Access application for the entire domain +echo "Creating Access application for *.$CF_DOMAIN..." + +DOMAIN_APP_RESPONSE=$(curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/access/apps" \ + -H "Authorization: Bearer $CF_API_TOKEN" \ + -H "Content-Type: application/json" \ + --data "{ + \"name\": \"Changemaker Services - $CF_DOMAIN\", + \"domain\": \"*.$CF_DOMAIN\", + \"type\": \"self_hosted\", + \"session_duration\": \"24h\", + \"app_launcher_visible\": true, + \"skip_interstitial\": true, + \"policies\": [\"$REUSABLE_POLICY_ID\"] + }") + +# Extract the application ID +DOMAIN_APP_ID=$(echo $DOMAIN_APP_RESPONSE | jq -r '.result.id') + +if [ -z "$DOMAIN_APP_ID" ] || [ "$DOMAIN_APP_ID" == "null" ]; then + echo "Error creating domain Access application. Response: $DOMAIN_APP_RESPONSE" + exit 1 +else + echo "Successfully created domain Access application with ID: $DOMAIN_APP_ID" +fi + +# Create bypass applications for public services +echo "Creating bypass applications for public services..." + +PUBLIC_SERVICES=("excalidraw" "rocket" "listmonk" "vw" "docs") + +for service in "${PUBLIC_SERVICES[@]}"; do + echo "Creating bypass access application for $service.$CF_DOMAIN..." SERVICE_APP_RESPONSE=$(curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/access/apps" \ -H "Authorization: Bearer $CF_API_TOKEN" \ -H "Content-Type: application/json" \ --data "{ - \"name\": \"$service $CF_DOMAIN\", + \"name\": \"$service $CF_DOMAIN (Public)\", \"domain\": \"$service.$CF_DOMAIN\", \"type\": \"self_hosted\", \"session_duration\": \"24h\", - \"app_launcher_visible\": true, + \"app_launcher_visible\": false, \"skip_interstitial\": true }") - # Extract the application ID from the response SERVICE_APP_ID=$(echo $SERVICE_APP_RESPONSE | jq -r '.result.id') if [ -z "$SERVICE_APP_ID" ] || [ "$SERVICE_APP_ID" == "null" ]; then @@ -180,9 +224,7 @@ create_bypass_policy() { else echo "Successfully created $service access application with ID: $SERVICE_APP_ID" - # Create bypass policy for everyone - echo "Creating bypass policy for $service application..." - + # Create bypass policy POLICY_RESPONSE=$(curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/access/apps/$SERVICE_APP_ID/policies" \ -H "Authorization: Bearer $CF_API_TOKEN" \ -H "Content-Type: application/json" \ @@ -196,130 +238,17 @@ create_bypass_policy() { \"exclude\": [] }") - # Check if policy creation was successful POLICY_SUCCESS=$(echo $POLICY_RESPONSE | jq -r '.success') if [ "$POLICY_SUCCESS" == "true" ]; then - POLICY_ID=$(echo $POLICY_RESPONSE | jq -r '.result.id') - echo "Bypass policy for $service created successfully with ID: $POLICY_ID" + echo "Bypass policy for $service created successfully" else - ERROR_MSG=$(echo $POLICY_RESPONSE | jq -r '.errors[0].message') - echo "Error creating bypass policy for $service: $ERROR_MSG" - echo "Full response: $POLICY_RESPONSE" - fi - fi -} - -for service in "${PROTECTED_SERVICES[@]}"; do - echo "Creating access application for $service.$CF_DOMAIN..." - - SERVICE_APP_RESPONSE=$(curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/access/apps" \ - -H "Authorization: Bearer $CF_API_TOKEN" \ - -H "Content-Type: application/json" \ - --data "{ - \"name\": \"$service $CF_DOMAIN\", - \"domain\": \"$service.$CF_DOMAIN\", - \"type\": \"self_hosted\", - \"session_duration\": \"24h\", - \"app_launcher_visible\": true, - \"skip_interstitial\": true - }") - - # Extract the application ID from the response - SERVICE_APP_ID=$(echo $SERVICE_APP_RESPONSE | jq -r '.result.id') - - if [ -z "$SERVICE_APP_ID" ] || [ "$SERVICE_APP_ID" == "null" ]; then - echo "Error creating $service access application. Response: $SERVICE_APP_RESPONSE" - else - echo "Successfully created $service access application with ID: $SERVICE_APP_ID" - - # Create policy for admin email - echo "Creating admin email policy for $service application..." - - POLICY_RESPONSE=$(curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/access/apps/$SERVICE_APP_ID/policies" \ - -H "Authorization: Bearer $CF_API_TOKEN" \ - -H "Content-Type: application/json" \ - --data "{ - \"name\": \"Allow Admin Email\", - \"decision\": \"allow\", - \"include\": [{ - \"email\": { - \"email\": \"$ADMIN_EMAIL\" - } - }], - \"require\": [], - \"exclude\": [], - \"precedence\": 1, - \"purpose\": \"Admin Authentication\", - \"session_duration\": \"24h\" - }") - - # Check if policy creation was successful - POLICY_SUCCESS=$(echo $POLICY_RESPONSE | jq -r '.success') - - if [ "$POLICY_SUCCESS" == "true" ]; then - POLICY_ID=$(echo $POLICY_RESPONSE | jq -r '.result.id') - echo "Admin email policy for $service created successfully with ID: $POLICY_ID" - else - ERROR_MSG=$(echo $POLICY_RESPONSE | jq -r '.errors[0].message') - echo "Error creating admin email policy for $service: $ERROR_MSG" + echo "Error creating bypass policy for $service: $(echo $POLICY_RESPONSE | jq -r '.errors[0].message')" fi fi done -# Create bypass policies for specified services -for service in "${BYPASS_SERVICES[@]}"; do - create_bypass_policy "$service" -done - -# 2. Create specific access application for Gitea -echo "Creating access application for gitea.$CF_DOMAIN..." -GITEA_APP_RESPONSE=$(curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/access/apps" \ - -H "Authorization: Bearer $CF_API_TOKEN" \ - -H "Content-Type: application/json" \ - --data "{ - \"name\": \"Gitea $CF_DOMAIN\", - \"domain\": \"gitea.$CF_DOMAIN\", - \"type\": \"self_hosted\", - \"app_launcher_visible\": true, - \"skip_interstitial\": true - }") - -# Extract the application ID from the response -GITEA_APP_ID=$(echo $GITEA_APP_RESPONSE | jq -r '.result.id') - -if [ -z "$GITEA_APP_ID" ] || [ "$GITEA_APP_ID" == "null" ]; then - echo "Error creating Gitea access application. Response: $GITEA_APP_RESPONSE" -else - echo "Successfully created Gitea access application with ID: $GITEA_APP_ID" - - # Create bypass policy for everyone - Updated format - echo "Creating bypass policy for Gitea application..." - - POLICY_RESPONSE=$(curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/access/apps/$GITEA_APP_ID/policies" \ - -H "Authorization: Bearer $CF_API_TOKEN" \ - -H "Content-Type: application/json" \ - --data "{ - \"name\": \"Bypass for Everyone\", - \"decision\": \"bypass\", - \"include\": [{ - \"everyone\": {} - }], - \"require\": [], - \"exclude\": [] - }") - - # Check if policy creation was successful - POLICY_SUCCESS=$(echo $POLICY_RESPONSE | jq -r '.success') - - if [ "$POLICY_SUCCESS" == "true" ]; then - POLICY_ID=$(echo $POLICY_RESPONSE | jq -r '.result.id') - echo "Bypass policy for Gitea created successfully with ID: $POLICY_ID" - else - ERROR_MSG=$(echo $POLICY_RESPONSE | jq -r '.errors[0].message') - echo "Error creating bypass policy for Gitea: $ERROR_MSG" - echo "Full response: $POLICY_RESPONSE" - fi -fi - -echo "Cloudflare Access applications setup complete." +echo "Cloudflare Access setup complete." +echo "Admin access configured for: $ADMIN_EMAIL and users with @$CF_DOMAIN email addresses" +echo "Public services (excalidraw, rocket, listmonk, vw) are accessible without authentication" +echo "All other services require authentication through the unified Access policy" diff --git a/config.md b/config.md index 9bc74dd..c89f151 100644 --- a/config.md +++ b/config.md @@ -1,6 +1,2 @@ # Configuring Changemaker -The following is a configuration guide for Changemaker. - -# testing - -# testing again \ No newline at end of file +The following is a configuration guide for Changemaker. \ No newline at end of file diff --git a/config.sh b/config.sh index ebdc8f8..e3d7116 100755 --- a/config.sh +++ b/config.sh @@ -476,7 +476,10 @@ update_env_var "EXCALIDRAW_PUBLIC_SOCKET_URL" "https://excalidraw.$domain_name" # Update OpenWebUI settings echo -e "\nConfiguring OpenWebUI..." update_env_var "OPEN_WEBUI_PORT" "3005" -update_env_var "OPEN_WEBUI_URL" "https://open-web-ui.$domain_name" +update_env_var "OPEN_WEBUI_URL" "https://chat.$domain_name" + +# Update N8N settings +update_env_var "N8N_EDITOR_BASE_URL" "n8n.$domain_name" # Update service URLs in the services.yaml file echo -e "\nUpdating service URLs in services.yaml file..." diff --git a/configs/homepage/services.yaml b/configs/homepage/services.yaml index 6b75299..6d56d94 100644 --- a/configs/homepage/services.yaml +++ b/configs/homepage/services.yaml @@ -32,7 +32,7 @@ description: Self-hosted Git service icon: gitea - OpenWebUI: - href: https://open-webui.test.com + href: https://chat.test.com description: UI for Ollama models icon: mdi-robot-happy diff --git a/mkdocs/docs/javascripts/extra.js b/mkdocs/docs/javascripts/extra.js new file mode 100644 index 0000000..e69de29 diff --git a/mkdocs/mkdocs.yml b/mkdocs/mkdocs.yml index bf1cbbf..53303d3 100755 --- a/mkdocs/mkdocs.yml +++ b/mkdocs/mkdocs.yml @@ -43,6 +43,12 @@ markdown_extensions: copyright: Copyright © 2024 The Bunker Operations - Built with Change Maker +extra_javascript: + - javascripts/extra.js + +extra: + generator: false + plugins: - social - search