Background
-
Old code derived default gateway from
config.DirectoryService.Get<IRouter>().SingleOrDefault().IP. -
Wrong for greenfield: firewall (OPNsense, etc.) doesn’t exist as VM yet at install time.
-
Proxmox host installer (
answer.toml), DC static-IP setup (Stage3Windows), and Linux/PE config emit (MainWinPE) all need a real reachable gateway during install - not a future VM IP. -
Hence: split gateway-during-install (real upstream) from router-as-firewall (future VM, may not exist yet).
Phase 1 - Upstream gateway (current)
-
NETSetupConfig.GatewayIPcarries the actual upstream port IP. -
ISP/DC gateway, customer’s existing network gateway, or test bench’s real router.
-
All gateway-emitting code paths read
GatewayIPfirst. -
Fallback to
Get<IRouter>().IPonly whenGatewayIP == IP.None(legacy customer JSONs). -
Test fixture auto-populates
GatewayIPfrom the Hyper-V external switch’s bound NIC default route: -
VirtualHyperVTestBase.EnsureFreeIP -
VirtualHyperVTestBase.PatchDhcpToHostGateway -
Test bench reuses the real upstream - no fake gateway baked into fixtures.
LIBERATOR EXCEPTION (2026-05-27): ProxmoxAutoInstallExtensions.ToProxmoxAutoInstall now Liberator-gates the install-time network section. When the config has an OPNsense VM targeted at this host’s serial (IsLiberatorHost), the answer.toml emits 10.0.0.200/24 gw 10.0.0.1 dns 10.0.0.1 (Mikrotik factory LAN) regardless of GatewayIP / customer OU subnet. Reason: on a fresh Liberator install the customer OU subnet does not exist as a routable subnet - only the Mikrotik factory IP is reachable. All Phase 1/2 IPs come from src/NETSetup/Helpers/LiberatorNetwork.cs. See docs/Liberator.adoc "Proxmox Host IP - Two Phases" for the full table.
Phase 2 - Firewall takeover (shipped)
-
Trigger: OPNsense VM provisioned by
EnsureCustomerVmsAND reachable on its LAN IP via HTTPS:443. -
Helper:
src/NETSetup/Helpers/EnsureGatewayTakeover.cs. Runs everynetsetup updatecycle at Phase 3e (afterConfigureOpnsenseVlans+RewireVmNicsToVlans). -
Idempotent skip when
config.GatewayIPalready == OPNsense LAN IP. Best-effort: failures log warning + continue. -
After flip:
-
Proxmox host: awk-in-place rewrite of
gatewayline underiface vmbr0in/etc/network/interfaces+ifreload -a. -
In-memory:
config.GatewayIP = opnsenseLanso NixOS VMs re-templatenetworking.defaultGatewaynextUpdateNixosVmcycle. -
Customer JSON on disk keeps Phase 1 upstream IP unchanged (by design - reinstall must start from real upstream).
-
Outcomes (unit-test enum):
NoOpnsense,OpnsenseUnreachable,AlreadyTakenOver,FlippedToOpnsense.
LIBERATOR PHASE 2 NOTE (2026-05-27): EnsureGatewayTakeover flips the customer-OU gateway line on iface vmbr0. On a Liberator host, ConfigureProxmoxBridges separately writes the mgmt sub-interface vmbr0v250 at 10.0.250.2/24 gw 10.0.250.1 (Mikrotik mgmt, NOT OPNsense), which becomes the host’s default route. The two helpers are orthogonal: takeover deals with the vmbr0 (LAN VLAN routing for VM upstream), ConfigureProxmoxBridges deals with the vmbr0v250 (host OOB mgmt). On Liberator both run in Phase 3e in this order: ConfigureOpnsenseVlans → ConfigureMikrotikVlans → ConfigureProxmoxBridges → RewireVmNicsToVlans → EnsureGatewayTakeover.
Code map (where gateway is read today)
-
src/NETSetup/Extensions/ProxmoxAutoInstallExtensions.cs-answer.tomlnetwork-manualsection. Liberator gate (IsLiberatorHost) forces10.0.0.200/24gw10.0.0.1for Liberator hosts; non-Liberator stays onGatewayIP. -
src/NETSetup/Stages/2-WinPE/MainWinPE.cs- Linux config bundle written to USB SYSTEM partition. -
src/NETSetup/Stages/3-NETSetupWindows/Stage3Windows.cs+WindowsServerMethods.SetIPv4Configuration- DC static IPv4. -
src/NETSetup/Helpers/EnsureGatewayTakeover.cs- Phase 2 host gateway flip onvmbr0+ in-memoryconfig.GatewayIPrewrite (LAN gateway). -
src/NETSetup/Helpers/ConfigureProxmoxBridges.cs- Liberator-only Phase 2 mgmt sub-ifacevmbr0v250rewrite at10.0.250.2/24gw10.0.250.1dns NixDns. Idempotent, onlyifreload -aon diff. -
src/NETSetup/Helpers/LiberatorNetwork.cs-public constholder for ALL Liberator Phase 1/2 IPs + mgmt VLAN id + bond/bridge names. Consumed byProxmoxAutoInstallExtensions,ConfigureProxmoxBridges,MikrotikDesiredStateBuilder. No literals elsewhere. -
src/NETSetup/Config/Nix/Templates/NixTemplateFactory.cs- readsconfig.GatewayIPeach emit, so NixOS VMs follow Phase 2 flip automatically. Also injectsExtraARecords["proxmox"] = 10.0.250.2for Liberator NixDns configs soproxmox.<domain>resolves once Phase 2 has run.
Open follow-ups
-
Windows DC NIC rewrite: extend
WindowsServerMethods.SetIPv4Configuration(PSDirect) so existing Windows VMs follow the Phase 2 flip. Today: Windows VMs keep their install-time gateway until reinstall. -
Multi-firewall HA / VRRP: gateway should track the VRRP virtual IP, not a single firewall’s LAN IP.