## feat: integrate hillock XDP, TC, nftables, and iptables firewall backends#435
Open
Gepsonka wants to merge 14 commits into
Open
## feat: integrate hillock XDP, TC, nftables, and iptables firewall backends#435Gepsonka wants to merge 14 commits into
Gepsonka wants to merge 14 commits into
Conversation
|
All contributors have signed the CLA. Thank you! |
Collaborator
Author
|
I have read the CLA Document and I hereby sign the CLA |
pigri
added a commit
that referenced
this pull request
Jul 10, 2026
Redo of the botched merge 0322c46, which resolved conflicts by taking the branch side wholesale and silently reverted ~8500 lines of main's post-fork work (identity, edge_set, service_graph, passive_scan, penalty_signals, identity_mmdb, fqdn/sni stores, tcx overlay_capture, egress edge-drop, CLI/ML config, blocking-log, IDS, config, xdp-e2e CI, ...). This merge instead keeps main's additions (82 files at main parity, 0 reverted) and layers the hillock XDP/TC/iptables/nftables firewall integration on top. Conflict resolutions: - firewall/mod.rs: keep both (branch ja4/tcp-fp capture + main tcx overlay). - firewall/iptables.rs, nftables.rs: keep hillock backends; port main's egress edge-drop (ban_edge/unban_edge) onto them (native FORWARD-chain layered alongside hillock's IP filter). - access-rules: keep both (XDP/TC firewall-rules backend + egress EdgeFallback); reimplement ban_edge_kernel_global/unban_edge_kernel_global as hillock 5-tuple drop rulesets via the dispatcher (FIREWALL_SKELS was replaced by dispatchers). - app/lib.rs: keep the branch's hillock dispatcher init (replaces the inline bpf::XdpSkelBuilder attach loop main improved). - amygdala 0.1.5 -> 0.1.9 (needed for main's dns.fqdn / identity.k8s scheme fields); hillock stays 0.1.0 (git patch; not yet published to the registry). Verified: cargo check --workspace --all-targets clean; firewall+fingerprint e2e all pass (iptables 12/12, nftables 14/14, xdp 7/7, tc 1/1, fingerprint e2e 1/1, fingerprint unit 14/14). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds egress_edge_e2e_tests covering the edge-drop (per-flow src->dst) paths:
- egress_edge_nftables / egress_edge_iptables: the REAL enforcement path
(native FORWARD-hook chain) — verifies rule/element install+remove, TTL,
idempotency. Both pass (nft 8/8, ipt 6/6).
- egress_edge_xdp_kernel_is_safe_noop: safety regression guard.
The tests surfaced a real bug: hillock's XDP firewall-rules backend cannot
express a per-flow src->dst drop. A rule with both src_ip and dst_ip matches
the destination ONLY (ignoring src) and logs a kernel "integer out of range" —
installing it blackholes ALL traffic to the destination. The previous
ban_edge_kernel_global port did exactly this.
Fix: ban_edge_kernel_global / unban_edge_kernel_global are now deliberate
no-ops (return false) so ban_edge_global falls through to the correct
nftables/iptables FORWARD-hook fallback. Documented with a TODO to re-enable a
kernel edge-drop once hillock exposes a dedicated banned_edges map.
Known gap (follow-up): app/lib.rs only registers the nftables/iptables edge
fallback for those backends (`_ => {}` for XDP), so in XDP-primary mode an
egress edge-drop is currently a silent no-op — a fallback should be registered
there too.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
hillock 0.2.1 is now published to the gen0sec registry, so the load-bearing
`[patch]` sourcing hillock from git (which CI couldn't fetch —
"revision ... not found") is removed and all crates depend on the registry
version:
synapse-security / synapse-smart-firewall / synapse-access-rules /
synapse-app: hillock 0.1.0 -> 0.2.1.
The 0.1->0.2 API is compatible with the branch's usage — cargo check
--workspace --all-targets is clean and the full firewall+fingerprint e2e suite
passes on 0.2.1 (iptables 12/12, nftables 14/14, xdp 7/7, tc 1/1, fingerprint
e2e 1/1, egress edge 3/3, fingerprint unit 14/14).
Also applies nightly rustfmt (fixes the CI Formatting/Windows fmt failures):
import ordering in firewall/{iptables,nftables}.rs + egress_edge_e2e_tests.rs.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CI's Wellness Check + Windows clippy jobs (stable clippy, now 1.97) surfaced lints once the earlier fmt / hillock-git-fetch failures were cleared: - synapse-access-rules: for_kv_map (`map.iter()` ignoring the key -> `map.values()`), unneeded returns, a very-complex type factored into a `DispatcherList` alias. - synapse-app / synapse-utils / tests/e2e: collapsible if, unneeded return, redundant `&` in warn!, unit let-bindings (cargo clippy --fix). - smart-firewall e2e/test files: `#![allow(clippy::disallowed_methods)]` — unwrap/expect are idiomatic in tests (matches the repo convention in synapse-waf / synapse-utils). Verified locally with the exact CI commands (stable clippy 1.97): cargo clippy --locked --workspace --all-targets -- --deny warnings => clean cargo clippy --locked --workspace --features classifier --all-targets ... => clean cargo +nightly fmt --check => clean Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
thalamus_ids_windows.rs: replace a `match { Some => .., None => return None }`
with the `?` operator (clippy::question_mark, stable 1.97). Windows-only code,
so not caught by the Linux clippy jobs; surfaced by the Windows Build clippy.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The Windows clippy job (unix=false ⇒ all(unix, feature="bpf") is false) hit
real compile errors in the merged hillock wiring:
- synapse-app/src/lib.rs always declares the local `hillock_handles` /
`hillock_tc_handles` vecs, typed with `hillock_init::{HillockXdpHandle,
HillockTcHandle}` — which only existed under cfg(all(unix, feature="bpf")).
Add non-(unix+bpf) stub types so the declarations type-check; they are never
constructed (all populate/read paths are cfg-gated), so the vecs stay empty.
- Allow unused `hillock_tc_handles` (populated/consumed only under the bpf cfg).
- Gate `BPF_FIREWALL_PIN_ROOT` to the bpf cfg (unused otherwise).
Validated the non-bpf path on Linux (unix=true ⇒ same cfg as Windows):
cargo clippy -p synapse-app --no-default-features --all-targets -- -D warnings => clean
Default Linux+bpf clippy + nightly fmt still clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
lib.rs:6652 (Windows branch of network-interface detection): drop the `return` on the tail `match` (clippy::needless_return). Windows-only code, invisible to the Linux clippy jobs. Verified the ENTIRE Windows target is now clippy-clean via cross-compilation (mingw): cargo clippy --all-targets --target x86_64-pc-windows-gnu -- -D warnings => clean. No more Windows-only lints hiding behind the fail-fast. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Replaces synapse's own eBPF pipeline,
nftshelling-out, and rawiptablescrate usage with hillock as the single firewall enforcement layer. Hillock provides the XDP dispatcher, TC attachment, nftables netlink backend, and iptables chain management — synapse wraps them with IP ban/allow logic and fingerprint program injection.What changed
xdp_pipelineskeleton → hillockXdpDispatcherwith tail-call chain (ip_filter → port_filter → firewall_rules → ja4_capture → tcp_fingerprint)OpenTcFirewallRulesattached ingress+egress per interface, backend registered globallynftCLI shelling-out withhillock::linux::nftables::FirewallRuleBackendiptablescrate withhillock::linux::iptables::IpTablesFirewallRules, auto-managing INPUT jump rulesFirewallBackendtrait intoIpFirewallBackend(L3/L4) andFingerprintFirewallBackend(L7 JA4) — callers depend only on what they needOnceLock<Mutex<Option<...>>>globals0.0.1to0.1.0at commit58fb0ac(withiptables/nftablesfeature flags)std::mem::transmutewithBox::leakfor BPF skeleton lifetime management--features bpf,amygdala-reactorworkspace buildE2E test coverage (34 tests, 544 checks)
All use real
hping3traffic through veth pairs + netns. Run with:make test-e2e-all # or test-e2e-nftables / test-e2e-iptables / test-e2e-xdpFiles changed
33 files, +7,376 / −1,635 lines