-
Notifications
You must be signed in to change notification settings - Fork 1
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.
The agent connects outbound to the server over WebSocket.
./agent-linux-amd64 -s <server-ip>:1024 -k <key>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>:4444Daemonize the agent so it detaches from the terminal.
./agent-linux-amd64 -s <server-ip>:1024 -k <key> -bOn Unix this re-executes the binary with setsid and stdio redirected to /dev/null. On Windows it spawns a detached process.
| 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 |
{
"key": "<base64url-key>",
"server_addr": "<server-ip>:1024",
"mode": "agent"
}./agent-linux-amd64 -c agent.jsonOn startup the agent discovers all local subnets automatically:
- Enumerates network interfaces via
net.Interfaces() - On Linux: parses output of
ip route show - On Windows: parses output of
route print -4 - Filters out loopback and link-local ranges
- Sends the full subnet list to the server in the
registermessage
The server installs interception rules for each discovered subnet so traffic to those ranges is transparently tunneled through the agent.
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.
- The agent sends a
heartbeatmessage to the server every 10 seconds - If the WebSocket connection drops, the agent reconnects automatically with exponential backoff
- The server can also send a
reconnectmessage to force the agent to reconnect - The server can send a
disconnectmessage to tell the agent to exit
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-listenerandstop-agent-listenermessages
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-responsemessage - Triggered from the dashboard or via
discover <agent-id> <subnet>in the REPL
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-responsemessage - Triggered from the dashboard or via
portscan <agent-id> tcp|udp <target> [ports]
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
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.
| Platform | Architectures |
|---|---|
| Linux | amd64, arm64, arm, 386 |
| Windows | amd64, arm64, 386 |
| macOS | amd64, arm64 |
| FreeBSD | amd64, arm64, arm, 386 |
| OpenBSD | amd64, arm64, arm, 386 |
Use only on systems you own or have explicit written permission to test. Unauthorized use is prohibited.