mirror of
https://github.com/bunny-lab-io/Borealis.git
synced 2025-12-17 03:25:49 -07:00
Reverse VPN Tunnel Deployment - Milestone: Dependencies & Bootstrap (Windows)
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -19,9 +19,12 @@ database.db
|
|||||||
/Dependencies/Python/
|
/Dependencies/Python/
|
||||||
/Dependencies/AutoHotKey/
|
/Dependencies/AutoHotKey/
|
||||||
/Dependencies/git/
|
/Dependencies/git/
|
||||||
|
/Dependencies/VPN_Tunnel_Adapter/*
|
||||||
|
!/Dependencies/VPN_Tunnel_Adapter/README.md
|
||||||
|
!/Dependencies/VPN_Tunnel_Adapter/.gitkeep
|
||||||
/Data/Engine/Python_API_Endpoints/
|
/Data/Engine/Python_API_Endpoints/
|
||||||
|
|
||||||
# Misc Files/Folders
|
# Misc Files/Folders
|
||||||
.vs/s
|
.vs/s
|
||||||
__pycache__
|
__pycache__
|
||||||
/Update_Staging/
|
/Update_Staging/
|
||||||
|
|||||||
490
Borealis.ps1
490
Borealis.ps1
@@ -437,6 +437,21 @@ $gitZipUrl = "https://github.com/git-for-windows/git/releases/download/$git
|
|||||||
$gitZipPath = Join-Path $depsRoot $gitPackageName
|
$gitZipPath = Join-Path $depsRoot $gitPackageName
|
||||||
$gitInstallDir = Join-Path $depsRoot 'git'
|
$gitInstallDir = Join-Path $depsRoot 'git'
|
||||||
$gitExePath = Join-Path $gitInstallDir 'cmd\git.exe'
|
$gitExePath = Join-Path $gitInstallDir 'cmd\git.exe'
|
||||||
|
$wireGuardDownloadRoot = "https://download.wireguard.com/windows-client/"
|
||||||
|
$wireGuardInstallerDir = Join-Path $depsRoot 'VPN_Tunnel_Adapter'
|
||||||
|
$wireGuardBootstrapperName = 'wireguard-installer.exe'
|
||||||
|
$wireGuardBootstrapperPath = Join-Path $wireGuardInstallerDir $wireGuardBootstrapperName
|
||||||
|
$wireGuardMsiVersion = '0.5.3'
|
||||||
|
$wireGuardMsiFiles = @{
|
||||||
|
'X64' = "wireguard-amd64-$wireGuardMsiVersion.msi"
|
||||||
|
'AMD64' = "wireguard-amd64-$wireGuardMsiVersion.msi"
|
||||||
|
'ARM64' = "wireguard-arm64-$wireGuardMsiVersion.msi"
|
||||||
|
'X86' = "wireguard-x86-$wireGuardMsiVersion.msi"
|
||||||
|
}
|
||||||
|
$wintunVersion = '0.14.1'
|
||||||
|
$wintunZipName = "wintun-$wintunVersion.zip"
|
||||||
|
$wintunDownloadUrl = "https://www.wintun.net/builds/$wintunZipName"
|
||||||
|
$wintunZipPath = Join-Path $wireGuardInstallerDir $wintunZipName
|
||||||
|
|
||||||
# ---------------------- Dependency Installation Functions ----------------------
|
# ---------------------- Dependency Installation Functions ----------------------
|
||||||
function Install_Shared_Dependencies {
|
function Install_Shared_Dependencies {
|
||||||
@@ -561,6 +576,384 @@ function Install_Server_Dependencies {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Install_Agent_Dependencies {
|
function Install_Agent_Dependencies {
|
||||||
|
function Get-WireGuardMsiName {
|
||||||
|
param([string]$ArchitectureTag)
|
||||||
|
|
||||||
|
if (-not $ArchitectureTag) { return $wireGuardMsiFiles['X64'] }
|
||||||
|
$normalized = $ArchitectureTag.ToUpperInvariant()
|
||||||
|
if ($wireGuardMsiFiles.ContainsKey($normalized)) {
|
||||||
|
return $wireGuardMsiFiles[$normalized]
|
||||||
|
}
|
||||||
|
return $wireGuardMsiFiles['X64']
|
||||||
|
}
|
||||||
|
|
||||||
|
function Ensure-WireGuardInstallerFile {
|
||||||
|
param(
|
||||||
|
[string]$Url,
|
||||||
|
[string]$DestinationPath,
|
||||||
|
[string]$LogName = 'Install.log'
|
||||||
|
)
|
||||||
|
|
||||||
|
if (-not $Url -or -not $DestinationPath) { return }
|
||||||
|
$destDir = Split-Path $DestinationPath -Parent
|
||||||
|
if (-not (Test-Path $destDir)) {
|
||||||
|
try {
|
||||||
|
New-Item -ItemType Directory -Path $destDir -Force | Out-Null
|
||||||
|
Write-AgentLog -FileName $LogName -Message ("[WireGuard] Created installer cache at {0}" -f $destDir)
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Test-Path $DestinationPath -PathType Leaf) {
|
||||||
|
Write-AgentLog -FileName $LogName -Message ("[WireGuard] Installer already cached at {0}" -f $DestinationPath)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-AgentLog -FileName $LogName -Message ("[WireGuard] Downloading installer from {0}" -f $Url)
|
||||||
|
Invoke-WebRequest -Uri $Url -OutFile $DestinationPath
|
||||||
|
Write-AgentLog -FileName $LogName -Message ("[WireGuard] Cached installer at {0}" -f $DestinationPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
function Get-WireGuardInstallState {
|
||||||
|
$state = [ordered]@{
|
||||||
|
Installed = $false
|
||||||
|
Version = $null
|
||||||
|
ExePath = $null
|
||||||
|
ServicePresent = $false
|
||||||
|
DriverPresent = $false
|
||||||
|
DriverPaths = @()
|
||||||
|
}
|
||||||
|
|
||||||
|
$exeCandidates = @(
|
||||||
|
(Join-Path $env:ProgramFiles 'WireGuard\wireguard.exe'),
|
||||||
|
(Join-Path $env:ProgramFiles 'WireGuard\wg.exe'),
|
||||||
|
(Join-Path ${env:ProgramFiles(x86)} 'WireGuard\wireguard.exe'),
|
||||||
|
(Join-Path ${env:ProgramFiles(x86)} 'WireGuard\wg.exe')
|
||||||
|
) | Where-Object { $_ }
|
||||||
|
|
||||||
|
foreach ($candidate in $exeCandidates) {
|
||||||
|
if (Test-Path $candidate -PathType Leaf) {
|
||||||
|
$state.Installed = $true
|
||||||
|
if (-not $state.ExePath) { $state.ExePath = $candidate }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$svc = Get-Service -Name 'WireGuardManager' -ErrorAction Stop
|
||||||
|
if ($svc) { $state.ServicePresent = $true; $state.Installed = $true }
|
||||||
|
} catch {}
|
||||||
|
|
||||||
|
$driverCandidates = @()
|
||||||
|
if ($env:WINDIR) {
|
||||||
|
$driverCandidates += (Join-Path $env:WINDIR 'System32\drivers\wintun.sys')
|
||||||
|
$driverCandidates += (Join-Path $env:WINDIR 'System32\drivers\*wintun*.sys')
|
||||||
|
$driverCandidates += (Join-Path $env:WINDIR 'Sysnative\drivers\wintun.sys')
|
||||||
|
$driverCandidates += (Join-Path $env:WINDIR 'Sysnative\drivers\*wintun*.sys')
|
||||||
|
}
|
||||||
|
$driverCandidates = $driverCandidates | Where-Object { $_ }
|
||||||
|
$driverHits = @()
|
||||||
|
foreach ($driver in $driverCandidates) {
|
||||||
|
try {
|
||||||
|
$items = Get-ChildItem -Path $driver -ErrorAction SilentlyContinue -Force
|
||||||
|
foreach ($item in $items) {
|
||||||
|
if ($item -and $item.PSIsContainer -eq $false) {
|
||||||
|
$driverHits += $item.FullName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
if ($driverHits.Count -gt 0) {
|
||||||
|
$state.DriverPresent = $true
|
||||||
|
$state.Installed = $true
|
||||||
|
$state.DriverPaths = $driverHits | Select-Object -Unique
|
||||||
|
}
|
||||||
|
|
||||||
|
$uninstallRoots = @(
|
||||||
|
'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
|
||||||
|
'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
|
||||||
|
)
|
||||||
|
foreach ($root in $uninstallRoots) {
|
||||||
|
try {
|
||||||
|
$items = Get-ChildItem -Path $root -ErrorAction Stop
|
||||||
|
foreach ($item in $items) {
|
||||||
|
try {
|
||||||
|
$props = Get-ItemProperty -Path $item.PSPath -ErrorAction Stop
|
||||||
|
$name = $props.DisplayName
|
||||||
|
if ($name -and $name -like 'WireGuard*') {
|
||||||
|
$state.Installed = $true
|
||||||
|
if ($props.DisplayVersion) {
|
||||||
|
$state.Version = $props.DisplayVersion
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
} catch {}
|
||||||
|
if ($state.Version) { break }
|
||||||
|
}
|
||||||
|
|
||||||
|
return [pscustomobject]$state
|
||||||
|
}
|
||||||
|
|
||||||
|
function Install-WireGuardMsi {
|
||||||
|
param(
|
||||||
|
[string]$InstallerPath,
|
||||||
|
[string]$BootstrapperPath,
|
||||||
|
[string]$LogName = 'Install.log'
|
||||||
|
)
|
||||||
|
|
||||||
|
$logPrefix = '[WireGuard]'
|
||||||
|
if (-not (Test-IsAdmin)) {
|
||||||
|
$msg = "$logPrefix Admin rights are required to install WireGuard."
|
||||||
|
Write-AgentLog -FileName $LogName -Message $msg
|
||||||
|
throw $msg
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not (Test-Path $InstallerPath -PathType Leaf)) {
|
||||||
|
$msg = "$logPrefix Installer not found at $InstallerPath"
|
||||||
|
Write-AgentLog -FileName $LogName -Message $msg
|
||||||
|
throw $msg
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-AgentLog -FileName $LogName -Message ("$logPrefix Installing WireGuard from {0}" -f $InstallerPath)
|
||||||
|
$args = "/i `"$InstallerPath`" /qn /norestart"
|
||||||
|
try {
|
||||||
|
$proc = Start-Process -FilePath 'msiexec.exe' -ArgumentList $args -Wait -PassThru -WindowStyle Hidden -ErrorAction Stop
|
||||||
|
$exitCode = $proc.ExitCode
|
||||||
|
Write-AgentLog -FileName $LogName -Message ("$logPrefix msiexec exit code: {0}" -f $exitCode)
|
||||||
|
if ($exitCode -eq 0) { return }
|
||||||
|
|
||||||
|
$fallbackReason = "WireGuard MSI install returned exit code $exitCode"
|
||||||
|
Write-AgentLog -FileName $LogName -Message ("$logPrefix $fallbackReason")
|
||||||
|
|
||||||
|
if ($BootstrapperPath -and (Test-Path $BootstrapperPath -PathType Leaf)) {
|
||||||
|
Write-AgentLog -FileName $LogName -Message ("$logPrefix Falling back to bootstrapper at {0}" -f $BootstrapperPath)
|
||||||
|
try {
|
||||||
|
$bp = Start-Process -FilePath $BootstrapperPath -ArgumentList '/install','/quiet' -Wait -PassThru -WindowStyle Hidden -ErrorAction Stop
|
||||||
|
$bpExit = $bp.ExitCode
|
||||||
|
Write-AgentLog -FileName $LogName -Message ("$logPrefix Bootstrapper exit code: {0}" -f $bpExit)
|
||||||
|
if ($bpExit -eq 0) { return }
|
||||||
|
throw "$logPrefix Bootstrapper returned exit code $bpExit"
|
||||||
|
} catch {
|
||||||
|
$err = $_.Exception.Message
|
||||||
|
Write-AgentLog -FileName $LogName -Message ("$logPrefix Bootstrapper install failed: {0}" -f $err)
|
||||||
|
throw
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw $fallbackReason
|
||||||
|
} catch {
|
||||||
|
$err = $_.Exception.Message
|
||||||
|
Write-AgentLog -FileName $LogName -Message ("$logPrefix Installation failed: {0}" -f $err)
|
||||||
|
throw
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function New-WireGuardKeyPair {
|
||||||
|
param(
|
||||||
|
[string]$WireGuardExe,
|
||||||
|
[string]$WgExe
|
||||||
|
)
|
||||||
|
|
||||||
|
$pair = @{ PrivateKey = $null; PublicKey = $null; Source = $null }
|
||||||
|
$cliCandidates = @()
|
||||||
|
if ($WgExe) { $cliCandidates += $WgExe }
|
||||||
|
if ($WireGuardExe) { $cliCandidates += $WireGuardExe }
|
||||||
|
|
||||||
|
foreach ($cli in $cliCandidates) {
|
||||||
|
if (-not $cli -or -not (Test-Path $cli -PathType Leaf)) { continue }
|
||||||
|
try {
|
||||||
|
# Only wg.exe supports genkey; wireguard.exe likely won't, but attempt anyway
|
||||||
|
$priv = (& $cli genkey)
|
||||||
|
if ($priv) {
|
||||||
|
$priv = $priv.Trim()
|
||||||
|
$pair.PrivateKey = $priv
|
||||||
|
$pair.Source = $cli
|
||||||
|
try {
|
||||||
|
$padLen = 4 - ($priv.Length % 4)
|
||||||
|
$privForPub = $priv
|
||||||
|
if ($padLen -lt 4) {
|
||||||
|
$privForPub = $priv + ('=' * $padLen)
|
||||||
|
}
|
||||||
|
$pub = ($privForPub | & $cli pubkey)
|
||||||
|
if ($pub) { $pair.PublicKey = $pub.Trim() }
|
||||||
|
} catch {}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not $pair.PrivateKey) {
|
||||||
|
try {
|
||||||
|
$rng = [System.Security.Cryptography.RandomNumberGenerator]::Create()
|
||||||
|
$bytes = New-Object byte[] 32
|
||||||
|
$rng.GetBytes($bytes)
|
||||||
|
$priv = [System.Convert]::ToBase64String($bytes)
|
||||||
|
$pair.PrivateKey = $priv
|
||||||
|
$pair.PublicKey = $null
|
||||||
|
$pair.Source = 'rng'
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $pair
|
||||||
|
}
|
||||||
|
|
||||||
|
function Ensure-WireGuardDriver {
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory = $true)][string]$WireGuardExe,
|
||||||
|
[Parameter()][string]$LogName = 'Install.log'
|
||||||
|
)
|
||||||
|
|
||||||
|
$logPrefix = '[WireGuard]'
|
||||||
|
$state = Get-WireGuardInstallState
|
||||||
|
if ($state.DriverPresent) {
|
||||||
|
Write-AgentLog -FileName $LogName -Message "$logPrefix Driver already present."
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not (Test-Path $WireGuardExe -PathType Leaf)) {
|
||||||
|
$msg = "$logPrefix Cannot install driver: wireguard.exe not found at $WireGuardExe"
|
||||||
|
Write-AgentLog -FileName $LogName -Message $msg
|
||||||
|
throw $msg
|
||||||
|
}
|
||||||
|
|
||||||
|
# Try installing/refreshing the manager service (also stages the driver)
|
||||||
|
try {
|
||||||
|
Write-AgentLog -FileName $LogName -Message "$logPrefix Invoking wireguard.exe /installmanagerservice to seed driver."
|
||||||
|
& $WireGuardExe /installmanagerservice | Out-Null
|
||||||
|
$wgExit = $LASTEXITCODE
|
||||||
|
Write-AgentLog -FileName $LogName -Message ("$logPrefix /installmanagerservice exit code: {0}" -f $wgExit)
|
||||||
|
} catch {
|
||||||
|
Write-AgentLog -FileName $LogName -Message ("$logPrefix /installmanagerservice failed: {0}" -f $_.Exception.Message)
|
||||||
|
}
|
||||||
|
|
||||||
|
$stateAfterManager = Get-WireGuardInstallState
|
||||||
|
if ($stateAfterManager.DriverPresent) {
|
||||||
|
Write-AgentLog -FileName $LogName -Message "$logPrefix Driver present after /installmanagerservice."
|
||||||
|
return
|
||||||
|
}
|
||||||
|
$state = $stateAfterManager
|
||||||
|
|
||||||
|
$wgCliExe = $null
|
||||||
|
try {
|
||||||
|
$wgCliCandidate = Join-Path (Split-Path $WireGuardExe -Parent) 'wg.exe'
|
||||||
|
if (Test-Path $wgCliCandidate -PathType Leaf) { $wgCliExe = $wgCliCandidate }
|
||||||
|
} catch {}
|
||||||
|
|
||||||
|
$bootstrapName = 'BorealisBootstrap'
|
||||||
|
$bootstrapDir = Join-Path $env:TEMP 'Borealis-WireGuard-Bootstrap'
|
||||||
|
$bootstrapConf = Join-Path $bootstrapDir "$bootstrapName.conf"
|
||||||
|
try {
|
||||||
|
if (-not (Test-Path $bootstrapDir)) {
|
||||||
|
New-Item -ItemType Directory -Path $bootstrapDir -Force | Out-Null
|
||||||
|
}
|
||||||
|
} catch {}
|
||||||
|
|
||||||
|
$keyPair = New-WireGuardKeyPair -WireGuardExe $WireGuardExe -WgExe $wgCliExe
|
||||||
|
if (-not $keyPair.PrivateKey) {
|
||||||
|
$msg = "$logPrefix Failed to generate WireGuard keypair for driver bootstrap."
|
||||||
|
Write-AgentLog -FileName $LogName -Message $msg
|
||||||
|
throw $msg
|
||||||
|
}
|
||||||
|
|
||||||
|
$peerKey = if ($keyPair.PublicKey) { $keyPair.PublicKey } else { $keyPair.PrivateKey }
|
||||||
|
$conf = @"
|
||||||
|
[Interface]
|
||||||
|
PrivateKey = $($keyPair.PrivateKey)
|
||||||
|
Address = 10.255.255.2/32
|
||||||
|
ListenPort = 0
|
||||||
|
"@
|
||||||
|
if ($keyPair.PublicKey) {
|
||||||
|
$conf += @"
|
||||||
|
|
||||||
|
[Peer]
|
||||||
|
PublicKey = $peerKey
|
||||||
|
AllowedIPs = 10.255.255.1/32
|
||||||
|
"@
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Set-Content -Path $bootstrapConf -Value $conf -Encoding ASCII -Force
|
||||||
|
Write-AgentLog -FileName $LogName -Message ("$logPrefix Created driver bootstrap config at {0}" -f $bootstrapConf)
|
||||||
|
} catch {
|
||||||
|
$msg = "$logPrefix Failed to write bootstrap config: $($_.Exception.Message)"
|
||||||
|
Write-AgentLog -FileName $LogName -Message $msg
|
||||||
|
throw $msg
|
||||||
|
}
|
||||||
|
|
||||||
|
$serviceName = "WireGuardTunnel$bootstrapName"
|
||||||
|
try {
|
||||||
|
Write-AgentLog -FileName $LogName -Message ("$logPrefix Installing bootstrap tunnel service to seed driver ({0})" -f $serviceName)
|
||||||
|
& $WireGuardExe /installtunnelservice $bootstrapConf | Out-Null
|
||||||
|
$installExit = $LASTEXITCODE
|
||||||
|
Write-AgentLog -FileName $LogName -Message ("$logPrefix /installtunnelservice exit code: {0}" -f $installExit)
|
||||||
|
if ($installExit -ne 0) {
|
||||||
|
throw "wireguard.exe /installtunnelservice failed with exit code $installExit"
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
$msg = "$logPrefix Failed to install bootstrap tunnel service: $($_.Exception.Message)"
|
||||||
|
Write-AgentLog -FileName $LogName -Message $msg
|
||||||
|
throw $msg
|
||||||
|
}
|
||||||
|
|
||||||
|
Start-Sleep -Seconds 2
|
||||||
|
try {
|
||||||
|
& $WireGuardExe /uninstalltunnelservice $bootstrapName | Out-Null
|
||||||
|
$uninstallExit = $LASTEXITCODE
|
||||||
|
Write-AgentLog -FileName $LogName -Message ("$logPrefix /uninstalltunnelservice exit code: {0}" -f $uninstallExit)
|
||||||
|
Write-AgentLog -FileName $LogName -Message ("$logPrefix Removed bootstrap tunnel service {0}" -f $serviceName)
|
||||||
|
} catch {
|
||||||
|
Write-AgentLog -FileName $LogName -Message ("$logPrefix Cleanup of bootstrap tunnel service failed: {0}" -f $_.Exception.Message)
|
||||||
|
}
|
||||||
|
|
||||||
|
try { Remove-Item -Path $bootstrapConf -Force -ErrorAction SilentlyContinue } catch {}
|
||||||
|
try { Remove-Item -Path $bootstrapDir -Recurse -Force -ErrorAction SilentlyContinue } catch {}
|
||||||
|
|
||||||
|
$post = Get-WireGuardInstallState
|
||||||
|
$postDriver = $post.DriverPresent
|
||||||
|
$postMsg = "[WireGuard] Driver presence after bootstrap: $postDriver (Exe: $WireGuardExe)"
|
||||||
|
Write-AgentLog -FileName $LogName -Message $postMsg
|
||||||
|
if ($postDriver) { return }
|
||||||
|
|
||||||
|
# Fallback: install Wintun driver directly via pnputil using the official Wintun package
|
||||||
|
try {
|
||||||
|
Ensure-WireGuardInstallerFile -Url $wintunDownloadUrl -DestinationPath $wintunZipPath -LogName $LogName
|
||||||
|
} catch {
|
||||||
|
Write-AgentLog -FileName $LogName -Message ("$logPrefix Failed to cache Wintun zip: {0}" -f $_.Exception.Message)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Test-Path $wintunZipPath -PathType Leaf) {
|
||||||
|
$extractRoot = Join-Path $env:TEMP 'Borealis-Wintun'
|
||||||
|
try { Remove-Item -Recurse -Force -ErrorAction SilentlyContinue $extractRoot } catch {}
|
||||||
|
try { New-Item -ItemType Directory -Force -Path $extractRoot | Out-Null } catch {}
|
||||||
|
try {
|
||||||
|
Expand-Archive -Path $wintunZipPath -DestinationPath $extractRoot -Force
|
||||||
|
Write-AgentLog -FileName $LogName -Message ("$logPrefix Expanded Wintun zip to {0}" -f $extractRoot)
|
||||||
|
} catch {
|
||||||
|
Write-AgentLog -FileName $LogName -Message ("$logPrefix Failed to expand Wintun zip: {0}" -f $_.Exception.Message)
|
||||||
|
}
|
||||||
|
|
||||||
|
$infPath = Get-ChildItem -Path $extractRoot -Recurse -Filter '*.inf' -ErrorAction SilentlyContinue | Select-Object -First 1
|
||||||
|
if ($infPath -and (Test-Path $infPath.FullName -PathType Leaf)) {
|
||||||
|
try {
|
||||||
|
Write-AgentLog -FileName $LogName -Message ("$logPrefix Installing Wintun driver via pnputil: {0}" -f $infPath.FullName)
|
||||||
|
pnputil.exe /add-driver "`"$($infPath.FullName)`"" /install | Out-Null
|
||||||
|
$postPnP = Get-WireGuardInstallState
|
||||||
|
$postPnPDriver = $postPnP.DriverPresent
|
||||||
|
Write-AgentLog -FileName $LogName -Message ("$logPrefix Driver presence after pnputil install: $postPnPDriver")
|
||||||
|
if (-not $postPnPDriver) {
|
||||||
|
throw "$logPrefix pnputil install completed but driver still missing."
|
||||||
|
}
|
||||||
|
return
|
||||||
|
} catch {
|
||||||
|
Write-AgentLog -FileName $LogName -Message ("$logPrefix pnputil driver install failed: {0}" -f $_.Exception.Message)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-AgentLog -FileName $LogName -Message "$logPrefix No Wintun INF found in extracted package."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw "$logPrefix Driver still missing after bootstrap and pnputil fallback."
|
||||||
|
}
|
||||||
|
|
||||||
# AutoHotKey portable
|
# AutoHotKey portable
|
||||||
Run-Step "Dependency: AutoHotKey" {
|
Run-Step "Dependency: AutoHotKey" {
|
||||||
$ahkVersion = "2.0.19"
|
$ahkVersion = "2.0.19"
|
||||||
@@ -619,6 +1012,103 @@ function Install_Agent_Dependencies {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Run-Step "Dependency: WireGuard VPN Adapter" {
|
||||||
|
$logName = 'Install.log'
|
||||||
|
$arch = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture
|
||||||
|
$archKey = $null
|
||||||
|
try { $archKey = $arch.ToString().ToUpperInvariant() } catch { $archKey = 'X64' }
|
||||||
|
$msiName = Get-WireGuardMsiName -ArchitectureTag $archKey
|
||||||
|
$msiPath = $null
|
||||||
|
if ($msiName) {
|
||||||
|
$msiPath = Join-Path $wireGuardInstallerDir $msiName
|
||||||
|
Ensure-WireGuardInstallerFile -Url ("$wireGuardDownloadRoot$msiName") -DestinationPath $msiPath -LogName $logName
|
||||||
|
} else {
|
||||||
|
Write-AgentLog -FileName $logName -Message ("[WireGuard] Unable to resolve MSI name for architecture '{0}'. Defaulting to cached bootstrapper only." -f $archKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
Ensure-WireGuardInstallerFile -Url ("$wireGuardDownloadRoot$wireGuardBootstrapperName") -DestinationPath $wireGuardBootstrapperPath -LogName $logName
|
||||||
|
|
||||||
|
$state = Get-WireGuardInstallState
|
||||||
|
$stateVersion = if ($state.Version) { $state.Version } else { 'unknown' }
|
||||||
|
$stateExe = if ($state.ExePath) { $state.ExePath } else { 'n/a' }
|
||||||
|
$stateSummary = "[WireGuard] Detected install state: Installed={0}; Version={1}; Service={2}; Driver={3}; Exe={4}" -f `
|
||||||
|
$state.Installed, $stateVersion, $state.ServicePresent, $state.DriverPresent, $stateExe
|
||||||
|
Write-AgentLog -FileName $logName -Message $stateSummary
|
||||||
|
if ($state.DriverPaths -and $state.DriverPaths.Count -gt 0) {
|
||||||
|
Write-AgentLog -FileName $logName -Message ("[WireGuard] Driver paths: {0}" -f ($state.DriverPaths -join '; '))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not ($state.Installed -and $state.DriverPresent -and $state.ServicePresent)) {
|
||||||
|
$installerCandidate = $null
|
||||||
|
if ($msiPath -and (Test-Path $msiPath -PathType Leaf)) {
|
||||||
|
$installerCandidate = $msiPath
|
||||||
|
} elseif (Test-Path $wireGuardBootstrapperPath -PathType Leaf) {
|
||||||
|
$installerCandidate = $wireGuardBootstrapperPath
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not $installerCandidate) {
|
||||||
|
throw "WireGuard installer cache missing; expected $msiPath or $wireGuardBootstrapperPath"
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($installerCandidate.ToLowerInvariant().EndsWith('.msi')) {
|
||||||
|
Install-WireGuardMsi -InstallerPath $installerCandidate -BootstrapperPath $wireGuardBootstrapperPath -LogName $logName
|
||||||
|
} else {
|
||||||
|
$logPrefix = '[WireGuard]'
|
||||||
|
Write-AgentLog -FileName $logName -Message ("$logPrefix Installing via bootstrapper at {0}" -f $installerCandidate)
|
||||||
|
$bootstrapArgs = '/install /quiet'
|
||||||
|
try {
|
||||||
|
$proc = Start-Process -FilePath $installerCandidate -ArgumentList $bootstrapArgs -Wait -PassThru -WindowStyle Hidden -ErrorAction Stop
|
||||||
|
Write-AgentLog -FileName $logName -Message ("$logPrefix Bootstrapper exit code: {0}" -f $proc.ExitCode)
|
||||||
|
if ($proc.ExitCode -ne 0) {
|
||||||
|
throw "WireGuard bootstrapper returned exit code $($proc.ExitCode)"
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
$err = $_.Exception.Message
|
||||||
|
Write-AgentLog -FileName $logName -Message ("$logPrefix Bootstrapper install failed: {0}" -f $err)
|
||||||
|
throw
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$state = Get-WireGuardInstallState
|
||||||
|
$postVersion = if ($state.Version) { $state.Version } else { 'unknown' }
|
||||||
|
$postExe = if ($state.ExePath) { $state.ExePath } else { 'n/a' }
|
||||||
|
$postSummary = "[WireGuard] Post-install state: Installed={0}; Version={1}; Service={2}; Driver={3}; Exe={4}" -f `
|
||||||
|
$state.Installed, $postVersion, $state.ServicePresent, $state.DriverPresent, $postExe
|
||||||
|
Write-AgentLog -FileName $logName -Message $postSummary
|
||||||
|
if ($state.Installed -and $state.DriverPresent) {
|
||||||
|
Write-Host "WireGuard installed and verified (version: $($state.Version))." -ForegroundColor Green
|
||||||
|
} else {
|
||||||
|
Write-Host "WireGuard installed (driver pending bootstrap)." -ForegroundColor Yellow
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-Host "WireGuard already installed (version: $($state.Version))." -ForegroundColor Green
|
||||||
|
}
|
||||||
|
|
||||||
|
# Ensure wintun driver is seeded even before first tunnel is created
|
||||||
|
$wgExe = $state.ExePath
|
||||||
|
if (-not $wgExe -or -not (Test-Path $wgExe -PathType Leaf)) {
|
||||||
|
# try default install path
|
||||||
|
$wgExe = Join-Path $env:ProgramFiles 'WireGuard\wireguard.exe'
|
||||||
|
}
|
||||||
|
if ($wgExe -and (Test-Path $wgExe -PathType Leaf)) {
|
||||||
|
try {
|
||||||
|
Ensure-WireGuardDriver -WireGuardExe $wgExe -LogName $logName
|
||||||
|
$finalState = Get-WireGuardInstallState
|
||||||
|
if (-not ($finalState.Installed -and $finalState.DriverPresent)) {
|
||||||
|
throw "WireGuard driver still missing after bootstrap attempts."
|
||||||
|
}
|
||||||
|
Write-Host "WireGuard driver verified." -ForegroundColor Green
|
||||||
|
} catch {
|
||||||
|
Write-AgentLog -FileName $logName -Message ("[WireGuard] Driver bootstrap failed: {0}" -f $_.Exception.Message)
|
||||||
|
throw
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$msg = "[WireGuard] Unable to locate wireguard.exe after installation."
|
||||||
|
Write-AgentLog -FileName $logName -Message $msg
|
||||||
|
throw $msg
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ensure-AnsibleExecutionEnvironment {
|
function Ensure-AnsibleExecutionEnvironment {
|
||||||
|
|||||||
@@ -32,17 +32,18 @@ At each milestone: pause, run the listed checks, talk to the operator, and commi
|
|||||||
## Detailed Steps — Windows Implementation
|
## Detailed Steps — Windows Implementation
|
||||||
|
|
||||||
### 1) Dependencies & Bootstrap — Milestone: Dependencies & Bootstrap (Windows)
|
### 1) Dependencies & Bootstrap — Milestone: Dependencies & Bootstrap (Windows)
|
||||||
|
- Agents editing this document should mark tasks they complete with `[x]` (leave `[ ]` otherwise).
|
||||||
- WireGuard packaging:
|
- WireGuard packaging:
|
||||||
- Bundle official WireGuard for Windows (driver + client).
|
- [x] Bundle official WireGuard for Windows (driver + client).
|
||||||
- Download installers into `Dependencies/VPN_Tunnel_Adapter/` and keep them there (no deletion) for ad-hoc reinstalls.
|
- [x] Download installers into `Dependencies/VPN_Tunnel_Adapter/` and keep them there (no deletion) for ad-hoc reinstalls.
|
||||||
- Update `Borealis.ps1`:
|
- Update `Borealis.ps1`:
|
||||||
- Install/verify WireGuard driver/client idempotently with admin rights.
|
- [x] Install/verify WireGuard driver/client idempotently with admin rights.
|
||||||
- Log to `Agent/Logs/install.log`.
|
- [x] Log to `Agent/Logs/install.log`.
|
||||||
- Do not start any tunnel yet.
|
- [x] Do not start any tunnel yet.
|
||||||
- Linux: do nothing yet (see later section).
|
- Linux: do nothing yet (see later section).
|
||||||
- Checkpoint tests:
|
- Checkpoint tests:
|
||||||
- WireGuard binaries available in agent runtime.
|
- [x] WireGuard binaries available in agent runtime.
|
||||||
- WireGuard driver installed and visible.
|
- [x] WireGuard driver installed and visible.
|
||||||
|
|
||||||
### 2) Engine VPN Server & ACLs — Milestone: Engine VPN Server & ACLs (Windows)
|
### 2) Engine VPN Server & ACLs — Milestone: Engine VPN Server & ACLs (Windows)
|
||||||
- Configure WireGuard listener on UDP port 30000; bind only on engine host.
|
- Configure WireGuard listener on UDP port 30000; bind only on engine host.
|
||||||
|
|||||||
Reference in New Issue
Block a user