Pentestas / help

Linux agent

Outbound-only agent that connects to the platform over WebSocket and runs scans inside your network. Installs into /opt/pentestas-agent. Suitable for dedicated Linux boxes, EC2 instances, LXC containers, and Kubernetes pods.

Solo-app behaviour — the installer drops a manual-start pentestas-agent launcher on $PATH. It does not register a systemd service, and it does not start at boot. You launch the agent manually when you want it connected. To enable always-on operation, copy the unit file shipped under contrib/ into systemd yourself — see Always-on (opt-in) below.

Install

  1. In the Pentestas UI, go to Settings → Agents → New agent.
  2. Name it (e.g. corp-fra-01) and add the public IPs it will connect from to the allowlist.
  3. Copy the install command.
  4. Run on the target host:
bash
curl -fsSL https://app.pentestas.com/agent/install.sh | sudo bash -s -- --key pa_YOUR_KEY

The installer:

  • Creates /opt/pentestas-agent/ with a Python virtualenv.
  • Installs websockets, httpx, cryptography, and optionally mitmproxy.
  • Drops an env file at /opt/pentestas-agent/config (chmod 0600) holding the key.
  • Drops a launcher at /opt/pentestas-agent/bin/pentestas-agent and symlinks it into /usr/local/bin/ so the command is on your $PATH.
  • Ships a systemd unit file under /opt/pentestas-agent/contrib/not installed, not enabled. Opt-in only.
  • If a previous install registered the unit at /etc/systemd/system/pentestas-agent.service, the installer migrates it: stops the service, disables it, removes the unit, runs daemon-reload. After the upgrade the host is in the new manual-only state.

Flags accepted by the installer:

  • --key <AGENT_KEY> (required)
  • --url <wss://…> — override the platform URL (default wss://app.pentestas.com/api/agents/ws)
  • --prefix <DIR> — install location (default /opt/pentestas-agent)
  • --no-browser — skip mitmproxy (no browser launcher support); smaller footprint
  • --dry-run — print commands, don't execute

Start the agent

Run the launcher in a terminal (or a tmux / screen session if you want it to outlive your SSH session):

bash
pentestas-agent

Press Ctrl-C to stop. The agent runs in the foreground so you can see logs directly; this is intentional and matches how customers said they wanted the agent to feel — a solo desktop app you start when you need it.

Verify

While the agent is running you'll see in the terminal:

You should see:

[INFO] pentestas-agent 0.3.0 starting (caps=network_scan,web_scan,browser_launcher)
[INFO] platform=wss://app.pentestas.com/api/agents/ws
[INFO] connected to wss://app.pentestas.com/api/agents/ws
[INFO] welcome: Connected to Pentestas platform

In the UI, the agent row flips from PendingConnected within 5 seconds.

Sub-commands

The agent binary supports three sub-commands:

Sub-command Purpose
connect Long-lived connection loop (what the pentestas-agent launcher invokes)
version Print agent version + discovered capabilities
probe One-shot diagnostic: platform URL, key presence, detected browsers

Run manually to debug:

bash
sudo -u pentestas /opt/pentestas-agent/venv/bin/python \
    -m scanner.agent.agent probe

Capabilities detected at runtime

The agent advertises its capabilities to the platform on each connect:

  • network_scan — always available (uses built-in asyncio TCP scanner).
  • web_scan — advertised if the DirectScanEngine module is importable (present in the Docker image, not in the slim PyPI install).
  • browser_launcher — advertised if mitmproxy is installed and at least one browser is discovered on the host.

Dispatch endpoints refuse to send jobs that don't match the agent's advertised capabilities, so the UI never sends a web-scan job to a network-only agent.

Updating

Stop the agent (Ctrl-C in its terminal), then re-run the installer with the same key. The tarball is re-downloaded and the launcher is replaced. No key rotation needed.

bash
curl -fsSL https://app.pentestas.com/agent/install.sh | sudo bash -s -- --key pa_YOUR_KEY
pentestas-agent

Always-on (opt-in)

If you do want the agent to start at boot, the installer ships the systemd unit under contrib/. Enable it manually:

bash
sudo cp /opt/pentestas-agent/contrib/pentestas-agent.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now pentestas-agent
journalctl -u pentestas-agent -f

This makes the agent behave the same way the previous installer did: started at boot, restarted on failure, logs to the journal. You're trading the solo-app feel for always-on operation; it's a deliberate choice, not the default.

Uninstall

bash
# If you opted into always-on operation:
sudo systemctl disable --now pentestas-agent
sudo rm -f /etc/systemd/system/pentestas-agent.service
sudo systemctl daemon-reload

# Remove the agent itself + the symlink:
sudo rm -rf /opt/pentestas-agent /usr/local/bin/pentestas-agent

Key rotation is separate — do it in the UI, then re-install.

Docker variant

For users who want the full scan engine without a venv on the host, deploy via Docker:

bash
docker run -d --restart=always \
  --name pentestas-agent \
  -e PENTESTAS_AGENT_KEY=pa_YOUR_KEY \
  -v pentestas-agent-state:/var/lib/pentestas-agent \
  pentestas/agent:latest

Same protocol. Trades disk footprint (~500 MB image) for a guaranteed-consistent engine version.

Troubleshooting

See Troubleshooting for the common cases (wrong IP in allowlist, WebSocket blocked, clock skew).