#Requires -Version 5.1 <# .SYNOPSIS Bootstrap temporary WireGuard + OpenSSH assistance tunnel. .PARAMETER Token Invitation token from /join/ .PARAMETER ApiBase Public API base URL .PARAMETER StateDir Persistent state directory #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string]$Token, [string]$ApiBase = $(if ($env:SUPPORT_API_BASE) { $env:SUPPORT_API_BASE } else { "https://support.marcatos.ddns.net" }), [string]$StateDir = $(Join-Path $env:ProgramData "AssistenzaSimone") ) $ErrorActionPreference = "Stop" $Modules = Join-Path $PSScriptRoot "modules" Import-Module (Join-Path $Modules "Logging.psm1") -Force Import-Module (Join-Path $Modules "Admin.psm1") -Force Import-Module (Join-Path $Modules "State.psm1") -Force Import-Module (Join-Path $Modules "Api.psm1") -Force Import-Module (Join-Path $Modules "WireGuard.psm1") -Force Import-Module (Join-Path $Modules "OpenSSH.psm1") -Force Import-Module (Join-Path $Modules "Firewall.psm1") -Force $id = [Security.Principal.WindowsIdentity]::GetCurrent() $principal = New-Object Security.Principal.WindowsPrincipal($id) if (-not $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { $argList = "-ExecutionPolicy Bypass -File `"$PSCommandPath`" -Token `"$Token`" -ApiBase `"$ApiBase`"" Start-Process -FilePath "powershell.exe" -Verb RunAs -ArgumentList $argList | Out-Null exit 0 } Ensure-AssistenzaAdmin $script:LogDir = Join-Path $StateDir "logs" Initialize-AssistenzaLogging -LogDir $script:LogDir Write-AssistenzaLog -Level INFO -Message "bootstrap_start" $statePath = Join-Path $StateDir "state.json" if (Test-Path $statePath) { $existing = Get-AssistenzaState -Path $statePath if ($existing -and $existing.status -eq "ACTIVE") { Write-Host "Sessione precedente attiva trovata. Esegui cleanup.ps1 prima di continuare." -ForegroundColor Yellow exit 2 } if ($existing -and $existing.status -eq "INCOMPLETE") { Write-Host "Stato incompleto rilevato — eseguo cleanup sicuro..." -ForegroundColor Yellow & (Join-Path $PSScriptRoot "cleanup.ps1") -Force } } New-Item -ItemType Directory -Force -Path $StateDir | Out-Null $snapshot = New-AssistenzaSnapshot $tunnelName = "assistenza-simone" $privateKey = $null $publicKey = $null try { Assert-WireGuardAvailable $wgInstalledByUs = Install-WireGuardIfNeeded $keys = New-LocalWireGuardKeypair $privateKey = $keys.PrivateKey $publicKey = $keys.PublicKey Write-AssistenzaLog -Level INFO -Message "wg_keypair_generated" $hostname = $env:COMPUTERNAME $redeem = Invoke-AssistenzaRedeem -ApiBase $ApiBase -Token $Token -Pubkey $publicKey -Hostname $hostname Write-AssistenzaLog -Level INFO -Message "session_registered session=$($redeem.session_id)" $confPath = Join-Path $StateDir "$tunnelName.conf" Write-WireGuardConfig -Path $confPath -PrivateKey $privateKey -Address $redeem.wireguard.interface_address ` -PeerPublicKey $redeem.wireguard.peer_public_key -Endpoint $redeem.wireguard.endpoint ` -AllowedIPs $redeem.wireguard.allowed_ips -Keepalive $redeem.wireguard.persistent_keepalive Start-WireGuardTunnel -ConfigPath $confPath -Name $tunnelName $ssh = Ensure-OpenSSHSupportUser -AdminPubkey $redeem.ssh.admin_pubkey -Snapshot $snapshot $fw = Ensure-AssistenzaFirewallRule -RemoteAddress "10.90.0.0/24" $state = [ordered]@{ status = "ACTIVE" session_id = $redeem.session_id session_token = $redeem.session_token vpn_ip = $redeem.vpn_ip api_base = $ApiBase tunnel_name = $tunnelName conf_path = $confPath wg_installed_by_us = $wgInstalledByUs ssh = $ssh firewall = $fw snapshot = $snapshot created_at = (Get-Date).ToUniversalTime().ToString("o") } Save-AssistenzaState -Path $statePath -State $state Write-Host "" Write-Host "========================================" -ForegroundColor Green Write-Host " ASSISTENZA ATTIVA" -ForegroundColor Green Write-Host " SESSION: $($redeem.session_id)" -ForegroundColor Green Write-Host " Comunica questo codice all'assistenza" -ForegroundColor Green Write-Host "========================================" -ForegroundColor Green Write-Host "" Write-AssistenzaLog -Level INFO -Message "bootstrap_ok session=$($redeem.session_id)" } catch { Write-AssistenzaLog -Level ERROR -Message ("bootstrap_failed " + $_.Exception.Message) $fail = [ordered]@{ status = "INCOMPLETE"; snapshot = $snapshot; error = $_.Exception.Message } Save-AssistenzaState -Path $statePath -State $fail Write-Host "ERRORE: $($_.Exception.Message)" -ForegroundColor Red Write-Host "Esegui cleanup.ps1 per ripristinare." -ForegroundColor Yellow exit 1 } finally { if ($privateKey) { $privateKey = $null } }