|
| 1 | +# UTMStack Forwarder |
| 2 | + |
| 3 | +The UTMStack Forwarder is a standalone log collection service that receives logs from external integrations and forwards them to the UTMStack backend in real time. |
| 4 | + |
| 5 | +It runs as an independent Linux service (`UTMStackForwarder`) alongside the UTMStack Agent. Both connect directly to the backend — there is no communication between them. |
| 6 | + |
| 7 | +--- |
| 8 | + |
| 9 | +## What it does |
| 10 | + |
| 11 | +The Forwarder opens listeners on your server and waits for logs to arrive. As soon as a log comes in, it sends it to the UTMStack backend immediately — no local storage, no buffering. |
| 12 | + |
| 13 | +It supports four types of listeners: |
| 14 | + |
| 15 | +| Listener | Protocol | Typical use | |
| 16 | +|---|---|---| |
| 17 | +| **Syslog** | TCP, UDP, TLS | Firewalls, switches, routers, security appliances | |
| 18 | +| **Netflow** | UDP | Network traffic data (v5, v9, IPFIX) | |
| 19 | +| **File** | — | Log files on the local server (nginx, postgresql) | |
| 20 | +| **HTTP/HTTPS** | HTTP, HTTPS | Webhooks, APIs, custom applications | |
| 21 | + |
| 22 | +--- |
| 23 | + |
| 24 | +## How it works |
| 25 | + |
| 26 | +### Boot sequence |
| 27 | + |
| 28 | +When the service starts: |
| 29 | + |
| 30 | +1. Reads the encrypted configuration (`collector-config.yml`) |
| 31 | +2. Connects to the UTMStack backend |
| 32 | +3. Starts a ping goroutine (heartbeat every 15 seconds) |
| 33 | +4. Starts the log forwarding goroutine |
| 34 | +5. Syncs the integration config file (`log-collector-config.json`) |
| 35 | +6. Starts all enabled listeners |
| 36 | + |
| 37 | +### Log flow |
| 38 | + |
| 39 | +``` |
| 40 | +Syslog listener ──────┐ |
| 41 | +Netflow listener ──────┤──► Internal queue (10,000 slots) ──► UTMStack backend |
| 42 | +File listener ──────┤ |
| 43 | +HTTP listener ──────┘ |
| 44 | +``` |
| 45 | + |
| 46 | +Every listener pushes logs into a shared internal queue. A single goroutine drains that queue and streams logs to the backend over gRPC. If the backend is unreachable, logs arriving during the outage are dropped — there is no local buffer by design. |
| 47 | + |
| 48 | +### Live configuration |
| 49 | + |
| 50 | +The Forwarder watches `log-collector-config.json` for changes using `fsnotify`. When you run a CLI command to enable or disable an integration, the file changes and the relevant listener starts or stops automatically — **no service restart needed**. |
| 51 | + |
| 52 | +--- |
| 53 | + |
| 54 | +## Installation |
| 55 | + |
| 56 | +```bash |
| 57 | +# Install the service |
| 58 | +./utmstack_forwarder install <server_address> <utm_key> <yes|no> |
| 59 | + |
| 60 | +# yes = skip TLS certificate validation |
| 61 | +# no = validate TLS certificate (recommended for production) |
| 62 | +``` |
| 63 | + |
| 64 | +Example: |
| 65 | +```bash |
| 66 | +./utmstack_forwarder install 192.168.1.100 my-utm-key no |
| 67 | +``` |
| 68 | + |
| 69 | +This will: |
| 70 | +1. Verify connectivity to the backend (ports 9000 and 50051) |
| 71 | +2. Register the forwarder with the UTMStack backend |
| 72 | +3. Save the encrypted configuration |
| 73 | +4. Install and start the `UTMStackForwarder` system service |
| 74 | + |
| 75 | +```bash |
| 76 | +# Uninstall |
| 77 | +./utmstack_forwarder uninstall |
| 78 | +``` |
| 79 | + |
| 80 | +--- |
| 81 | + |
| 82 | +## Managing integrations |
| 83 | + |
| 84 | +### Enable a syslog integration |
| 85 | + |
| 86 | +```bash |
| 87 | +# UDP (most common for syslog) |
| 88 | +./utmstack_forwarder enable-integration firewall-fortigate-traffic 7005 udp |
| 89 | + |
| 90 | +# TCP |
| 91 | +./utmstack_forwarder enable-integration firewall-fortigate-traffic 7005 tcp |
| 92 | + |
| 93 | +# TCP with TLS (requires a certificate loaded first) |
| 94 | +./utmstack_forwarder enable-integration firewall-fortigate-traffic 7005 tls |
| 95 | +``` |
| 96 | + |
| 97 | +### Enable a netflow integration |
| 98 | + |
| 99 | +```bash |
| 100 | +./utmstack_forwarder enable-integration netflow 2055 udp |
| 101 | +``` |
| 102 | + |
| 103 | +### Enable an HTTP integration |
| 104 | + |
| 105 | +```bash |
| 106 | +# No authentication — for trusted internal networks |
| 107 | +./utmstack_forwarder enable-integration my-app 7999 http |
| 108 | + |
| 109 | +# Bearer token authentication |
| 110 | +./utmstack_forwarder enable-integration my-app 7999 http --auth bearer |
| 111 | + |
| 112 | +# HMAC authentication — compatible with Meta, GitHub, Stripe, etc. |
| 113 | +./utmstack_forwarder enable-integration meta 7999 http --auth hmac --signature-header X-Hub-Signature-256 |
| 114 | +./utmstack_forwarder enable-integration github 7999 http --auth hmac --signature-header X-Hub-Signature-256 |
| 115 | +./utmstack_forwarder enable-integration stripe 7999 http --auth hmac --signature-header Stripe-Signature |
| 116 | +``` |
| 117 | + |
| 118 | +### Enable an HTTPS integration |
| 119 | + |
| 120 | +```bash |
| 121 | +# Load the TLS certificate first |
| 122 | +./utmstack_forwarder load-tls-certs /path/to/cert.crt /path/to/key.key |
| 123 | + |
| 124 | +# Then enable |
| 125 | +./utmstack_forwarder enable-integration my-app 443 https --auth bearer |
| 126 | +``` |
| 127 | + |
| 128 | +### Disable an integration |
| 129 | + |
| 130 | +```bash |
| 131 | +./utmstack_forwarder disable-integration firewall-fortigate-traffic udp |
| 132 | +./utmstack_forwarder disable-integration my-app http |
| 133 | +``` |
| 134 | + |
| 135 | +### Change a port |
| 136 | + |
| 137 | +```bash |
| 138 | +./utmstack_forwarder change-port firewall-fortigate-traffic udp 7010 |
| 139 | +./utmstack_forwarder change-port my-app http 8080 |
| 140 | +``` |
| 141 | + |
| 142 | +### Adding a custom integration type |
| 143 | + |
| 144 | +If the integration name you want does not exist in the built-in catalog, the Forwarder creates it automatically: |
| 145 | + |
| 146 | +```bash |
| 147 | +./utmstack_forwarder enable-integration my-custom-firewall 7999 udp |
| 148 | +# Output: New data type "my-custom-firewall" created. |
| 149 | +# Integration "my-custom-firewall" enabled on udp port 7999 |
| 150 | +``` |
| 151 | + |
| 152 | +The new type is saved in `log-collector-catalog.json`. You can manage custom types: |
| 153 | + |
| 154 | +```bash |
| 155 | +# List all types (built-in and custom) |
| 156 | +./utmstack_forwarder list-datatypes |
| 157 | + |
| 158 | +# Remove a custom type (must be disabled first) |
| 159 | +./utmstack_forwarder remove-datatype my-custom-firewall |
| 160 | +``` |
| 161 | + |
| 162 | +--- |
| 163 | + |
| 164 | +## HTTP/HTTPS authentication |
| 165 | + |
| 166 | +### No authentication |
| 167 | + |
| 168 | +The listener accepts every POST without any check. Use only on isolated networks. |
| 169 | + |
| 170 | +```bash |
| 171 | +./utmstack_forwarder enable-integration my-app 7999 http |
| 172 | +``` |
| 173 | + |
| 174 | +Sending logs: |
| 175 | +```bash |
| 176 | +curl -X POST http://your-server:7999/logs \ |
| 177 | + -d '{"event": "login", "user": "john"}' |
| 178 | +``` |
| 179 | + |
| 180 | +--- |
| 181 | + |
| 182 | +### Bearer token |
| 183 | + |
| 184 | +When enabled, the Forwarder generates a random token and displays it **once**. Store it securely. |
| 185 | + |
| 186 | +```bash |
| 187 | +./utmstack_forwarder enable-integration my-app 7999 http --auth bearer |
| 188 | +# Output: |
| 189 | +# Token for my-app: a3f8c2d1e4b57f9... |
| 190 | +# Store this token securely — it won't be shown again. |
| 191 | +``` |
| 192 | + |
| 193 | +Sending logs: |
| 194 | +```bash |
| 195 | +curl -X POST http://your-server:7999/logs \ |
| 196 | + -H "Authorization: Bearer a3f8c2d1e4b57f9..." \ |
| 197 | + -d '{"event": "login", "user": "john"}' |
| 198 | +``` |
| 199 | + |
| 200 | +Configure this token as an HTTP header secret in your external platform. |
| 201 | + |
| 202 | +--- |
| 203 | + |
| 204 | +### HMAC signature |
| 205 | + |
| 206 | +Used by platforms like Meta, GitHub, and Stripe. The platform signs each request with a shared secret — the Forwarder verifies the signature without the secret ever travelling in the request. |
| 207 | + |
| 208 | +```bash |
| 209 | +./utmstack_forwarder enable-integration meta 7999 http \ |
| 210 | + --auth hmac \ |
| 211 | + --signature-header X-Hub-Signature-256 |
| 212 | +``` |
| 213 | + |
| 214 | +When enabled, a token file is generated at `certs/integration-http-meta.token`. Configure this token as the webhook secret in the external platform (Meta, GitHub, etc.). |
| 215 | + |
| 216 | +The `--signature-header` flag specifies which header the platform uses to send the signature: |
| 217 | + |
| 218 | +| Platform | Header | |
| 219 | +|---|---| |
| 220 | +| Meta / Facebook | `X-Hub-Signature-256` | |
| 221 | +| GitHub | `X-Hub-Signature-256` | |
| 222 | +| Stripe | `Stripe-Signature` | |
| 223 | +| Custom | any header you choose | |
| 224 | + |
| 225 | +--- |
| 226 | + |
| 227 | +## HTTP/HTTPS body format |
| 228 | + |
| 229 | +The HTTP and HTTPS listeners accept **any format** — JSON, NDJSON, plain text, XML, or anything else. The body is forwarded as-is to the UTMStack event processor, which applies the corresponding filter for that DataType. No parsing or transformation happens in the Forwarder. |
| 230 | + |
| 231 | +```bash |
| 232 | +# JSON |
| 233 | +curl -X POST http://your-server:7999/logs \ |
| 234 | + -H "Content-Type: application/json" \ |
| 235 | + -d '{"event":"login","user":"john"}' |
| 236 | + |
| 237 | +# Plain syslog text |
| 238 | +curl -X POST http://your-server:7999/logs \ |
| 239 | + -H "Content-Type: text/plain" \ |
| 240 | + -d 'Jan 10 12:00:01 fw01 kernel: packet blocked src=1.2.3.4' |
| 241 | + |
| 242 | +# Any other format — the event processor handles it |
| 243 | +curl -X POST http://your-server:7999/logs \ |
| 244 | + --data-binary @/path/to/logfile.xml |
| 245 | +``` |
| 246 | + |
| 247 | +The only limit is **8 MB per request**. |
| 248 | + |
| 249 | +--- |
| 250 | + |
| 251 | +## TLS for syslog |
| 252 | + |
| 253 | +```bash |
| 254 | +# Load your certificates |
| 255 | +./utmstack_forwarder load-tls-certs /path/to/cert.crt /path/to/key.key /path/to/ca.crt |
| 256 | + |
| 257 | +# Enable TLS on a syslog integration |
| 258 | +./utmstack_forwarder enable-integration firewall-cisco-asa 1470 tls |
| 259 | +``` |
| 260 | + |
| 261 | +All TLS connections use TLS 1.2/1.3 only with AEAD cipher suites. |
| 262 | + |
| 263 | +--- |
| 264 | + |
| 265 | +## Configuration files |
| 266 | + |
| 267 | +All files are stored in the Forwarder's installation directory. |
| 268 | + |
| 269 | +| File | Description | |
| 270 | +|---|---| |
| 271 | +| `collector-config.yml` | Encrypted credentials (server address, ID, key) | |
| 272 | +| `collector-uuid.yml` | Unique installation identifier | |
| 273 | +| `log-collector-config.json` | Integration settings (ports, protocols, enabled status) | |
| 274 | +| `log-collector-catalog.json` | User-defined custom DataTypes | |
| 275 | +| `certs/integration.crt` | TLS certificate for syslog TLS and HTTPS | |
| 276 | +| `certs/integration.key` | TLS private key | |
| 277 | +| `certs/integration-http-<name>.token` | Auth token for HTTP/HTTPS integrations | |
| 278 | +| `logs/utmstack_collector.log` | Service log file | |
| 279 | + |
| 280 | +--- |
| 281 | + |
| 282 | +## Built-in integration types |
| 283 | + |
| 284 | +| Name | Protocol | Default port | |
| 285 | +|---|---|---| |
| 286 | +| `syslog` | UDP/TCP | 7014 | |
| 287 | +| `vmware-esxi` | UDP/TCP | 7002 | |
| 288 | +| `antivirus-esmc-eset` | UDP/TCP | 7003 | |
| 289 | +| `antivirus-kaspersky` | UDP/TCP | 7004 | |
| 290 | +| `firewall-cisco-asa` | UDP/TCP | 514/1470 | |
| 291 | +| `firewall-cisco-firepower` | UDP/TCP | 514/1470 | |
| 292 | +| `cisco-switch` | UDP/TCP | 514/1470 | |
| 293 | +| `firewall-meraki` | UDP/TCP | 514/1470 | |
| 294 | +| `firewall-fortigate-traffic` | UDP/TCP | 7005 | |
| 295 | +| `firewall-paloalto` | UDP/TCP | 7006 | |
| 296 | +| `firewall-mikrotik` | UDP/TCP | 7007 | |
| 297 | +| `firewall-sophos-xg` | UDP/TCP | 7008 | |
| 298 | +| `firewall-sonicwall` | UDP/TCP | 7009 | |
| 299 | +| `deceptive-bytes` | UDP/TCP | 7010 | |
| 300 | +| `antivirus-sentinel-one` | UDP/TCP | 7012 | |
| 301 | +| `ibm-aix` | UDP/TCP | 7016 | |
| 302 | +| `firewall-pfsense` | UDP/TCP | 7017 | |
| 303 | +| `firewall-fortiweb` | UDP/TCP | 7018 | |
| 304 | +| `suricata` | UDP/TCP | 7019 | |
| 305 | +| `netflow` | UDP | 2055 | |
| 306 | +| `nginx` | file | `/var/log/nginx/` | |
| 307 | +| `postgresql` | file | `/var/log/postgresql/` | |
| 308 | + |
| 309 | +--- |
| 310 | + |
| 311 | +## Service management |
| 312 | + |
| 313 | +```bash |
| 314 | +systemctl start UTMStackForwarder |
| 315 | +systemctl stop UTMStackForwarder |
| 316 | +systemctl restart UTMStackForwarder |
| 317 | +systemctl status UTMStackForwarder |
| 318 | +``` |
| 319 | + |
| 320 | +--- |
| 321 | + |
| 322 | +## Platform support |
| 323 | + |
| 324 | +Linux only (amd64, arm64). |
0 commit comments