Self-host your own digital island
1{ config, pkgs, lib, ... }:
2
3with lib;
4let
5 cfg = config.eilean;
6 domain = config.networking.domain;
7in
8{
9 options.eilean.turn = {
10 enable = mkEnableOption "TURN server";
11 secretFile = mkOption {
12 type = types.nullOr types.str;
13 default = null;
14 };
15 };
16
17 config = mkIf cfg.turn.enable {
18 services.coturn = rec {
19 enable = true;
20 no-cli = true;
21 no-tcp-relay = true;
22 secure-stun = true;
23 use-auth-secret = true;
24 static-auth-secret-file = "${cfg.turn.secretFile}";
25 realm = "turn.${domain}";
26 relay-ips = with config.eilean; [
27 serverIpv4
28 serverIpv6
29 ];
30 cert = "${config.security.acme.certs.${realm}.directory}/full.pem";
31 pkey = "${config.security.acme.certs.${realm}.directory}/key.pem";
32 };
33
34 networking.firewall =
35 with config.services.coturn;
36 let
37 turn-range = {
38 from = min-port;
39 to = max-port;
40 };
41 stun-ports = [
42 listening-port
43 tls-listening-port
44 # these are only used if server has more than one IP address (of the same family
45 #alt-listening-port
46 #alt-tls-listening-port
47 ];
48 in {
49 allowedTCPPorts = stun-ports;
50 allowedTCPPortRanges = [ turn-range ];
51 allowedUDPPorts = stun-ports;
52 allowedUDPPortRanges = [ turn-range ];
53 };
54
55 security.acme.certs.${config.services.coturn.realm} = {
56 postRun = "systemctl reload nginx.service; systemctl restart coturn.service";
57 group = "turnserver";
58 };
59 services.nginx.enable = true;
60 services.nginx.virtualHosts = {
61 "${config.services.coturn.realm}" = {
62 forceSSL = true;
63 enableACME = true;
64 };
65 };
66 users.groups."turnserver".members = [ config.services.nginx.user ];
67
68 eilean.dns.enable = true;
69 eilean.services.dns.zones.${config.networking.domain}.records = [
70 {
71 name = "turn";
72 type = "CNAME";
73 data = "vps";
74 }
75 ];
76 };
77}