at 17.09-beta 12 kB view raw
1{ config, lib, pkgs, ... }: 2with lib; 3let 4 cfg = config.services.coturn; 5 pidfile = "/run/turnserver/turnserver.pid"; 6 configFile = pkgs.writeText "turnserver.conf" '' 7listening-port=${toString cfg.listening-port} 8tls-listening-port=${toString cfg.tls-listening-port} 9alt-listening-port=${toString cfg.alt-listening-port} 10alt-tls-listening-port=${toString cfg.alt-tls-listening-port} 11${concatStringsSep "\n" (map (x: "listening-ip=${x}") cfg.listening-ips)} 12${concatStringsSep "\n" (map (x: "relay-ip=${x}") cfg.relay-ips)} 13min-port=${toString cfg.min-port} 14max-port=${toString cfg.max-port} 15${lib.optionalString cfg.lt-cred-mech "lt-cred-mech"} 16${lib.optionalString cfg.no-auth "no-auth"} 17${lib.optionalString cfg.use-auth-secret "use-auth-secret"} 18${lib.optionalString (cfg.static-auth-secret != null) ("static-auth-secret=${cfg.static-auth-secret}")} 19realm=${cfg.realm} 20${lib.optionalString cfg.no-udp "no-udp"} 21${lib.optionalString cfg.no-tcp "no-tcp"} 22${lib.optionalString cfg.no-tls "no-tls"} 23${lib.optionalString cfg.no-dtls "no-dtls"} 24${lib.optionalString cfg.no-udp-relay "no-udp-relay"} 25${lib.optionalString cfg.no-tcp-relay "no-tcp-relay"} 26${lib.optionalString (cfg.cert != null) "cert=${cfg.cert}"} 27${lib.optionalString (cfg.pkey != null) "pkey=${cfg.pkey}"} 28${lib.optionalString (cfg.dh-file != null) ("dh-file=${cfg.dh-file}")} 29no-stdout-log 30syslog 31pidfile=${pidfile} 32${lib.optionalString cfg.secure-stun "secure-stun"} 33${lib.optionalString cfg.no-cli "no-cli"} 34cli-ip=${cfg.cli-ip} 35cli-port=${toString cfg.cli-port} 36${lib.optionalString (cfg.cli-password != null) ("cli-password=${cfg.cli-password}")} 37${cfg.extraConfig} 38''; 39in { 40 options = { 41 services.coturn = { 42 enable = mkEnableOption "coturn TURN server"; 43 listening-port = mkOption { 44 type = types.int; 45 default = 3478; 46 description = '' 47 TURN listener port for UDP and TCP. 48 Note: actually, TLS and DTLS sessions can connect to the 49 "plain" TCP and UDP port(s), too - if allowed by configuration. 50 ''; 51 }; 52 tls-listening-port = mkOption { 53 type = types.int; 54 default = 5349; 55 description = '' 56 TURN listener port for TLS. 57 Note: actually, "plain" TCP and UDP sessions can connect to the TLS and 58 DTLS port(s), too - if allowed by configuration. The TURN server 59 "automatically" recognizes the type of traffic. Actually, two listening 60 endpoints (the "plain" one and the "tls" one) are equivalent in terms of 61 functionality; but we keep both endpoints to satisfy the RFC 5766 specs. 62 For secure TCP connections, we currently support SSL version 3 and 63 TLS version 1.0, 1.1 and 1.2. 64 For secure UDP connections, we support DTLS version 1. 65 ''; 66 }; 67 alt-listening-port = mkOption { 68 type = types.int; 69 default = cfg.listening-port + 1; 70 defaultText = "listening-port + 1"; 71 description = '' 72 Alternative listening port for UDP and TCP listeners; 73 default (or zero) value means "listening port plus one". 74 This is needed for RFC 5780 support 75 (STUN extension specs, NAT behavior discovery). The TURN Server 76 supports RFC 5780 only if it is started with more than one 77 listening IP address of the same family (IPv4 or IPv6). 78 RFC 5780 is supported only by UDP protocol, other protocols 79 are listening to that endpoint only for "symmetry". 80 ''; 81 }; 82 alt-tls-listening-port = mkOption { 83 type = types.int; 84 default = cfg.tls-listening-port + 1; 85 defaultText = "tls-listening-port + 1"; 86 description = '' 87 Alternative listening port for TLS and DTLS protocols. 88 ''; 89 }; 90 listening-ips = mkOption { 91 type = types.listOf types.str; 92 default = []; 93 example = [ "203.0.113.42" "2001:DB8::42" ]; 94 description = '' 95 Listener IP addresses of relay server. 96 If no IP(s) specified in the config file or in the command line options, 97 then all IPv4 and IPv6 system IPs will be used for listening. 98 ''; 99 }; 100 relay-ips = mkOption { 101 type = types.listOf types.str; 102 default = []; 103 example = [ "203.0.113.42" "2001:DB8::42" ]; 104 description = '' 105 Relay address (the local IP address that will be used to relay the 106 packets to the peer). 107 Multiple relay addresses may be used. 108 The same IP(s) can be used as both listening IP(s) and relay IP(s). 109 110 If no relay IP(s) specified, then the turnserver will apply the default 111 policy: it will decide itself which relay addresses to be used, and it 112 will always be using the client socket IP address as the relay IP address 113 of the TURN session (if the requested relay address family is the same 114 as the family of the client socket). 115 ''; 116 }; 117 min-port = mkOption { 118 type = types.int; 119 default = 49152; 120 description = '' 121 Lower bound of UDP relay endpoints 122 ''; 123 }; 124 max-port = mkOption { 125 type = types.int; 126 default = 65535; 127 description = '' 128 Upper bound of UDP relay endpoints 129 ''; 130 }; 131 lt-cred-mech = mkOption { 132 type = types.bool; 133 default = false; 134 description = '' 135 Use long-term credential mechanism. 136 ''; 137 }; 138 no-auth = mkOption { 139 type = types.bool; 140 default = false; 141 description = '' 142 This option is opposite to lt-cred-mech. 143 (TURN Server with no-auth option allows anonymous access). 144 If neither option is defined, and no users are defined, 145 then no-auth is default. If at least one user is defined, 146 in this file or in command line or in usersdb file, then 147 lt-cred-mech is default. 148 ''; 149 }; 150 use-auth-secret = mkOption { 151 type = types.bool; 152 default = false; 153 description = '' 154 TURN REST API flag. 155 Flag that sets a special authorization option that is based upon authentication secret. 156 This feature can be used with the long-term authentication mechanism, only. 157 This feature purpose is to support "TURN Server REST API", see 158 "TURN REST API" link in the project's page 159 https://github.com/coturn/coturn/ 160 161 This option is used with timestamp: 162 163 usercombo -> "timestamp:userid" 164 turn user -> usercombo 165 turn password -> base64(hmac(secret key, usercombo)) 166 167 This allows TURN credentials to be accounted for a specific user id. 168 If you don't have a suitable id, the timestamp alone can be used. 169 This option is just turning on secret-based authentication. 170 The actual value of the secret is defined either by option static-auth-secret, 171 or can be found in the turn_secret table in the database. 172 ''; 173 }; 174 static-auth-secret = mkOption { 175 type = types.nullOr types.str; 176 default = null; 177 description = '' 178 'Static' authentication secret value (a string) for TURN REST API only. 179 If not set, then the turn server 180 will try to use the 'dynamic' value in turn_secret table 181 in user database (if present). The database-stored value can be changed on-the-fly 182 by a separate program, so this is why that other mode is 'dynamic'. 183 ''; 184 }; 185 realm = mkOption { 186 type = types.str; 187 default = config.networking.hostName; 188 example = "example.com"; 189 description = '' 190 The default realm to be used for the users when no explicit 191 origin/realm relationship was found in the database, or if the TURN 192 server is not using any database (just the commands-line settings 193 and the userdb file). Must be used with long-term credentials 194 mechanism or with TURN REST API. 195 ''; 196 }; 197 cert = mkOption { 198 type = types.nullOr types.str; 199 default = null; 200 example = "/var/lib/acme/example.com/fullchain.pem"; 201 description = '' 202 Certificate file in PEM format. 203 ''; 204 }; 205 pkey = mkOption { 206 type = types.nullOr types.str; 207 default = null; 208 example = "/var/lib/acme/example.com/key.pem"; 209 description = '' 210 Private key file in PEM format. 211 ''; 212 }; 213 dh-file = mkOption { 214 type = types.nullOr types.str; 215 default = null; 216 description = '' 217 Use custom DH TLS key, stored in PEM format in the file. 218 ''; 219 }; 220 secure-stun = mkOption { 221 type = types.bool; 222 default = false; 223 description = '' 224 Require authentication of the STUN Binding request. 225 By default, the clients are allowed anonymous access to the STUN Binding functionality. 226 ''; 227 }; 228 no-cli = mkOption { 229 type = types.bool; 230 default = false; 231 description = '' 232 Turn OFF the CLI support. 233 ''; 234 }; 235 cli-ip = mkOption { 236 type = types.str; 237 default = "127.0.0.1"; 238 description = '' 239 Local system IP address to be used for CLI server endpoint. 240 ''; 241 }; 242 cli-port = mkOption { 243 type = types.int; 244 default = 5766; 245 description = '' 246 CLI server port. 247 ''; 248 }; 249 cli-password = mkOption { 250 type = types.nullOr types.str; 251 default = null; 252 description = '' 253 CLI access password. 254 For the security reasons, it is recommended to use the encrypted 255 for of the password (see the -P command in the turnadmin utility). 256 ''; 257 }; 258 no-udp = mkOption { 259 type = types.bool; 260 default = false; 261 description = "Disable UDP client listener"; 262 }; 263 no-tcp = mkOption { 264 type = types.bool; 265 default = false; 266 description = "Disable TCP client listener"; 267 }; 268 no-tls = mkOption { 269 type = types.bool; 270 default = false; 271 description = "Disable TLS client listener"; 272 }; 273 no-dtls = mkOption { 274 type = types.bool; 275 default = false; 276 description = "Disable DTLS client listener"; 277 }; 278 no-udp-relay = mkOption { 279 type = types.bool; 280 default = false; 281 description = "Disable UDP relay endpoints"; 282 }; 283 no-tcp-relay = mkOption { 284 type = types.bool; 285 default = false; 286 description = "Disable TCP relay endpoints"; 287 }; 288 extraConfig = mkOption { 289 type = types.lines; 290 default = ""; 291 description = "Additional configuration options"; 292 }; 293 }; 294 }; 295 296 config = mkIf cfg.enable { 297 users.extraUsers = [ 298 { name = "turnserver"; 299 uid = config.ids.uids.turnserver; 300 description = "coturn TURN server user"; 301 } ]; 302 users.extraGroups = [ 303 { name = "turnserver"; 304 gid = config.ids.gids.turnserver; 305 members = [ "turnserver" ]; 306 } ]; 307 308 systemd.services.coturn = { 309 description = "coturn TURN server"; 310 after = [ "network.target" ]; 311 wantedBy = [ "multi-user.target" ]; 312 313 unitConfig = { 314 Documentation = "man:coturn(1) man:turnadmin(1) man:turnserver(1)"; 315 }; 316 317 serviceConfig = { 318 Type = "simple"; 319 ExecStart = "${pkgs.coturn}/bin/turnserver -c ${configFile}"; 320 RuntimeDirectory = "turnserver"; 321 User = "turnserver"; 322 Group = "turnserver"; 323 AmbientCapabilities = 324 mkIf ( 325 cfg.listening-port < 1024 || 326 cfg.alt-listening-port < 1024 || 327 cfg.tls-listening-port < 1024 || 328 cfg.alt-tls-listening-port < 1024 || 329 cfg.min-port < 1024 330 ) "cap_net_bind_service"; 331 Restart = "on-abort"; 332 }; 333 }; 334 }; 335}