Active relay-abuse guard for SRTP-constrained TURN deployments.
What problem this solves
A TURN allocation can carry any UDP/TCP payload the client sends. Attackers sometimes abuse open relays for non-media traffic. This plugin classifies each frame by RFC 7983 first-byte demultiplexing and an RTP payload-type allowlist, then either monitors (telemetry only) or drops rejected frames.
It is drop-only: it never rewrites frames. Changing RTP header bytes would invalidate an SRTP authentication tag (RFC 3711).
Implements Xirsys.XTurn.Plugin in :active mode on both :egress and
:ingress.
Options
:mode-:monitor(default) emits[:xturn, :guard, :reject]telemetry and passes the frame through;:enforcedrops rejected frames.:payload_types- allowed RTP payload types (default[0, 8]for PCMU/PCMA).:match- keyword filter onAllocationfields forattach?/2(default attaches to all).
RFCs
- RFC 7983 (first-byte demux)
- RFC 3550 (RTP/RTCP)
- RFC 5766 (TURN data path)
- RFC 3711 (SRTP; why frames are not rewritten)
Examples
iex> alloc = %Xirsys.XTurn.Plugin.Allocation{}
iex> Xirsys.XTurn.Plugin.Guard.attach?(alloc, [])
true
iex> Xirsys.XTurn.Plugin.Guard.mode()
:active
iex> Xirsys.XTurn.Plugin.Guard.hooks()
[:egress, :ingress]
Summary
Functions
Attach when :match filters are empty or all listed allocation fields match.
Classify payload and optionally drop it.
Inspects both client-to-peer and peer-to-client frames.
Build immutable guard state from options.
Always :active (concurrent, drop-capable).
Functions
Attach when :match filters are empty or all listed allocation fields match.
Classify payload and optionally drop it.
Returns {:ok, payload} when allowed (or when :monitor mode rejects),
or :drop when :enforce mode rejects.
Inspects both client-to-peer and peer-to-client frames.
Build immutable guard state from options.
Raises ArgumentError when :mode is not :monitor or :enforce.
Always :active (concurrent, drop-capable).