Operator Guide: Running SignalBridge at the Edge
What you’re operating
SignalBridge sits in the operator environment: it ingests S1AP/NGAP signalling (from file, TCP PCAP stream, or stdin), filters what you allow, anonymises subscriber identities when configured, and exports to PCAP, TCP, UDP, or HTTP(S) NDJSON batches—typically toward analysis or a platform like Signal Cloud. Your job is to wire capture → policy → egress safely and observably.
Before you start
- Data governance: Confirm what may leave the core (raw vs anonymised, retention, lawful basis).
- Network: Inbound path to your capture source (file mount, mirror port, or TCP listener); outbound to ingest (HTTPS URL, TCP/UDP peer). Firewall and TLS termination as required.
- Secrets: If you use encrypted HTTP output, the config includes a hex encryption key (32-byte). Treat it like any key material—vault, rotation policy, no plain-text tickets.
Deploy the binary
Operators usually take a released signalbridge from the build pipeline. If you must build on-site, use the same dependency list as in the README (libpcap, yaml-cpp, curl, OpenSSL, zlib). The public bundle vendors parsers under third_party/s1see/ so a standard clone builds without a separate S1-SEE checkout.
Configuration (config/conduit.yaml)
config/conduit.yaml)The sample file shows the knobs you actually turn:
# When set (hex-encoded 32-byte key), HTTP output is encrypted with AES-256-GCM.
encryption_key: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
anonymisation:
enabled: false
mcc: "999"
mnc: "99"
# imsi_map_path: "" # Optional: write "original -> anonymised" mapping when done
replacement_byte: 0 # Legacy: used when mcc empty (zero-fill mode)
filter:
# Include only these protocols (empty = all). Values: S1AP, NGAP
protocol_include: []
# Exclude these protocols
protocol_exclude: []
# Include only these procedure codes (empty = all)
procedure_include: []
# Exclude these procedure codes
procedure_exclude: []
# IP allow list (empty = allow all)
ip_allow: []
# IP deny list
ip_deny: []
# Drop encrypted NAS (cannot anonymise without keys)
drop_encrypted_nas: falseOperator checklist:
| Area | What to decide |
|---|---|
| Anonymisation | On/off, synthetic MCC/MNC, optional imsi_map_path for audit/debug (protect that file). |
| Filters | S1AP-only vs NGAP vs both; procedure allow/deny lists to cut volume; IP allow/deny to scope eNB/gNB or probes. |
| Encrypted NAS | drop_encrypted_nas: true when you cannot decrypt—avoids leaking opaque payloads you can’t anonymise. |
| HTTP(S) security | Real encryption_key in prod; HTTPS URL to trusted ingest; path must match what the receiver expects (e.g. /frames/{uuid}). |
| Inputs | file with path, or tcp listener address, or stdin (often used under a supervisor). Comments in YAML mention grpc as a type—confirm against your release notes if present. |
| Outputs | http/https URL, or file, or tcp/udp peer per your downstream. |
Example output stanza from the same file:
outputs:
- type: "http"
path: "http://127.0.0.1:9876/frames/550e8400-e29b-41d4-a716-446655440000"
# Set to file path, or use type: https with address for HTTP streaming
# For HTTP streaming: type: https, address: "https://ingest.example.com/frames/{uuid}"
# For TCP output: type: tcp, address: "host:port"
# For UDP output: type: udp, address: "host:port"Ingest path conventions are also summarized in config/ingest_endpoints.yaml.
Validate, then run
Dry-run config parsing (no traffic processing):
./signalbridge validate -c /path/to/conduit.yamlLive run:
./signalbridge run -c /path/to/conduit.yamlCLI override for a one-off file test:
./signalbridge run -i capture.pcap -o anonymised.pcapPrometheus metrics
Metrics bind is CLI, not YAML: -m / --metrics <addr>, default 127.0.0.1:9090. For scraping from another host, set an interface/IP your monitoring can reach and open the port in policy. Endpoint is /metrics (see apps/signalbridge.cc help string and metrics server startup).
Local smoke test (optional)
To verify HTTP streaming before pointing at production, a reference Python ingest exists under server/ (signalvault_ingest.py); use only on controlled lab networks. Details: README.md § HTTP streaming.
Run as a service (typical pattern)
- Run
signalbridge run -c ...under systemd (or equivalent) withRestart=on-failure, explicit user, read-only config path, and locked-down permissions on YAML and anyimsi_map_pathoutput. - Redirect logs to your aggregator; rely on metrics for throughput and error trending.
- Align capture restart (TCP reconnect, file rotation) with your input mode—use
--loopfor TCP if your deployment expects repeated connections and config reload (per root README).
Updated 3 days ago
