From 37fa40936a846db36be0ad2071cbce4766900e55 Mon Sep 17 00:00:00 2001 From: Max Audron Date: Fri, 26 Dec 2025 17:21:05 +0100 Subject: add teamspeak6 server --- modules/teamspeak/default.nix | 48 ++++++--- modules/teamspeak/teamspeak6-server.nix | 183 ++++++++++++++++++++++++++++++++ pkgs/teamspeak6-server/default.nix | 70 ++++++++++++ 3 files changed, 284 insertions(+), 17 deletions(-) create mode 100644 modules/teamspeak/teamspeak6-server.nix create mode 100644 pkgs/teamspeak6-server/default.nix diff --git a/modules/teamspeak/default.nix b/modules/teamspeak/default.nix index 310eb13..f3e94f7 100644 --- a/modules/teamspeak/default.nix +++ b/modules/teamspeak/default.nix @@ -1,6 +1,8 @@ { config, lib, pkgs, ... }: { + imports = [ ./teamspeak6-server.nix ]; + services.teamspeak3 = let ip = "178.63.224.12"; in @@ -17,22 +19,34 @@ Restart = lib.mkForce "always"; }; }; - - virtualisation.oci-containers.containers = { - teamspeak6-server = { - image = "teamspeaksystems/teamspeak6-server:latest"; - autoStart = true; - ports = [ - "178.63.224.13:9987:9987/udp" # Default voice port - "178.63.224.13:30033:30033/tcp" # File transfer port - ]; - environment = { - TSSERVER_LICENSE_ACCEPTED="accept"; - TSSERVER_DEFAULT_PORT="9987"; - TSSERVER_VOICE_IP="0.0.0.0"; - TSSERVER_FILE_TRANSFER_PORT="30033"; - TSSERVER_FILE_TRANSFER_IP="0.0.0.0"; - }; + + services.teamspeak6 = + let + ip = "178.63.224.13"; in + { + enable = true; + package = pkgs.callPackage ../../pkgs/teamspeak6-server {}; + openFirewall = true; + voiceIP = ip; + queryIP = ip; + fileTransferIP = ip; }; - }; + + # virtualisation.oci-containers.containers = { + # teamspeak6-server = { + # image = "teamspeaksystems/teamspeak6-server:latest"; + # autoStart = true; + # ports = [ + # "178.63.224.13:9987:9987/udp" # Default voice port + # "178.63.224.13:30033:30033/tcp" # File transfer port + # ]; + # environment = { + # TSSERVER_LICENSE_ACCEPTED="accept"; + # TSSERVER_DEFAULT_PORT="9987"; + # TSSERVER_VOICE_IP="0.0.0.0"; + # TSSERVER_FILE_TRANSFER_PORT="30033"; + # TSSERVER_FILE_TRANSFER_IP="0.0.0.0"; + # }; + # }; + # }; } diff --git a/modules/teamspeak/teamspeak6-server.nix b/modules/teamspeak/teamspeak6-server.nix new file mode 100644 index 0000000..b637031 --- /dev/null +++ b/modules/teamspeak/teamspeak6-server.nix @@ -0,0 +1,183 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.teamspeak6; + user = "teamspeak6"; + group = "teamspeak6"; +in +{ + options = { + services.teamspeak6 = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to run the Teamspeak 6 voice communication server daemon. + ''; + }; + + package = mkPackageOption pkgs "teamspeak6-server" {}; + + dataDir = mkOption { + type = types.path; + default = "/var/lib/teamspeak6-server"; + description = '' + Directory to store TS6 database and other state/data files. + ''; + }; + + logPath = mkOption { + type = types.path; + default = "/var/log/teamspeak6-server/"; + description = '' + Directory to store log files in. + ''; + }; + + voiceIP = mkOption { + type = types.nullOr types.str; + default = null; + example = "[::]"; + description = '' + IP on which the server instance will listen for incoming voice connections. Defaults to any IP. + ''; + }; + + defaultVoicePort = mkOption { + type = types.port; + default = 9987; + description = '' + Default UDP port for clients to connect to virtual servers - used for first virtual server, subsequent ones will open on incrementing port numbers by default. + ''; + }; + + fileTransferIP = mkOption { + type = types.nullOr types.str; + default = null; + example = "[::]"; + description = '' + IP on which the server instance will listen for incoming file transfer connections. Defaults to any IP. + ''; + }; + + fileTransferPort = mkOption { + type = types.port; + default = 30033; + description = '' + TCP port opened for file transfers. + ''; + }; + + queryIP = mkOption { + type = types.nullOr types.str; + default = null; + example = "0.0.0.0"; + description = '' + IP on which the server instance will listen for incoming ServerQuery connections. Defaults to any IP. + ''; + }; + + queryPort = mkOption { + type = types.port; + default = 10011; + description = '' + TCP port opened for ServerQuery connections using the raw telnet protocol. + ''; + }; + + querySshPort = mkOption { + type = types.port; + default = 10022; + description = '' + TCP port opened for ServerQuery connections using the SSH protocol. + ''; + }; + + queryHttpPort = mkOption { + type = types.port; + default = 10080; + description = '' + TCP port opened for ServerQuery connections using the HTTP protocol. + ''; + }; + + openFirewall = mkOption { + type = types.bool; + default = false; + description = "Open ports in the firewall for the TeamSpeak3 server."; + }; + + openFirewallServerQuery = mkOption { + type = types.bool; + default = false; + description = "Open ports in the firewall for the TeamSpeak3 serverquery (administration) system. Requires openFirewall."; + }; + }; + }; + + config = mkIf cfg.enable { + users.users."${user}" = { + description = "Teamspeak6 voice communication server daemon"; + group = group; + # uid = config.ids.uids.teamspeak; + home = cfg.dataDir; + createHome = true; + isSystemUser = true; + }; + + users.groups."${group}" = { + # gid = config.ids.gids.teamspeak; + }; + + systemd.tmpfiles.rules = [ + "d '${cfg.logPath}' - ${user} ${group} - -" + ]; + + networking.firewall = mkIf cfg.openFirewall { + allowedTCPPorts = [ + cfg.fileTransferPort + ] + ++ (map (port: mkIf cfg.openFirewallServerQuery port) [ + cfg.queryPort + cfg.querySshPort + cfg.queryHttpPort + ]); + # subsequent vServers will use the incremented voice port, let's just open the next 10 + allowedUDPPortRanges = [ + { + from = cfg.defaultVoicePort; + to = cfg.defaultVoicePort + 10; + } + ]; + }; + + systemd.services.teamspeak6-server = { + description = "Teamspeak6 voice communication server daemon"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + + serviceConfig = { + ExecStart = '' + ${cfg.package}/bin/tsserver \ + --db-sql-path=${cfg.package}/share/teamspeak6-server/sql/ \ + --log-path=${cfg.logPath} \ + --accept-license=1 \ + --default-voice-port=${toString cfg.defaultVoicePort} \ + --filetransfer-port=${toString cfg.fileTransferPort} \ + --query-ssh-port=${toString cfg.querySshPort} \ + --query-http-port=${toString cfg.queryHttpPort} \ + ${optionalString (cfg.voiceIP != null) "--voice-ip=${cfg.voiceIP}"} \ + ${optionalString (cfg.fileTransferIP != null) "--filetransfer-ip=${cfg.fileTransferIP}"} \ + ${optionalString (cfg.queryIP != null) "--query-ssh-ip=${cfg.queryIP}"} \ + ${optionalString (cfg.queryIP != null) "--query-http-ip=${cfg.queryIP}"} \ + ''; + WorkingDirectory = cfg.dataDir; + User = user; + Group = group; + Restart = "on-failure"; + }; + }; + }; +} diff --git a/pkgs/teamspeak6-server/default.nix b/pkgs/teamspeak6-server/default.nix new file mode 100644 index 0000000..050eff6 --- /dev/null +++ b/pkgs/teamspeak6-server/default.nix @@ -0,0 +1,70 @@ +{ + lib, + stdenvNoCC, + fetchurl, + autoPatchelfHook, + makeWrapper, + + libgcc, + libcxx, + libssh, + llvmPackages, +}: + +stdenvNoCC.mkDerivation (finalAttrs: rec { + pname = "teamspeak6-server"; + version = "6.0.0-beta7"; + + src = fetchurl { + url = "https://github.com/teamspeak/teamspeak6-server/releases/download/v${ + lib.replaceString "-" "%2F" version + }/teamspeak-server_linux_amd64-v${version}.tar.bz2"; + hash = "sha256-zVJl+Yis7BHQXAUkyUL9R5aJTG4JJxICmuM7x3RssaM="; + }; + + sourceRoot = "./teamspeak-server_linux_amd64"; + + propagatedBuildInputs = [ + libgcc + libcxx + libssh + llvmPackages.libunwind + ]; + + nativeBuildInputs = [ + autoPatchelfHook + makeWrapper + ]; + + dontConfigure = true; + dontBuild = true; + + installPhase = '' + runHook preInstall + + mkdir -p $out/bin $out/share/teamspeak6-server + + rm libatomic.so.1 libc++.so.1 libssh.so.4 libunwind.so.1 + cp -a * $out/share/teamspeak6-server + + makeWrapper $out/share/teamspeak6-server/tsserver $out/bin/tsserver \ + --prefix LD_LIBRARY_PATH : "${ + lib.makeLibraryPath [ + libgcc + libcxx + libssh + llvmPackages.libunwind + ] + }" + + runHook postInstall + ''; + + meta = { + description = "TeamSpeak voice communication server (beta version)"; + homepage = "https://teamspeak.com/"; + # license = lib.licenses.teamspeak; + mainProgram = "tsserver"; + platforms = [ "x86_64-linux" ]; + }; +}) -- cgit v1.2.3