328 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
		
		
			
		
	
	
			328 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
| 
								 | 
							
								{ config, lib, pkgs, ... }:
							 | 
						||
| 
								 | 
							
								with lib;
							 | 
						||
| 
								 | 
							
								let
							 | 
						||
| 
								 | 
							
								  cfg = config.services.coturn;
							 | 
						||
| 
								 | 
							
								  pidfile = "/run/turnserver/turnserver.pid";
							 | 
						||
| 
								 | 
							
								  configFile = pkgs.writeText "turnserver.conf" ''
							 | 
						||
| 
								 | 
							
								listening-port=${toString cfg.listening-port}
							 | 
						||
| 
								 | 
							
								tls-listening-port=${toString cfg.tls-listening-port}
							 | 
						||
| 
								 | 
							
								alt-listening-port=${toString cfg.alt-listening-port}
							 | 
						||
| 
								 | 
							
								alt-tls-listening-port=${toString cfg.alt-tls-listening-port}
							 | 
						||
| 
								 | 
							
								${concatStringsSep "\n" (map (x: "listening-ip=${x}") cfg.listening-ips)}
							 | 
						||
| 
								 | 
							
								${concatStringsSep "\n" (map (x: "relay-ip=${x}") cfg.relay-ips)}
							 | 
						||
| 
								 | 
							
								min-port=${toString cfg.min-port}
							 | 
						||
| 
								 | 
							
								max-port=${toString cfg.max-port}
							 | 
						||
| 
								 | 
							
								${lib.optionalString cfg.lt-cred-mech "lt-cred-mech"}
							 | 
						||
| 
								 | 
							
								${lib.optionalString cfg.no-auth "no-auth"}
							 | 
						||
| 
								 | 
							
								${lib.optionalString cfg.use-auth-secret "use-auth-secret"}
							 | 
						||
| 
								 | 
							
								${lib.optionalString (cfg.static-auth-secret != null) ("static-auth-secret=${cfg.static-auth-secret}")}
							 | 
						||
| 
								 | 
							
								realm=${cfg.realm}
							 | 
						||
| 
								 | 
							
								${lib.optionalString cfg.no-udp "no-udp"}
							 | 
						||
| 
								 | 
							
								${lib.optionalString cfg.no-tcp "no-tcp"}
							 | 
						||
| 
								 | 
							
								${lib.optionalString cfg.no-tls "no-tls"}
							 | 
						||
| 
								 | 
							
								${lib.optionalString cfg.no-dtls "no-dtls"}
							 | 
						||
| 
								 | 
							
								${lib.optionalString cfg.no-udp-relay "no-udp-relay"}
							 | 
						||
| 
								 | 
							
								${lib.optionalString cfg.no-tcp-relay "no-tcp-relay"}
							 | 
						||
| 
								 | 
							
								${lib.optionalString (cfg.cert != null) "cert=${cfg.cert}"}
							 | 
						||
| 
								 | 
							
								${lib.optionalString (cfg.pkey != null) "pkey=${cfg.pkey}"}
							 | 
						||
| 
								 | 
							
								${lib.optionalString (cfg.dh-file != null) ("dh-file=${cfg.dh-file}")}
							 | 
						||
| 
								 | 
							
								no-stdout-log
							 | 
						||
| 
								 | 
							
								syslog
							 | 
						||
| 
								 | 
							
								pidfile=${pidfile}
							 | 
						||
| 
								 | 
							
								${lib.optionalString cfg.secure-stun "secure-stun"}
							 | 
						||
| 
								 | 
							
								${lib.optionalString cfg.no-cli "no-cli"}
							 | 
						||
| 
								 | 
							
								cli-ip=${cfg.cli-ip}
							 | 
						||
| 
								 | 
							
								cli-port=${toString cfg.cli-port}
							 | 
						||
| 
								 | 
							
								${lib.optionalString (cfg.cli-password != null) ("cli-password=${cfg.cli-password}")}
							 | 
						||
| 
								 | 
							
								${cfg.extraConfig}
							 | 
						||
| 
								 | 
							
								'';
							 | 
						||
