PacketYeeter is a high-performance, eBPF-based DDoS protection and traffic filtering tool written in Go. It leverages the Linux Kernel's XDP (Express Data Path) and TC (Traffic Control) subsystems to inspect, classify, and drop malicious traffic at line rate.
-
SYN Flood Detection & Mitigation (Layer 4)
- Detection: Uses eBPF TC (Ingress/Egress) to track TCP handshake states. It identifies source IPs that initiate connections (SYN) but never complete the handshake (ACK); pending entries are cleared once a matching ACK arrives.
- Mitigation: Incomplete-handshake signals are streamed to the analyzer, which applies the
-ddos-min-incompletethreshold and returns a block decision over gRPC — blocking is analyzer-driven, not an automatic kernel-space decision. - Enforcement: XDP drops packets from IPs the collector has been told to block, before they reach the OS network stack.
- SYN cookies: PacketYeeter does not implement its own SYN cookie challenge/response in XDP — because the XDP program transparently passes legitimate traffic straight into the local kernel's TCP stack, a spoofed SYN-ACK challenge answered directly by XDP would leave the client believing the connection is already established, so there is no protocol-safe way to hand it off to the real stack afterward without sending a second, unexpected SYN-ACK. Instead, the collector checks
net.ipv4.tcp_syncookiesat startup and logs a warning if it's disabled, since that's the kernel's own (already-present, battle-tested) SYN cookie implementation, complementing PacketYeeter's incomplete-handshake detection andblocked_ipsenforcement above.
-
TCP Flag Sanitization
- Detects and drops invalid TCP flag combinations commonly used in reconnaissance scans and attacks:
- SYN-FIN (Impossible state)
- Xmas Tree (FIN + PSH + URG)
- NULL Scan (No flags)
- Each detection is classified by scan type and reported to the analyzer as a
SIGNAL_BAD_FLAGSsignal (previously these drops were kernel-only and invisible outsidepacketyeeter_tcp_bad_flags_blocks_total). Repeat offenders accumulate reputation penalties and can be banned via the same feedback loop used for other floods.
- Detects and drops invalid TCP flag combinations commonly used in reconnaissance scans and attacks:
-
IP Allowlist (CIDR Support)
- Protect specific IPs or ranges (CIDR notation) from ever being blocked.
- Allowlisted CIDRs are synced into kernel-space LPM trie maps (
allowlist_v4/allowlist_v6) at startup and updated dynamically when the analyzer pushes allowlist commands, so the XDP program bypasses matching traffic directly; the collector's userspace block-decision path also honors the same list as a second layer of defense. (TC-side handshake/latency tracking still observes allowlisted traffic — it only tracks state, it never blocks.) - Supports both IPv4 and IPv6 CIDRs.
3.5. Per-CIDR Policy Engine
* Lets an operator force a block or monitor decision for a whole network range via the -policy flag, checked in XDP right after the allowlist and before every other detection.
* block drops all matching traffic outright (still subject to the collector's own -dry-run/monitor mode, so a new policy can be tested log-only before it takes effect).
* monitor forces monitor-mode for matching sources only — useful for staging a CIDR's blast radius, or for a range that shouldn't be dropped by any detection but isn't fully allowlisted either.
* Policy rules are kernel-space LPM trie maps (policy_v4/policy_v6), populated once at startup from -policy; they are not currently mutated at runtime by the analyzer (unlike the allowlist).
3.6. Structured Incident Logging
* Every kernel-space drop decision (policy block, blocked-IP enforcement, ICMP/UDP rate-limit drop, IPv6 fragment drop, bad-flags drop) emits a compact structured record — source address, kernel timestamp, and a reason code — over a dedicated eBPF perf event array, in addition to whatever counters/signals that detection already produces.
* The collector decodes these records and logs a single structured logrus entry per incident (fields: ip, reason, kernel_timestamp), giving operators a unified, per-packet-drop audit trail instead of having to correlate several counters.
* Each incident also increments packetyeeter_kernel_incidents_total{reason=...}, a low-cardinality Prometheus counter (six known reason values) for dashboards/alerting.
* This is purely an observability feature — it does not change enforcement behavior or generate new analyzer signals for reasons that already have one (bad flags, ICMP/UDP floods already stream SIGNAL_* events to the analyzer).
-
Volumetric Rate Limiting (ICMP & UDP)
- ICMP: Limits the rate of ICMP packets from a single source to prevent ping floods.
- UDP: Strict rate limiting for UDP traffic to mitigate amplification/flood attacks.
- Thresholds are enforced directly in XDP for maximum performance.
-
Reputation Engine (Anomaly Scoring)
- Concept: Assigns a numerical "Reputation Score" to every IP, JA4 fingerprint, and ASN interacting with the system.
- Scoring:
- Scores start at 0.
- Points are added per detected signal using a per-signal weight (default
5.0, capped at20for incomplete-handshake signals). The associated ASN is penalized at a fraction of that weight (0.1–0.25×), and the associated JA4H fingerprint at0.6×. - Scores degrade over time (decay factor
0.95every 30 minutes) to forgive transient issues.
- Enforcement: If a score exceeds the configured threshold (analyzer default:
75.0, via-reputation-threshold), the entity is marked as a "Bad Actor" and subsequent traffic is dropped (or logged only in Dry-Run Mode). - Metrics:
packetyeeter_reputation_score(Gauge) tracks the current score of all tracked entities.
-
JA4T SSL/TCP Fingerprinting (Layer 4)
- Detection: Passive TCP fingerprinting based on window size, TCP options, and ordering (JA4T format), passed through from HAProxy SPOE.
- Abuse Detection: JA4T abuse signals feed into the same generic AI signal-aggregation/confidence scoring as other behavioral signals (no JA4T-specific frequency window).
- Metrics:
packetyeeter_ja4t_suspicious_total(Counter) tracks abuse events.
-
JA4L / Latency Monitoring
- Detection: Measures the RTT (Round Trip Time) of the TCP handshake (SYN-ACK -> ACK) passively via eBPF.
- Adaptive Baseline: Maintains an EWMA per ASN to avoid penalizing inherently high-latency networks; flags spikes relative to each ASN.
- Alerting:
- Logs warnings for high latency events.
- Metrics:
packetyeeter_high_latency_handshakes_total(Counter),packetyeeter_high_latency_max_ms(Gauge),packetyeeter_latency_ewma_by_asn_ms(GaugeVec).
-
GeoIP / ASN Intelligence
- Enrichment: Integrates with MaxMind GeoLite2 ASN databases to tag metrics with Autonomous System (ASN) and Organization data. Optionally also loads a GeoLite2-Country/City database (
-geoip-country) for country-level enrichment, surfaced in the Inspector's "Threats by Country" panel. - Insights: Break down latency, abuse events, and traffic anomalies by Provider (e.g., "Google Cloud", "DigitalOcean") or by country.
- Metrics:
packetyeeter_latency_by_asn_seconds(Histogram): Latency distribution per ASN.packetyeeter_abuse_by_asn_total(Counter): Anomalies and blocks grouped by ASN.
- Enrichment: Integrates with MaxMind GeoLite2 ASN databases to tag metrics with Autonomous System (ASN) and Organization data. Optionally also loads a GeoLite2-Country/City database (
-
HAProxy Stick-Table Integration (Layer 7)
- Implements the HAProxy Peer Protocol (v2).
- Allows PacketYeeter to act as a "peer" to HAProxy, receiving stick-table updates (e.g., HTTP req rate limits, error rates) and blocking corresponding IPs at the XDP layer.
-
HAProxy SPOE / L7 Analytics (JA4H + AI Heuristics)
- Goal: Detect proxies/bots via protocol latency, JA4H fingerprinting, and behavioral signals.
- Mechanism: HAProxy SPOE sends timestamps + HTTP features (JA4H via Lua, host, UA, headers, cookies) to PacketYeeter.
- Logic:
- Compare proxy lag (
client_req_msminus network RTT) against an adaptive per-ASN threshold. - JA4H fingerprinting via upstream lua (
fingerprint_ja4h). - Heuristics: suspicious UA, missing headers, host-aware cookie expectations, honeypot paths, sequential path enumeration (alpha/numeric), low asset ratio (HTML >> assets).
- Detection:
- Static:
len(signals) >= 2OR severe signals (honeypot,numeric_seq,alpha_seq). - Adaptive (EWMA): per-ASN proxy-lag baseline in milliseconds, with a 1000ms floor; flags when
proxy_lag_ms > max(1000, ewma_lag_ms*3 + 200)(and, when RTT is known, also requiresproxy_lag_ms > rtt_ms*2).
- Static:
- Compare proxy lag (
- Metrics:
packetyeeter_client_req_time_ms(Histogram)packetyeeter_proxy_lag_max_ms(Gauge)packetyeeter_proxy_lag_ewma_by_asn_ms(GaugeVec)packetyeeter_spoe_anomaly_total(Counter)packetyeeter_spoe_handler_seconds(Histogram)packetyeeter_spoe_processing_seconds(Histogram)packetyeeter_spoe_queue_depth(Gauge)packetyeeter_spoe_queue_drops_total(Counter)packetyeeter_ai_signals_total(Counter)packetyeeter_ai_signals_by_type_total(CounterVec)packetyeeter_ai_signals_by_asn_total(CounterVec)packetyeeter_ai_detections_total(Counter)packetyeeter_ai_detections_by_asn_total(CounterVec)packetyeeter_ai_detections_by_ja4h_total(CounterVec)packetyeeter_ai_detections_by_ip_total(CounterVec)packetyeeter_ai_signal_ewma_by_asn(GaugeVec)packetyeeter_ai_signal_ewma_by_ja4h(GaugeVec)
Consistency: signals are canonicalized (case-insensitive) and block commands are deduped per IP to avoid double blocks from overlapping detectors.
Logging schema (JSON):
component,event,ip,asn,ja4h,confidence,ml_confidence,ml_category,bot_category,reason,duration_secs,signal_count,signal_breakdown,source_breakdown
Dashboards: Prom/Influx dashboards map panels to metrics; see
docs/observability.md.
-
Monitor / Dry-Run Mode
- Run the analyzer with
-dry-runto log detections and update metrics without sending BLOCK commands to the collector. - Run the collector with
-dry-runto put its own kernel-space detections (bad flags, SYN-flood blocklist, ICMP/UDP rate limits) into log-only mode without dropping matching traffic. - The two flags are independent; for a full dry-run rollout, enable both.
- Run the analyzer with
-
Observability & Metrics
- Prometheus Exporters: Each daemon exposes its own metrics endpoint (collector default
:2112, analyzer default:9091) covering block counts, pps rates, reputation, and attack types. - Structured Logging: All logs are emitted in JSON format for easy ingestion by Logstash/Fluentd/Vector.
- Grafana Dashboard: Includes a pre-built dashboard (
grafana-dashboard.json) for visualizing attack traffic (IPs excluded in default dashboard; private dashboards can include IPs from metrics).
- Prometheus Exporters: Each daemon exposes its own metrics endpoint (collector default
CONTRIBUTING.md: build, test, and PR workflow.SECURITY.md: private vulnerability reporting guidance.docs/operations.md: deployment, listener exposure, systemd, and rollout guidance.docs/troubleshooting.md: common eBPF, build, and runtime issues.
PacketYeeter runs as two cooperating daemons connected over gRPC:
- Collector (
packetyeeter-collector) — runs on each protected host. It loads the eBPF/XDP/TC programs, performs line-rate packet inspection and enforcement (blocking, rate limiting, flag sanitization), terminates the HAProxy Peer and SPOE protocols, and streams behavioral signals to the analyzer. It applies BLOCK commands returned by the analyzer directly in kernel-space maps. Requires root / BPF capabilities. - Analyzer (
packetyeeter-analyzer) — a userspace-only "brain" that receives signals from one or more collectors, runs the reputation engine, AI/ML bot detection, JA4+ fingerprint lookups, GeoIP/ASN enrichment, and threat intelligence (Shodan InternetDB), then returns BLOCK commands. It needs no special privileges and can run on a separate host.
graph TD
subgraph host["Protected Host"]
subgraph kernel["Kernel Space (eBPF)"]
XDP[XDP Filters<br/>block / rate-limit / bad-flags]
TC[TC Ingress/Egress<br/>handshake + latency tracking]
end
Collector[packetyeeter-collector<br/>loads BPF, HAProxy Peer + SPOE]
XDP <--> Collector
TC <--> Collector
Collector -->|:2112 /metrics| PromC[Prometheus]
end
subgraph brain["Analyzer Host"]
Analyzer[packetyeeter-analyzer<br/>reputation • AI/ML • JA4DB • threat intel]
Analyzer -->|:9091 /metrics| PromA[Prometheus]
Analyzer -->|:9092 inspector UI| Web[Browser]
end
Collector <-->|gRPC StreamSignals / Commands<br/>:9090| Analyzer
Analyzer -->|Shodan InternetDB / GeoIP| Ext[(External Data)]
PromC --> Grafana[Grafana Dashboard]
PromA --> Grafana
The AnalyzerService gRPC contract (api/proto/v1/packetyeeter.proto) exposes a bidirectional StreamSignals(stream Signal) -> stream Command channel (collector → analyzer signals, analyzer → collector commands) plus request/response RPCs for JA4H/JA4T lookups, bot/AI-crawler verification, threat intel, and reputation.
| Binary | Location | Purpose |
|---|---|---|
packetyeeter-collector |
cmd/collector |
eBPF loader + enforcer, HAProxy Peer/SPOE, gRPC client. Root required. |
packetyeeter-analyzer |
cmd/analyzer |
AI/ML + reputation + threat-intel gRPC server. No privileges needed. |
yeetctl |
cmd/yeetctl |
CLI to inspect collector state over a UNIX socket. |
yeetexplorer |
cmd/yeetexplorer |
Interactive terminal (TUI) dashboard for live inspection. |
labeler |
cmd/labeler |
Offline tool to label captured sessions for ML training. |
- OS: Linux (Kernel 5.4+ recommended) for the collector. The analyzer is portable userspace Go.
- Collector build dependencies:
clang,llvmlibbpf-devlinux-headers(matching current kernel)
- Go: 1.26.4+
- Proto (optional, only to regenerate):
buf,protoc-gen-go,protoc-gen-go-grpc(make install-buf).
-
Clone & Tidy:
git clone https://github.com/awlx/packetyeeter.git cd packetyeeter make deps -
Build with the Makefile (recommended):
make # proto + collector + analyzer make collector # packetyeeter-collector only (needs the compiled BPF object, see below) make analyzer # packetyeeter-analyzer only make yeetctl # yeetctl CLI
The BPF object (
pkg/collector/ebpf/c/protector.bpf.o) is embedded into the collector via//go:embed, so it must be compiled before building the collector:clang -O2 -g -target bpf -I/usr/include/x86_64-linux-gnu \ -c pkg/collector/ebpf/c/protector.bpf.c \ -o pkg/collector/ebpf/c/protector.bpf.o go build -o packetyeeter-collector ./cmd/collectorNOTE:
make test/go test ./...needs the compiledprotector.bpf.opresent (run theclangstep ordeploy.shfirst).Testing tiers:
make portable-test— unit/integration tests that don't need Linux/eBPF; runs anywhere.make e2e-test— spins up a realhaproxybinary (must be onPATH) and drives it against the collector's HAProxy peer-protocol listener and SPOE agent to validate wire compatibility. Portable to any OS withhaproxyinstalled; no kernel/eBPF required.make e2e-ebpf-test— loads and attaches the real eBPF/XDP program to a scratch dummy interface and verifies that a block command from the analyzer is written to and readable from the real kernel map. Requires Linux, root, and the compiled BPF object (make bpf); not portable.
-
Remote deployment with
deploy.sh:# Usage: ./deploy.sh <host> [collector|analyzer|both] [options] # Deploy both daemons to a host and install/enable systemd services ./deploy.sh webfrontend01.example.com both -i ens192 --install-service # Deploy only the collector, pointing it at a remote analyzer ./deploy.sh webfrontend01.example.com collector -i eth0 --analyzer-addr 10.0.0.5:9090 # Deploy only the analyzer ./deploy.sh analyzer.example.com analyzer --listen-addr 0.0.0.0:9090 # First-time host: install build deps too ./deploy.sh webfrontend01.example.com both --install-deps --install-service
Options:
--install-deps,--install-service,--regen-proto,-i/--interface,--analyzer-addr,--listen-addr,--metrics-addr. -
Pre-built binaries, packages, and Docker images: every push to
mainand everyvX.Y.Ztag builds and publishes release artifacts via CI:- Standalone binaries and checksums (
SHA256SUMS) forpacketyeeter-collector/packetyeeter-analyzer(linux/amd64) andyeetctl/yeetexplorer/labeler(linux/amd64 + linux/arm64) — attached to the GitHub Release for tags, or downloadable as a CI build artifact formain. .debpackages (linux/amd64) built with nfpm frompackaging/nfpm/{collector,analyzer}.yaml, installing binaries to/opt/packetyeeter/{collector,analyzer}/, systemd units to/etc/systemd/system/, and config to/etc/default/. Installing the package does not enable or start the service — review the config first, thensudo systemctl enable --now packetyeeter-<collector|analyzer>. Build locally withmake install-nfpm packages.- Docker images at
ghcr.io/awlx/packetyeeter-analyzerandghcr.io/awlx/packetyeeter-collector, taggedmain/commit SHA frommainpushes, and<tag>/latest/commit SHA from version tags. Build locally withdocker build --target analyzer .ordocker build --target collector .. The collector image needs to run with the same capabilities as the systemd unit below (NET_ADMIN,BPF,PERFMON,NET_RAW,SYS_ADMIN, unlimited memlock) to load eBPF/XDP — it is not meant to run as an unprivileged container.
The collector and analyzer binaries/images/packages are linux/amd64 only: the collector's eBPF object is compiled for the host architecture, and the analyzer links against onnxruntime via cgo, so neither cross-compiles cleanly without a matching cross toolchain.
- Standalone binaries and checksums (
Start the analyzer first (anywhere; no root needed), then the collector
on each protected host pointing at the analyzer's gRPC address. For new
deployments, start both daemons with -dry-run (the analyzer's flag
suppresses BLOCK commands; the collector's flag suppresses its own
kernel-space drops), review logs and metrics, then roll out enforcement
gradually after tuning thresholds and allowlists.
# Analyzer (brain) — listens for collectors on :9090, metrics on :9091
./packetyeeter-analyzer -listen-addr 0.0.0.0:9090 -metrics-addr :9091 \
-geoip-asn /var/lib/GeoIP/GeoLite2-ASN.mmdb
# Collector (enforcer) — root required to load eBPF
sudo ./packetyeeter-collector -i eth0 -analyzer-addr 127.0.0.1:9090| Flag | Default | Description |
|---|---|---|
-i |
eth0 |
Network interface to attach eBPF programs to. |
-analyzer-addr |
127.0.0.1:9090 |
Analyzer gRPC address to connect to. |
-metrics-addr |
:2112 |
Prometheus metrics HTTP listen address. |
-haproxy-port |
8765 |
HAProxy Peer protocol port. |
-spoe-port |
9876 |
HAProxy SPOE agent port. |
-socket |
/var/run/packetyeeter-collector.sock |
UNIX socket for yeetctl. |
-geoip-asn |
"" |
Path to GeoLite2-ASN.mmdb for ASN enrichment. |
-allowlist |
"" |
Comma-separated CIDRs to bypass all filtering (IPv4/IPv6). |
-policy |
"" |
Comma-separated per-CIDR policy overrides as CIDR=action (block or monitor), e.g. 203.0.113.0/24=block,198.51.100.0/24=monitor. |
-block-duration |
5m |
Default duration to keep an IP blocked. |
-poll-interval |
1s |
How often to poll the eBPF maps. |
-signal-queue-size |
10000 |
Collector → analyzer signal queue size. |
-dry-run |
false |
Monitor mode: the collector's own kernel-space detections (bad flags, SYN-flood blocklist, ICMP/UDP rate limits) log/count but never drop traffic. Independent of the analyzer's -dry-run, which only suppresses BLOCK commands sent back over gRPC. |
-v |
false |
Verbose logging. |
| Flag | Default | Description |
|---|---|---|
-listen-addr |
0.0.0.0:9090 |
gRPC listen address for collectors. |
-metrics-addr |
:9091 |
Prometheus metrics HTTP listen address. |
-inspect-addr |
127.0.0.1:9092 |
Read-only HTTP inspector UI address. |
-geoip-asn |
"" |
Path to GeoLite2-ASN.mmdb for ASN enrichment. |
-geoip-country |
"" |
Path to GeoLite2-Country.mmdb or GeoLite2-City.mmdb (optional). Enables country-level enrichment and the Inspector's "Threats by Country" panel; without it, country fields report "unknown". |
-reputation-threshold |
75.0 |
Reputation score at which an entity is treated as a bad actor. |
-reputation-max-entries |
500000 |
Max tracked reputation entries. |
-reputation-max-age |
24h |
Max age before a reputation entry is evicted. |
-reputation-asn-max-hosts |
5000 |
Max tracked hosts per ASN. |
-ai-confidence-threshold |
0.7 |
Minimum AI confidence to flag a bot/scraper. |
-ai-workers |
16 |
AI detection worker pool size. |
-ai-queue-size |
10000 |
AI detection queue size. |
-ml-model |
"" |
Optional path to an ONNX ML model. |
-ddos-min-incomplete |
400 |
Min incomplete handshakes for a DDoS categorization. |
-ddos-min-pattern |
800 |
Min pattern matches for a DDoS categorization. |
-ddos-min-total |
1500 |
Min total events for a DDoS categorization. |
-ddos-require-highfreq |
true |
Require high-frequency traffic for DDoS categorization. |
-disable-ddos-category |
false |
Disable the DDoS categorization path. |
-enable-high-cardinality-metrics |
false |
Emit per-IP / per-JA4H high-cardinality metrics. |
-enable-pprof |
false |
Enable the pprof HTTP server. |
-pprof-addr |
:6060 |
pprof listen address. |
-dry-run |
false |
Log detections but do not send BLOCK commands (Monitor Mode). |
-v |
false |
Verbose logging. |
Threat intelligence uses the free, keyless Shodan InternetDB API — no API key is required.
PacketYeeter is designed to be monitored via Prometheus and Grafana.
-
Metrics Endpoints:
- Collector:
http://<collector-host>:2112/metrics - Analyzer:
http://<analyzer-host>:9091/metrics
All metrics are prefixed
packetyeeter_. Key series include:packetyeeter_tcp_blocks_total,packetyeeter_udp_blocks_total,packetyeeter_icmp_blocks_total,packetyeeter_haproxy_blocks_total: blocks by protocol/source.packetyeeter_tcp_syn_flood_blocks_total: SYN flood blocks.packetyeeter_tcp_bad_flags_blocks_total: invalid TCP flag blocks.packetyeeter_kernel_incidents_total{reason}: structured kernel-space incident records (collector endpoint), broken down by reason (blocked_ip,policy_block,icmp_rate,udp_rate,udp_frag,bad_flags). See "Structured Incident Logging" above.packetyeeter_udp_max_rate_pps,packetyeeter_icmp_max_rate_pps: peak UDP/ICMP PPS.packetyeeter_ja4t_suspicious_total: suspicious JA4T abuse events.packetyeeter_high_latency_handshakes_total,packetyeeter_high_latency_max_ms,packetyeeter_latency_ewma_by_asn_ms: JA4L latency signals.packetyeeter_proxy_lag_max_ms,packetyeeter_proxy_lag_ewma_by_asn_ms,packetyeeter_client_req_time_ms: SPOE / proxy-lag signals.packetyeeter_reputation_score: current reputation score per entity.packetyeeter_ai_signals_total,packetyeeter_ai_detections_total(plus_by_asn,_by_ja4h,_by_ip,_by_typevariants): AI bot/scraper signals and detections.packetyeeter_attack_campaign_detections_total,packetyeeter_active_attack_campaigns,packetyeeter_carpet_bombing_detections_total,packetyeeter_campaign_baseline_*: observe-only DDoS campaign and adaptive baseline signals.packetyeeter_ml_*,packetyeeter_ja4db_*,packetyeeter_bot_verification_*,packetyeeter_threat_intel_*,packetyeeter_rate_limit_*: ML inference, JA4DB, bot verification, threat-intel, and rate-limiter metrics.
See
docs/observability.mdfor the full metric catalog and dashboard panel mappings. - Collector:
-
Inspector UI: The analyzer serves a read-only web inspector at
http://127.0.0.1:9092(-inspect-addr) for live inspection of sessions, detections, and reputation. Keep it bound to loopback or behind trusted access controls. -
Grafana Dashboard: A production-ready dashboard is included:
grafana-dashboard.json. Import it into Grafana with a Prometheus data source configured. The default dashboard excludes IPs; build a private dashboard if IP visibility is needed. Seeexamples/prometheus-scrape.ymlfor a minimal Prometheus scrape config andexamples/prometheus-alerts.ymlfor example alert rules. -
Logs: Logs are output in structured JSON format, e.g.:
{"action":"WOULD BLOCK (Dry Run)","ip":"192.0.2.15","level":"warning","msg":"Rate Limit Exceeded","pps":5323,"reason":"rate_limit_exceeded","time":"..."}
yeetctl inspects the collector's state over its UNIX socket. Both the
collector and yeetctl default to /var/run/packetyeeter-collector.sock; use
-socket on the collector or -sock on yeetctl to override it.
SOCK=/var/run/packetyeeter-collector.sock
# List currently blocked IPs and their remaining TTL
sudo ./yeetctl -sock $SOCK list
# View current reputation scores (entities with score > 0)
sudo ./yeetctl -sock $SOCK reputation
# Show AI detection summaries (by IP, JA4H, ASN)
sudo ./yeetctl -sock $SOCK ai
# Show verified/unverified bot activity
sudo ./yeetctl -sock $SOCK botsThe collector reports blocked IPs directly from its eBPF maps. Reputation, AI, and bot summaries currently return empty collector-side state until analyzer state is exposed over the management API.
For an interactive live view, run yeetexplorer (a terminal UI dashboard).
PacketYeeter ships two systemd units — one per daemon. make install-services
copies them into place, or install manually:
-
Install binaries:
sudo mkdir -p /opt/packetyeeter/collector /opt/packetyeeter/analyzer sudo cp packetyeeter-collector /opt/packetyeeter/collector/ sudo cp packetyeeter-analyzer /opt/packetyeeter/analyzer/
-
Install config & units:
sudo cp packetyeeter-collector.default /etc/default/packetyeeter-collector sudo cp packetyeeter-analyzer.default /etc/default/packetyeeter-analyzer sudo cp packetyeeter-collector.service /etc/systemd/system/ sudo cp packetyeeter-analyzer.service /etc/systemd/system/
-
Configure: Edit
/etc/default/packetyeeter-collector(interface, analyzer address, allowlist, …) and/etc/default/packetyeeter-analyzer(listen address, GeoIP path, …). The collector runs withCAP_SYS_ADMIN/NET_ADMIN/BPF/PERFMON/NET_RAWandLimitMEMLOCK=infinity; the analyzer runs hardened (NoNewPrivileges,ProtectSystem=strict,ReadWritePaths=/var/lib/packetyeeter). Avoid removing collector capabilities or adding restrictive device/network hardening unless BPF load, XDP attach, TC attach, and map access have been validated on the target kernel. -
Enable & start (start the analyzer first; the collector
Wantsit):sudo systemctl daemon-reload sudo systemctl enable --now packetyeeter-analyzer sudo systemctl enable --now packetyeeter-collector
-
View logs:
journalctl -u packetyeeter-collector -f journalctl -u packetyeeter-analyzer -f
The scripts/ directory contains Python/Scapy utilities to test detection and
tooling for the ML pipeline:
- SYN Flood:
python3 scripts/flood_test.py <TargetIP> --count 500 - Bad Flags:
python3 scripts/flag_test.py <TargetIP> --count 20 - ML pipeline: training/evaluation helpers such as
train_model.py,train_advanced_model.py,evaluate_model.py, andsessions_to_training.py.
PacketYeeter is licensed under GPL-2.0 (required for Kernel BPF compatibility).
The full license text is available in LICENSE.
PacketYeeter implements fingerprinting derived from the JA4+ suite (JA4H, JA4T, JA4L). These algorithms originate from FoxIO-LLC/ja4 and are subject to the FoxIO License 1.1, which is separate from and additional to the GPL-2.0 license covering PacketYeeter's own code:
- The original JA4 (TLS client) algorithm is BSD-3-Clause licensed.
- The JA4+ algorithms (including JA4H/JA4T/JA4L) are licensed under the FoxIO License 1.1, which permits open-source and internal use but restricts commercial redistribution. If you intend to use PacketYeeter commercially, review the FoxIO License terms and contact FoxIO LLC regarding the JA4+ components.
See NOTICE for full third-party attribution.