# NFT-SEC-02 + NFT-SEC-05 — No-egress contract + DNS blackhole defense-in-depth

**Task**: AZ-437_nft_sec_02_05_no_egress
**Name**: Combined no-network-egress + DNS-blackhole defense-in-depth (AC-NEW-10 / Mode B accepted residual risk #1)
**Description**: Implement NFT-SEC-02 (Docker network `internal: true` blocks all egress; no DNS lookup; no outbound TCP/UDP/ICMP) and NFT-SEC-05 (DNS blackhole defense-in-depth: even if `internal: true` is misconfigured, no DNS-based exfiltration). Both share the egress-counter observation pattern.
**Complexity**: 3 points
**Dependencies**: AZ-406, AZ-407
**Component**: Blackbox Tests / Security (epic AZ-262)
**Tracker**: AZ-437
**Epic**: AZ-262 (E-BBT)

## Problem

The "no network egress" guarantee is the project's data-residency cornerstone. NFT-SEC-02 verifies the Docker `internal: true` net behavior; NFT-SEC-05 verifies the defense-in-depth (DNS-blackhole sidecar) so that a single misconfiguration cannot create an exfiltration path.

## Outcome

- pytest scenarios at `e2e/tests/security/test_nft_sec_02_no_egress.py` and `test_nft_sec_05_dns_blackhole.py`.
- NFT-SEC-02: 5 min Derkachi replay; Docker network stats counter; assert `non_e2e_net_egress_packets == 0`.
- NFT-SEC-05: same replay; verify DNS blackhole sidecar is healthy; force a DNS resolution attempt from the SUT (via runner-issued `nslookup` invocation through SUT exec — done as a probe); assert resolution fails AND no UDP packet leaves the host even with a hypothetical net misconfiguration.

## Scope

### Included
- Docker network egress counter read.
- DNS-resolution probe + UDP egress observation.

### Excluded
- The cache-poisoning budget — owned by NFT-SEC-01.
- MAVLink signing-rejection — owned by NFT-SEC-03.

## Acceptance Criteria

**AC-1: NFT-SEC-02 — egress counter**
Given a 5 min Derkachi replay against `e2e-net.internal: true`
Then `docker network inspect e2e-net` shows zero packets to non-`e2e-net` destinations from the SUT container's interface.

**AC-2: NFT-SEC-05 — DNS-blackhole health**
Given the DNS-blackhole sidecar configured per `environment.md`
When the test pings the sidecar's health endpoint via the e2e network
Then a 200/healthy response is received.

**AC-3: NFT-SEC-05 — DNS resolution fails**
Given the SUT container executes a runner-issued `nslookup example.com`
Then the lookup fails (NXDOMAIN, timeout, or "no servers can be reached") AND the host's outbound interface counter shows no incremented UDP-53 packets during the probe.

**AC-4: parameterization**
Given conftest parameterization
Then both methods run per `(fc_adapter, vio_strategy)`.

## System Under Test Boundary

End-to-end through public boundaries.

- **Allowed**: Docker network stats (public Docker API), host-level interface counter (a public OS artifact), runner-issued exec into SUT container for the nslookup probe (this is a security probe, not a SUT modification).
- **Forbidden**: importing SUT internals to detect outbound calls.

## Constraints

- The nslookup probe MUST execute inside the SUT container's network namespace (via `docker exec`); execution from the runner host doesn't validate the SUT's net isolation.

## Document Dependencies

- `_docs/02_document/tests/security-tests.md` § NFT-SEC-02, § NFT-SEC-05
- `_docs/02_document/tests/test-data.md` § Security
- `_docs/02_document/tests/environment.md` § DNS blackhole sidecar
