at 23.11-beta 3.4 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 cfg = config.services.teeworlds; 7 register = cfg.register; 8 9 teeworldsConf = pkgs.writeText "teeworlds.cfg" '' 10 sv_port ${toString cfg.port} 11 sv_register ${if cfg.register then "1" else "0"} 12 ${optionalString (cfg.name != null) "sv_name ${cfg.name}"} 13 ${optionalString (cfg.motd != null) "sv_motd ${cfg.motd}"} 14 ${optionalString (cfg.password != null) "password ${cfg.password}"} 15 ${optionalString (cfg.rconPassword != null) "sv_rcon_password ${cfg.rconPassword}"} 16 ${concatStringsSep "\n" cfg.extraOptions} 17 ''; 18 19in 20{ 21 options = { 22 services.teeworlds = { 23 enable = mkEnableOption (lib.mdDoc "Teeworlds Server"); 24 25 openPorts = mkOption { 26 type = types.bool; 27 default = false; 28 description = lib.mdDoc "Whether to open firewall ports for Teeworlds"; 29 }; 30 31 name = mkOption { 32 type = types.nullOr types.str; 33 default = null; 34 description = lib.mdDoc '' 35 Name of the server. Defaults to 'unnamed server'. 36 ''; 37 }; 38 39 register = mkOption { 40 type = types.bool; 41 example = true; 42 default = false; 43 description = lib.mdDoc '' 44 Whether the server registers as public server in the global server list. This is disabled by default because of privacy. 45 ''; 46 }; 47 48 motd = mkOption { 49 type = types.nullOr types.str; 50 default = null; 51 description = lib.mdDoc '' 52 Set the server message of the day text. 53 ''; 54 }; 55 56 password = mkOption { 57 type = types.nullOr types.str; 58 default = null; 59 description = lib.mdDoc '' 60 Password to connect to the server. 61 ''; 62 }; 63 64 rconPassword = mkOption { 65 type = types.nullOr types.str; 66 default = null; 67 description = lib.mdDoc '' 68 Password to access the remote console. If not set, a randomly generated one is displayed in the server log. 69 ''; 70 }; 71 72 port = mkOption { 73 type = types.port; 74 default = 8303; 75 description = lib.mdDoc '' 76 Port the server will listen on. 77 ''; 78 }; 79 80 extraOptions = mkOption { 81 type = types.listOf types.str; 82 default = []; 83 description = lib.mdDoc '' 84 Extra configuration lines for the {file}`teeworlds.cfg`. See [Teeworlds Documentation](https://www.teeworlds.com/?page=docs&wiki=server_settings). 85 ''; 86 example = [ "sv_map dm1" "sv_gametype dm" ]; 87 }; 88 }; 89 }; 90 91 config = mkIf cfg.enable { 92 networking.firewall = mkIf cfg.openPorts { 93 allowedUDPPorts = [ cfg.port ]; 94 }; 95 96 systemd.services.teeworlds = { 97 description = "Teeworlds Server"; 98 wantedBy = [ "multi-user.target" ]; 99 after = [ "network.target" ]; 100 101 serviceConfig = { 102 DynamicUser = true; 103 ExecStart = "${pkgs.teeworlds}/bin/teeworlds_srv -f ${teeworldsConf}"; 104 105 # Hardening 106 CapabilityBoundingSet = false; 107 PrivateDevices = true; 108 PrivateUsers = true; 109 ProtectHome = true; 110 ProtectKernelLogs = true; 111 ProtectKernelModules = true; 112 ProtectKernelTunables = true; 113 RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ]; 114 RestrictNamespaces = true; 115 SystemCallArchitectures = "native"; 116 }; 117 }; 118 }; 119}