Add self-healing Cloudflare tunnel with 60s watchdog for USB deck.

Replaces fragile batch-based tunnel install with a single PowerShell
script (cloudflare/start-tunnel.ps1) that installs cloudflared as a
Windows service (admin) or runs as a background process (non-admin),
clears stale EventLog registry keys that caused service rollback, and
runs a 60-second watchdog that auto-restarts the connector on failure.
Hostname changed to aether.thetempleofdoom.com. LAUNCH.bat and
pack-usb.bat updated accordingly.
This commit is contained in:
AetherForge
2026-06-01 15:03:17 -07:00
parent feba06e008
commit 3605d540da
18 changed files with 1455 additions and 215 deletions

View File

@@ -37,6 +37,11 @@ echo.
set "BUNDLED_GO=%ROOT%\toolchain\go\bin\go.exe"
set "GO_BIN="
if exist "%ROOT%\toolchain\go" if not exist "%BUNDLED_GO%" (
echo [Go] Incomplete toolchain folder — removing broken install...
rd /s /q "%ROOT%\toolchain\go" 2>nul
)
if exist "%BUNDLED_GO%" (
echo [Go] Using bundled toolchain: %ROOT%\toolchain\go
set "GO_BIN=%ROOT%\toolchain\go\bin\go.exe"
@@ -53,42 +58,61 @@ if not errorlevel 1 (
goto go_ready
)
:: Go not found - offer to download portable toolchain
echo [Go] Not found. Downloading portable Go toolchain...
echo This only happens once. The toolchain is saved to toolchain\go\
:: Go not found - extract bundled zip or download once
echo [Go] Not found. Setting up portable Go toolchain...
echo Saved under: %ROOT%\toolchain\go\
echo.
if /i "%PROCESSOR_ARCHITECTURE%"=="AMD64" (
set "GO_ARCH=amd64"
) else if /i "%PROCESSOR_ARCHITECTURE%"=="ARM64" (
set "GO_ARCH=arm64"
) else (
if /i "%PROCESSOR_ARCHITECTURE%"=="ARM64" (
set "GO_ARCH=arm64"
) else (
set "GO_ARCH=386"
set "GO_ARCH=386"
)
set "GO_VERSION=1.26.3"
set "GO_ZIP=go%GO_VERSION%.windows-%GO_ARCH%.zip"
set "GO_PACK_ZIP=%ROOT%\toolchain\pack\%GO_ZIP%"
set "GO_DEST=%ROOT%\toolchain\%GO_ZIP%"
if not exist "%ROOT%\toolchain" mkdir "%ROOT%\toolchain"
if not exist "%ROOT%\toolchain\pack" mkdir "%ROOT%\toolchain\pack"
if exist "%GO_PACK_ZIP%" (
echo [Go] Extracting bundled %GO_ZIP%...
copy /y "%GO_PACK_ZIP%" "%GO_DEST%" >nul
) else (
echo [Go] Downloading %GO_ZIP% from go.dev...
set "GO_URL=https://go.dev/dl/%GO_ZIP%"
powershell -NoProfile -Command "& { [Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12; Invoke-WebRequest -Uri '%GO_URL%' -OutFile '%GO_DEST%' }"
if errorlevel 1 (
echo.
echo ERROR: Could not download Go. Copy toolchain\go\ from a PC that has it,
echo or add toolchain\pack\%GO_ZIP% to this folder, then re-run LAUNCH.bat.
echo.
pause
exit /b 1
)
)
set "GO_VERSION=1.22.4"
set "GO_ZIP=go%GO_VERSION%.windows-%GO_ARCH%.zip"
set "GO_URL=https://go.dev/dl/%GO_ZIP%"
set "GO_DEST=%ROOT%\toolchain\go_%GO_ARCH%.zip"
powershell -NoProfile -Command "& { [Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12; Invoke-WebRequest -Uri '%GO_URL%' -OutFile '%GO_DEST%' }"
if errorlevel 1 (
echo.
echo ERROR: Could not download Go. Please either:
echo a) Install Go from https://go.dev/dl/ on this PC, then re-run LAUNCH.bat
echo b) Copy C:\Program Files\Go\ into toolchain\go\ from a PC that has Go
echo.
if not exist "%GO_DEST%" (
echo ERROR: Go archive missing after copy/download.
pause
exit /b 1
)
echo [Go] Extracting toolchain...
powershell -NoProfile -Command "Expand-Archive -Path '%GO_DEST%' -DestinationPath '%ROOT%\toolchain' -Force"
powershell -NoProfile -Command "Expand-Archive -LiteralPath '%GO_DEST%' -DestinationPath '%ROOT%\toolchain' -Force"
if errorlevel 1 (
echo ERROR: Extraction failed. Check free disk space and path: %ROOT%\toolchain
pause
exit /b 1
)
del "%GO_DEST%" 2>nul
if not exist "%BUNDLED_GO%" (
echo ERROR: Extraction failed.
echo ERROR: Extraction failed%BUNDLED_GO% not found.
echo Delete toolchain\go and toolchain\pack, then re-run LAUNCH.bat.
pause
exit /b 1
)
@@ -146,76 +170,24 @@ if not exist "%ROOT%\data\blueprints" mkdir "%ROOT%\data\blueprints"
if not exist "%ROOT%\data\preps" mkdir "%ROOT%\data\preps"
:: ----------------------------------------------------------------
:: 5. Cloudflare Tunnel — MSI + token service (no JSON setup)
:: 5. Cloudflare Tunnel - start in background window + 60s watchdog
:: ----------------------------------------------------------------
set "SERVER_PORT=8989"
set "CF_MSI=%ROOT%\cloudflare\cloudflared-windows-amd64.msi"
if not exist "%CF_MSI%" set "CF_MSI=%~dp0cloudflared-windows-amd64.msi"
if not exist "%CF_MSI%" set "CF_MSI=%~dp0..\cloudflared-windows-amd64.msi"
set "CF_TOKEN=eyJhIjoiODk1NDc5YWIzNTQwZGFhNmQ2MWFlNzAyYTUxNjQ0NzUiLCJ0IjoiYWFhYzYzMTctMzgyYS00OTM3LTgxY2YtYjM2ZjVkNjZjYTU4IiwicyI6Ik1XRXlaV0ZqTlRndE5XTTRPUzAwT0RCa0xXRTNaR010WkdRNU56UTJZMlJoTmpNMiJ9"
set "CF_HOSTNAME=killa.thetempleofdoom.com"
set "CF_BIN="
set "CF_HOSTNAME=aether.thetempleofdoom.com"
set "CF_READY=0"
where cloudflared >nul 2>nul
if not errorlevel 1 (
set "CF_BIN=cloudflared"
goto cf_check_service
)
if exist "%ProgramFiles%\cloudflare\cloudflared\cloudflared.exe" (
set "CF_BIN=%ProgramFiles%\cloudflare\cloudflared\cloudflared.exe"
goto cf_check_service
)
if exist "%ProgramFiles(x86)%\cloudflare\cloudflared\cloudflared.exe" (
set "CF_BIN=%ProgramFiles(x86)%\cloudflare\cloudflared\cloudflared.exe"
goto cf_check_service
)
if not exist "%CF_MSI%" (
echo [CF] WARNING: cloudflared not found and no MSI bundled. Skipping tunnel.
if not exist "%ROOT%\cloudflare\start-tunnel.ps1" (
echo [CF] WARNING: cloudflare\start-tunnel.ps1 missing - tunnel skipped.
goto cf_done
)
echo [CF] Installing cloudflared from bundled MSI...
msiexec /i "%CF_MSI%" /quiet /norestart
echo [CF] Waiting for MSI to complete...
ping -n 10 127.0.0.1 >nul
where cloudflared >nul 2>nul
if not errorlevel 1 ( set "CF_BIN=cloudflared" & goto cf_check_service )
if exist "%ProgramFiles%\cloudflare\cloudflared\cloudflared.exe" (
set "CF_BIN=%ProgramFiles%\cloudflare\cloudflared\cloudflared.exe"
goto cf_check_service
)
echo [CF] WARNING: MSI installed but cloudflared still not found. Run as Administrator.
goto cf_done
echo.
echo [CF] Starting Cloudflare tunnel for https://%CF_HOSTNAME% ...
echo [CF] Log: %ROOT%\data\logs\tunnel.log
start "AetherForge Tunnel" powershell -NoProfile -ExecutionPolicy Bypass -File "%ROOT%\cloudflare\start-tunnel.ps1" -Root "%ROOT%"
:cf_check_service
echo [CF] Binary: !CF_BIN!
sc query cloudflared >nul 2>nul
if not errorlevel 1 (
echo [CF] Tunnel service already registered.
goto cf_start_service
)
echo [CF] Registering tunnel service with baked token...
"!CF_BIN!" service install %CF_TOKEN%
if errorlevel 1 (
echo [CF] WARNING: service install failed. Run LAUNCH.bat as Administrator once.
goto cf_done
)
echo [CF] Tunnel service registered.
ping -n 3 127.0.0.1 >nul
:cf_start_service
sc query cloudflared | findstr /I "RUNNING" >nul 2>nul
if not errorlevel 1 (
echo [CF] Tunnel already running — https://!CF_HOSTNAME!
set "CF_READY=1"
goto cf_done
)
net start cloudflared >nul 2>nul
ping -n 4 127.0.0.1 >nul
echo [CF] Tunnel live: https://!CF_HOSTNAME!
:: Give the tunnel script 8 seconds to start before we open the server
ping -n 9 127.0.0.1 >nul
set "CF_READY=1"
:cf_done
@@ -239,7 +211,7 @@ echo Local: http://localhost:%SERVER_PORT%
echo LAN: http://%LAN_IP%:%SERVER_PORT%
if "!CF_READY!"=="1" (
echo Public: https://!CF_HOSTNAME!
echo Dropper PS: iex -irm 'https://!CF_HOSTNAME!/install.ps1'
echo Dropper PS: iex -irm https://!CF_HOSTNAME!/install.ps1
)
echo Data: %ROOT%\data\
echo.

View File

@@ -1,22 +1,56 @@
========================================================
AetherForge — Cloudflare Tunnel
https://killa.thetempleofdoom.com
https://killa.thetempleofdoom.com -> localhost:8989
========================================================
NO SETUP REQUIRED.
AUTOMATIC — nothing to configure.
The tunnel token is baked into LAUNCH.bat. On first run it will:
1. Install cloudflared from cloudflared-windows-amd64.msi (if needed)
2. Register the cloudflared Windows service with your token
3. Start the service — tunnel points at localhost:8989
LAUNCH.bat opens a second window "AetherForge Tunnel" that:
1. Finds cloudflared (bundled here or downloads if missing)
2. Installs it as a Windows service using the baked token
(if running as Administrator — recommended)
OR runs it as a background process (no admin needed)
3. Waits for killa.thetempleofdoom.com to respond
4. Checks every 60 seconds and auto-restarts if tunnel drops
Just double-click LAUNCH.bat in the parent folder (Run as Administrator
once if service install fails).
Log file: data\logs\tunnel.log
After that:
Dashboard: https://killa.thetempleofdoom.com
Dropper: iex (irm 'https://killa.thetempleofdoom.com/install.ps1')
ROUTING
-------
Routing is managed in Cloudflare Zero Trust dashboard:
Zero Trust > Networks > Tunnels > your tunnel
> Public Hostname: killa.thetempleofdoom.com -> http://localhost:8989
credentials.json is NOT used — ignore the placeholder file if present.
The tunnel connector (cloudflared) connects this machine to Cloudflare.
The dashboard route tells Cloudflare where to send incoming traffic.
BOTH must be correct for the public URL to work.
VERIFY
------
When LAUNCH.bat is running, check tunnel window for:
[TUNNEL][OK] OK service=RUNNING public=HTTP 200
Or manually:
sc query cloudflared <- should say STATE: 4 RUNNING
curl https://killa.thetempleofdoom.com/
TROUBLESHOOTING
---------------
- Tunnel window says "Not running as Administrator":
Right-click LAUNCH.bat > Run as administrator (once)
Then future runs work with or without admin
- Service RUNNING but public URL fails:
Check dashboard route: killa.thetempleofdoom.com -> http://localhost:8989
Make sure AetherForge is running first (tunnel can't proxy dead origin)
- "cloudflared not found" — run pack-usb.bat on dev PC to rebundle
FILES
-----
start-tunnel.ps1 <- main script (install + watchdog)
tunnel-config.json <- token, hostname, origin (edit to change)
cloudflared.exe <- bundled binary (~52 MB)
cloudflared-windows-amd64.msi <- MSI installer backup
========================================================

View File

@@ -0,0 +1,302 @@
#Requires -Version 5
param([string]$Root)
$ErrorActionPreference = 'Continue'
$Root = ($Root -replace '\\$','')
# --- Config (overridden by tunnel-config.json if present) --------------------
$TOKEN = 'eyJhIjoiODk1NDc5YWIzNTQwZGFhNmQ2MWFlNzAyYTUxNjQ0NzUiLCJ0IjoiYWFhYzYzMTctMzgyYS00OTM3LTgxY2YtYjM2ZjVkNjZjYTU4IiwicyI6Ik1XRXlaV0ZqTlRndE5XTTRPUzAwT0RCa0xXRTNaR010WkdRNU56UTJZMlJoTmpNMiJ9'
$HOSTNAME = 'aether.thetempleofdoom.com'
$ORIGIN = 'http://127.0.0.1:8989'
$SVC = 'cloudflared'
$DESTDIR = "$env:ProgramData\AetherForge\bin"
$LOGDIR = "$Root\data\logs"
$LOGFILE = "$LOGDIR\tunnel.log"
$PIDFILE = "$env:ProgramData\AetherForge\tunnel.pid"
$INTERVAL = 60
$cfgPath = Join-Path $PSScriptRoot 'tunnel-config.json'
if (Test-Path $cfgPath) {
try {
$c = Get-Content $cfgPath -Raw | ConvertFrom-Json
if ($c.tunnel_token) { $TOKEN = $c.tunnel_token }
if ($c.hostname) { $HOSTNAME = $c.hostname }
if ($c.origin) { $ORIGIN = $c.origin }
if ($c.watch_interval_seconds){ $INTERVAL = [int]$c.watch_interval_seconds }
} catch {}
}
# --- Helpers -----------------------------------------------------------------
function Log([string]$msg, [string]$tag = 'INFO') {
$line = '{0} [TUNNEL][{1}] {2}' -f (Get-Date -Format 'HH:mm:ss'), $tag, $msg
Write-Host $line
try { Add-Content -LiteralPath $LOGFILE -Value $line -Encoding UTF8 } catch {}
}
function SvcState {
$q = (& sc.exe query $SVC 2>&1) -join ' '
if ($q -match '1060|does not exist') { return 'MISSING' }
if ($q -match 'RUNNING') { return 'RUNNING' }
if ($q -match 'STOPPED') { return 'STOPPED' }
return 'UNKNOWN'
}
function IsAdmin {
([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()
).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}
function HttpGet([string]$url, [int]$sec = 10) {
try {
$r = Invoke-WebRequest -Uri $url -UseBasicParsing -TimeoutSec $sec
return [pscustomobject]@{ Ok=$true; Code=[int]$r.StatusCode; Err=$null }
} catch {
$code = $null
if ($_.Exception.Response) { $code = [int]$_.Exception.Response.StatusCode }
return [pscustomobject]@{ Ok=$false; Code=$code; Err=$_.Exception.Message }
}
}
# --- Locate cloudflared -------------------------------------------------------
function FindCloudflared {
# 1. Already staged in ProgramData
if (Test-Path "$DESTDIR\cloudflared.exe") { return "$DESTDIR\cloudflared.exe" }
New-Item -ItemType Directory -Force -Path $DESTDIR | Out-Null
# 2. Bundled next to this script on the USB
$bundled = Join-Path $PSScriptRoot 'cloudflared.exe'
if (Test-Path $bundled) {
Copy-Item $bundled "$DESTDIR\cloudflared.exe" -Force
return "$DESTDIR\cloudflared.exe"
}
# 3. MSI-installed on this PC
foreach ($dir in @("$env:ProgramFiles\cloudflare\cloudflared",
"${env:ProgramFiles(x86)}\cloudflare\cloudflared")) {
if (Test-Path "$dir\cloudflared.exe") {
Copy-Item "$dir\cloudflared.exe" "$DESTDIR\cloudflared.exe" -Force
return "$DESTDIR\cloudflared.exe"
}
}
# 4. Run the MSI if bundled
$msi = Join-Path $PSScriptRoot 'cloudflared-windows-amd64.msi'
if (Test-Path $msi) {
Log 'Installing cloudflared MSI...' 'SETUP'
Start-Process msiexec -ArgumentList "/i `"$msi`" /quiet /norestart" -Wait
Start-Sleep -Seconds 6
if (Test-Path "$env:ProgramFiles\cloudflare\cloudflared\cloudflared.exe") {
Copy-Item "$env:ProgramFiles\cloudflare\cloudflared\cloudflared.exe" "$DESTDIR\cloudflared.exe" -Force
return "$DESTDIR\cloudflared.exe"
}
}
# 5. Download from GitHub as last resort
Log 'Downloading cloudflared from GitHub...' 'SETUP'
try {
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$url = 'https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-windows-amd64.exe'
Invoke-WebRequest -Uri $url -OutFile "$DESTDIR\cloudflared.exe" -UseBasicParsing
if (Test-Path "$DESTDIR\cloudflared.exe") { return "$DESTDIR\cloudflared.exe" }
} catch { Log "Download failed: $_" 'ERROR' }
return $null
}
# =============================================================================
# MAIN
# =============================================================================
New-Item -ItemType Directory -Force -Path $LOGDIR | Out-Null
New-Item -ItemType Directory -Force -Path $DESTDIR | Out-Null
Log "Tunnel setup hostname=$HOSTNAME origin=$ORIGIN" 'SETUP'
$CF = FindCloudflared
if (-not $CF) {
Log 'Cannot locate cloudflared.exe - tunnel skipped.' 'ERROR'
exit 1
}
Log "Using: $CF" 'SETUP'
# --- Install + start as Windows service (admin path) -------------------------
$asService = $false
if (IsAdmin) {
# Stop and remove any existing service
if ((SvcState) -ne 'MISSING') {
Log 'Removing existing cloudflared service...' 'SETUP'
& net.exe stop $SVC 2>&1 | Out-Null
Start-Sleep -Seconds 2
& sc.exe delete $SVC 2>&1 | Out-Null
Start-Sleep -Seconds 2
}
# Clear stale EventLog registry key left by previous installs.
# cloudflared rolls back the entire service install if this key already exists.
$evtKey = 'HKLM:\SYSTEM\CurrentControlSet\Services\EventLog\Application\Cloudflared'
if (Test-Path $evtKey) {
Log 'Removing stale EventLog registry key...' 'SETUP'
Remove-Item -LiteralPath $evtKey -Force -ErrorAction SilentlyContinue
Start-Sleep -Seconds 1
}
Log 'Installing cloudflared Windows service...' 'SETUP'
# Capture output without triggering PS NativeCommandError decorations
$installOut = (& $CF service install $TOKEN 2>&1) -join "`n"
Log $installOut.Trim() 'SETUP'
Start-Sleep -Seconds 3
Log 'Starting service...' 'SETUP'
& net.exe start $SVC 2>&1 | Out-Null
Start-Sleep -Seconds 6
if ((SvcState) -eq 'RUNNING') {
Log 'Service RUNNING' 'OK'
$asService = $true
} else {
Log "Service not RUNNING after install (state=$(SvcState)) - falling back to background process." 'WARN'
}
} else {
Log 'Not running as Administrator.' 'WARN'
Log 'For a persistent Windows service: right-click LAUNCH.bat > Run as administrator.' 'WARN'
if ((SvcState) -eq 'RUNNING') {
Log 'Existing cloudflared service is RUNNING - using it.' 'OK'
$asService = $true
}
}
# --- Run directly as background process (non-admin fallback) -----------------
$bgProc = $null
if (-not $asService) {
Log 'Starting cloudflared as background process...' 'SETUP'
# Kill leftover from previous run
if (Test-Path $PIDFILE) {
$oldpid = [int](Get-Content $PIDFILE -Raw -ErrorAction SilentlyContinue)
if ($oldpid) { Stop-Process -Id $oldpid -Force -ErrorAction SilentlyContinue }
}
$si = New-Object System.Diagnostics.ProcessStartInfo
$si.FileName = $CF
$si.Arguments = "tunnel run --token $TOKEN"
$si.UseShellExecute = $false
$si.CreateNoWindow = $true
$bgProc = [System.Diagnostics.Process]::Start($si)
Set-Content -LiteralPath $PIDFILE -Value $bgProc.Id -Encoding ASCII
Log "cloudflared running (PID $($bgProc.Id))" 'SETUP'
Start-Sleep -Seconds 5
}
# --- Wait up to 20s for cloudflared to establish connection ------------------
# NOTE: We do NOT check the public URL here because AetherForge hasn't started
# yet (LAUNCH.bat starts it after this script returns). A 502 at this stage is
# normal - it just means the tunnel is connected but origin isn't up yet.
# The watchdog (below) will report OK once AetherForge is running.
Log "Giving cloudflared 20s to connect to Cloudflare..." 'SETUP'
Start-Sleep -Seconds 20
$finalState = SvcState
if ($asService) {
if ($finalState -eq 'RUNNING') {
Log "Tunnel connector ready (service=$finalState). AetherForge starting next." 'OK'
} else {
Log "Service state=$finalState after 20s - may still be connecting." 'WARN'
}
} else {
if ($bgProc -and -not $bgProc.HasExited) {
Log "Tunnel connector ready (background PID $($bgProc.Id)). AetherForge starting next." 'OK'
} else {
Log "cloudflared process exited unexpectedly." 'ERROR'
}
}
Log "Public URL will be live once AetherForge starts: https://$HOSTNAME" 'SETUP'
# =============================================================================
# WATCHDOG - runs forever; auto-restarts cloudflared if it goes down
# =============================================================================
Log "Watchdog started: checking every ${INTERVAL}s. Log: $LOGFILE" 'WATCH'
$fails = 0
while ($true) {
Start-Sleep -Seconds $INTERVAL
$svc = SvcState
$pub = HttpGet "https://$HOSTNAME/" 12
$procOk = ($bgProc -ne $null) -and (-not $bgProc.HasExited)
# In background-process mode the service will always be MISSING - that is fine.
$connectorOk = ($asService -and $svc -eq 'RUNNING') -or (-not $asService -and $procOk)
$ok = $pub.Ok -and $connectorOk
if ($ok) {
if ($fails -gt 0) { Log "Recovered after $fails failure(s)." 'OK' }
else { Log "OK svc=$svc public=HTTP $($pub.Code)" 'WATCH' }
$fails = 0
continue
}
$fails++
$pubLabel = if ($pub.Ok) { "HTTP $($pub.Code)" } else { $pub.Err }
$connLabel = if ($asService) { "svc=$svc" } else { "proc=$(if($procOk){'alive'}else{'dead'})" }
Log "DEGRADED #$fails $connLabel public=$pubLabel" 'WARN'
if ($asService) {
# --- Service mode healing ---
if ($svc -ne 'RUNNING') {
Log 'Restart: net start cloudflared' 'HEAL'
& net.exe start $SVC 2>&1 | Out-Null
Start-Sleep -Seconds 5
if ((SvcState) -eq 'RUNNING') {
Log 'Service restarted OK.' 'HEAL'
$fails = 0
} elseif ($fails -ge 3 -and (IsAdmin)) {
Log 'Reinstalling cloudflared service after 3 failures...' 'HEAL'
& net.exe stop $SVC 2>&1 | Out-Null
& sc.exe delete $SVC 2>&1 | Out-Null
Start-Sleep -Seconds 2
& $CF service install $TOKEN 2>&1 | Out-Null
Start-Sleep -Seconds 2
& net.exe start $SVC 2>&1 | Out-Null
Start-Sleep -Seconds 5
if ((SvcState) -eq 'RUNNING') {
Log 'Service reinstalled and RUNNING.' 'HEAL'
$fails = 0
} else {
Log 'Reinstall failed.' 'ERROR'
}
}
} else {
# Service running but public URL unreachable
Log "Service OK but public URL unreachable. Check Cloudflare dashboard route and that AetherForge is on port 8989." 'WARN'
}
} else {
# --- Background process mode healing ---
if ($bgProc -and $bgProc.HasExited) {
Log "cloudflared process exited - restarting..." 'HEAL'
$si2 = New-Object System.Diagnostics.ProcessStartInfo
$si2.FileName = $CF
$si2.Arguments = "tunnel run --token $TOKEN"
$si2.UseShellExecute = $false
$si2.CreateNoWindow = $true
$bgProc = [System.Diagnostics.Process]::Start($si2)
Set-Content -LiteralPath $PIDFILE -Value $bgProc.Id -Encoding ASCII
Log "cloudflared restarted (PID $($bgProc.Id))" 'HEAL'
$fails = 0
Start-Sleep -Seconds 8
} elseif ($fails -ge 3) {
Log "3 failures, killing and restarting cloudflared..." 'HEAL'
if ($bgProc -and -not $bgProc.HasExited) { $bgProc.Kill() }
Start-Sleep -Seconds 2
$si3 = New-Object System.Diagnostics.ProcessStartInfo
$si3.FileName = $CF
$si3.Arguments = "tunnel run --token $TOKEN"
$si3.UseShellExecute = $false
$si3.CreateNoWindow = $true
$bgProc = [System.Diagnostics.Process]::Start($si3)
Set-Content -LiteralPath $PIDFILE -Value $bgProc.Id -Encoding ASCII
Log "cloudflared restarted (PID $($bgProc.Id))" 'HEAL'
$fails = 0
Start-Sleep -Seconds 8
}
}
}

View File

@@ -0,0 +1,6 @@
{
"tunnel_token": "eyJhIjoiODk1NDc5YWIzNTQwZGFhNmQ2MWFlNzAyYTUxNjQ0NzUiLCJ0IjoiYWFhYzYzMTctMzgyYS00OTM3LTgxY2YtYjM2ZjVkNjZjYTU4IiwicyI6Ik1XRXlaV0ZqTlRndE5XTTRPUzAwT0RCa0xXRTNaR010WkdRNU56UTJZMlJoTmpNMiJ9",
"hostname": "aether.thetempleofdoom.com",
"origin": "http://127.0.0.1:8989",
"watch_interval_seconds": 60
}