Self-host your own digital island
1{ config, pkgs, lib, ... }: 2 3with lib; 4let 5 cfg = config.eilean; 6 domain = config.networking.domain; 7 staticAuthSecretFile = "/run/coturn/static-auth-secret"; 8in 9{ 10 options.eilean.turn = { 11 enable = mkEnableOption "TURN server"; 12 }; 13 14 config = mkIf cfg.turn.enable { 15 services.coturn = rec { 16 enable = true; 17 no-cli = true; 18 no-tcp-relay = true; 19 secure-stun = true; 20 use-auth-secret = true; 21 static-auth-secret-file = staticAuthSecretFile; 22 realm = "turn.${domain}"; 23 relay-ips = with config.eilean; [ 24 serverIpv4 25 serverIpv6 26 ]; 27 cert = "${config.security.acme.certs.${realm}.directory}/full.pem"; 28 pkey = "${config.security.acme.certs.${realm}.directory}/key.pem"; 29 }; 30 31 systemd.services = { 32 coturn-static-auth-secret-generator = { 33 description = "Generate coturn static auth secret file"; 34 script = '' 35 if [ ! -f '${staticAuthSecretFile}' ]; then 36 umask 077 37 tr -dc A-Za-z0-9 </dev/urandom | head -c 32 > '${staticAuthSecretFile}' 38 chown ${config.systemd.services.coturn.serviceConfig.User}:${config.systemd.services.coturn.serviceConfig.Group} '${staticAuthSecretFile}' 39 fi 40 ''; 41 serviceConfig.Type = "oneshot"; 42 serviceConfig.RemainAfterExit = true; 43 }; 44 "coturn" = { 45 after = [ "coturn-static-auth-secret-generator.service" ]; 46 requires = [ "coturn-static-auth-secret-generator.service" ]; 47 }; 48 }; 49 50 networking.firewall = 51 with config.services.coturn; 52 let 53 turn-range = { 54 from = min-port; 55 to = max-port; 56 }; 57 stun-ports = [ 58 listening-port 59 tls-listening-port 60 # these are only used if server has more than one IP address (of the same family 61 #alt-listening-port 62 #alt-tls-listening-port 63 ]; 64 in { 65 allowedTCPPorts = stun-ports; 66 allowedTCPPortRanges = [ turn-range ]; 67 allowedUDPPorts = stun-ports; 68 allowedUDPPortRanges = [ turn-range ]; 69 }; 70 71 security.acme.certs.${config.services.coturn.realm} = { 72 postRun = "systemctl reload nginx.service; systemctl restart coturn.service"; 73 group = "turnserver"; 74 }; 75 services.nginx.enable = true; 76 services.nginx.virtualHosts = { 77 "${config.services.coturn.realm}" = { 78 forceSSL = true; 79 enableACME = true; 80 }; 81 }; 82 users.groups."turnserver".members = [ config.services.nginx.user ]; 83 84 eilean.dns.enable = true; 85 eilean.services.dns.zones.${config.networking.domain}.records = [ 86 { 87 name = "turn"; 88 type = "CNAME"; 89 data = "vps"; 90 } 91 ]; 92 }; 93}