Skip to content
All posts
5 min readcommit 1156e30

We ran an open TURN relay for 45 minutes

A file-permission change meant our TURN server silently ignored its own configuration and fell back to defaults. One warning line, no authentication.


During the migration we moved coturn onto the same host as everything else and wrote its configuration file with mode 0600, on the reasonable-sounding grounds that it contains a shared secret.

coturn runs as an unprivileged user. It could not read a root-owned file with those permissions, logged a single warning about it, and started anyway on its compiled-in defaults.

What defaults meant

  • No external-ip, so the relay advertised an address no client could reach — every relayed call was silent
  • No authentication, so anyone who found the port could relay traffic through it

The first symptom is what got our attention: calls that needed a relay had no audio. The second was the actual problem, and we would not have gone looking for it if the first had not been broken too.

A config file the process cannot read does not fail loudly. It produces a working process with different behaviour.

The fix, and the wider lesson

The file is 0644, which is correct for a file whose owning process runs unprivileged, and the secret in it is scoped to the relay. We also fixed the peer allowlist, which had been written against a private address while the media server advertises its public one.

What was at risk

A TURN server relays media it cannot read. WebRTC traffic is encrypted end to end with DTLS-SRTP, and the relay sits outside that: it forwards packets without holding the keys. So the exposure here was our bandwidth and our relay capacity, not conversations, transcripts or credentials.

We are not going to claim nobody used it. The window was roughly 45 minutes on a host that had been serving traffic for less than a day, and we have no evidence either way — which is the honest position rather than a reassuring one.

The habit worth taking from this is not about coturn. It is that hardening a service can break it in a direction that still looks like it is running. We tightened a permission, the process could no longer read its own security configuration, and the result was less secure than before we started.

This is the platform that broke

Voxera runs WebRTC transport, streaming speech-to-text, your model and text-to-speech as one pipeline — including the parts described above, now that they work.