Documentation
¶
Overview ¶
============================================================================= NFTBan v1.75.1 - Installer nftables Service Enable ============================================================================= SPDX-License-Identifier: MPL-2.0 meta:name="installer-switchop-enable" meta:type="lib" meta:owner="Antonios Voulvoulis <contact@nftban.com>" meta:created_date="2026-04-04" meta:description="Enable and start nftables service with xt-compat pre-check" meta:inventory.files="internal/installer/switchop/enable.go" meta:inventory.binaries="" meta:inventory.env_vars="" meta:inventory.config_files="" meta:inventory.systemd_units="nftables.service" meta:inventory.network="" meta:inventory.privileges="root" =============================================================================
============================================================================= NFTBan v1.73 - Installer Ghost Table Cleanup ============================================================================= SPDX-License-Identifier: MPL-2.0 meta:name="installer-switchop-ghost" meta:type="lib" meta:owner="Antonios Voulvoulis <contact@nftban.com>" meta:created_date="2026-04-04" meta:description="Remove ghost nftables tables from conflicting firewalls" meta:inventory.files="internal/installer/switchop/ghost.go" meta:inventory.binaries="" meta:inventory.env_vars="" meta:inventory.config_files="" meta:inventory.systemd_units="" meta:inventory.network="" meta:inventory.privileges="root" =============================================================================
============================================================================= NFTBan v1.73 - Installer Firewall Rebuild ============================================================================= SPDX-License-Identifier: MPL-2.0 meta:name="installer-switchop-rebuild" meta:type="lib" meta:owner="Antonios Voulvoulis <contact@nftban.com>" meta:created_date="2026-04-04" meta:description="Run nftban firewall rebuild with timeout — FATAL on failure" meta:inventory.files="internal/installer/switchop/rebuild.go" meta:inventory.binaries="" meta:inventory.env_vars="" meta:inventory.config_files="" meta:inventory.systemd_units="" meta:inventory.network="" meta:inventory.privileges="root" =============================================================================
============================================================================= NFTBan v1.73 - Installer SSH Port Live Set Guard ============================================================================= SPDX-License-Identifier: MPL-2.0 meta:name="installer-switchop-sshguard" meta:type="lib" meta:owner="Antonios Voulvoulis <contact@nftban.com>" meta:created_date="2026-04-04" meta:description="Ensure SSH port is in live nft sets before rebuild" meta:inventory.files="internal/installer/switchop/sshguard.go" meta:inventory.binaries="" meta:inventory.env_vars="" meta:inventory.config_files="" meta:inventory.systemd_units="" meta:inventory.network="" meta:inventory.privileges="root" =============================================================================
============================================================================= NFTBan v1.75.1 - Installer Takeover Operations ============================================================================= SPDX-License-Identifier: MPL-2.0 meta:name="installer-switchop-takeover" meta:type="lib" meta:owner="Antonios Voulvoulis <contact@nftban.com>" meta:created_date="2026-04-04" meta:description="Disable conflicting firewalls during takeover with CSF panel disarm" meta:inventory.files="internal/installer/switchop/takeover.go" meta:inventory.binaries="" meta:inventory.env_vars="" meta:inventory.config_files="" meta:inventory.systemd_units="" meta:inventory.network="" meta:inventory.privileges="root" =============================================================================
Index ¶
- Constants
- Variables
- func AssertSSHInLiveSet(exec executor.Executor, sshPort int, log *logging.Logger)
- func CleanGhostTables(exec executor.Executor, log *logging.Logger)
- func ComputeCronBackupSHA256(content []byte) string
- func DisableConflicts(exec executor.Executor, conflicts []detect.Conflict, panel detect.PanelType, ...) error
- func EnableNftables(exec executor.Executor, distro *detect.DistroInfo, log *logging.Logger) error
- func InjectEmergencySSH(exec executor.Executor, sshPort int, log *logging.Logger) error
- func Rebuild(exec executor.Executor, log *logging.Logger) error
- func RemoveEmergencySSH(exec executor.Executor, log *logging.Logger)
- func VerifyCronBackupEntry(exec executor.Executor, entry CronManifestEntry) ([]byte, error)
- type CronManifest
- type CronManifestEntry
Constants ¶
const ( // CronManifestSchemaVersion is the on-disk schema version of the // manifest. Reader rejects manifests whose schema_version field // does not match this constant exactly. Bumping this constant is // a contract event (treat as Amendment-1 §31 A.4 evolution). CronManifestSchemaVersion = "1.0.0" // CronManifestDir is the on-disk directory the manifest writer // stores backups + manifest.json under. Hardcoded by §42.2 lock. CronManifestDir = "/var/lib/nftban/state/csf-cron-backup" // CronManifestFile is the absolute path of the manifest JSON // file (CronManifestDir + "/manifest.json"). CronManifestFile = "/var/lib/nftban/state/csf-cron-backup/manifest.json" // CronCSFSrcPath / CronLFDSrcPath are the canonical /etc/cron.d // source paths the writer backs up and the reader restores to. // Hardcoded by §42.2 lock — only these two cron files are // backed up; never any other /etc/cron.d/* entry. CronCSFSrcPath = "/etc/cron.d/csf-cron" CronLFDSrcPath = "/etc/cron.d/lfd-cron" )
Variables ¶
var ( // ErrCronManifestSchemaMismatch is returned by the reader when // manifest.json parses but its schema_version does not match // CronManifestSchemaVersion exactly. ErrCronManifestSchemaMismatch = errors.New("cron manifest: schema_version mismatch") // ErrCronManifestSHA256Mismatch is returned by the reader when // a manifest entry's recorded sha256 does not match the actual // sha256 of the on-disk backup file. Indicates corruption or // tampering — restore MUST refuse this entry. ErrCronManifestSHA256Mismatch = errors.New("cron manifest: sha256 mismatch — backup file does not match manifest entry") // ErrCronManifestUnknownEntry is returned when the manifest lists // a Path that is not one of the two §42.2-locked cron source // paths (/etc/cron.d/csf-cron or /etc/cron.d/lfd-cron). Defensive // guard; readers MUST refuse unknown entries. ErrCronManifestUnknownEntry = errors.New("cron manifest: entry path is not in the §42.2 locked set {csf-cron, lfd-cron}") // ErrCronManifestParseFailed is returned by the reader when // manifest.json cannot be parsed as JSON. Distinct from a // missing manifest (ReadCronBackupManifest returns ok=false in // that case, no error). ErrCronManifestParseFailed = errors.New("cron manifest: failed to parse manifest.json") )
Functions ¶
func AssertSSHInLiveSet ¶
AssertSSHInLiveSet verifies the SSH port exists in the live nft tcp_ports_in sets for both ip and ip6. If missing, adds it. Call after EnableNftables (nftban tables must exist) and before/after rebuild.
func CleanGhostTables ¶
CleanGhostTables removes all known ghost nftables tables. Ignores errors for tables that don't exist.
func ComputeCronBackupSHA256 ¶ added in v1.100.4
ComputeCronBackupSHA256 returns the lowercase-hex sha256 of the given content. Used by the writer to record the manifest entry and by the reader to verify the on-disk backup file's integrity before A.4 restoration.
func DisableConflicts ¶
func DisableConflicts(exec executor.Executor, conflicts []detect.Conflict, panel detect.PanelType, log *logging.Logger) error
DisableConflicts stops, disables, and masks all conflicting firewalls. For CSF conflicts on DirectAdmin servers, also disarms CustomBuild so that `./build update` does not re-enable CSF.
func EnableNftables ¶
EnableNftables enables and starts the nftables service, then verifies. Runs cleanXtCompat() first to remove stale xt target rules that would prevent nftables from starting (common on CSF/cPanel servers).
func InjectEmergencySSH ¶ added in v1.74.0
InjectEmergencySSH creates a minimal inet table that accepts the SSH port. This table acts as a last-resort safety net during install transitions. It MUST be removed only after nftban rules are proven in the kernel. Idempotent: deletes any existing emergency table before creating.
Priority -1: evaluated before nftban chains (priority 0). Policy accept: fail-open — safety net, not security boundary.
func Rebuild ¶
Rebuild runs "nftban firewall rebuild" and returns an error if it fails. Shell rebuild exit code contract (authoritative — do not redefine):
0 = PROTECTED (all checks passed) 1 = DEGRADED (firewall operational, some module checks failed) 2 = FAILED (rollback happened) 3 = FATAL (rollback also failed)
Exit 1 (DEGRADED) is expected during upgrade: module-scoped chains require the daemon to be running, which may not be the case yet. Only exit 2+ is treated as a fatal rebuild failure.
func RemoveEmergencySSH ¶ added in v1.74.0
RemoveEmergencySSH removes the emergency SSH table. Call only after nftban rules are proven in the kernel with SSH port present. No-op if table doesn't exist.
func VerifyCronBackupEntry ¶ added in v1.100.4
func VerifyCronBackupEntry(exec executor.Executor, entry CronManifestEntry) ([]byte, error)
VerifyCronBackupEntry reads the on-disk backup for entry and compares its sha256 to the manifest record. Returns ErrCronManifestSHA256Mismatch on mismatch. Reads via the executor abstraction.
Types ¶
type CronManifest ¶ added in v1.100.4
type CronManifest struct {
SchemaVersion string `json:"schema_version"`
CapturedAt time.Time `json:"captured_at"`
Files []CronManifestEntry `json:"files"`
}
CronManifest is the manifest.json on-disk shape.
func ReadCronBackupManifest ¶ added in v1.100.4
func ReadCronBackupManifest(exec executor.Executor, log *logging.Logger) (CronManifest, bool, error)
ReadCronBackupManifest returns the parsed manifest if present and schema-valid. Three return shapes:
- Manifest absent (no manifest.json at CronManifestFile): returns (zero, false, nil). Caller (A.4 step) treats this as the graceful soft-skip case for pre-PR-26 hosts.
- Manifest present but corrupt (parse failure or schema mismatch): returns (zero, true, ErrCronManifestParseFailed or ErrCronManifestSchemaMismatch). Caller refuses A.4.
- Manifest present and parseable: returns (manifest, true, nil). Caller still verifies per-entry sha256 against on-disk backups before restoring.
Per-entry integrity is the caller's responsibility (use ComputeCronBackupSHA256 + compare to entry.SHA256). The reader here only validates the manifest structure.
func WriteCronBackupManifest ¶ added in v1.100.4
WriteCronBackupManifest captures the two §42.2-locked cron files (CronCSFSrcPath, CronLFDSrcPath) before they are removed at install-time. For each file that exists:
- Reads content via exec.ReadFile.
- Reads metadata via exec.Stat (mode/uid/gid/size).
- Computes sha256.
- Writes the content to CronManifestDir/<backup-name> via exec.WriteFileAtomic.
Then writes manifest.json containing exactly the entries that were backed up. Entries for files that did not exist at capture time are NOT included in the manifest.
Returns the manifest that was written, plus an error if any step failed. The caller (disarmCSFArtifacts) MAY proceed with the rm even if manifest writing fails — the rm is the install-time invariant; the manifest is best-effort fidelity. But on success the caller should log the manifest path so the operator can observe it.
MUST be called BEFORE the cron files are removed; otherwise the content read returns os.ErrNotExist and the entry is skipped.
type CronManifestEntry ¶ added in v1.100.4
type CronManifestEntry struct {
Path string `json:"path"` // absolute /etc/cron.d/<name>
BackupName string `json:"backup_name"` // basename within CronManifestDir
SHA256 string `json:"sha256"` // hex sha256 of the backed-up content
Mode uint32 `json:"mode"` // os.FileMode-compatible permission bits
UID int `json:"uid"`
GID int `json:"gid"`
Size int64 `json:"size"`
}
CronManifestEntry records one backed-up cron file.