PR26.3: DirectAdmin adapter under panelfw#530
Conversation
PR26.3 — DirectAdmin adapter, the first specimen under the PR26.2
panelfw.PanelAdapter contract. Read-only by interface contract; no
firewall mutation, no service writes, no host destructive testing.
internal/installer/panelfw/adapters/directadmin/:
- Detect: 4-signal evidence (install dir / binary / service active /
TCP listener) → strong (3+) or weak (1-2) confidence
- RequiredPorts: default TCP 2222, override via
/usr/local/directadmin/conf/directadmin.conf `port=N`
- ValidateReachability: ss -lnt parse for the required port
- init() registers the adapter via panelfw.Register
cmd/nftban-installer/main.go:
- blank import to fire the adapter's init() during process startup,
so phaseValidate sees DirectAdmin in panelfw.RegisteredAdapters()
on a real DA host
Hard exclusions:
- no cPanel / Plesk / cyberpanel adapter
- no authority residue classifier
- no restore semantics change
- no firewall mutation
- no destructive host testing
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
Clarifies PR26.3 scope after auditor disposition:
- Top-level doc-comment: "control-plane only"; full DirectAdmin
service-port surface (16+ public-facing ports) is NOT validated
here — that lands in PR26.4 via
internal/ports/panel_loader.LoadPanelConfig("directadmin") and
/etc/nftban/conf.d/panels/directadmin/main.conf.
- PR26.4 follow-up note inline at the top of directadmin.go.
- ValidateReachability error message: explicitly says
"control-plane port N not in LISTEN state — control-plane
unreachable" so the user-facing AssertionResult.Detail (and
log lines) cannot be misread as a full panel-survival claim.
- New test: ErrorMentionsControlPlane (positive: "control-plane"
is in the message; negative: no affirmative full-surface claim).
- New test: Reason_DoesNotImplyFullPortSurvival at the framework
integration layer.
- Tightened existing TestFrameworkIntegration_DA_Detected_NotReachable_Blocks
to assert the surfaced Reason mentions "control-plane".
No internal/ports import in this PR (deliberately deferred to
PR26.4). No new mutation surface; adapter remains read-only. No
cPanel/Plesk/classifier/restore code added.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Path A applied — control-plane scope clarificationPer the auditor disposition, scope of this adapter is now explicitly bounded to DirectAdmin control-plane reachability only. Full DirectAdmin service-port surface validation is deferred to PR26.4. Changes in
Hard exclusions preserved: PR26.3 does NOT import Lab4 re-proof (post-Path-A, base
🤖 Generated with Claude Code |
Summary
DirectAdmin adapter — the first specimen registered under the PR26.2
panelfw.PanelAdaptercontract. Read-only adapter implementation. No real-host destructive testing in this PR.Scope
Hard exclusions preserved:
What landed
internal/installer/panelfw/adapters/directadmin/directadmin.gointernal/installer/panelfw/adapters/directadmin/directadmin_test.gocmd/nftban-installer/main.goinit()fires during process startupDetect (4 signals)
/usr/local/directadmin//usr/local/directadmin/directadmindirectadmin.service(viaServiceActive)<port>inLISTENstate viass -lntparseConfidence: 3+ →
strong; 1–2 →weak(with warning); 0 →Detected=false.RequiredPorts
[2222]port=Nfrom/usr/local/directadmin/conf/directadmin.conf(tolerates inline comments, falls back to default on malformed/missing config)ValidateReachability
LISTENstate viass -lnt:22222≠:2222)Tests
22 tests in
./internal/installer/panelfw/adapters/directadmin/..., all green on lab4:TestDetect_AllSignals_Strong/_Absent_NotDetected/_PartialInstall_Weak/_ServiceOnly_WeakTestRequiredPorts_Default/_ConfigOverride/_MalformedConfig_FallsBackToDefault(5 sub-tests) /_ConfigInlineCommentTestValidateReachability_Listening_OK/_NotListening_ReturnsError/_PortPrefixCollision/_SsErrorsOut_NotListening/_OverridePortHonoredTestIDTestFrameworkIntegration_DA_Detected_Reachable_Passes/_NotReachable_Blocks/_Absent_Passes/_NotReachable_OperatorDisabled_Passes(proves--no-panelstill works for DA)TestInitRegistration_AdapterPresent(provesinit()populates the global registry)TestReadOnly_NoWrites_NoMutationCommands(structural mutation audit)Lab proof (lab4, RHEL/cPanel, go1.25.8)
Branch base:
fdbebe8c(origin/main, post-PR26.2 merge).TMPDIR=/root/build-tmp(lab4: both /tmp and /var/tmp are noexec under cPanel/usr/tmpDSK).Behavior on a real DirectAdmin host (post-merge)
When the installer runs on a host where
/usr/local/directadmin/exists,directadminbinary is present,directadmin.serviceis active, and TCP 2222 is listening:panelfw.RegisteredAdapters()returns[directadmin](init() fires on startup).phaseValidatecallsRunAssertionsWithOptswith the operator-derived policy.assertPanelSurvivalcallspanelfw.EvaluateAdapters([directadmin], policy):RequiredTCP=[2222][2222], [], nilFatal=false,PortsApplied=true,ReachableAfter=trueIf TCP 2222 is NOT listening (DirectAdmin stopped, panel-enable failed, or another bug):
Fatal=true, the assertion fails,AllPassed=false, install drops toStateDegraded. dns2's silent panel-enable failure is now caught at install time — unless the operator passes--no-panel.Test plan
go test ./internal/installer/panelfw/...green on lab4go vet ./internal/installer/panelfw/... ./internal/installer/validate/... ./cmd/nftban-installer/...clean on lab4go test ./...green on lab4 (66 packages, 0 fail)🤖 Generated with Claude Code