obmp-docker/scripts/wsl-portproxy.ps1

92 lines
3.6 KiB
PowerShell
Raw Normal View History

<#
.SYNOPSIS
Forward router-facing OpenBMP ports from the Windows host into WSL.
.DESCRIPTION
Physical routers cannot reach the WSL VM's NAT address, and that address
changes on every 'wsl --shutdown' (portability finding 4). This script
(re)creates the netsh portproxy rules that forward the router-facing BMP
port and Kafka from the Windows LAN IP into the current WSL address, plus
the matching inbound firewall rules. Idempotent: existing rules for the
same listen ports are replaced, so RE-RUN IT AFTER EVERY WSL RESTART.
Must run in an ELEVATED PowerShell.
.PARAMETER RouterPort
Router-facing BMP port (default 1790, the IANA BMP port). Compose publishes
the same port on the WSL side (ROUTER_FACING_PORT:5000), so the proxy
forwards Windows:RouterPort -> WSL:RouterPort.
.PARAMETER WslIp
WSL address to forward to. Default: auto-detected via 'wsl hostname -I'.
deploy.sh: teardown subcommand, fresh-host preflight, guided interactive flow Implements the one-shot goal from the greenfield audit: tear down fully and/or deploy cleanly on a pristine WSL instance with nothing but the interactive script. - './deploy.sh teardown': leave-it-down removal across ALL compose profiles (core/test/auth/evpn-test/scale-out -- the old reset missed the last two), networks, named volumes, rendered gobgpd.confs. Data wipe is opt-in (--wipe-data, guarded on native hosts) and preserves backups/ unless --purge-backups; --purge-images reclaims images. Prints the Windows-side cleanup (wsl-portproxy.ps1 -Remove, new switch). - fresh-host preflight: verifies the docker DAEMON (not just the client), offers to install docker-ce from the official repo (--install-prereqs for unattended), and handles the classic pristine-WSL trap: systemd off -> writes /etc/wsl.conf [boot] systemd=true and stops with exact restart instructions instead of dying cryptically. - sudo authenticates ONCE up front (no more password prompt buried mid-provision); --reset now covers all profiles and preserves backups/ - guided flow: banner, Step N/6 headers, context lines explaining HOST_IP-vs-router-facing before the address prompts, router-facing IP validated as a dotted quad (a failed Windows-LAN autodetect can no longer write a <WINDOWS_LAN_IP> placeholder into .env), stage completions print green checkmarks, loud abort note on the plan confirm, post-deploy Verify + teardown hints. - shared helpers moved to scripts/deploy-lib.sh; setup.sh sources it too (duplicate get_env/set_env/ask/confirm definitions deleted), keeping setup.sh as a standalone provisioning primitive. Verified live on this host: teardown left zero obmp containers and removed rendered configs; unattended redeploy brought the stack back. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 17:12:49 -07:00
.PARAMETER Remove
Teardown mode: delete the portproxy + firewall rules this script creates
(pair with './deploy.sh teardown' on the Linux side).
.EXAMPLE
powershell -ExecutionPolicy Bypass -File scripts\wsl-portproxy.ps1
deploy.sh: teardown subcommand, fresh-host preflight, guided interactive flow Implements the one-shot goal from the greenfield audit: tear down fully and/or deploy cleanly on a pristine WSL instance with nothing but the interactive script. - './deploy.sh teardown': leave-it-down removal across ALL compose profiles (core/test/auth/evpn-test/scale-out -- the old reset missed the last two), networks, named volumes, rendered gobgpd.confs. Data wipe is opt-in (--wipe-data, guarded on native hosts) and preserves backups/ unless --purge-backups; --purge-images reclaims images. Prints the Windows-side cleanup (wsl-portproxy.ps1 -Remove, new switch). - fresh-host preflight: verifies the docker DAEMON (not just the client), offers to install docker-ce from the official repo (--install-prereqs for unattended), and handles the classic pristine-WSL trap: systemd off -> writes /etc/wsl.conf [boot] systemd=true and stops with exact restart instructions instead of dying cryptically. - sudo authenticates ONCE up front (no more password prompt buried mid-provision); --reset now covers all profiles and preserves backups/ - guided flow: banner, Step N/6 headers, context lines explaining HOST_IP-vs-router-facing before the address prompts, router-facing IP validated as a dotted quad (a failed Windows-LAN autodetect can no longer write a <WINDOWS_LAN_IP> placeholder into .env), stage completions print green checkmarks, loud abort note on the plan confirm, post-deploy Verify + teardown hints. - shared helpers moved to scripts/deploy-lib.sh; setup.sh sources it too (duplicate get_env/set_env/ask/confirm definitions deleted), keeping setup.sh as a standalone provisioning primitive. Verified live on this host: teardown left zero obmp containers and removed rendered configs; unattended redeploy brought the stack back. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 17:12:49 -07:00
powershell -ExecutionPolicy Bypass -File scripts\wsl-portproxy.ps1 -Remove
#>
param(
[int]$RouterPort = 1790,
[int]$KafkaPort = 9092,
deploy.sh: teardown subcommand, fresh-host preflight, guided interactive flow Implements the one-shot goal from the greenfield audit: tear down fully and/or deploy cleanly on a pristine WSL instance with nothing but the interactive script. - './deploy.sh teardown': leave-it-down removal across ALL compose profiles (core/test/auth/evpn-test/scale-out -- the old reset missed the last two), networks, named volumes, rendered gobgpd.confs. Data wipe is opt-in (--wipe-data, guarded on native hosts) and preserves backups/ unless --purge-backups; --purge-images reclaims images. Prints the Windows-side cleanup (wsl-portproxy.ps1 -Remove, new switch). - fresh-host preflight: verifies the docker DAEMON (not just the client), offers to install docker-ce from the official repo (--install-prereqs for unattended), and handles the classic pristine-WSL trap: systemd off -> writes /etc/wsl.conf [boot] systemd=true and stops with exact restart instructions instead of dying cryptically. - sudo authenticates ONCE up front (no more password prompt buried mid-provision); --reset now covers all profiles and preserves backups/ - guided flow: banner, Step N/6 headers, context lines explaining HOST_IP-vs-router-facing before the address prompts, router-facing IP validated as a dotted quad (a failed Windows-LAN autodetect can no longer write a <WINDOWS_LAN_IP> placeholder into .env), stage completions print green checkmarks, loud abort note on the plan confirm, post-deploy Verify + teardown hints. - shared helpers moved to scripts/deploy-lib.sh; setup.sh sources it too (duplicate get_env/set_env/ask/confirm definitions deleted), keeping setup.sh as a standalone provisioning primitive. Verified live on this host: teardown left zero obmp containers and removed rendered configs; unattended redeploy brought the stack back. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 17:12:49 -07:00
[string]$WslIp = "",
[switch]$Remove
)
$ErrorActionPreference = "Stop"
$id = [System.Security.Principal.WindowsIdentity]::GetCurrent()
if (-not (New-Object System.Security.Principal.WindowsPrincipal($id)).IsInRole(
[System.Security.Principal.WindowsBuiltInRole]::Administrator)) {
Write-Error "Run this from an ELEVATED PowerShell (netsh portproxy needs admin)."
exit 1
}
deploy.sh: teardown subcommand, fresh-host preflight, guided interactive flow Implements the one-shot goal from the greenfield audit: tear down fully and/or deploy cleanly on a pristine WSL instance with nothing but the interactive script. - './deploy.sh teardown': leave-it-down removal across ALL compose profiles (core/test/auth/evpn-test/scale-out -- the old reset missed the last two), networks, named volumes, rendered gobgpd.confs. Data wipe is opt-in (--wipe-data, guarded on native hosts) and preserves backups/ unless --purge-backups; --purge-images reclaims images. Prints the Windows-side cleanup (wsl-portproxy.ps1 -Remove, new switch). - fresh-host preflight: verifies the docker DAEMON (not just the client), offers to install docker-ce from the official repo (--install-prereqs for unattended), and handles the classic pristine-WSL trap: systemd off -> writes /etc/wsl.conf [boot] systemd=true and stops with exact restart instructions instead of dying cryptically. - sudo authenticates ONCE up front (no more password prompt buried mid-provision); --reset now covers all profiles and preserves backups/ - guided flow: banner, Step N/6 headers, context lines explaining HOST_IP-vs-router-facing before the address prompts, router-facing IP validated as a dotted quad (a failed Windows-LAN autodetect can no longer write a <WINDOWS_LAN_IP> placeholder into .env), stage completions print green checkmarks, loud abort note on the plan confirm, post-deploy Verify + teardown hints. - shared helpers moved to scripts/deploy-lib.sh; setup.sh sources it too (duplicate get_env/set_env/ask/confirm definitions deleted), keeping setup.sh as a standalone provisioning primitive. Verified live on this host: teardown left zero obmp containers and removed rendered configs; unattended redeploy brought the stack back. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 17:12:49 -07:00
# -Remove: teardown mode. Deletes the portproxy + firewall rules this script
# creates (used by './deploy.sh teardown' guidance). No WSL IP needed.
if ($Remove) {
foreach ($listen in @($RouterPort, $KafkaPort)) {
netsh interface portproxy delete v4tov4 listenport=$listen listenaddress=0.0.0.0 2>$null | Out-Null
Write-Host "portproxy rule removed: 0.0.0.0:$listen"
$ruleName = "OpenBMP $listen"
if (Get-NetFirewallRule -DisplayName $ruleName -ErrorAction SilentlyContinue) {
Remove-NetFirewallRule -DisplayName $ruleName
Write-Host "firewall rule removed: $ruleName"
}
}
Write-Host ""
Write-Host "Remaining portproxy rules:"
netsh interface portproxy show v4tov4
exit 0
}
if (-not $WslIp) {
$WslIp = (wsl hostname -I).Trim().Split(" ")[0]
if (-not $WslIp) { Write-Error "Could not auto-detect the WSL IP; pass -WslIp."; exit 1 }
}
Write-Host "WSL address: $WslIp"
# listenport => connectport (same port both sides; compose maps RouterPort
# down to the collector's in-container 5000 on the WSL side)
$maps = @{ $RouterPort = $RouterPort; $KafkaPort = $KafkaPort }
foreach ($listen in $maps.Keys) {
netsh interface portproxy delete v4tov4 listenport=$listen listenaddress=0.0.0.0 2>$null | Out-Null
netsh interface portproxy add v4tov4 listenport=$listen listenaddress=0.0.0.0 `
connectport=$($maps[$listen]) connectaddress=$WslIp | Out-Null
Write-Host "portproxy 0.0.0.0:$listen -> ${WslIp}:$($maps[$listen])"
$ruleName = "OpenBMP $listen"
if (-not (Get-NetFirewallRule -DisplayName $ruleName -ErrorAction SilentlyContinue)) {
New-NetFirewallRule -DisplayName $ruleName -Direction Inbound `
-LocalPort $listen -Protocol TCP -Action Allow | Out-Null
Write-Host "firewall rule added: $ruleName"
}
}
Write-Host ""
Write-Host "Active portproxy rules:"
netsh interface portproxy show v4tov4
Write-Host "Routers target the Windows LAN IP on port $RouterPort (see docs/router-bmp-config.md)."