Skip to content

Repository files navigation

COTBridge

Repository: github.com/snstac/cotbridge

git clone https://github.com/snstac/cotbridge.git
# or (SSH)
git clone git@github.com:snstac/cotbridge.git

COTBridge is a PyTAK-based Cursor on Target (CoT) bridge: it relays CoT traffic between heterogeneous TAK endpoints (different transports, subnets, or trust zones), similar in spirit to a cross-domain relay or guarded “lane” across a separation boundary.

Important: COTBridge is software forwarding. It is not a hardware data diode. For strict one-way policies use forward-only lanes, network segmentation, and operational controls.

Architecture

COTBridge is typically deployed where edge gateways already emit Cursor on Target (CoT) on lightweight transports (for example UDP mesh), while upstream enrollment toward TAKServer stays centralized.

Without COTBridge, each upstream-facing gateway tends to carry its own TLS client identity toward TAKServer. With COTBridge on an “all-in-one” gateway box, ADSB-/AIS-style feeders remain local CoT producers, Mesh SA absorbs multicast fan-in, and COTBridge terminates mesh ingress and holds one outbound TLS session to TAKServer. That concentrates PKI / credential lifecycle at the bridge rather than duplicating it across every edge feeder.

flowchart LR
  subgraph edge [Edge_box]
    adsb[ADSBCoT]
    aisc[AISCoT]
    mesh[Mesh_SA_UDP]
    ch[COTBridge]
    adsb --> mesh
    aisc --> mesh
    mesh --> ch
  end
  tak[TAK_Server_TLS]
  cloud[CloudTAK_TLS_optional]
  ch -->|"single_TLS_session"| tak
  ch -.->|"second_remote_requires_split_ingress"| cloud
Loading

The dashed edge marks policy/configuration territory, not an automatically dual-published TLS fan-out (see Ingress fan-out limit below).

Ingress fan-out limit

Today each enabled [lane:*] calls PyTAK protocol_factory on ingress independently (run_lane in src/cotbridge/bridge.py). Two lanes configured with the same multicast / UDP ingress will contend on bind—configure distinct ingress endpoints, place an intermediate UDP broker (“pub/sub”), deploy multiple hosts, or track future support for multi-egress from one ingress (single reader plus multiple TLS sinks).

For local UDP feeders on a fixed port, listen with udp://:18087 or udp+ro://:18087 (all interfaces, same as 0.0.0.0) or udp+ro://127.0.0.1:18087 (loopback). Feeders send with udp+wo://127.0.0.1:18087 (or the host IP). Do not use bare udp://127.0.0.1:PORT on loopback — use udp+ro:// for listen or tcp:// for outbound TCP feeders.

Install

pip install .
# protobuf CoT payloads (optional, matches PyTAK):
pip install '.[with_takproto]'

Configuration

INI file with optional global [cotbridge] and one or more [lane:*] sections. Each lane declares an ingress and egress PyTAK COT_URL pair and a mode:

Mode Traffic
forward Ingress → egress only
reverse Egress → ingress only
duplex Both directions (ensure no feedback loops)

See examples/cotbridge.ini. PyTAK URL schemes and TLS options follow PyTAK configuration.

CLI

cotbridge --config /etc/cotbridge.ini

Environment overrides (same as PyTAK-style tooling):

Variable Purpose
COTBRIDGE_CONFIG Default path if --config omitted
DEBUG Verbose logs when truthy
PYTAK_MULTICAST_LOCAL_ADDRS Comma/space-separated multicast source addresses; inherited by lanes unless a lane overrides it
PYTAK_MULTICAST_TTL Default multicast TTL; inherited by lanes unless a lane overrides it

Transport environment values sit between [cotbridge] defaults and explicit [lane:*] values. This lets a network manager supply runtime interface addresses without rewriting the operator-owned lane configuration.

Logging goes to stderr; under systemd use journalctl -u cotbridge. On startup, each enabled lane logs its ingress → egress plan and connection steps (setup, ingress connected, active); enrollment token= values in tak:// URLs are redacted in logs.

