No description
  • Go 99.2%
  • Nix 0.4%
  • Dockerfile 0.3%
  • Makefile 0.1%
Find a file
2026-03-14 14:47:16 -05:00
.forgejo/workflows ci: downgrade checkout action to v4 for Forgejo runner compatibility 2026-03-04 13:34:05 -06:00
.github Bump actions/download-artifact from 7 to 8 2026-03-04 19:37:25 +00:00
docs fix: security audit fixes — ReDoS, SNMP memory, credential handling, update security 2026-03-14 14:47:16 -05:00
pb fix: sync AgentError proto with server (add job_id, message fields) 2026-02-15 08:56:31 -06:00
proto fix: sync AgentError proto with server (add job_id, message fields) 2026-02-15 08:56:31 -06:00
.dockerignore Optimize CI caching for Blacksmith runners, fix SNMP bulk walk on Mikrotik 2026-02-11 10:31:10 -06:00
.envrc major overhaul to use more C for snmp, may not be stable 2026-02-09 12:31:41 -06:00
.gitignore fix: avoid copying sync.Once in host key tests 2026-03-04 13:32:53 -06:00
agent.go fix: security audit fixes — ReDoS, SNMP memory, credential handling, update security 2026-03-14 14:47:16 -05:00
agent_test.go test: push coverage from 92% to 97.6% (249 tests) 2026-03-04 16:35:02 -06:00
checks.go fix: security audit fixes — ReDoS, SNMP memory, credential handling, update security 2026-03-14 14:47:16 -05:00
checks_test.go test: achieve 92%+ coverage with comprehensive integration and edge case tests 2026-03-04 16:06:29 -06:00
docker-compose.example.yml enable ping in docker container for non-root user 2026-02-11 10:58:30 -06:00
Dockerfile fix ICMP ping in Docker by trying raw sockets before unprivileged UDP 2026-02-12 11:18:21 -06:00
flake.lock Full rewrite in golang 2026-02-11 10:04:30 -06:00
flake.nix dev: add gopls/delve to flake, add Makefile for proto/test/build 2026-02-15 08:58:13 -06:00
go.mod ci: add Renovate for automated Go dependency updates 2026-03-04 13:27:53 -06:00
go.sum ci: add Renovate for automated Go dependency updates 2026-03-04 13:27:53 -06:00
hostkeys.go fix: security audit fixes — ReDoS, SNMP memory, credential handling, update security 2026-03-14 14:47:16 -05:00
hostkeys_test.go fix: security audit fixes — ReDoS, SNMP memory, credential handling, update security 2026-03-14 14:47:16 -05:00
log.go increase test coverage and improve logger output 2026-02-11 10:42:19 -06:00
log_test.go increase test coverage and improve logger output 2026-02-11 10:42:19 -06:00
main.go fix: security audit fixes — ReDoS, SNMP memory, credential handling, update security 2026-03-14 14:47:16 -05:00
main_test.go test: push coverage from 92% to 97.6% (249 tests) 2026-03-04 16:35:02 -06:00
Makefile dev: add gopls/delve to flake, add Makefile for proto/test/build 2026-02-15 08:58:13 -06:00
mikrotik.go fix: security audit fixes — ReDoS, SNMP memory, credential handling, update security 2026-03-14 14:47:16 -05:00
mikrotik_test.go test: achieve 92%+ coverage with comprehensive integration and edge case tests 2026-03-04 16:06:29 -06:00
ping.go test: push coverage from 92% to 97.6% (249 tests) 2026-03-04 16:35:02 -06:00
ping_test.go test: push coverage from 92% to 97.6% (249 tests) 2026-03-04 16:35:02 -06:00
README.md Remove CAP_NET_RAW requirement from documentation 2026-02-10 13:27:08 -06:00
renovate.json ci: add Renovate for automated Go dependency updates 2026-03-04 13:27:53 -06:00
SECURITY_AUDIT.md security: implement audit fixes (TOFU host keys, update TOCTOU, TLS enforcement, read timeouts) 2026-02-15 09:06:39 -06:00
snmp.go fix: security audit fixes — ReDoS, SNMP memory, credential handling, update security 2026-03-14 14:47:16 -05:00
snmp_test.go test: push coverage from 92% to 97.6% (249 tests) 2026-03-04 16:35:02 -06:00
ssh.go security: implement audit fixes (TOFU host keys, update TOCTOU, TLS enforcement, read timeouts) 2026-02-15 09:06:39 -06:00
ssh_test.go security: use net.JoinHostPort for SSH addresses to support IPv6 2026-02-12 10:58:28 -06:00
update.go fix: security audit fixes — ReDoS, SNMP memory, credential handling, update security 2026-03-14 14:47:16 -05:00
update_test.go test: push coverage from 92% to 97.6% (249 tests) 2026-03-04 16:35:02 -06:00
websocket.go fix: fall back to IPv4 when WebSocket handshake fails 2026-03-04 15:14:58 -06:00
websocket_test.go test: achieve 92%+ coverage with comprehensive integration and edge case tests 2026-03-04 16:06:29 -06:00
workerpool.go security: implement audit fixes (TOFU host keys, update TOCTOU, TLS enforcement, read timeouts) 2026-02-15 09:06:39 -06:00
workerpool_test.go security: fixes 1-5 — payload limits, non-blocking submit, panic recovery, handshake timeout, write error propagation 2026-02-12 10:55:24 -06:00

