No description
  • Go 98.5%
  • Makefile 0.9%
  • Dockerfile 0.6%
Find a file
2026-04-30 08:45:25 +07:00
checker Only apply on services scope 2026-04-29 18:47:20 +07:00
plugin Initial commit 2026-04-26 19:55:05 +07:00
.gitignore Initial commit 2026-04-26 19:55:05 +07:00
Dockerfile Initial commit 2026-04-26 19:55:05 +07:00
go.mod Initial commit 2026-04-26 19:55:05 +07:00
go.sum Initial commit 2026-04-26 19:55:05 +07:00
LICENSE Initial commit 2026-04-26 19:55:05 +07:00
main.go Initial commit 2026-04-26 19:55:05 +07:00
Makefile Initial commit 2026-04-26 19:55:05 +07:00
NOTICE Initial commit 2026-04-26 19:55:05 +07:00
README.md Include rules section 2026-04-30 08:45:25 +07:00

checker-stun-turn

happyDomain checker that probes STUN and TURN servers end-to-end: DNS / SRV discovery, TCP/UDP reachability, TLS / DTLS handshake, STUN binding, open-relay check, authenticated TURN Allocate (long-term creds or REST API shared secret), relay address sanity, and a CreatePermission + Send round-trip through the relay.

Backed by github.com/pion/stun + github.com/pion/turn.

Tests performed per endpoint

Test What it proves
dial:<transport> DNS resolves, port is reachable, TLS/DTLS handshake succeeds.
tls / dtls Records TLS version + cipher + peer cert CN.
stun_binding Server answers RFC 5389 Binding Request; measures RTT.
stun_reflexive_public Server returned a public XOR-MAPPED address (not RFC1918).
turn_open_relay_check Unauthenticated Allocate is rejected with 401 + REALM/NONCE.
turn_allocate_auth Authenticated Allocate succeeds; relay address returned.
turn_relay_public Relay address is publicly routable.
turn_relay_echo CreatePermission + Send to the probe peer succeed.
turn_channel_bind (optional) ChannelBind exercised via the relay conn.

Most common failures surfaced with a fix

Each failing sub-test carries a Fix field that is rendered prominently in the HTML report (yellow callout at the top of the card and inline with each row). Mapping:

  • UDP/TCP dial timeouts → firewall/NAT guidance
  • TLS handshake errors → certificate reissue guidance (coturn cert=/pkey=)
  • STUN binding returns RFC1918 → external-ip= for coturn
  • Unauthenticated Allocate accepted → enable lt-cred-mech, close the open relay
  • Allocate 401 loop → check NTP (TURN nonces are time-sensitive)
  • Allocate 441 → wrong username/password or wrong REST shared secret
  • Allocate 442 → try different transport or enable it server-side
  • Allocate 486/508 → quota / port-range issues on the server
  • Relay address is private → set relay-ip= to a public IP
  • Relay echo fails → min-port/max-port range not publicly reachable

Rules

Code Description Severity
stun_turn.discovery Verifies that at least one STUN/TURN endpoint could be discovered (explicit URI or SRV lookup). CRITICAL
stun_turn.srv_stun Verifies that at least one STUN endpoint is reachable via SRV (_stun/_stuns) or an explicit URI. WARNING
stun_turn.srv_turn Verifies that at least one TURN endpoint is reachable via SRV (_turn/_turns) or an explicit URI. CRITICAL
stun_turn.dial Verifies that every discovered endpoint accepts a connection (TCP/TLS handshake or UDP socket). CRITICAL
stun_turn.tls_transport Verifies that at least one TLS/DTLS transport (stuns/turns) succeeds when present. CRITICAL
stun_turn.ipv6_coverage Verifies at least one STUN/TURN hostname resolves to an IPv6 address. WARNING
stun_turn.stun_binding Verifies that the STUN Binding request receives a XOR-MAPPED-ADDRESS reply. CRITICAL
stun_turn.reflexive_public Flags endpoints that return a private/loopback reflexive address (server unaware of its public IP). CRITICAL
stun_turn.stun_latency Compares the STUN Binding RTT against the configured warning/critical thresholds. CRITICAL
stun_turn.turn_open_relay Verifies the TURN server requires authentication (challenges unauthenticated Allocate with 401). CRITICAL
stun_turn.turn_auth Verifies the supplied TURN credentials (or REST shared secret) yield a successful Allocate. CRITICAL
stun_turn.relay_public Flags TURN servers whose allocated relay address is private/loopback (missing public relay-ip). CRITICAL
stun_turn.relay_echo Verifies the TURN relay path can carry traffic to the configured probe peer (CreatePermission + Send). WARNING

Usage

Build and run:

make           # standalone binary
make plugin    # .so plugin for happyDomain
./checker-stun-turn -listen :8080

Trigger a check:

curl -sX POST localhost:8080/collect -H 'content-type: application/json' -d '{
  "options": {
    "zone": "example.com",
    "serverURI": "turns:turn.example.com:5349?transport=tcp",
    "mode": "turn",
    "username": "alice",
    "credential": "s3cret",
    "transports": "udp,tcp,tls",
    "probePeer": "1.1.1.1:53",
    "timeout": 5
  }
}' | jq .

Options

Scope Option Type Default Notes
run zone string (auto-filled) used for _stun._udp / _turn._udp / _turns._tcp SRV discovery
run serverURI string explicit URI, RFC 7064/7065
run mode choice auto stun, turn, auto
user username string long-term credentials
user credential secret long-term credentials
user sharedSecret secret REST-API auth (draft-uberti), takes precedence
user realm string optional explicit realm
user transports string udp,tcp,tls comma-separated among udp,tcp,tls,dtls
user probePeer string 1.1.1.1:53 target for the relay echo test
user testChannelBind bool false
user warningRTT uint 200 ms
user criticalRTT uint 1000 ms
user timeout uint 5 s per-probe

License

MIT (see LICENSE).