281ac48d28
NexusGuard CI / server-core-test (push) Failing after 3m30s
NexusGuard CI / server-core-build (push) Has been skipped
NexusGuard CI / device-agent-test (push) Failing after 3s
NexusGuard CI / device-agent-cross-build (amd64, linux) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (amd64, windows) (push) Has been skipped
NexusGuard CI / device-agent-cross-build (arm64, linux) (push) Has been skipped
NexusGuard CI / dashboard-test (push) Failing after 3s
NexusGuard CI / dashboard-dist (push) Has been skipped
5.4 KiB
5.4 KiB
Multi-Interface Refactor
TL;DR
Objective: Refactor NexusGuard from single WireGuard interface to multi-interface per WgServer.
Context
Original Request: User wants firewall bug fixed + multi-node isolation like wgdashboard where each node has configurable wg_isolation and NAT interface. Interview Summary:
- Default deny all for client<->client, allow server->client default
- Isolation configurable per node via UI checkbox
- NAT interface (eth0/eth1/ens5) configurable per node
- Current architecture only supports 1 local interface (wg0)
Research Findings:
- WgManager hardcoded to wg0 (wgmanager_linux.go:25)
- Firewall InitNetwork() runs once globally for single subnet
- NAT uses auto-detected default route interface
- WgServer model lacks InterfaceName, IsLocal, PeerIsolation, NatInterface fields
Work Objectives
Core Objective: Enable multiple local WireGuard interfaces, each with independent subnet, firewall isolation, and NAT egress interface.
Concrete Deliverables:
- Database migration adding 4 fields to wg_servers table
- WgManager supporting multiple interfaces by name
- Firewall manager with per-interface chains (forward_wgX, input_wgX)
- Startup initialization loop for all IsLocal=true servers
- API handlers using server context for all operations
- Cleanup of hardcoded Local Primary Node references
Definition of Done:
- Migration runs: ALTER TABLE wg_servers ADD COLUMN ...
- wg0, wg1, wg2 interfaces can run simultaneously
- Each interface has independent peer isolation (configurable)
- Each interface uses configured NAT interface for masquerade
- Firewall rules scoped to correct interface chain
- Peer sync works per server (WgServerID filter)
- All existing tests pass
- Manual QA: 2+ local nodes with different subnets/NAT interfaces
Must Have:
- Backward compatible: existing single-node deployments work unchanged
- Default values: InterfaceName=wg0, IsLocal=false, PeerIsolation=true, NatInterface= (auto)
Must NOT Have (Guardrails):
- NO breaking changes to external node provisioning
- NO nft flush table - only atomic add/remove
- NO hardcoded interface names in firewall code
- NO cross-interface peer leakage
Verification Strategy
Test Decision:
- Infrastructure exists: YES (Go test with -tags dev, GORM AutoMigrate)
- Automated tests: Tests-after (add tests for new multi-interface logic)
- Framework: Go testing (standard library)
QA Policy: Every task includes agent-executed QA scenarios.
| Domain | Tool | Evidence Pattern |
|---|---|---|
| Go unit/integration | go test -tags dev ./... | .sisyphus/evidence/task-{N}-test.log |
| nftables rules | bash (nft list) | .sisyphus/evidence/task-{N}-nftables.txt |
| WireGuard interfaces | bash (ip link, wg show) | .sisyphus/evidence/task-{N}-wg.txt |
| API endpoints | bash (curl) | .sisyphus/evidence/task-{N}-api.json |
| Wave 2 (Core Logic - 4 parallel): | ||
| ├── T5: LinuxWgManager multi-interface implementation [deep] | ||
| ├── T6: LinuxManager InitNetworkForServer + Teardown [deep] | ||
| ├── T7: NAT per-interface masquerade rules [unspecified-high] | ||
| ├── T8: Peer sync per-server (WgServerID filter) [unspecified-high] | ||
| Wave 3 (Startup & Recovery - 3 parallel): | ||
| ├── T9: Main.go startup loop for all local servers [deep] | ||
| ├── T10: Firewall rules re-apply per server [unspecified-high] | ||
| ├── T11: Input rule (WG port) per server [quick] | ||
| Wave 4 (API Handlers - 5 parallel): | ||
| ├── T12: servers.go Create/Update with multi-interface [quick] | ||
| ├── T13: peers.go device creation with server context [quick] | ||
| ├── T14: peer_sync.go SyncLocalPeers per server [quick] | ||
| ├── T15: rules.go syncRuleToFirewall per server [quick] | ||
| ├── T16: provisioning.go server-aware [quick] | ||
| Wave 5 (Cleanup & Migration - 2 parallel): | ||
| ├── T17: Remove hardcoded Local Primary Node refs [quick] | ||
| ├── T18: Migration script + backfill defaults [quick] |
TODOs
- 1. Database Migration + Model Updates [quick]
- 2. WgManager Interface + Multi-Interface Struct [deep]
- 3. NetManager Interface + Per-Server Methods [deep]
- 4. nftables Chain-Per-Interface Scaffolding [quick]
- 5. LinuxWgManager Multi-Interface Implementation [deep]
- 6. LinuxManager InitNetworkForServer + Teardown [deep]
- 7. NAT Per-Interface Masquerade Rules [unspecified-high]
- 8. Peer Sync Per-Server (WgServerID Filter) [unspecified-high]
- 9. Main.go Startup Loop for All Local Servers [deep]
- 10. Firewall Rules Re-apply Per Server [unspecified-high]
- 11. Input Rule (WG Port) Per Server [quick]
- 12. servers.go Create/Update Multi-Interface [quick]
- 13. peers.go Device Creation with Server Context [quick]
- 14. peer_sync.go SyncLocalPeers Per Server [quick]
- 15. rules.go syncRuleToFirewall Per Server [quick]
- 16. provisioning.go Server-Aware [quick]
- 17. Remove Hardcoded Local Primary Node References [quick]
- 18. Migration Script + Backfill Defaults [quick]
- 19. Unit Tests for Multi-Interface Logic [unspecified-low]
- 20. Integration Test: 2 Local Nodes Different Subnets [unspecified-high]
- 21. Manual QA Checklist Execution [unspecified-high]
- F1. Plan Compliance Audit — oracle
- F2. Code Quality Review — unspecified-high
- F3. Real Manual QA — unspecified-high + playwright
- F4. Scope Fidelity Check — deep