Towerops Agent

A lightweight Rust-based remote polling agent for Towerops SNMP monitoring.

Overview

The Towerops agent enables customers to deploy SNMP polling infrastructure on their internal networks. The agent connects to the Towerops server via WebSocket and executes SNMP queries as directed by the server.

Features

  • Local SNMP Polling: Poll devices on your internal network without exposing them to the internet
  • SNMP Trap Receiver: Listen for SNMP v1 and v2c traps from network devices
  • Secure Communication: All communication with Towerops uses WebSocket over TLS with token authentication
  • Real-time Updates: Server pushes configuration changes instantly via persistent WebSocket connection
  • Automatic Reconnection: Exponential backoff reconnection on network failures
  • Automatic Updates: Checks for new versions hourly and self-updates when available (requires Docker socket access)
  • Low Resource Usage: Built in Rust for minimal memory and CPU footprint (< 256 MB RAM typical)
  • Docker Ready: Pre-built Docker images for easy deployment

Quick Start

Using Pre-built Image

Pull the latest image from Docker Hub:

docker pull ghcr.io/towerops-app/towerops-agent:latest

Using Docker Compose

  1. Create a docker-compose.yml file:
version: '3.8'

services:
  towerops-agent:
    image: ghcr.io/towerops-app/towerops-agent:latest
    restart: unless-stopped
    environment:
      - TOWEROPS_API_URL=https://towerops.net
      - TOWEROPS_AGENT_TOKEN=your-agent-token-here
      - LOG_LEVEL=info
      # Optional: Enable SNMP trap listener
      - TRAP_ENABLED=true
      - TRAP_PORT=162
    ports:
      # SNMP trap listener (UDP) - only needed if TRAP_ENABLED=true
      - "162:162/udp"
  1. Start the agent:
docker-compose up -d

Configuration

The agent is configured via environment variables:

Variable Description Default
TOWEROPS_API_URL Towerops API endpoint Required
TOWEROPS_AGENT_TOKEN Agent authentication token Required
LOG_LEVEL Logging level (error, warn, info, debug) info
TRAP_ENABLED Enable SNMP trap listener false
TRAP_PORT UDP port for SNMP traps 162

Obtaining an Agent Token

  1. Log in to your Towerops account
  2. Navigate to your organization's Agents page
  3. Click "Create New Agent"
  4. Copy the token (it will only be shown once)

Architecture

The agent uses a WebSocket-based architecture for real-time communication:

  • WebSocket Client: Maintains a persistent connection to the Towerops server
  • SNMP Executor: Executes SNMP queries (GET, WALK) as directed by the server
  • Trap Listener: Optional UDP listener for receiving SNMP traps from devices

Communication Flow

  1. Agent establishes WebSocket connection to {api_url}/socket/agent/websocket
  2. Agent authenticates by joining PubSub channel with token
  3. Server pushes SNMP jobs (queries to execute) to agent
  4. Agent executes queries and sends results back via WebSocket
  5. Periodic heartbeats maintain connection health
  6. On disconnect, agent reconnects with exponential backoff (1s to 60s)

SNMP Trap Listener

When enabled (TRAP_ENABLED=true), the agent listens for SNMP traps:

  • Supports SNMPv1 and SNMPv2c trap formats
  • Logs received traps with source address, enterprise OID, and variable bindings
  • Default port 162 (standard SNMP trap port)

Building from Source

Prerequisites

  • Rust 1.91 or later

Build

cargo build --release

The binary will be in target/release/towerops-agent.

Docker Build

docker build -t towerops-agent .

Troubleshooting

Agent Not Connecting

  • Verify the API URL is correct (accepts http://, https://, ws://, or wss://)
  • Check that the agent token is valid and hasn't been revoked
  • Ensure network connectivity to the Towerops API
  • Check logs for connection errors: docker logs towerops-agent

No Metrics Appearing

  • Check that equipment is assigned to this agent in Towerops
  • Verify SNMP credentials are correct in Towerops equipment settings
  • Review agent logs for SNMP polling errors
  • Ensure the agent is connected (check Towerops UI for agent status)

Traps Not Received

  • Ensure TRAP_ENABLED=true is set
  • Verify UDP port 162 is exposed and not blocked by firewall
  • Check that devices are configured to send traps to the agent's IP
  • Look for trap messages in logs with LOG_LEVEL=debug

Resource Requirements

  • Memory: 64-128 MB typical, 256 MB maximum
  • CPU: 0.1-0.5 cores typical
  • Network: Minimal (small protobuf messages over WebSocket)

Security

  • Agent token should be kept secret (treat like a password)
  • All API communication uses TLS with certificate verification
  • Agent requires no inbound network connections (except optional trap listener on UDP 162)
  • SNMP community strings are only used locally and never logged

License

Copyright 2026 Towerops