[CmdletBinding()] param([string]$ListenIp = '', [string]$OutputPath = '') $ErrorActionPreference = 'Stop' if (-not $ListenIp) { $interfaces = @(Get-NetIPConfiguration | Where-Object { $_.IPv4DefaultGateway -and $_.IPv4Address }) $addresses = @($interfaces | ForEach-Object { $_.IPv4Address.IPAddress } | Select-Object -Unique) if ($addresses.Count -ne 1) { throw 'Specify -ListenIp with the non-loopback IPv4 address assigned to this server NIC.' } $ListenIp = $addresses[0] } $address = $null if (-not [Net.IPAddress]::TryParse($ListenIp,[ref]$address) -or $address.AddressFamily -ne [Net.Sockets.AddressFamily]::InterNetwork -or [Net.IPAddress]::IsLoopback($address) -or $ListenIp -eq '0.0.0.0') { throw 'Use an assigned non-loopback IPv4 NIC address; do not use 0.0.0.0.' } if (-not (Get-NetIPAddress -AddressFamily IPv4 -IPAddress $ListenIp -ErrorAction SilentlyContinue)) { throw "$ListenIp is not assigned to this server. On cloud hosts, use the NIC private IPv4, not the NAT public IPv4." } if (-not $OutputPath) { $OutputPath = Join-Path $PSScriptRoot 'BuddyDefense.caddyfile' } $site = @" https://BuddyDefense.xworld.ren:15888 { bind $ListenIp reverse_proxy 127.0.0.1:15888 { transport http { read_timeout 0 write_timeout 0 } } } "@ [IO.File]::WriteAllText([IO.Path]::GetFullPath($OutputPath),$site,(New-Object Text.UTF8Encoding($false))) Write-Output "Generated $OutputPath. Merge this site into the existing Caddyfile, then validate and reload." Write-Output $site