systemd

  • Packaged installs: .deb ships debian/cotbridge.service under /lib/systemd/system/ (ExecStart=/usr/bin/cotbridge), creates user/group cotbridge, and installs /etc/default/cotbridge plus /etc/cotbridge.ini from /usr/share/cotbridge/cotbridge.ini.example on first install (cotbridge.service, /etc/default/cotbridge paths mirror Debian conventions).

  • Manual / pip installs: use systemd/cotbridge.service (expects ExecStart=/usr/bin/cotbridge; adjust ExecStart= if your cotbridge lives elsewhere—for example ~/.local/bin after pip install --user). Optional defaults for COTBRIDGE_CONFIG: examples/cotbridge.default/etc/default/cotbridge.

sudo install -Dm644 systemd/cotbridge.service /etc/systemd/system/cotbridge.service
sudo install -Dm644 examples/cotbridge.ini /etc/cotbridge.ini
sudo install -Dm644 examples/cotbridge.default /etc/default/cotbridge
sudo systemctl daemon-reload
sudo systemctl enable --now cotbridge

Cockpit UI

Minimal app in cockpit-cotbridge/; see cockpit-cotbridge/README.md.

Install Cockpit itself separately (cockpit / cockpit-ws on your distro). The Python wheels data-files and Debian packages land assets under /usr/share/cockpit/cotbridge/. Developers without packaging may still run:

(cd cockpit-cotbridge && sudo make install)

Reload Cockpit to open COTBridge from the tools menu.

DEB/RPM packaging

Pattern mirrors snstac/pytak and snstac/adsbcot: root Makefile coordinates stdeb (setup.py + stdeb.cfg), debian/install_pkg_build_deps.sh primes APT deps, and python3 setup.py bdist_rpm emits SPEC-derived RPMs (Fedora smoke CI).

sudo bash debian/install_pkg_build_deps.sh
make package                # produces deb_dist/*.deb (+ faux_latest/ duplicates)

RPM on Fedora (container-friendly):

dnf install -y git python3 rpm-build python3-setuptools
python3 setup.py bdist_rpm --python=/usr/bin/python3

RPM metadata declares Requires: python3; pyproject.toml also declares pytak. Confirm PyTAK is satisfied (dnf install python3-pytak, COPR, or pip) on your target fleet—upstream distro naming shifts occasionally.

GitHub Actions (.github/workflows/ci.yml) runs pytest on PR/push and attaches Debian/Fedora artifacts when tagging.

Deployment

  • Docker / Compose: deploy/docker/README.md — image runs COTBridge plus Cockpit on port 9090 (cockpit-ws --no-tls; use a reverse proxy in production). Use Compose profile hostnet on Linux when bridging multicast CoT.
  • Ansible: ansible/README.mdcotbridge_deploy=docker for the Compose stack, or native for cockpit + pip install on the host (better match for AryaOS-style gateways).

References

The snstac TAK sensor ecosystem

Different sensor, same workflow — pick the gateway for your application; most have a matching Cockpit plugin for browser-based management:

Application Gateway Cockpit plugin
Aircraft via ADS-B (1090 MHz / 978 MHz UAT) adsbcot cockpit-adsbcot
Ships & vessels via AIS aiscot cockpit-aiscot, cockpit-aiscatcher
Drone / UAS Remote ID (counter-UAS) dronecot cockpit-dronecot
Own position via GPS/GNSS lincot cockpit-lincot, cockpit-gps
Radio direction finding (KrakenSDR) kraktak
APRS amateur radio aprscot
Weather stations windtak
CoT routing / TAK Server bridging cotbridge

All gateways are built on PyTAK, speak Cursor on Target (CoT) to ATAK, WinTAK, iTAK, TAK Server, and Mesh SA, ship as signed Debian/RPM packages at snstac.github.io/packages, and come pre-installed on AryaOS, the situational-awareness OS for Raspberry Pi.

About

Cursor on Target Ferryman

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages