I spent more hours than I’d like to admit to try and get coturn to work with continuwuity.
I have had coturn set up for a while, together with jitsi on the same server, and a matrix server elsewhere. Up until a couple of weeks ago, everything was working just fine; now, only jitsi+coturn is working correctly. I cannot figure out what the issue is with continuwuity.
Here’s the relevant coturn config:
{
config,
private-settings,
secrets,
...
}:
let
inherit (private-settings) domains gsv;
in
{
age.secrets.turn = {
rekeyFile = secrets.gsv-turn;
owner = "turnserver";
};
services.coturn = {
enable = true;
realm = "turn.${domains.blog}";
listening-ips = [ "0.0.0.0" ];
listening-port = 3478;
tls-listening-port = 3480;
relay-ips = [ gsv.ip ];
min-port = 49152;
max-port = 65535;
cert = "${config.security.acme.certs."turn.${domains.blog}".directory}/fullchain.pem";
pkey = "${config.security.acme.certs."turn.${domains.blog}".directory}/key.pem";
# no-auth = true;
no-tcp = true;
secure-stun = true;
# lt-cred-mech = true;
use-auth-secret = true;
static-auth-secret-file = config.age.secrets.turn.path;
extraConfig = ''
no-multicast-peers
total-quota=50
'';
};
# allow coturn to read certificate files
users.users.turnserver.extraGroups = [ "nginx" ];
services.nginx.virtualHosts = {
"turn.${domains.blog}" = {
forceSSL = true;
enableACME = true;
};
};
security.acme.certs = {
"turn.${domains.blog}" = {
postRun = "systemctl reload nginx.service; systemctl restart coturn.service";
};
};
networking.firewall.allowedTCPPorts = [
config.services.coturn.listening-port
config.services.coturn.tls-listening-port
];
networking.firewall.allowedUDPPorts = [
config.services.coturn.listening-port
config.services.coturn.tls-listening-port
];
networking.firewall.allowedUDPPortRanges = [
{
from = config.services.coturn.min-port;
to = config.services.coturn.max-port;
}
];
}
and here’s the relevant continuwuity excerpt:
turn_uris =
let
coturn = outputs.nixosConfigurations.gsv.config.services.coturn;
in
[
"turns:turn.${domains.blog}:${builtins.toString coturn.tls-listening-port}?transport=udp"
"turns:turn.${domains.blog}:${builtins.toString coturn.tls-listening-port}?transport=tcp"
"turn:turn.${domains.blog}:${builtins.toString coturn.listening-port}?transport=udp"
"turn:turn.${domains.blog}:${builtins.toString coturn.listening-port}?transport=tcp"
];
turn_secret_file = config.age.secrets.turn.path;
I should note that if I remove use-auth-secret and static-auth-secret-file and set no-auth = true; in the coturn config, everything works like a charm. That leads me to be pretty certain that the issue is closely related to the auth mechanism. I just… can’t find how.
Any help would be more than appreciated.
Edit: completely forgot to add: the symptom in matrix is that if both clients are not in the same local network, then calls ring alright, but accepting the call leads to “Call connecting…” which never gets resolved. At the same time, the coturn logs will contain:
Sep 15 20:45:11 gsv turnserver[3372392]: 46: (3372458): ERROR: session 004000000000000003: check_stun_auth: Cannot find credentials of user <1758036189:@user:matrix.<domain>>