Skip to content
Chokri Hammedi edited this page Apr 21, 2026 · 3 revisions

Agent

The agent is a lightweight binary that runs on the remote host. It connects back to the server, registers its subnets, and forwards traffic on demand. No root or administrator privileges are required.


Modes

Standard Mode (default)

The agent connects outbound to the server over WebSocket.

./agent-linux-amd64 -s <server-ip>:1024 -k <key>

Bind Mode

The agent listens on a local TCP port and waits for the server to dial in. Useful when the agent host cannot reach the server directly but the server can reach the agent.

# On the agent host
./agent-linux-amd64 -m agent-bind -p 4444 -k <key>

# From the server REPL
connect <agent-ip>:4444

Background Mode

Daemonize the agent so it detaches from the terminal.

./agent-linux-amd64 -s <server-ip>:1024 -k <key> -b

On Unix this re-executes the binary with setsid and stdio redirected to /dev/null. On Windows it spawns a detached process.


CLI Flags

Flag Description
-s, --server Server address, e.g. <ip>:1024
-k, --key Base64url-encoded 32-byte AES-256 key
-m, --mode agent (default) or agent-bind
-p, --port Port to listen on in bind mode
-b, --background Run as background daemon
-c, --config Path to JSON config file

Config File

{
  "key": "<base64url-key>",
  "server_addr": "<server-ip>:1024",
  "mode": "agent"
}
./agent-linux-amd64 -c agent.json

Subnet Discovery

On startup the agent discovers all local subnets automatically:

  1. Enumerates network interfaces via net.Interfaces()
  2. On Linux: parses output of ip route show
  3. On Windows: parses output of route print -4
  4. Filters out loopback and link-local ranges
  5. Sends the full subnet list to the server in the register message

The server installs interception rules for each discovered subnet so traffic to those ranges is transparently tunneled through the agent.


Internet Detection

Before registering, the agent probes internet access by attempting a TCP dial to an external address. The result is included in the register message and shown in the dashboard. This allows the server to know which agents can be used as a default egress.


Heartbeat and Reconnect

  • The agent sends a heartbeat message to the server every 10 seconds
  • If the WebSocket connection drops, the agent reconnects automatically with exponential backoff
  • The server can also send a reconnect message to force the agent to reconnect
  • The server can send a disconnect message to tell the agent to exit

Port Forwarding

The server can instruct the agent to open local port forwards:

  • TCP forward: agent listens on a local port and bridges connections to a target host
  • UDP forward: agent listens on a local UDP port with per-client session tracking and idle timeout
  • Forwards are started and stopped via start-agent-listener and stop-agent-listener messages

Ping Sweep

The server can request the agent to discover live hosts in a subnet:

  • Uses concurrent TCP port probing (tcpPing) across the subnet
  • Results are returned as a ping-sweep-response message
  • Triggered from the dashboard or via discover <agent-id> <subnet> in the REPL

Port Scan

The server can request a TCP or UDP port scan via the agent:

  • Concurrent dial workers probe each port
  • Results are returned as a port-scan-response message
  • Triggered from the dashboard or via portscan <agent-id> tcp|udp <target> [ports]

DNS Resolution

The agent resolves DNS queries on behalf of the server:

  • Uses the system resolver first
  • Falls back to public resolvers: 8.8.8.8, 1.1.1.1, 8.8.4.4
  • Handles both A and AAAA records

ICMP

The agent handles two types of ICMP messages:

  • icmp-request: ping a specific target and return the result
  • icmp_proxy: transparently proxy ICMP echo requests for the server's interception layer

Uses golang.org/x/net/icmp for raw IPv4 and IPv6 ICMP, with a fallback to the system ping binary if raw sockets are unavailable.


Supported Platforms

Platform Architectures
Linux amd64, arm64, arm, 386
Windows amd64, arm64, 386
macOS amd64, arm64
FreeBSD amd64, arm64, arm, 386
OpenBSD amd64, arm64, arm, 386

Clone this wiki locally