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