Skip to content

cnaize/meds

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

64 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Go Version Go Reference License: MIT Platform Version Status Go Report Card


Meds: net healing

Intelligent firewall in Go

It integrates with Linux Netfilter via NFQUEUE, inspects inbound traffic in user space, and applies filtering to block malicious traffic in real-time. Once a connection is checked, the engine "teaches" the Linux kernel to handle it. By assigning Conntrack marks, Meds offloads flows back to the kernel space, achieving maximum wire-speed throughput and minimal CPU overhead.

Designed to cure your network from malicious traffic


🚀 Installation

Requirements:

  • Linux with iptables + NFQUEUE + conntrack support
  • Root privileges (sudo) — required for interacting with Netfilter/Netlink

The application manages iptables and conntrack rules automatically.

Download

Download the latest binary from Releases or build from sources.

Build from sources

go build -o meds ./cmd/daemon

🧩 Quickstart

sudo MEDS_USERNAME=admin MEDS_PASSWORD=mypass ./meds
# Metrics available at: http://localhost:8000/metrics
# API available at: http://localhost:8000/swagger/index.html
# Basic Auth: admin / mypass

Command-line options

./meds -help
Usage of ./meds:
  -api-addr string
    	api server address (default ":8000")
  -db-path string
    	path to database file (default "meds.db")
  -log-level string
    	zerolog level (default "info")
  -logger-queue-len uint
    	logger queue length (all workers) (default 2048)
  -loggers-count uint
    	logger workers count (default 3)
  -rate-limiter-burst uint
    	max packets at once (per ip) (default 1500)
  -rate-limiter-cache-size uint
    	rate limiter cache size (all buckets) (default 100000)
  -rate-limiter-cache-ttl duration
    	rate limiter cache ttl (per bucket) (default 5m0s)
  -rate-limiter-rate uint
    	max packets per second (per ip) (default 3000)
  -reader-queue-len uint
    	nfqueue queue length (per reader) (default 8192)
  -readers-count uint
    	nfqueue readers count (default 12)
  -update-interval duration
    	update frequency (default 4h0m0s)
  -update-timeout duration
    	update timeout (per filter) (default 1m0s)
  -workers-count uint
    	nfqueue workers count (per reader) (default 1)

Prometheus metrics

👉 http://localhost:8000/metrics

The metrics endpoint is protected by the same BasicAuth credentials as the API.

Swagger UI

Interactive API docs:
👉 http://localhost:8000/swagger/index.html

You can browse and test all API endpoints directly from your browser.

OpenAPI spec (JSON):
👉 http://localhost:8000/swagger/doc.json

You can import this spec into Postman, Insomnia, or Hoppscotch.


🔍 How It Works

                  PACKET
                    │
┌───────────────────▼───────────────────┐
│ KERNEL SPACE (iptables / Netfilter)   │
│ ───────────────────────────────────── │
│  1. Restore Connmark                  │
│                                       │
│  2. Check Block List  ──► DROP      ◄─┼──┐
│      (Mark: 0x100000)                 │  │
│                                       │  │
│  3. Check Trust List  ──► ACCEPT      │  │
│      (Mark: 0x200000)                 │  │
│                                       │  │
│  4. First 10 packets  ──┐             │  │
│                         │             │  │
│  5. Save Connmark       │             │  │
└─────────────────────────┼─────────────┘  │
                          │                │
┌─────────────────────────▼─────────────┐  │
│ USER SPACE (Meds Firewall)            │  │
│ ───────────────────────────────────── │  │
│  1. Rate Limiter (per source IP)      │  │
│  2. L3/L4 Filters (IP, Geo, ASN)      │  │
│  3. L7 Inspection (DNS, SNI, TLS JA3) │  │
│                                       │  │
│ [DECISION ENGINE]                     │  │
│  * BLOCK: Mark 0x100000  ──► REPEAT ──┼──┘
│  * TRUST: Mark 0x200000  ──► ACCEPT   │
└───────────────────────────────────────┘
  • Early Drop: Blocked traffic (0x100000) is handled by the kernel immediately. This ensures that known threats are dropped at the earliest possible stage, eliminating unnecessary context switches and user-space overhead.

  • Stateful Acceleration: Once a connection is verified as Trusted (0x200000), it is offloaded to the kernel's fast path. Subsequent packets in the flow are processed entirely in-kernel at wire-speed, eliminating user-space overhead for established sessions.

  • Deep Inspection: Only new or unclassified traffic (the "Decision Phase") is sent to Meds for deep L3/L4/L7 analysis. This phase is limited to a 10-packet window to extract metadata (DNS, SNI, JA3) before the kernel takes over.


✨ Key Features

  • Hybrid Kernel/User-space Processing
    Meds utilizes a stateful marking architecture. It "teaches" the Linux kernel how to handle specific flows by assigning Conntrack marks, achieving wire-speed performance for established connections.

  • Intelligent NFQUEUE Balancing
    Intercepts traffic using NFQUEUE with balance and bypass options, ensuring multi-core scaling and system stability even if the user-space process is restarted.

  • Lock-free Core Architecture
    The core engine is built for high-concurrency performance: no mutexes in the hot path. All filtering, counters, and rate-limiters utilize atomic operations.

  • Rate Limiting
    Uses token bucket algorithm to limit burst and sustained traffic per source IP, protecting the system against high-frequency floods (SYN, DNS, ICMP, or generic packet floods).

  • Blacklist-based filtering

  • Geo-blocking (ASN-based)
    Efficiently blocks traffic from specific countries using ASN metadata from IPLocate.io:

    • Lightweight alternative to heavy GeoIP databases
    • Dynamic configuration via API/Swagger
  • TLS SNI & JA3 filtering
    Extracts and inspects TLS ClientHello data directly from TCP payload before handshake completion:

    Enables real-time blocking of malicious TLS clients such as malware beacons, scanners, or C2 frameworks.

  • HTTP API for runtime configuration
    Built-in API server allows dynamically adding or removing IP or Country entries in global white/black lists.
    Auth via BasicAuth using MEDS_USERNAME / MEDS_PASSWORD.

  • Prometheus metrics export
    Exposes metrics for observability:

    • Total packets processed
    • Dropped packets (with reasons)
    • Accepted packets (with reasons)
    • Internal errors (with types)

    Metrics are available at /metrics via the built-in API server, compatible with Prometheus scrape targets.


📊 Example Metrics (Prometheus)

# HELP meds_core_packets_accepted_total Total number of accepted packets
# TYPE meds_core_packets_accepted_total counter
meds_core_packets_accepted_total{filter="empty",reason="default"} 12021
meds_core_packets_accepted_total{filter="empty",reason="trusted packet"} 420
meds_core_packets_accepted_total{filter="ip",reason="WhiteList"} 139

# HELP meds_core_packets_dropped_total Total number of dropped packets
# TYPE meds_core_packets_dropped_total counter
meds_core_packets_dropped_total{filter="asn",reason="Spamhaus"} 263
meds_core_packets_dropped_total{filter="domain",reason="StevenBlack"} 3
meds_core_packets_dropped_total{filter="geo",reason="IPLocate"} 43
meds_core_packets_dropped_total{filter="ip",reason="FireHOL"} 1443

# HELP meds_core_packets_processed_total Total number of processed packets
# TYPE meds_core_packets_processed_total counter
meds_core_packets_processed_total 14332

📜 License

Meds is released under the MIT License.
See LICENSE for details.


🤝 Contributing

Pull requests and feature suggestions are welcome!
If you find a bug, please open an issue or submit a fix.


Made with ❤️ in Go