diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..c7c55bd --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,25 @@ +# Contributing to Glutton + +Thanks for considering a contribution. Glutton is a security tool, so small source-verified changes are easier to review than broad rewrites. + +See [Getting started](docs/setup.md) for the toolchain, Spicy/HILTI, and Glutton build steps. + +## Guidelines + +- **Pick an issue** from the [tracker](https://github.com/mushorg/glutton/issues). Useful labels: `good first issue`, `help wanted`, `protocol`, `enhancement`. Reproduce older issues against `main` before starting. For protocol work, read [Extension system](docs/extension-system.md), [Adding a protocol](docs/protocols/adding-a-protocol.md), and [Spicy cheatsheet](docs/protocols/spicy-cheatsheet.md) first to gauge effort. +- **Comment before you start** so a maintainer can confirm scope or redirect. +- **Keep PRs small and source-verified.** Split large work into a thin first slice. +- **Add tests** beside the package you change. +- **Update docs in the same PR** when behavior changes: + - Build/CI/Docker or Go version → [Getting started](docs/setup.md) + - Config defaults or rules behavior → [Configuration](docs/configuration.md) + - Handler registration or protocol behavior → [Architecture](docs/architecture.md), [Extension system](docs/extension-system.md), [FAQ](docs/faq.md) + - Producer event fields → [Logging and producers](docs/logging.md) + - Spicy parser coverage → [Spicy cheatsheet](docs/protocols/spicy-cheatsheet.md) + +## Code style and PRs + +- **Format** Mirror the structure of existing handlers in `protocols/tcp/` and `protocols/udp/`. +- **Respect the boundary:** parsing belongs in `.spicy` files, protocol logic in Go. Never commit generated parser artifacts — they're git-ignored. +- **Test before pushing:** run `go test ./protocols/... ./rules/...` while iterating, and the full `CC=clang CXX=clang++ go test ./...` (Spicy must be installed) before opening a PR. If you changed any `.spicy` file, run `make spicy` first so tests pick up the regenerated parser. +- **Write a focused PR:** describe what changed, how you tested it, and which docs moved with it. Keep unrelated cleanup in its own PR. \ No newline at end of file diff --git a/README.md b/README.md index f757787..30d586a 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,133 @@ # Glutton -![Tests](https://github.com/mushorg/glutton/actions/workflows/workflow.yml/badge.svg) -[![GoDoc](https://godoc.org/github.com/mushorg/glutton?status.svg)](https://godoc.org/github.com/mushorg/glutton) -Glutton is a protocol-agnostic, low-interaction honeypot that intercepts network traffic and logs interactions to help analyze malicious activities. It's built using Golang and leverages iptables and TPROXY to redirect all traffic to specific protocol handlers. +[![Tests](https://github.com/mushorg/glutton/actions/workflows/workflow.yml/badge.svg)](https://github.com/mushorg/glutton/actions/workflows/workflow.yml) +[![Go Reference](https://pkg.go.dev/badge/github.com/mushorg/glutton.svg)](https://pkg.go.dev/github.com/mushorg/glutton) +[![Go Version](https://img.shields.io/github/go-mod/go-version/mushorg/glutton)](go.mod) +[![License](https://img.shields.io/github/license/mushorg/glutton)](LICENSE) +[![Discord](https://img.shields.io/badge/discord-Honeynet-5865F2?logo=discord&logoColor=white)](https://discord.gg/xzESEhgPtk) + +> A highly sensitive, protocol-agnostic, low-interaction TCP/UDP honeypot in Go. + +Modern attackers increasingly rely on stealthy techniques like low-volume scans, partial protocol handshakes, and subtle behavioral anomalies to evade detection by conventional honeypots. These systems often fail to capture such activities due to rigid protocol emulation, incomplete logging, or reliance on predefined attack signatures. + +Glutton is built to bridge this gap with its catch-all TCP/UDP approach. It captures traffic across all TCP and UDP ports and protocols without requiring a specific protocol implementation for each service. Its dynamic rule engine then either redirects traffic to a protocol-specific handler, forwards it to an upstream target through the built-in TCP proxy, or captures it generically so the payload is preserved even when the protocol is unknown. Together, this gives security teams visibility into reconnaissance activities that might otherwise go undetected. + +Glutton's core is designed for: + +- **Protocol-agnosticism:** Instead of fully emulating each protocol, Glutton uses configurable rules and generic handlers to process any TCP/UDP-based interaction on all ports. +- **Detailed logging:** Glutton records all connections, including metadata and payloads, to preserve even partial interactions for further analysis. +- **Extensibility:** Its flexible mapping of protocol handlers and configurable rules allows it to quickly adapt to support new protocols without the need for extensive architectural changes. + +Beyond Go handlers, Glutton also includes an emerging Spicy parser path. Spicy is the parser-definition language from the Zeek project; it lets contributors describe byte-level protocol grammars in a small DSL instead of writing the parser in Go. Currently Glutton uses Spicy for HTTP parsing and TCP-payload protocol detection only. + +Out of the box, Glutton ships handlers that capture exploit probes targeting Citrix ADC (CVE-2019-19781), VMware vCenter (`hyper/send`), and Ethereum JSON-RPC wallets, alongside protocol-interaction handlers for SMTP, RDP, SMB, and many more, plus generic TCP/UDP fallbacks and TCP proxy forwarding for everything else. See [What Glutton captures](#what-glutton-captures) below for the full list. + +## Quick start + +Glutton requires Linux, root privileges for iptables, and a build toolchain compatible with the [CI workflow](.github/workflows/workflow.yml) — currently Go 1.23+, Spicy 1.13.1, clang 17, libpcap, iptables, and zlib1g. + +```bash +git clone https://github.com/mushorg/glutton.git +cd glutton + +# Install Spicy/HILTI under /opt/spicy (see docs/setup.md), then: +export PATH=/opt/spicy/bin:$PATH +make spicy +make build + +sudo bin/server -i eth0 -c config/ -l /var/log/glutton.log +``` + +> **SSH safety:** Glutton's iptables rule excludes one TCP port from TPROXY redirection so your SSH session survives. Both `ports.ssh` (`config/config.yaml`) and the CLI flag `-s/--ssh` (`app/server.go`) default to `2222`. If your sshd listens on a different port (the typical `22`, for example), set `ports.ssh` in your config or pass `-s ` explicitly to the port your sshd actually listens on before exposing the sensor, or you will lock yourself out. + +Edit `config/config.yaml` before deployment. Set `addresses` to your host's public IPs and review `ports.`*, `producers.`*, `capture_traffic.enabled`, `dial_timeout`, and the rules in `config/rules.yaml`. Full reference in [docs/configuration.md](docs/configuration.md). + +For full build, install, and runtime details — including Spicy setup, privileges, and operational hazards — see [docs/setup.md](docs/setup.md). + +## Docker + +The repository ships a `Dockerfile`. For real traffic capture the container needs the host network namespace and `NET_ADMIN`, since TPROXY operates on a real interface: + +```bash +docker build -t glutton . +docker run --rm --network host --cap-add=NET_ADMIN -it glutton +``` + +This requires the host kernel to support iptables `mangle` and the `xt_TPROXY` module. Without `--network host` the container will install rules inside the container network namespace and never see external traffic. + +For full Docker, privileges, and host-placement guidance, see [docs/setup.md](docs/setup.md). + +## What Glutton captures + + +| Name | What it captures | +| --------------------------- | ---------------------------------------- | +| Citrix ADC (CVE-2019-19781) | `GET /vpn/*` RCE probes | +| VMware "hyper/send" | `* hyper/send` request-body exploit | +| Ethereum JSON-RPC | `POST` body containing `eth_blockNumber` | +| Wallet probes | URIs containing `wallet` | +| SMTP | mail submission probes | +| RDP | Remote Desktop handshake | +| SMB | Windows file-sharing probes | +| FTP | file transfer commands | +| SIP | VoIP signaling traffic | +| RFB/VNC | remote framebuffer auth | +| Telnet | interactive login attempts | +| MQTT | IoT pub/sub messages | +| iSCSI | block-storage target probes | +| BitTorrent | peer handshake traffic | +| Memcache | key-value cache commands | +| Jabber/XMPP | instant messaging stream | +| ADB | Android Debug Bridge probes | +| MongoDB | wire protocol queries | +| Hadoop YARN | `POST */cluster/apps/new-application` | +| Docker Engine API | `GET /v1.16/version` | +| HTTP | generic web requests | +| generic TCP | unrecognized TCP payloads | +| generic UDP | unrecognized UDP payloads | + + +Example producer event shape: + +```json +{ + "timestamp": "2026-05-15T12:00:00Z", + "transport": "tcp", + "srcHost": "203.0.113.10", + "srcPort": "54321", + "dstPort": 80, + "sensorID": "00000000-0000-0000-0000-000000000000", + "rule": "Rule: tcp", + "handler": "http", + "payload": "R0VUIC8gSFRUUC8xLjENCg0K", + "scanner": "", + "decoded": { "protocol": "http", "fields": {} } +} +``` + +## Where it fits + +Glutton is a breadth-oriented sensor: it trades the deep per-protocol emulation of specialized honeypots for coverage across the TCP/UDP port space. It is not a SIEM, not a high-interaction honeynet, and not a Cowrie replacement for SSH-only deployments. Compared to tools such as Cowrie (SSH/Telnet, high-interaction shell), Dionaea (malware capture), and T-Pot (bundled distribution), Glutton's distinctive surface is broad protocol coverage in one Go binary, a dynamic rule engine, `proxy_tcp` forwarding, and a parser-extension path that can grow with new protocols. ## Documentation -For more details, please read the [documentation](https://go-glutton.readthedocs.io/en/latest/), which provides the following sections: -* [Introduction](https://go-glutton.readthedocs.io/en/latest/) -* [Setup](https://go-glutton.readthedocs.io/en/latest/setup/) -* [Configuration](https://go-glutton.readthedocs.io/en/latest/configuration/) -* [Extension](https://go-glutton.readthedocs.io/en/latest/extension/) -* [FAQs](https://go-glutton.readthedocs.io/en/latest/faq/) \ No newline at end of file +- [Getting started](docs/setup.md) +- [Configuration](docs/configuration.md) +- [Architecture](docs/architecture.md) +- [Logging and producers](docs/logging.md) +- [Extension system](docs/extension-system.md) · [Adding a protocol](docs/protocols/adding-a-protocol.md) · [Spicy cheatsheet](docs/protocols/spicy-cheatsheet.md) +- [FAQ](docs/faq.md) + +## Community and contributing + +Glutton was built by [Lukas Rist](https://github.com/glaslos), [Muhammad Bilal Arif](https://github.com/furusiyya), and [the community](https://github.com/mushorg/glutton/graphs/contributors?all=1). + +For contributing see: + +- Contributor guide: [CONTRIBUTING.md](CONTRIBUTING.md) +- Issues and PRs: [github.com/mushorg/glutton](https://github.com/mushorg/glutton) +- Chat: [Honeynet Project Discord](https://discord.gg/xzESEhgPtk) + +## License + +Glutton is released under the [MIT License](LICENSE). \ No newline at end of file diff --git a/docs/architecture.md b/docs/architecture.md new file mode 100644 index 0000000..e63448c --- /dev/null +++ b/docs/architecture.md @@ -0,0 +1,76 @@ +# Architecture + +Glutton is built around four moving parts: transparent redirection, rule-based dispatch, protocol handlers, and optional producer output. It does not bind every public service port directly — it installs iptables TPROXY rules that redirect matching TCP and UDP traffic to local listener ports, then reconstructs enough metadata to pick a handler. + +```mermaid +flowchart TD + Net[Incoming TCP/UDP traffic] --> IPT[iptables mangle PREROUTING TPROXY] + IPT --> Listen[127.0.0.1 TCP/UDP listeners] + Listen --> Rules[Rule matching] + Rules --> Meta[connection.Metadata] + Meta --> Dispatch[Protocol handler registry] + Dispatch --> GoHandler[Go protocol handler] + Dispatch --> Proxy[proxy_tcp forwarder] + Dispatch --> Spicy[Optional Spicy detection/parsing] + Spicy --> GoHandler + Proxy --> Upstream[Upstream TCP service] + GoHandler --> ProcessLog[slog JSON process logs] + Proxy --> ProcessLog + GoHandler --> Producer[Optional HTTP / hpfeeds producer events] + Proxy --> Producer +``` + +## Components + +| Component | Source | Role | +| --- | --- | --- | +| CLI + runtime | `app/server.go`, `glutton.go` | Flags, init, listeners, rule load, dispatch, signal handling. | +| Listener | `server.go` | Local TCP/UDP TPROXY listeners on `127.0.0.1`. | +| iptables integration | `iptables.go` | Append/remove mangle PREROUTING TPROXY rules. | +| Rules engine | `rules/rules.go` | Compiles BPF expressions, returns the first matching rule. | +| Handler registry | `protocols/protocols.go` | Maps rule targets (`smtp`, `http`, `proxy_tcp`, `tcp`, …) to handler funcs. | +| TCP/UDP handlers | `protocols/tcp/`, `protocols/udp/` | Protocol interaction, logging, producer calls, fake responses. | +| Spicy bridge | `protocols/spicy/` | Initializes Spicy/HILTI runtime; parses selected payloads. | +| Logging | `producer/logger.go` | JSON `slog` to stdout + rotating file. | +| Producers | `producer/producer.go` | Optional structured events to HTTP / hpfeeds. | + +## Startup + +1. `app/server.go` parses flags and binds them into Viper. +2. `glutton.New(...)` builds the connection table, reads or writes the sensor ID under `--var-dir`, creates the logger, loads config and rules. +3. `glutton.Init()` resolves public addresses for `interface`, starts the local TCP/UDP listeners, initializes optional producers, builds the handler maps, and initializes Spicy if `spicy.enabled` is true. +4. `glutton.Start()` installs the iptables TPROXY rules and starts the listener loops. + +The sensor ID is stored as binary UUID data in `/glutton.id`. Default `--var-dir` is `/var/lib/glutton`. + +## TCP dispatch + +1. Connection is redirected to the local TCP listener; Glutton accepts it. +2. `applyRulesOnConn(...)` runs the rule set against the connection's remote and local addresses. +3. If no rule matches, a fallback rule with target `default` is synthesized. +4. The connection is registered in the table and the connection timeout is applied. +5. If the rule type is `proxy_tcp`, the proxy handler runs. Otherwise the handler for the matched target runs in a goroutine. + +## UDP dispatch + +1. A UDP packet is read from the local UDP listener with original source/destination addresses preserved. +2. The rules engine runs with network type `udp`. +3. If no rule matches, target `udp` is used. +4. The packet is registered and the handler runs in a goroutine. + +Today the UDP handler map only contains the generic `udp` handler. + +## Spicy boundary + +Spicy is optional, gated by `spicy.enabled`. When on, the Spicy/HILTI runtime is initialized and compiled parser modules are registered. Current usage: + +- `TCP::Protocol` inspects raw TCP payload bytes in the generic `tcp` handler path; detected HTTP, RDP, or MongoDB payloads route to more specific handling. +- `HTTP::Request` parses HTTP request bytes for the Spicy HTTP handler path. + +Spicy does not replace Go protocol handlers. The parser extracts fields from bytes; Go still owns reads, writes, fake responses, logging, producer calls, timeouts, and fallback behavior. + +One routing wrinkle: a rule with target `http` calls the Go HTTP handler directly. The Spicy HTTP handler is reached *only* from the generic `tcp` catch-all path when Spicy detection classifies the payload as HTTP. + +## Output + +Process logs always go through `slog` JSON to stdout and the configured `--logpath` file (rotated via lumberjack). Producer events are separate and only emitted when `producers.enabled` and a sink (`producers.http.enabled` or `producers.hpfeeds.enabled`) are on. See [Logging and producers](logging.md). diff --git a/docs/configuration.md b/docs/configuration.md index 7d036a1..d369e25 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -1,96 +1,83 @@ # Configuration -Glutton’s behavior is controlled by several configuration files written in YAML (and JSON for schema validation). This page details the available configuration options, how they’re loaded, and best practices for customizing your setup. +Glutton uses Viper. It reads two files from `--confpath`: `config/config.yaml` (main settings) and `config/rules.yaml` (TCP/UDP traffic rounting rules). If either is missing, Glutton falls back to embedded defaults. -## Configuration Files +For the exact defaults shipped with the binary, see `[config/config.yaml](../config/config.yaml)` and `[config/rules.yaml](../config/rules.yaml)`. -### config/config.yaml +## CLI flags -This file holds the core settings for Glutton. Key configuration options include: +CLI flags override the matching keys in `config.yaml`. -- **ports:** Defines the network ports used for traffic interception. - - **tcp:** The TCP port for intercepted connections (default: `5000`). - - **udp:** The UDP port for intercepted packets (default: `5001`). - - **ssh:** Typically excluded from redirection to avoid interfering with SSH (default: `22`). -- **interface:** The network interface Glutton listens on (default: `eth0`). -- **max_tcp_payload:** Maximum TCP payload size in bytes (default: `4096`). -- **conn_timeout:** The connection timeout duration in seconds (default: `45`). -- **confpath:** The directory path where the configuration file resides. -- **producers:** - - **enabled**: Boolean flag to enable or disable logging/producer functionality. - - **http:** HTTP producer for sending logs to a remote endpoint, like [Ochi](https://github.com/honeynet/ochi). - - **hpfeeds:** [HPFeeds](https://github.com/hpfeeds/hpfeeds) producer for sharing data with other security tools. -- **addresses:** A list of additional public IP addresses for traffic handling. -Example configuration: +| Flag | Short | Default | Notes | +| ------------- | ----- | ------------------ | ---------------------------------------------------------------------------- | +| `--interface` | `-i` | `eth0` | Bound as `interface`. | +| `--ssh` | `-s` | `2222` | Overrides `ports.ssh`. Match this to the port your sshd actually listens on. | +| `--logpath` | `-l` | `/dev/null` | Rotating JSON log file path. Logs also go to stdout. | +| `--confpath` | `-c` | `config/` | Directory holding `config.yaml` and `rules.yaml`. | +| `--debug` | `-d` | `false` | Parsed and bound, but not yet wired into `slog.HandlerOptions`. | +| `--version` | — | `false` | Prints version and exits before runtime init. | +| `--var-dir` | — | `/var/lib/glutton` | Directory for `glutton.id`. | -```yaml -# config/config.yaml - -ports: - tcp: 5000 - udp: 5001 - ssh: 22 - -rules_path: config/rules.yaml - -addresses: ["1.2.3.4"] - -interface: eth0 - -producers: - enabled: true # enables producers - http: - enabled: true # enables http producer - # Connect with Ochi here or other remote log aggregation servers - remote: http://localhost:3000/publish?token=token - hpfeeds: - enabled: false # disables HPFeeds - host: 172.26.0.2 - port: 20000 - # HPFeeds specific details go here - ident: ident - auth: auth - channel: test - -conn_timeout: 45 -max_tcp_payload: 4096 -``` -### config/rules.yaml +## Main config -This file defines the rules that Glutton uses to determine which protocol handler should process incoming traffic. +Source: `config/config.yaml`. Keys you'll most often touch: -Key elements include: -- **type**: `conn_handler` to pass off to the appropriate protocol handler or `drop` to ignore packets. -- **target**: Indicates the protocol handler (e.g., "http", "ftp") to be used. -- **match**: Define criteria such as source IP ranges or destination ports to match incoming traffic, according to [BPF syntax](https://biot.com/capstats/bpf.html). +| Key | Default | Description | +| -------------------------------------------------------------------- | ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `ports.tcp` | `5000` | Local TCP TPROXY listener port. | +| `ports.udp` | `5001` | Local UDP TPROXY listener port. | +| `ports.ssh` | `2222` | Destination port excluded from TPROXY redirection (see [SSH exclusion](#ssh-exclusion)). | +| `rules_path` | `config/rules.yaml` | Path to the rules file. | +| `addresses` | `["1.2.3.4", "5.4.3.2"]` | Public addresses used for payload sanitization. | +| `interface` | `eth0` | Interface used for public IP discovery and TPROXY rule installation. | +| `producers.enabled` | `false` | Creates the producer object. | +| `producers.http.enabled` | `false` | Enables HTTP producer POSTs. | +| `producers.http.remote` | `https://localhost:9000` | HTTP endpoint. Userinfo in the URL supplies basic auth. | +| `producers.hpfeeds.enabled` | `false` | Enables hpfeeds output. | +| `producers.hpfeeds.host` / `.port` / `.ident` / `.auth` / `.channel` | — | hpfeeds broker connection. | +| `conn_timeout` | `45` | Connection deadline in seconds (also the `proxy_tcp` idle I/O timeout). | +| `max_tcp_payload` | `4096` | Generic TCP handler threshold and `proxy_tcp` per-direction capture cap. | +| `dial_timeout` | `5` | Outbound `proxy_tcp` dial timeout in seconds. | +| `capture_traffic.enabled` | `false` | Enables raw payload capture in `proxy_tcp` logs and produced events. Proxying still forwards traffic when disabled. | +| `spicy.enabled` | `true` | Initializes Spicy/HILTI and enables Spicy-backed paths (HTTP parsing, TCP-payload protocol detection). Set `false` if you build without Spicy or want the Spicy-free dispatch path. | -Example rule: -```yaml -# config/rules.yaml +### SSH exclusion + +`ports.ssh` is the destination port iptables skips when redirecting traffic into the honeypot, so your management SSH session survives. Both `ports.ssh` (default `2222`) and the CLI flag `--ssh` (default `2222`) need to match the port your sshd actually listens on. If your sshd is on `22`, pass `--ssh 22` or set `ports.ssh: 22` before exposing the sensor — otherwise the management port will be redirected into the honeypot and you'll lock yourself out. + +## Rules + +Rules decide which handler receives a redirected TCP connection or UDP packet. They're parsed by `rules/rules.go` and evaluated in order, **first match wins**, so put specific rules before broad catch-alls. +### Rule shape + +```yaml rules: - name: Telnet filter match: tcp dst port 23 or port 2323 or port 23231 - type: conn_handler # will find the appropriate target protocol handler + type: conn_handler target: telnet - - match: tcp dst port 6969 - type: drop # drops any matching packets - target: bittorrent ``` -## Configuration Loading Process -Glutton uses the [Viper](https://github.com/spf13/viper) library to load configuration settings. The process works as follows: -- **Default Settings**: Glutton initializes with default values for critical parameters. -- **File-based Overrides**: Viper looks for `config.yaml` in the directory specified by confpath. If found, the settings from the file override the defaults. -- **Additional Sources**: Environment variables or command-line flags can further override file-based configurations, allowing for flexible deployments. +| Field | Required | Description | +| -------- | -------- | ------------------------------------------------------------------------------------ | +| `name` | no | Human-readable label. `Rule.String()` returns the `match` expression, not this name. | +| `match` | yes | BPF expression compiled with `pcap.NewBPF(...)`. | +| `type` | yes | `conn_handler` or `proxy_tcp`. | +| `target` | yes | Handler key for `conn_handler`; `host:port` upstream for `proxy_tcp`. | + + +### Rule types + +`**conn_handler**` — `target` is a handler key. Current TCP keys: `smtp`, `rdp`, `smb`, `ftp`, `sip`, `rfb`, `telnet`, `mqtt`, `iscsi`, `bittorrent`, `memcache`, `jabber`, `adb`, `mongodb`, `http`, `proxy_tcp`, `tcp`. UDP keys: `udp`. If the target isn't registered, the listener accepts the connection but no handler runs. + +`**proxy_tcp**` — forwards a matched TCP connection to an upstream `host:port`. The address is parsed at rule-load time and stored in rule metadata; at dispatch the proxy handler dials it and pipes bytes both directions. Tunable via `dial_timeout`, `conn_timeout`, `max_tcp_payload`, and `capture_traffic.enabled` in the main config. -## Best Practices +### Catch-all interaction with Spicy -- **Backup Your Files**: Always save a backup of your configuration files before making changes. -- **Validate Configurations**: Use YAML validators and the provided JSON schema to ensure your configuration is error-free. -- **Test Changes**: After modifying your configuration, restart Glutton and review the logs to confirm that your changes have been applied as expected. +The default rules end with `match: tcp` → `target: tcp`, the generic TCP handler peeks at the initial bytes and uses the spicy parser to detect HTTP, RDP, or MongoDB payloads, if detected traffic is routed to a specific handler otherwise it fallback to generic TCP handler. \ No newline at end of file diff --git a/docs/extension-system.md b/docs/extension-system.md new file mode 100644 index 0000000..46e695d --- /dev/null +++ b/docs/extension-system.md @@ -0,0 +1,81 @@ +# Extension system + +Glutton's extension model has three layers, kept deliberately separate: + +```text +rules decide which named target should handle traffic +Go handlers own connection lifecycle, logging, producers, and fake responses +Spicy parsers extract structured fields from selected byte streams +``` + +Most extensions are a Go handler plus a rule. A Spicy parser is optional and only worthwhile when byte-level field extraction will be reused downstream. See [Adding a protocol](protocols/adding-a-protocol.md) for the end-to-end walkthrough. + +## Handler responsibilities + +A Go protocol handler owns runtime behavior: + +- read from the connection or packet +- update timeouts when appropriate +- decide what response to write +- log process-level details +- call `ProduceTCP(...)` or `ProduceUDP(...)` +- close the connection when done +- preserve fallback behavior for malformed or unknown input + +TCP handler shape: + +```go +func HandleExample(ctx context.Context, conn net.Conn, md connection.Metadata, logger interfaces.Logger, h interfaces.Honeypot) error +``` + +UDP handler shape: + +```go +func HandleExample(ctx context.Context, srcAddr, dstAddr *net.UDPAddr, data []byte, md connection.Metadata) error +``` + +Registration happens through `MapTCPProtocolHandlers(...)` or `MapUDPProtocolHandlers(...)` in `protocols/protocols.go`. + +## Rule responsibilities + +Rules route traffic before a handler runs. A `conn_handler` rule sends traffic to a registered handler key; a `proxy_tcp` rule sends it to an upstream `host:port`: + +```yaml +rules: + - match: tcp dst port 11211 + type: conn_handler + target: memcache + - match: tcp dst port 9889 + type: proxy_tcp + target: 127.0.0.1:9889 +``` + +If the `conn_handler` target isn't registered in the handler map, the listener doesn't run a handler. See [Configuration → Rules](configuration.md#rules) for matching details. + +## Spicy responsibilities + +Spicy parsers own byte-level structure, not honeypot behavior. A parser turns raw payload bytes into named fields like `method`, `uri.path`, `headers[0].name`. The Go side still decides how many bytes to read, which parser to call, what to log, which producer event to emit, and what response to write. + +Current Spicy-backed paths: + +- `HTTP::Request` is registered as parser key `http`. +- `TCP::Protocol` is registered as parser key `tcp`. +- The generic TCP handler path can use `TCP::Protocol` to detect HTTP, RDP, or MongoDB. +- HTTP payloads detected through the generic TCP path can be handled by `protocols/spicy/handlers/http.go`. + +A rule target of `http` calls the Go HTTP handler in `protocols/tcp/http.go`; it does not auto-select the Spicy HTTP handler. + +## Producer responsibilities + +Handlers choose what to pass to producers. The envelope is fixed (`producer.Event`); the `decoded` payload is handler-specific. When adding a handler, decide what raw payload to include, what decoded structure is stable enough for downstream consumers, whether public addresses need sanitization, and what protocol name to pass to `ProduceTCP(...)` / `ProduceUDP(...)`. + +## Tests + +For a new handler or parser: + +- handler registration test in `protocols/protocols_test.go` when adding map keys +- handler behavior tests beside the handler package +- parser tests under `protocols/spicy/` for Spicy field contracts +- rules tests under `rules/` when rule behavior changes + +Cover both successful and malformed input. diff --git a/docs/extension.md b/docs/extension.md deleted file mode 100644 index f1963d9..0000000 --- a/docs/extension.md +++ /dev/null @@ -1,65 +0,0 @@ -# Extension - -Glutton is built to be easily extensible. Developers can add new protocol handlers or modify existing behavior to suit custom requirements. - -## Adding a New Protocol Handler - -### Create a New Module - - - Add your new protocol handler in the appropriate subdirectory under `protocols/` (e.g., `protocols/tcp` or `protocols/udp`). - - Implement the handler function conforming to the expected signature: - - For TCP: `func(context.Context, net.Conn, connection.Metadata, logger interfaces.Logger, h interfaces.Honeypot) error` - - For UDP: `func(context.Context, *net.UDPAddr, *net.UDPAddr, []byte, connection.Metadata) error` - - For example: - - - // protocols/tcp/new_protocol.go - - package tcp - - import ( - "context" - "net" - - "github.com/mushorg/glutton/connection" - "github.com/mushorg/glutton/protocols/interfaces" - ) - - // HandleNewProtocol handles incoming connections. - func HandleNewProtocol(ctx context.Context, conn net.Conn, md connection.Metadata, logger interfaces.Logger, h interfaces.Honeypot) error { - // Log the connection for demonstration purposes. - logger.Info("Received NewProtocol connection from %s", conn.RemoteAddr().String()) - // Here you could add protocol-specific handling logic. - // For now, simply close the connection. - return conn.Close() - } - - -### Register the Handler - - Modify the mapping function (e.g., `protocols.MapTCPProtocolHandlers` or `protocols.MapUDPProtocolHandlers` in `protocols/protocols.go`) to include your new handler. - - Update configuration or rules (in `config/rules.yaml` or `rules/rules.yaml`) if needed to route specific traffic to your handler. - -For example: - - func MapTCPProtocolHandlers(log interfaces.Logger, h interfaces.Honeypot) map[string]TCPHandlerFunc { - protocolHandlers := map[string]TCPHandlerFunc{} - protocolHandlers["smtp"] = func(ctx context.Context, conn net.Conn, md connection.Metadata) error { - return tcp.HandleSMTP(ctx, conn, md, log, h) - } - ... - protocolHandlers["new"] = func(ctx context.Context, conn net.Conn, md connection.Metadata) error { - return tcp.HandleNewProtocol(ctx, conn, md, log, h) - } - ... - } - -3. **Test Your Extension:** - - Write tests similar to those in `protocols/protocols_test.go` to verify your new handler’s functionality. - - Use `go test` to ensure that your changes do not break existing functionality. - -## Customizing Logging and Rules - -- **Logging:** The logging mechanism is provided by the Producer (located in `producer/`). You can modify or extend it to suit your logging infrastructure. -- **Rules Engine:** The rules engine (found in `rules/`) can be extended to support additional matching criteria or custom rule types. - diff --git a/docs/faq.md b/docs/faq.md index 27f4c79..df3309e 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -1,21 +1,28 @@ -# Frequently Asked Questions +# FAQ -### Q: What is Glutton? -**A:** Glutton is a protocol-agnostic honeypot that intercepts network traffic, applies customizable rules, and logs interactions to help analyze malicious activities. +## Is Glutton high-interaction? -### Q: Which protocols does Glutton support? -**A:** Out of the box, Glutton supports multiple protocols via its TCP and UDP handlers. The repository includes handlers for protocols such as HTTP, FTP, SMTP, Telnet, MQTT, and more. You can extend support to additional protocols as needed. +No. Glutton sits in the low-interaction range: handlers emulate enough protocol behavior to capture useful probes and payloads, but they're controlled Go implementations, not real services or shells. -### Q: How do I add a new protocol or extend existing functionality? -**A:** You can add a new protocol handler by implementing the appropriate interface in the `protocols/` directory and registering your handler in the corresponding mapping function. See the [Extension](extension.md) section for detailed instructions. +## Which protocols are registered? -### Q: How do I configure Glutton? -**A:** Configuration is managed through YAML files: +TCP: SMTP, RDP, SMB, FTP, SIP, RFB/VNC, Telnet, MQTT, iSCSI, BitTorrent, Memcache, Jabber, ADB, MongoDB, HTTP, generic TCP, plus `proxy_tcp` forwarding. UDP: a generic UDP handler. -- **config/config.yaml:** General settings such as port numbers and interface names. -- **config/rules.yaml:** Defines rules for matching and processing network traffic. +The HTTP handler also dispatches a handful of nested, payload-driven mini-handlers once a request is parsed: -See the [Configuration](configuration.md) section for detailed instructions. +- Ethereum JSON-RPC +- Hadoop YARN exploit +- Docker Engine API +- Citrix ADC / NetScaler (CVE-2019-19781) +- VMware "hyper/send" attack +- Wallet probes -### Q: What are the system prerequisites? -**A:** Glutton requires a Linux system, so if you're using a different OS, you'll have to use Docker to set it up. Specific installation commands are provided in the [Setup](setup.md) section. +These nested branches live inside the HTTP handler rather than being registered as separate handler keys, so they're not selectable via a rule `target`. + +## Does Spicy parse every protocol? + +No. Current grammar files are `http.spicy` and `tcp.spicy`. Spicy is used for selected HTTP parsing and TCP-payload protocol detection only. + +## Why does Glutton require Linux? + +Glutton is built on Linux-only kernel facilities and tooling like TPROXY, iptables and libpcap. On macOS or Windows you can edit the Go code, but the binary will not redirect traffic, manage iptables, or load the Spicy runtime. Use a Linux VM, container, or remote host for anything beyond static analysis. diff --git a/docs/index.md b/docs/index.md deleted file mode 100644 index 7821a45..0000000 --- a/docs/index.md +++ /dev/null @@ -1,13 +0,0 @@ -# Introduction - -Glutton is a protocol-agnostic honeypot designed to emulate various network services and protocols. It is built in Go and aims to capture and analyze malicious network activity by intercepting connections and logging detailed interaction data. Glutton is highly configurable, allowing users to define custom rules and extend its functionality by adding new protocol handlers. - -Key features include: - -- **Protocol Agnostic:** Supports TCP and UDP traffic across a variety of protocols. -- **Rule-Based Processing:** Uses configurable rules to determine how incoming connections are handled. -- **Extensibility:** Easily extend the tool by adding new protocol handlers. -- **Logging and Analysis:** Captures connection metadata and payloads for further analysis. - -This documentation will guide you through the installation, deployment, understanding its network interactions, extending its functionality, and addressing common questions. - diff --git a/docs/logging.md b/docs/logging.md new file mode 100644 index 0000000..6c0a086 --- /dev/null +++ b/docs/logging.md @@ -0,0 +1,80 @@ +# Logging and producers + +Glutton has two output paths: process logs through Go `slog`, and optional producer events sent to HTTP or hpfeeds sinks. Handlers can emit both, but they're configured separately. + +## Process logs + +`producer.NewLogger(...)` creates a JSON `slog` logger that writes every record to: + +- stdout +- the path configured by `--logpath` + +The file writer uses lumberjack rotation: 200 MB max size, 356 days max age, compression on. Every record carries the `sensorID` attribute (read from / written to `/glutton.id`). + +The `--debug` flag is parsed but not wired into `slog.HandlerOptions`, so it does not currently lower the log level. + +## Producer events + +Producer events follow the `producer.Event` schema: + +| JSON field | Meaning | +| --- | --- | +| `timestamp` | UTC event timestamp. | +| `transport` | `tcp` or `udp`. | +| `srcHost` | Source IP. | +| `srcPort` | Source port. | +| `dstPort` | Original destination port from metadata. | +| `sensorID` | Glutton sensor ID. | +| `rule` | Rule string when metadata includes a rule. | +| `handler` | Handler name supplied by the protocol handler. | +| `payload` | Base64-encoded payload bytes. | +| `scanner` | Scanner classification from `scanner.IsScanner(...)`. | +| `decoded` | Handler-specific decoded data. | + +Events are emitted only when (1) `producers.enabled` is true so a producer object exists, (2) a handler calls `ProduceTCP(...)` or `ProduceUDP(...)`, and (3) at least one sink is enabled. Before output, configured `addresses` values are scrubbed from the payload and replaced with `1.2.3.4`. + +Example shape: + +```json +{ + "timestamp": "2026-05-15T12:00:00Z", + "transport": "tcp", + "srcHost": "203.0.113.10", + "srcPort": "54321", + "dstPort": 80, + "sensorID": "00000000-0000-0000-0000-000000000000", + "rule": "Rule: tcp", + "handler": "http", + "payload": "R0VUIC8gSFRUUC8xLjENCg0K", + "scanner": "", + "decoded": { "protocol": "http", "fields": {} } +} +``` + +`decoded` is handler-specific. For `proxy_tcp`, it contains per-direction entries (`direction`, `payload`, `payload_hash`, `bytes`, `truncated`) when `capture_traffic.enabled` is true; samples are capped by `max_tcp_payload`, and `truncated` reflects whether more bytes were forwarded than captured. + +## HTTP producer + +When `producers.http.enabled` is true, Glutton marshals each event as JSON and POSTs it to `producers.http.remote` with `Content-Type: application/json`. From source: + +- HTTP client timeout: 10s; TLS handshake timeout: 5s. +- Events from private source IPs are skipped. +- Userinfo in the remote URL is used as HTTP Basic Auth. +- Query strings in the configured URL are preserved. + +## hpfeeds producer + +When `producers.hpfeeds.enabled` is true, Glutton connects to the broker at startup and publishes gob-encoded `producer.Event` values to `producers.hpfeeds.channel`. + +```yaml +producers: + hpfeeds: + enabled: false + host: 172.26.0.2 + port: 20000 + ident: ident + auth: auth + channel: test +``` + +Treat all logged payloads as attacker-controlled data in downstream pipelines. diff --git a/docs/protocols/adding-a-protocol.md b/docs/protocols/adding-a-protocol.md new file mode 100644 index 0000000..cf2364c --- /dev/null +++ b/docs/protocols/adding-a-protocol.md @@ -0,0 +1,136 @@ +# Adding a protocol + +End-to-end source changes to add a new protocol path. Start with a Go handler. Add a Spicy parser only when byte-level field extraction is useful and you're ready to wire that parser into live traffic. + +## 1. Pick the shape + +| Shape | Use when | +| --- | --- | +| Go handler only | Simple interaction, banner capture, response shaping, or payload logging. | +| Go handler + Spicy parser | You need structured parsing but Go still owns responses and producer events. | +| Spicy detection from generic TCP | You want catch-all TCP traffic classified before fallback handling. | + +A `.spicy` file alone does nothing — a compiled parser must be called from Go or routed through handler logic. + +## 2. Add a TCP handler + +Create `protocols/tcp/example.go`: + +```go +package tcp + +import ( + "context" + "fmt" + "net" + + "github.com/mushorg/glutton/connection" + "github.com/mushorg/glutton/protocols/interfaces" +) + +type decodedExample struct { + Greeting string `json:"greeting,omitempty"` +} + +func HandleExample(ctx context.Context, conn net.Conn, md connection.Metadata, logger interfaces.Logger, h interfaces.Honeypot) error { + defer conn.Close() + + if err := h.UpdateConnectionTimeout(ctx, conn); err != nil { + return err + } + + buf := make([]byte, 256) + n, err := conn.Read(buf) + if err != nil { + return fmt.Errorf("failed to read example payload: %w", err) + } + payload := buf[:n] + + logger.Info("example protocol request handled") + + if err := h.ProduceTCP("example", conn, md, payload, decodedExample{Greeting: string(payload)}); err != nil { + logger.Error("failed to produce example event", "error", err) + } + + _, err = conn.Write([]byte("OK\r\n")) + return err +} +``` + +Style references in-tree: `protocols/tcp/http.go`, `protocols/tcp/tcp.go`, `protocols/tcp/mongodb.go` cover different interaction depths and decoded shapes. + +## 3. Register the handler + +In `protocols/protocols.go`, add to `MapTCPProtocolHandlers(...)`: + +```go +protocolHandlers["example"] = func(ctx context.Context, conn net.Conn, md connection.Metadata) error { + return tcp.HandleExample(ctx, conn, md, log, h) +} +``` + +UDP handlers register through `MapUDPProtocolHandlers(...)` instead. + +## 4. Add a rule + +In `config/rules.yaml`: + +```yaml +rules: + - match: tcp dst port 9999 + type: conn_handler + target: example +``` + +Place specific rules before broad catch-alls like `match: tcp`. + +## 5. Add tests + +- registration assertion in `protocols/protocols_test.go` +- handler behavior tests beside the handler +- malformed input / short read coverage +- producer call coverage when the handler emits decoded data + +Use the mock honeypot in `protocols/mocks/` for producer assertions. + +## 6. Optional: add a Spicy parser + +Add a grammar under `protocols/spicy/parsers/`. Existing examples: `http.spicy`, `tcp.spicy`. + +```bash +export PATH=/opt/spicy/bin:$PATH +make spicy +``` + +The Spicy Makefile generates gitignored C++ and headers under `protocols/spicy/`. Parser registration happens at runtime in `spicy.Initialize(...)`: names like `HTTP::Request` are split on `::`, lowercased by module name, and registered as parser key `http`. + +Call from Go: + +```go +parsed, err := spicy.Parse("example", payload) +if err != nil { + return err +} +``` + +Consume `parsed.Fields` in the handler. Do not move connection lifecycle, logging, producer calls, or fake responses into Spicy. + +## 7. Optional: detect from the generic TCP path + +The generic `tcp` target peeks at initial bytes and, when Spicy is enabled, calls the `tcp` parser to classify HTTP, RDP, or MongoDB payloads. To add a detector: + +1. extend `protocols/spicy/parsers/tcp.spicy` +2. regenerate parser artifacts with `make spicy` +3. update the switch in `protocols/protocols.go` +4. add parser and routing tests + +Only do this for protocols that should be detected from catch-all TCP. If the protocol has a stable port, a dedicated rule is simpler. + +## 8. Verify + +```bash +export PATH=/opt/spicy/bin:$PATH +CC=clang CXX=clang++ go test ./... +``` + +For faster iteration during development, scope to the package: `go test ./protocols/...`. diff --git a/docs/protocols/spicy-cheatsheet.md b/docs/protocols/spicy-cheatsheet.md new file mode 100644 index 0000000..559ae7e --- /dev/null +++ b/docs/protocols/spicy-cheatsheet.md @@ -0,0 +1,134 @@ +# Spicy cheatsheet + +This page covers only the Spicy concepts needed to work in this repository. For the language reference, use the upstream Spicy documentation. + +## What Spicy Does Here + +Glutton embeds the Spicy/HILTI runtime through cgo. The current bridge: + +- initializes the runtime on a locked OS thread +- lists compiled parser modules +- registers parser keys from module names +- parses payload bytes through a generic entry point +- flattens returned HILTI values into `map[string]interface{}` + +The Go side calls: + +```go +parsed, err := spicy.Parse("http", payload) +``` + +The result has: + +```go +type ParsedData struct { + Protocol string `json:"protocol"` + Fields map[string]interface{} `json:"fields"` + Error error `json:"-"` +} +``` + +## Current Parsers + +Current grammar files: + +```text +protocols/spicy/parsers/http.spicy +protocols/spicy/parsers/tcp.spicy +``` + +Current registered parser modules: + +| Spicy module/type | Go parser key | Purpose | +| --- | --- | --- | +| `HTTP::Request` | `http` | Parse HTTP request fields. | +| `TCP::Protocol` | `tcp` | Detect selected application protocols from raw TCP payload bytes. | + +## Grammar Shape + +A Spicy file declares a module and one or more units: + +```spicy +module HTTP; + +type Version = unit { + : /HTTP\//; + number: /[0-9]+\.[0-9]*/; +}; + +public type Request = unit { + method: /[^ \t\r\n]+/; + : /[ \t]+/; + version: Version; +}; +``` + +The real HTTP grammar is richer than this example. Read `protocols/spicy/parsers/http.spicy` before changing HTTP parsing. + +## Flattened Fields + +The bridge flattens parser output into field names: + +```text +method +uri.raw +uri.path +uri.query +version.number +headers[0].name +headers[0].value +body.content +``` + +Rules of thumb: + +- nested unit fields become dotted names +- vectors become indexed names such as `headers[0].name` +- bytes may arrive in Go as strings or byte slices depending on bridge handling +- parser consumers should tolerate missing fields for malformed input + +## Build Step + +Run this after changing `.spicy` files: + +```bash +export PATH=/opt/spicy/bin:$PATH +make spicy +``` + +The Spicy Makefile generates: + +- `protocols/spicy/*.cc` +- `protocols/spicy/spicy_linker.cc` +- `protocols/spicy/parsers/*.h` + +Those files are ignored by Git. + +## Registration + +At startup, `spicy.Initialize(...)` lists compiled parsers. Parser names that contain `::` are registered by lowercasing the module name before the first `::`. + +Examples: + +```text +HTTP::Request -> http +TCP::Protocol -> tcp +``` + +This is why Go calls `spicy.Parse("http", payload)` rather than `spicy.Parse("HTTP::Request", payload)`. + +## No `.evt` Files Today + +Some Spicy and Zeek documentation describes `.evt` event-translation files. Glutton's current repository does not include `.evt` files. It compiles `.spicy` grammar files and consumes parser output through the generic Go bridge. + +## What Stays In Go + +Keep these responsibilities in Go handlers: + +- how much data to read +- connection deadlines +- handler routing +- process logs +- producer event shape +- fake service responses +- fallback behavior after parse failure diff --git a/docs/setup.md b/docs/setup.md index 879d67e..8cae8a5 100644 --- a/docs/setup.md +++ b/docs/setup.md @@ -1,106 +1,95 @@ -# Setup +# Getting started -Follow these steps to install Glutton on your system. +Glutton is a Go-based, multi-protocol honeypot. It uses Linux iptables and TPROXY to transparently redirect TCP and UDP traffic to local listeners, dispatches connections through a BPF-style rule engine, runs protocol-specific handlers (or forwards to an upstream via `proxy_tcp`, or falls back to generic capture), and writes structured JSON logs and optional producer events. -## Environment Requirements +## Spicy +Glutton also includes an emerging Spicy parser path. Spicy is the parser-definition language from the Zeek project; it lets contributors describe byte-level protocol grammars in a small DSL instead of writing the parser in Go. Currently Glutton uses Spicy for HTTP parsing and TCP-payload protocol detection only. -- **Linux Required:** Glutton must be built and run on a Linux system. -- **Non-Linux Users:** For Windows or macOS, use Docker or the VSCode Dev Container Extension. -- **WSL Users:** When using WOS, we recommend running glutton with the [xanmod-kernel-WSL2](https://github.com/Locietta/xanmod-kernel-WSL2) -- For setting up the development environment using VS Code Dev Containers, refer to: - - [Install Dev Container](https://code.visualstudio.com/docs/devcontainers/containers) - - [Learn More](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) +## Requirements -## Prerequisites +Glutton is a Linux-only Go binary that depends on iptables, libpcap, a C/C++ toolchain, and Spicy/HILTI. Treat it as hostile-facing infrastructure once it's running: it receives unsolicited traffic, records attacker-controlled payloads, and manages network redirection rules. -Ensure you have [Go](https://go.dev/dl/) installed (recommended version: **Go 1.21** or later). In addition, you will need system packages for building and running Glutton: +| Requirement | Source of truth | +| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | +| Go 1.23+ | `go.mod` declares `go 1.23.5`; CI uses `^1.23`. | +| libpcap | Required by `github.com/google/gopacket/pcap`. | +| iptables | TPROXY rule management. | +| zlib + build-essential | Spicy and cgo builds. | +| clang / clang++ | `Makefile` uses `CC=clang CXX=clang++`; CI installs clang 17. | +| Spicy 1.13.1 under `/opt/spicy` | The cgo flags in `protocols/spicy/parser.go` expect headers under `/opt/spicy/include` and libraries under `/opt/spicy/lib`. | -### Debian/Ubuntu +## Build -```bash -sudo apt-get update -sudo apt-get install gcc libpcap-dev iptables -``` +CI runs on Ubuntu. Other distros need equivalent packages. -### Arch Linux ```bash -sudo pacman -S gcc libpcap iptables -``` - -### Fedora -```bash -sudo dnf install gcc libpcap-devel iptables -``` - -## Building Glutton +sudo apt-get update +sudo apt-get install -y libpcap-dev iptables zlib1g-dev build-essential clang -Clone the repository and build the project: +wget https://github.com/zeek/spicy/releases/download/v1.13.1/spicy_linux_ubuntu24.deb +sudo dpkg --install spicy_linux_ubuntu24.deb +sudo apt-get install -f -y +rm spicy_linux_ubuntu24.deb -```bash git clone https://github.com/mushorg/glutton.git cd glutton +export PATH=/opt/spicy/bin:$PATH +make spicy make build ``` -This will compile the project and place the server binary in the `bin/` directory. +`make spicy` runs the Spicy Makefile under `protocols/spicy/` to generate parser C++ and headers (gitignored). `make build` compiles `app/server.go` into `bin/server` with embedded version metadata. -## Testing the Installation +## Run -```bash -bin/server --version -``` -You should see output similar to: +Glutton modifies iptables rules and needs root (or `CAP_NET_ADMIN`). ```bash - _____ _ _ _ - / ____| | | | | | -| | __| |_ _| |_| |_ ___ _ __ -| | |_ | | | | | __| __/ _ \| '_ \ -| |__| | | |_| | |_| || (_) | | | | - \_____|_|\__,_|\__|\__\___/|_| |_| - - -glutton version v1.0.1+d2503ba 2025-02-21T05:48:07+00:00 +sudo bin/server --interface eth0 --confpath config/ --logpath /var/log/glutton.log ``` -## Usage +For Docker, mount or build the config you intend to run, and use the host network namespace so TPROXY rules apply to a real interface: -Glutton can be configured using several command-line flags: +```bash +docker build -t glutton . +docker run --rm --network host --cap-add=NET_ADMIN -it glutton +``` -- **--interface, -i**: `string` - Specifies the network interface (default: `eth0`) -- **--ssh, -s**: `int` - If set, it overrides the default SSH port -- **--logpath, -l**: `string` - Sets the file path for logging (default: `/dev/null`) -- **--confpath, -c**: `string` - Defines the path to the configuration directory (default: `config/`) -- **--debug, -d**: `bool` - Enables debug mode (default: `false`) -- **--version**: `bool` - Prints the version and exits -- **--var-dir**: `string` - Sets the directory for variable data storage (default: `/var/lib/glutton`) +Without `--network host` the container installs TPROXY rules on the docker bridge and never sees external traffic. The host kernel must have iptables `mangle` and `xt_TPROXY` available. -For example, to run Glutton with a custom interface and enable debug mode, you might use the following command: +### Verify ```bash -bin/server --interface --debug +bin/server --version ``` -Replace `` (e.g., `eth0`) with the interface you want to monitor. The command starts the Glutton server, which sets up TCP/UDP listeners and applies iptables rules for transparent proxying. +Prints the banner and version string and exits without initializing the runtime. Useful for confirming a build picked up the expected `Makefile` version metadata. + +## Privileges + +Glutton needs permission to: -**Configuration:** Before deployment, ensure your configuration files, in the `config/` folder by default, are properly set up. For detailed instructions, refer to the [Configuration](configuration.md) page. +- read from TPROXY sockets +- add and remove iptables mangle PREROUTING rules +- bind local TCP and UDP listener ports +- write its sensor ID under `--var-dir` (default `/var/lib/glutton`) +- write the configured log file -## Docker +`sudo` on bare metal or `--cap-add=NET_ADMIN` in Docker satisfies all of these. -To deploy using Docker: +## Host placement -1. Build the Docker image: - - ``` - docker build -t glutton . - ``` +- Run on a dedicated host, VM, or isolated network segment. Not a workstation, not anything with internal access. +- Restrict outbound egress unless a handler or producer needs it. `proxy_tcp` rules open outbound connections to whatever upstream the rule targets — keep that surface explicit. +- Keep producer endpoints (HTTP collector, hpfeeds broker) off the exposed honeypot network. +- Rotate and ship logs before disk pressure becomes operational risk. -2. Run the Container: - - ``` - docker run --rm --cap-add=NET_ADMIN -it glutton - ``` +Glutton is a sensor, not a containment boundary. Use network isolation around it. -The Docker container is preconfigured with the necessary dependencies (iptables, libpcap, etc.) and copies the configuration and rules files into the container. +## Operational hazards +- iptables state can be left behind if the process is killed without a clean shutdown. +- Captured payloads are attacker-controlled. Handle them as untrusted in any downstream pipeline. +- Some handlers send fake service responses. Don't route real internal clients through the sensor. +- Legal and privacy obligations vary by jurisdiction. Get local review before collecting or sharing payloads. diff --git a/mkdocs.yml b/mkdocs.yml index ecb8baf..152b01d 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,11 +1,14 @@ site_name: Glutton Documentation version: 1.0 nav: - - Introduction: index.md - - Setup: setup.md + - Getting started: setup.md - Configuration: configuration.md - - Extension: extension.md - - FAQs: faq.md + - Architecture: architecture.md + - Logging and producers: logging.md + - Extending: + - Extension system: extension-system.md + - Adding a protocol: protocols/adding-a-protocol.md + - Spicy cheatsheet: protocols/spicy-cheatsheet.md + - FAQ: faq.md theme: name: readthedocs -