Skip to content
Merged
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,10 @@ poc/

# Dev
.vscode
openspec/
.cache
.codex
openspec/
docs/roadmap.md
docs/engineering-guidelines.md

8 changes: 6 additions & 2 deletions config/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,9 @@ producers:
auth: auth
channel: test

conn_timeout: 45
max_tcp_payload: 4096
conn_timeout: 45 # idle I/O timeout in seconds for established connections.
max_tcp_payload: 4096 # bytes
dial_timeout: 5 # timeout in seconds for proxy target connection.

capture_traffic:
enabled: false
6 changes: 6 additions & 0 deletions config/rules.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ rules:
- match: tcp dst port 27017
type: conn_handler
target: mongodb
- match: tcp dst port 9889
type: proxy_tcp
target: 127.0.0.1:9889
- match: tcp dst port 3306
type: proxy_tcp
target: 127.0.0.1:3306
- match: tcp
type: conn_handler
target: tcp
Expand Down
20 changes: 16 additions & 4 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ This file holds the core settings for Glutton. Key configuration options include
- **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`).
- **conn_timeout:** Idle I/O timeout, in seconds, for established connections (default: `45`).
- **max_tcp_payload:** Maximum TCP payload size in bytes (default: `4096`). Proxy TCP uses this as the per-direction captured payload cap.
- **dial_timeout:** Timeout, in seconds, for opening outbound proxy TCP target connections (default: `5`).
- **capture_traffic.enabled:** Enables raw payload capture in logs and produced decoded events. When disabled, proxy TCP still forwards traffic and logs metadata, but raw payload bytes are omitted from decoded events.
- **confpath:** The directory path where the configuration file resides.
- **producers:**
- **enabled**: Boolean flag to enable or disable logging/producer functionality.
Expand Down Expand Up @@ -55,6 +57,10 @@ producers:

conn_timeout: 45
max_tcp_payload: 4096
dial_timeout: 5

capture_traffic:
enabled: false
```

### config/rules.yaml
Expand All @@ -63,8 +69,8 @@ This file defines the rules that Glutton uses to determine which protocol handle

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.
- **type**: `conn_handler` to pass off to the appropriate protocol handler, `proxy_tcp` to forward the TCP connection to an upstream target, or `drop` to ignore packets.
- **target**: For `conn_handler`, indicates the protocol handler (e.g., `http`, `ftp`) to use. For `proxy_tcp`, this must be the upstream target in `host:port` form.
- **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).

Example rule:
Expand All @@ -80,8 +86,14 @@ rules:
- match: tcp dst port 6969
type: drop # drops any matching packets
target: bittorrent
- name: Proxy TCP example
match: tcp dst port 9889
type: proxy_tcp
target: 127.0.0.1:9889
```

`proxy_tcp` dials the configured `target` and forwards bytes in both directions between the incoming connection and the upstream service. Produced decoded events use the `proxy_tcp` protocol name and can include one captured payload entry per direction. Captured payloads are capped by `max_tcp_payload`; when a direction transfers more bytes than the cap, the decoded event is marked as truncated.

## Configuration Loading Process
Glutton uses the [Viper](https://github.com/spf13/viper) library to load configuration settings. The process works as follows:

Expand Down
12 changes: 10 additions & 2 deletions glutton.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,10 +222,18 @@ func (g *Glutton) tcpListen() {
g.Logger.Error("Failed to set connection timeout", producer.ErrAttr(err))
}

if hfunc, ok := g.tcpProtocolHandlers[rule.Target]; ok {
var handlerName string
switch rule.Type {
case "proxy_tcp":
handlerName = rule.Type
default:
handlerName = rule.Target
}

if hfunc, ok := g.tcpProtocolHandlers[handlerName]; ok {
go func() {
if err := hfunc(g.ctx, conn, md); err != nil {
g.Logger.Error("Failed to handle TCP connection", producer.ErrAttr(err), slog.String("handler", rule.Target))
g.Logger.Error("Failed to handle ", producer.ErrAttr(err), slog.String("handler", handlerName))
}
}()
}
Expand Down
1 change: 0 additions & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,3 @@ nav:
- FAQs: faq.md
theme:
name: readthedocs

3 changes: 3 additions & 0 deletions protocols/protocols.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ func MapTCPProtocolHandlers(log interfaces.Logger, h interfaces.Honeypot) map[st
protocolHandlers["mongodb"] = func(ctx context.Context, conn net.Conn, md connection.Metadata) error {
return tcp.HandleMongoDB(ctx, conn, md, log, h)
}
protocolHandlers["proxy_tcp"] = func(ctx context.Context, conn net.Conn, md connection.Metadata) error {
return tcp.HandleProxyTCP(ctx, conn, md, log, h)
}
protocolHandlers["tcp"] = func(ctx context.Context, conn net.Conn, md connection.Metadata) error {
snip, bufConn, err := Peek(conn, 4)
if err != nil {
Expand Down
Loading
Loading