feat(felhomsshd): dedicated OOB sshd instance + port-adaptive belt (H1 Parts 2-4 agent)
internal/felhomsshd: agent-managed felhom-sshd (claim port [8822,2222,8022,62222] loud-fail-on-exhaustion; render config→sshd -t→reload never-restart-on-change [SF-2]; operator authorized_keys from the hub block outside ~/.ssh [SF-3]); the static-table nft belt mutating ONLY @operator_ips + @ssh_port [trap 4]; health/heal (reset-failed-then-restart with 10min cooldown, NEVER restart onto an invalid config) + the oob heartbeat stanza. configs/felhom-sshd.service (SAFE, no RuntimeDirectory [SF-1]). FELHOM_SSHD + FELHOM_OOB sudoers (set-elements only). oob.enabled config DEFAULT FALSE. Wired into main like wgtunnel. Non-hollow tests: claim clean/contention/idempotent/exhaustion; config safe+byte-stable+refuses-:22; belt mutate-then-idempotent + never-touches-rules; heal no-restart-on-invalid-config + cooldown; status reflects block. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
This commit is contained in:
@@ -32,10 +32,32 @@ type Config struct {
|
||||
LocalAPI LocalAPIConfig `json:"local_api"`
|
||||
LANResolver LANResolverConfig `json:"lan_resolver"`
|
||||
WGTunnel WGTunnelConfig `json:"wg_tunnel"`
|
||||
OOB OOBConfig `json:"oob"`
|
||||
SelfUpdate SelfUpdateConfig `json:"selfupdate"`
|
||||
LogLevel string `json:"log_level"` // debug|info|warn|error (default info)
|
||||
}
|
||||
|
||||
// OOBConfig configures the dedicated felhom-sshd OOB access instance + belt (TASK H1). **Enabled
|
||||
// DEFAULTS TO FALSE** — a rollout to a box without explicit oob.enabled=true is a no-op (no port
|
||||
// claim, no config render, no belt mutation, no oob report stanza) until the operator endpoint +
|
||||
// static belt table exist.
|
||||
type OOBConfig struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
IntervalSeconds int `json:"interval_seconds"` // reconcile cadence; default 60
|
||||
StateDir string `json:"state_dir"` // staged config/authkeys under <StateDir>/felhom-sshd/; default /var/lib/felhom-agent
|
||||
}
|
||||
|
||||
// WithDefaults fills the OOB reconcile cadence + state dir.
|
||||
func (o OOBConfig) WithDefaults() OOBConfig {
|
||||
if o.IntervalSeconds == 0 {
|
||||
o.IntervalSeconds = 60
|
||||
}
|
||||
if o.StateDir == "" {
|
||||
o.StateDir = "/var/lib/felhom-agent"
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
// SelfUpdateConfig configures the operator-signed agent self-update (TASK D1). The artifact HOST
|
||||
// is operator-controlled config; the artifact INTEGRITY comes only from the sha256 pinned inside
|
||||
// the operator-signed op — the hub's Day-0 manifest plays no role here, and a compromised Gitea
|
||||
|
||||
Reference in New Issue
Block a user