Add firewall integration suite covering fips0 default-deny baseline

End-to-end exercise the v0.3.0 nftables firewall baseline so the
security claim — "services on fips0 are not exposed by default" — is
validated in CI rather than by operator opt-in. The packaging postinst
state is pinned by the deb-install matrix; this suite pins the actual
ruleset behavior.

testing/firewall/ — new directory mirroring the acl-allowlist
precedent (kept in its own directory, not extending testing/static):

  docker-compose.yml (52 lines): two FIPS containers on bridge
  172.32.0.0/24, peered over UDP/2121. node-b mounts
  packaging/common/fips.nft RO at /etc/fips/fips.nft and a generated
  drop-in services.nft at /etc/fips/fips.d/.

  test.sh (247 lines): four-case asserter
    (a) curl from node-a to node-b:8000 → DROP (port not allowlisted;
        terminal counter drop fires)
    (b) curl from node-b to node-a:8000 → 200 OK (reply traverses
        node-b's ct state established,related accept)
    (c) ping6 a→b → success (icmpv6 echo-request accept)
    (d) nc -z a→b:22 → success (drop-in tcp dport 22 accept honored
        via include "/etc/fips/fips.d/*.nft")
  Plus drop-counter check after case (a) confirms the dropped
  connection actually hit the chain's terminal counter drop.

  generate-configs.sh (111 lines): mirrors acl-allowlist generator,
  produces the drop-in services.nft + fips configs.

  README.md (111 lines): how to run, expected output, design notes.

  .gitignore: ignores generated-configs/.

testing/ci-local.sh: FIREWALL_SUITES=(firewall) array + run_firewall
runner; dispatch in run_integration and run_suite mirroring
run_acl_allowlist.

.github/workflows/ci.yml: matrix row {suite: firewall, type:
firewall} + 3 steps gated on matrix.type == 'firewall' between
acl-allowlist and gateway. Reuses fips-linux artifact + fips-test:
latest image.

Activation note: the unified test image does not run systemd, so
test.sh invokes the fips-firewall.service ExecStart
(/usr/sbin/nft -f /etc/fips/fips.nft) directly. The systemd-unit
enablement path is covered by the deb-install matrix; this suite
exercises what the unit configures, not how it gets started.
This commit is contained in:
Johnathan Corgan
2026-05-03 21:06:09 +00:00
parent 5611e976ad
commit 33a2063672
7 changed files with 561 additions and 1 deletions
+19
View File
@@ -321,6 +321,9 @@ jobs:
topology: rekey-outbound-only
- suite: acl-allowlist
type: acl-allowlist
# ── Firewall baseline (fips0 nftables default-deny) ────────────
- suite: firewall
type: firewall
# ── Outbound LAN gateway integration test ──────────────────────
- suite: gateway
type: gateway
@@ -575,6 +578,22 @@ jobs:
run: |
docker compose -f testing/acl-allowlist/docker-compose.yml down --volumes --remove-orphans
# ── Firewall baseline integration test ─────────────────────────────────
- name: Run firewall baseline integration test
if: matrix.type == 'firewall'
run: bash testing/firewall/test.sh --skip-build --keep-up
- name: Collect logs on failure (firewall)
if: matrix.type == 'firewall' && failure()
run: |
docker compose -f testing/firewall/docker-compose.yml logs --no-color
docker exec fips-fw-container-b nft list table inet fips || true
- name: Stop containers (firewall)
if: matrix.type == 'firewall' && always()
run: |
docker compose -f testing/firewall/docker-compose.yml down --volumes --remove-orphans
# ── Chaos simulation ───────────────────────────────────────────────────
- name: Install Python deps (chaos)
if: matrix.type == 'chaos'