{ config, pkgs, ... }: { sops.secrets."coturn/auth_secret_vps" = { sopsFile = ./secrets/coturn_vps.yaml; mode = "0400"; owner = "turnserver"; group = "turnserver"; }; security.acme.certs."turn.ellie.town" = { webroot = "/var/lib/acme/acme-challenges"; }; networking.firewall = { allowedUDPPorts = [ 5349 ]; allowedTCPPorts = [ 5349 ]; allowedUDPPortRanges = [ { from = 50201; to = 65535; } ]; }; services.coturn = { enable = true; realm = "turn.ellie.town"; use-auth-secret = true; static-auth-secret-file = config.sops.secrets."coturn/auth_secret_vps".path; cert = "/var/lib/acme/turn.ellie.town/fullchain.pem"; pkey = "/var/lib/acme/turn.ellie.town/key.pem"; listening-ips = [ "0.0.0.0" "::" ]; listening-port = 3478; tls-listening-port = 5349; # Plain TURN disabled; only TURNS on 5349 is reachable. no-udp = true; no-tcp = true; lt-cred-mech = true; no-tcp-relay = true; # Stay above LiveKit's 50000-50200 UDP range (services/livekit.nix). min-port = 50201; max-port = 65535; }; services.nginx = { virtualHosts."turn.ellie.town" = { locations."/.well-known/acme-challenge/" = { root = "/var/lib/acme/acme-challenges"; }; }; }; }