| 
								 | 
							
								in {
							 | 
						||
| 
								 | 
							
								  options = {
							 | 
						||
| 
								 | 
							
								    services.coturn = {
							 | 
						||
| 
								 | 
							
								      enable = mkEnableOption "coturn TURN server";
							 | 
						||
| 
								 | 
							
								      listening-port = mkOption {
							 | 
						||
| 
								 | 
							
								        type = types.int;
							 | 
						||
| 
								 | 
							
								        default = 3478;
							 | 
						||
| 
								 | 
							
								        description = ''
							 | 
						||
| 
								 | 
							
								          TURN listener port for UDP and TCP.
							 | 
						||
| 
								 | 
							
								          Note: actually, TLS and DTLS sessions can connect to the
							 | 
						||
| 
								 | 
							
								          "plain" TCP and UDP port(s), too - if allowed by configuration.
							 | 
						||
| 
								 | 
							
								        '';
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								      tls-listening-port = mkOption {
							 | 
						||
| 
								 | 
							
								        type = types.int;
							 | 
						||
| 
								 | 
							
								        default = 5349;
							 | 
						||
| 
								 | 
							
								        description = ''
							 | 
						||
| 
								 | 
							
								          TURN listener port for TLS.
							 | 
						||
| 
								 | 
							
								          Note: actually, "plain" TCP and UDP sessions can connect to the TLS and
							 | 
						||
| 
								 | 
							
								          DTLS port(s), too - if allowed by configuration. The TURN server
							 | 
						||
| 
								 | 
							
								          "automatically" recognizes the type of traffic. Actually, two listening
							 | 
						||
| 
								 | 
							
								          endpoints (the "plain" one and the "tls" one) are equivalent in terms of
							 | 
						||
| 
								 | 
							
								          functionality; but we keep both endpoints to satisfy the RFC 5766 specs.
							 | 
						||
| 
								 | 
							
								          For secure TCP connections, we currently support SSL version 3 and
							 | 
						||
| 
								 | 
							
								          TLS version 1.0, 1.1 and 1.2.
							 | 
						||
| 
								 | 
							
								          For secure UDP connections, we support DTLS version 1.
							 | 
						||
| 
								 | 
							
								        '';
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								      alt-listening-port = mkOption {
							 | 
						||
| 
								 | 
							
								        type = types.int;
							 | 
						||
| 
								 | 
							
								        default = cfg.listening-port + 1;
							 | 
						||
| 
								 | 
							
								        defaultText = "listening-port + 1";
							 | 
						||
| 
								 | 
							
								        description = ''
							 | 
						||
| 
								 | 
							
								          Alternative listening port for UDP and TCP listeners;
							 | 
						||
| 
								 | 
							
								          default (or zero) value means "listening port plus one".
							 | 
						||
| 
								 | 
							
								          This is needed for RFC 5780 support
							 | 
						||
| 
								 | 
							
								          (STUN extension specs, NAT behavior discovery). The TURN Server
							 | 
						||
| 
								 | 
							
								          supports RFC 5780 only if it is started with more than one
							 | 
						||
| 
								 | 
							
								          listening IP address of the same family (IPv4 or IPv6).
							 | 
						||
| 
								 | 
							
								          RFC 5780 is supported only by UDP protocol, other protocols
							 | 
						||
| 
								 | 
							
								          are listening to that endpoint only for "symmetry".
							 | 
						||
| 
								 | 
							
								        '';
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								      alt-tls-listening-port = mkOption {
							 | 
						||
| 
								 | 
							
								        type = types.int;
							 | 
						||
| 
								 | 
							
								        default = cfg.tls-listening-port + 1;
							 | 
						||
| 
								 | 
							
								        defaultText = "tls-listening-port + 1";
							 | 
						||
| 
								 | 
							
								        description = ''
							 | 
						||
| 
								 | 
							
								          Alternative listening port for TLS and DTLS protocols.
							 | 
						||
| 
								 | 
							
								        '';
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								      listening-ips = mkOption {
							 | 
						||
| 
								 | 
							
								        type = types.listOf types.str;
							 | 
						||
| 
								 | 
							
								        default = [];
							 | 
						||
| 
								 | 
							
								        example = [ "203.0.113.42" "2001:DB8::42" ];
							 | 
						||
| 
								 | 
							
								        description = ''
							 | 
						||
| 
								 | 
							
								          Listener IP addresses of relay server.
							 | 
						||
| 
								 | 
							
								          If no IP(s) specified in the config file or in the command line options,
							 | 
						||
| 
								 | 
							
								          then all IPv4 and IPv6 system IPs will be used for listening.
							 | 
						||
| 
								 | 
							
								        '';
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								      relay-ips = mkOption {
							 | 
						||
| 
								 | 
							
								        type = types.listOf types.str;
							 | 
						||
| 
								 | 
							
								        default = [];
							 | 
						||
| 
								 | 
							
								        example = [ "203.0.113.42" "2001:DB8::42" ];
							 | 
						||
| 
								 | 
							
								        description = ''
							 | 
						||
| 
								 | 
							
								          Relay address (the local IP address that will be used to relay the
							 | 
						||
| 
								 | 
							
								          packets to the peer).
							 | 
						||
| 
								 | 
							
								          Multiple relay addresses may be used.
							 | 
						||
| 
								 | 
							
								          The same IP(s) can be used as both listening IP(s) and relay IP(s).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          If no relay IP(s) specified, then the turnserver will apply the default
							 | 
						||
| 
								 | 
							
								          policy: it will decide itself which relay addresses to be used, and it
							 | 
						||
| 
								 | 
							
								          will always be using the client socket IP address as the relay IP address
							 | 
						||
| 
								 | 
							
								          of the TURN session (if the requested relay address family is the same
							 | 
						||
| 
								 | 
							
								          as the family of the client socket).
							 | 
						||
| 
								 | 
							
								        '';
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								      min-port = mkOption {
							 | 
						||
| 
								 | 
							
								        type = types.int;
							 | 
						||
| 
								 | 
							
								        default = 49152;
							 | 
						||
| 
								 | 
							
								        description = ''
							 | 
						||
| 
								 | 
							
								          Lower bound of UDP relay endpoints
							 | 
						||
| 
								 | 
							
								        '';
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								      max-port = mkOption {
							 | 
						||
| 
								 | 
							
								        type = types.int;
							 | 
						||
| 
								 | 
							
								        default = 65535;
							 | 
						||
| 
								 | 
							
								        description = ''
							 | 
						||
| 
								 | 
							
								          Upper bound of UDP relay endpoints
							 | 
						||
| 
								 | 
							
								        '';
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								      lt-cred-mech = mkOption {
							 | 
						||
| 
								 | 
							
								        type = types.bool;
							 | 
						||
| 
								 | 
							
								        default = false;
							 | 
						||
| 
								 | 
							
								        description = ''
							 | 
						||
| 
								 | 
							
								          Use long-term credential mechanism.
							 | 
						||
| 
								 | 
							
								        '';
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								      no-auth = mkOption {
							 | 
						||
| 
								 | 
							
								        type = types.bool;
							 | 
						||
| 
								 | 
							
								        default = false;
							 | 
						||
| 
								 | 
							
								        description = ''
							 | 
						||
| 
								 | 
							
								          This option is opposite to lt-cred-mech.
							 | 
						||
| 
								 | 
							
								          (TURN Server with no-auth option allows anonymous access).
							 | 
						||
| 
								 | 
							
								          If neither option is defined, and no users are defined,
							 | 
						||
| 
								 | 
							
								          then no-auth is default. If at least one user is defined,
							 | 
						||
| 
								 | 
							
								          in this file or in command line or in usersdb file, then
							 | 
						||
| 
								 | 
							
								          lt-cred-mech is default.
							 | 
						||
| 
								 | 
							
								        '';
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								      use-auth-secret = mkOption {
							 | 
						||
| 
								 | 
							
								        type = types.bool;
							 | 
						||
| 
								 | 
							
								        default = false;
							 | 
						||
| 
								 | 
							
								        description = ''
							 | 
						||
| 
								 | 
							
								          TURN REST API flag.
							 | 
						||
| 
								 | 
							
								          Flag that sets a special authorization option that is based upon authentication secret.
							 | 
						||
| 
								 | 
							
								          This feature can be used with the long-term authentication mechanism, only.
							 | 
						||
| 
								 | 
							
								          This feature purpose is to support "TURN Server REST API", see
							 | 
						||
| 
								 | 
							
								          "TURN REST API" link in the project's page
							 | 
						||
| 
								 | 
							
								          https://github.com/coturn/coturn/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          This option is used with timestamp:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          usercombo -> "timestamp:userid"
							 | 
						||
| 
								 | 
							
								          turn user -> usercombo
							 | 
						||
| 
								 | 
							
								          turn password -> base64(hmac(secret key, usercombo))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          This allows TURN credentials to be accounted for a specific user id.
							 | 
						||
| 
								 | 
							
								          If you don't have a suitable id, the timestamp alone can be used.
							 | 
						||
| 
								 | 
							
								          This option is just turning on secret-based authentication.
							 | 
						||
| 
								 | 
							
								          The actual value of the secret is defined either by option static-auth-secret,
							 | 
						||
| 
								 | 
							
								          or can be found in the turn_secret table in the database.
							 | 
						||
| 
								 | 
							
								        '';
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								      static-auth-secret = mkOption {
							 | 
						||
| 
								 | 
							
								        type = types.nullOr types.str;
							 | 
						||
| 
								 | 
							
								        default = null;
							 | 
						||
| 
								 | 
							
								        description = ''
							 | 
						||
| 
								 | 
							
								          'Static' authentication secret value (a string) for TURN REST API only.
							 | 
						||
| 
								 | 
							
								          If not set, then the turn server
							 | 
						||
| 
								 | 
							
								          will try to use the 'dynamic' value in turn_secret table
							 | 
						||
| 
								 | 
							
								          in user database (if present). The database-stored  value can be changed on-the-fly
							 | 
						||
| 
								 | 
							
								          by a separate program, so this is why that other mode is 'dynamic'.
							 | 
						||
| 
								 | 
							
								        '';
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								      realm = mkOption {
							 | 
						||
| 
								 | 
							
								        type = types.str;
							 | 
						||
| 
								 | 
							
								        default = config.networking.hostName;
							 | 
						||
| 
								 | 
							
								        example = "example.com";
							 | 
						||
| 
								 | 
							
								        description = ''
							 | 
						||
| 
								 | 
							
								          The default realm to be used for the users when no explicit
							 | 
						||
| 
								 | 
							
								          origin/realm relationship was found in the database, or if the TURN
							 | 
						||
| 
								 | 
							
								          server is not using any database (just the commands-line settings
							 | 
						||
| 
								 | 
							
								          and the userdb file). Must be used with long-term credentials
							 | 
						||
| 
								 | 
							
								          mechanism or with TURN REST API.
							 | 
						||
| 
								 | 
							
								        '';
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								      cert = mkOption {
							 | 
						||
| 
								 | 
							
								        type = types.nullOr types.str;
							 | 
						||
| 
								 | 
							
								        default = null;
							 | 
						||
| 
								 | 
							
								        example = "/var/lib/acme/example.com/fullchain.pem";
							 | 
						||
| 
								 | 
							
								        description = ''
							 | 
						||
| 
								 | 
							
								          Certificate file in PEM format.
							 | 
						||
| 
								 | 
							
								        '';
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								      pkey = mkOption {
							 | 
						||
| 
								 | 
							
								        type = types.nullOr types.str;
							 | 
						||
| 
								 | 
							
								        default = null;
							 | 
						||
| 
								 | 
							
								        example = "/var/lib/acme/example.com/key.pem";
							 | 
						||
| 
								 | 
							
								        description = ''
							 | 
						||
| 
								 | 
							
								          Private key file in PEM format.
							 | 
						||
| 
								 | 
							
								        '';
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								      dh-file = mkOption {
							 | 
						||
| 
								 | 
							
								        type = types.nullOr types.str;
							 | 
						||
| 
								 | 
							
								        default = null;
							 | 
						||
| 
								 | 
							
								        description = ''
							 | 
						||
| 
								 | 
							
								          Use custom DH TLS key, stored in PEM format in the file.
							 | 
						||
| 
								 | 
							
								        '';
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								      secure-stun = mkOption {
							 | 
						||
| 
								 | 
							
								        type = types.bool;
							 | 
						||
| 
								 | 
							
								        default = false;
							 | 
						||
| 
								 | 
							
								        description = ''
							 | 
						||
| 
								 | 
							
								          Require authentication of the STUN Binding request.
							 | 
						||
| 
								 | 
							
								          By default, the clients are allowed anonymous access to the STUN Binding functionality.
							 | 
						||
| 
								 | 
							
								        '';
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								      no-cli = mkOption {
							 | 
						||
| 
								 | 
							
								        type = types.bool;
							 | 
						||
| 
								 | 
							
								        default = false;
							 | 
						||
| 
								 | 
							
								        description = ''
							 | 
						||
| 
								 | 
							
								          Turn OFF the CLI support.
							 | 
						||
| 
								 | 
							
								        '';
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								      cli-ip = mkOption {
							 | 
						||
| 
								 | 
							
								        type = types.str;
							 | 
						||
| 
								 | 
							
								        default = "127.0.0.1";
							 | 
						||
| 
								 | 
							
								        description = ''
							 | 
						||
| 
								 | 
							
								          Local system IP address to be used for CLI server endpoint.
							 | 
						||
| 
								 | 
							
								        '';
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								      cli-port = mkOption {
							 | 
						||
| 
								 | 
							
								        type = types.int;
							 | 
						||
| 
								 | 
							
								        default = 5766;
							 | 
						||
| 
								 | 
							
								        description = ''
							 | 
						||
| 
								 | 
							
								          CLI server port.
							 | 
						||
| 
								 | 
							
								        '';
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								      cli-password = mkOption {
							 | 
						||
| 
								 | 
							
								        type = types.nullOr types.str;
							 | 
						||
| 
								 | 
							
								        default = null;
							 | 
						||
| 
								 | 
							
								        description = ''
							 | 
						||
| 
								 | 
							
								          CLI access password.
							 | 
						||
| 
								 | 
							
								          For the security reasons, it is recommended to use the encrypted
							 | 
						||
| 
								 | 
							
								          for of the password (see the -P command in the turnadmin utility).
							 | 
						||
| 
								 | 
							
								        '';
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								      no-udp = mkOption {
							 | 
						||
| 
								 | 
							
								        type = types.bool;
							 | 
						||
| 
								 | 
							
								        default = false;
							 | 
						||
| 
								 | 
							
								        description = "Disable UDP client listener";
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								      no-tcp = mkOption {
							 | 
						||
| 
								 | 
							
								        type = types.bool;
							 | 
						||
| 
								 | 
							
								        default = false;
							 | 
						||
| 
								 | 
							
								        description = "Disable TCP client listener";
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								      no-tls = mkOption {
							 | 
						||
| 
								 | 
							
								        type = types.bool;
							 | 
						||
| 
								 | 
							
								        default = false;
							 | 
						||
| 
								 | 
							
								        description = "Disable TLS client listener";
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								      no-dtls = mkOption {
							 | 
						||
| 
								 | 
							
								        type = types.bool;
							 | 
						||
| 
								 | 
							
								        default = false;
							 | 
						||
| 
								 | 
							
								        description = "Disable DTLS client listener";
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								      no-udp-relay = mkOption {
							 | 
						||
| 
								 | 
							
								        type = types.bool;
							 | 
						||
| 
								 | 
							
								        default = false;
							 | 
						||
| 
								 | 
							
								        description = "Disable UDP relay endpoints";
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								      no-tcp-relay = mkOption {
							 | 
						||
| 
								 | 
							
								        type = types.bool;
							 | 
						||
| 
								 | 
							
								        default = false;
							 | 
						||
| 
								 | 
							
								        description = "Disable TCP relay endpoints";
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								      extraConfig = mkOption {
							 | 
						||
| 
								 | 
							
								        type = types.lines;
							 | 
						||
| 
								 | 
							
								        default = "";
							 | 
						||
| 
								 | 
							
								        description = "Additional configuration options";
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  config = mkIf cfg.enable {
							 | 
						||
| 
								 | 
							
								    users.extraUsers = [
							 | 
						||
| 
								 | 
							
								      { name = "turnserver";
							 | 
						||
| 
								 | 
							
								        uid = config.ids.uids.turnserver;
							 | 
						||
| 
								 | 
							
								        description = "coturn TURN server user";
							 | 
						||
| 
								 | 
							
								      } ];
							 | 
						||
| 
								 | 
							
								    users.extraGroups = [
							 | 
						||
| 
								 | 
							
								      { name = "turnserver";
							 | 
						||
| 
								 | 
							
								        gid = config.ids.gids.turnserver;
							 | 
						||
| 
								 | 
							
								        members = [ "turnserver" ];
							 | 
						||
| 
								 | 
							
								      } ];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    systemd.services.coturn = {
							 | 
						||
| 
								 | 
							
								      description = "coturn TURN server";
							 | 
						||
| 
								 | 
							
								      after = [ "network.target" ];
							 | 
						||
| 
								 | 
							
								      wantedBy = [ "multi-user.target" ];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      unitConfig = {
							 | 
						||
| 
								 | 
							
								        Documentation = "man:coturn(1) man:turnadmin(1) man:turnserver(1)";
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      serviceConfig = {
							 | 
						||
| 
								 | 
							
								        Type = "simple";
							 | 
						||
| 
								 | 
							
								        ExecStart = "${pkgs.coturn}/bin/turnserver -c ${configFile}";
							 | 
						||
| 
								 | 
							
								        RuntimeDirectory = "turnserver";
							 | 
						||
| 
								 | 
							
								        User = "turnserver";
							 | 
						||
| 
								 | 
							
								        Group = "turnserver";
							 | 
						||
| 
								 | 
							
								        Restart = "on-abort";
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								}
							 |