Documentation
¶
Overview ¶
============================================================================= NFTBan v1.73 - Installer Config Persistence ============================================================================= SPDX-License-Identifier: MPL-2.0 SPDX-FileCopyrightText: Copyright (c) 2024-2026 Antonios Voulvoulis <contact@nftban.com> meta:name="installer-render-config" meta:type="lib" meta:owner="Antonios Voulvoulis <contact@nftban.com>" meta:created_date="2026-04-04" meta:description="Persist SSH port and config values to conf.local and state" meta:inventory.files="internal/installer/render/config.go" meta:inventory.binaries="" meta:inventory.env_vars="" meta:inventory.config_files="/etc/nftban/nftban.conf.local" meta:inventory.systemd_units="" meta:inventory.network="" meta:inventory.privileges="root" =============================================================================
============================================================================= NFTBan v1.73 - Installer nftables.conf Rendering ============================================================================= SPDX-License-Identifier: MPL-2.0 SPDX-FileCopyrightText: Copyright (c) 2024-2026 Antonios Voulvoulis <contact@nftban.com> meta:name="installer-render-nftables" meta:type="lib" meta:owner="Antonios Voulvoulis <contact@nftban.com>" meta:created_date="2026-04-04" meta:description="Template rendering + nft syntax validation for nftables.conf" meta:inventory.files="internal/installer/render/nftables.go" meta:inventory.binaries="" meta:inventory.env_vars="" meta:inventory.config_files="/etc/nftban/nftables.conf" meta:inventory.systemd_units="" meta:inventory.network="" meta:inventory.privileges="root" =============================================================================
============================================================================= NFTBan v1.73 - Installer System nftables.conf Integration ============================================================================= SPDX-License-Identifier: MPL-2.0 SPDX-FileCopyrightText: Copyright (c) 2024-2026 Antonios Voulvoulis <contact@nftban.com> meta:name="installer-render-sysconf" meta:type="lib" meta:owner="Antonios Voulvoulis <contact@nftban.com>" meta:created_date="2026-04-04" meta:description="Integrate NFTBan include into system nftables.conf" meta:inventory.files="internal/installer/render/sysconf.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
- func DisarmSystemConf(exec executor.Executor, nftConfPath string, log *logging.Logger) error
- func IntegrateSystemConf(exec executor.Executor, nftConfPath string, dep IncludeDependency, ...) error
- func PersistSSHPort(exec executor.Executor, sshPort int, log *logging.Logger)
- func PersistSSHPortsUnion(exec executor.Executor, ports []int, log *logging.Logger)
- func RenderNftablesConf(exec executor.Executor, sshPort int, log *logging.Logger) error
- func RenderNftablesConfMultiPort(exec executor.Executor, sshPorts []int, log *logging.Logger) error
- type IncludeDependency
Constants ¶
const ( IncludeBeginMarker = "# >>> nftban firewall include (managed; do not edit between markers) >>>" IncludeEndMarker = "# <<< nftban firewall include (managed) <<<" )
v1.146 PR Phase-D — fenced marker idempotency.
Before v1.146 the writer emitted a bare comment + include with no end sentinel, and the purge remover used a loose case-sensitive `sed /nftban/d`. Result: the capitalised legacy comment ("# NFTBan firewall configuration") was orphaned and accumulated one line per install cycle, and there was no atomic way to remove exactly nftban's contribution.
The fenced markers below bracket the managed region so both the writer (here) and the shell removers (deb postrm / rpm %postun) can strip exactly nftban's lines and nothing the operator added. Markers are lowercase so a stale pre-v1.146 `sed /nftban/d` from an older package still matches them. IncludeBeginMarker / IncludeEndMarker are the canonical sentinels; the shell scriptlets MUST match these byte-for-byte (drift-guarded by hermetic test).
const IncludeDirective = `include "/etc/nftban/generated/nftban-boot.nft"`
IncludeDirective is the line nftban adds to the distro nftables.conf so a plain `systemctl reload nftables.service` re-includes the nftban ruleset.
v1.229.13 Lane 3D.4 — AUTHORITATIVE INCLUDE TRANSITION. Boot authority moved from the legacy runtime artifact to the VALIDATED generated boot projection. This constant and the shipping IncludeDependency in cmd/nftban-installer/phases.go changed TOGETHER, atomically: a tree carrying only one of the two transitions is invalid, and TestIncludeAuthorityTransitionIsAtomic fails on either half alone.
⛔ THIS IS THE ONLY ACTIVE BOOT AUTHORITY. See legacyIncludePath below.
Variables ¶
This section is empty.
Functions ¶
func DisarmSystemConf ¶ added in v1.148.0
DisarmSystemConf is the RESTORE-time inverse of IntegrateSystemConf: it strips the nftban-managed include (fenced block + legacy comment + any bare include line) from the distro nftables.conf, using the same drift-checked stripNftbanInclude logic. Once stripped, nftables.service can no longer `nft -f`-load /etc/nftban/nftables.conf and recreate the ip/ip6 nftban tables on boot.
v1.148 (delta 2.1, SELECT_V148_RESTORE_SHAPE_B_INCLUDE_DISARM=yes). This is a restore-specific reversal of v1.146 Shape-B boot persistence — NOT a general Shape-B rollback; install/update still call IntegrateSystemConf normally. Idempotent (no-op when the include is already absent); backs up before editing; never deletes /etc/nftban/nftables.conf; leaves all non-nftban config intact (only nftban-owned lines are removed).
func IntegrateSystemConf ¶
func IntegrateSystemConf(exec executor.Executor, nftConfPath string, dep IncludeDependency, bootProjectionReady bool, log *logging.Logger) error
IntegrateSystemConf renders exactly one fenced nftban include block into the system nftables.conf. It first strips any prior nftban contribution (legacy unfenced comment/include, duplicates, or an existing fenced block) so the result is always a single canonical block — self-healing an already-polluted file. Idempotent: when the file already contains exactly the canonical block and nothing stale, no write occurs (mtime preserved).
v1.146 Shape B (reboot-proven): nftban KEEPS the distro include (the daemon recreates set structure via netlink but does NOT load the rendered SSH ports / @ssh_ports rate-limit rule — only `nft -f` via this include does, so removing it would silently drop v1.145 protection every reboot). In addition to the fenced include it neutralizes the distro skeleton (flush ruleset + default empty `table inet filter`) via neutralizeDistroSkeleton. dep declares what the include depends on; bootProjectionReady MUST come from the result of the authoritative boot-projection render in THIS run, never from file existence — a stale artifact from a previous run is exactly what this signal exists to distinguish (EXISTS != ESTABLISHED_THIS_RUN).
func PersistSSHPort ¶
PersistSSHPort writes the detected SSH port to conf.local and state file. Also ensures TCP_PORTS_IN includes the SSH port (lockout prevention).
func PersistSSHPortsUnion ¶ added in v1.145.0
PersistSSHPortsUnion writes EVERY detected SSH listener port to the durable ports.d SSH file, so reload/rebuild and the ports loader keep all listeners whitelisted (lockout-safe) — not just the primary. Without this, a multi-port host's durable port intent collapses to the shipped default (22 only), and a shell render/reload could drop a secondary SSH management port. Idempotent overwrite; format PORT/PROTOCOL/DIRECTION (T=TCP, I=Input).
func RenderNftablesConf ¶
RenderNftablesConf reads the nftables.conf template, substitutes placeholders, validates syntax, and writes back atomically.
Backward-compat single-port entry point. v1.125 R-1 multi-port-aware callers should use RenderNftablesConfMultiPort which renders all detected SSH listener ports into the tcp_ports_in allow-set (closes the dns2-class lockout vector for hosts with sshd on multiple ports).
func RenderNftablesConfMultiPort ¶ added in v1.125.0
RenderNftablesConfMultiPort renders nftables.conf with multi-port SSH allow-set support (v1.125 R-1 — closes the dns2-class lockout vector where a host listens on multiple SSH ports, e.g. :22 + :55000, but the installer rendered only the first detected port into the firewall).
sshPorts[0] is the PRIMARY port used for the `__SSH_PORT__` template substitution (per-IP rate-limit rule and other single-port references in the template stay byte-identical to the v1.124 behavior for single-port hosts). All ports in sshPorts (primary AND any additional) are injected into the rendered tcp_ports_in allow-set so the firewall admits SSH on every detected port.
When len(sshPorts) == 1 this is semantically identical to the pre-v1.125 single-port render path. The single-port RenderNftablesConf is preserved as a thin wrapper around this function for backward compatibility with existing callers.
Types ¶
type IncludeDependency ¶ added in v1.229.13
type IncludeDependency int
IncludeDependency classifies WHICH readiness authority an include write depends on. It is DELIBERATELY not inferred from the include path: keying safety off a literal path string would make the interlock depend on a second literal that a future edit could silently desynchronise from the guard.
v1.229.13 Lane 3D.3 installs this interlock; Lane 3D.4 arms it by changing IncludeDirective and the shipping dependency together, atomically.
const ( // IncludeDependencyLegacy — the included artifact does not depend on the // generated boot projection. This is the SHIPPING dependency as of 3D.3, and // boot-projection readiness is irrelevant to it. IncludeDependencyLegacy IncludeDependency = iota // IncludeDependencyBootProjection — the included artifact IS the generated // boot projection, so the include must not be written unless that projection // was established by the authoritative render in THIS run. IncludeDependencyBootProjection )
func (IncludeDependency) String ¶ added in v1.229.13
func (d IncludeDependency) String() string