Compare commits

..
6 Commits
Author SHA1 Message Date
blake 1c5c21612a enable dns and update ip address 2026-06-12 23:54:04 -05:00
blake 01e420aa8d enable dns and update ip address 2026-06-12 23:54:04 -05:00
blake a422358acd source dedicated server shenangans 2026-06-12 23:54:04 -05:00
blake d5f619ce4d add srcds 2026-06-12 23:54:04 -05:00
blake 981a7b0c4a add cs2 server 2026-06-12 23:54:04 -05:00
blake 6509775612 add cs2 server 2026-06-12 23:54:04 -05:00
8 changed files with 363 additions and 27 deletions
Generated
+58 -1
View File
@@ -257,7 +257,7 @@
},
"fenix": {
"inputs": {
"nixpkgs": "nixpkgs_3",
"nixpkgs": "nixpkgs_4",
"rust-analyzer-src": "rust-analyzer-src"
},
"locked": {
@@ -907,6 +907,22 @@
}
},
"nixpkgs_3": {
"locked": {
"lastModified": 1739419412,
"narHash": "sha256-NCWZQg4DbYVFWg+MOFrxWRaVsLA7yvRWAf6o0xPR1hI=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "2d55b4c1531187926c2a423f6940b3b1301399b5",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_4": {
"locked": {
"lastModified": 1677063315,
"narHash": "sha256-qiB4ajTeAOVnVSAwCNEEkoybrAlA+cpeiBxLobHndE8=",
@@ -1137,6 +1153,7 @@
"nvf": "nvf",
"slippi": "slippi",
"sops-nix": "sops-nix",
"srcds-nix": "srcds-nix",
"stylix": "stylix",
"vpn-confinement": "vpn-confinement",
"watershot": "watershot"
@@ -1253,6 +1270,25 @@
"type": "github"
}
},
"srcds-nix": {
"inputs": {
"nixpkgs": "nixpkgs_3",
"treefmt-nix": "treefmt-nix"
},
"locked": {
"lastModified": 1739576881,
"narHash": "sha256-zudD0ycB1cOwvqFBlAwSKwjO9cZir2qzA4f43ixNYCQ=",
"owner": "ihaveamac",
"repo": "srcds-nix",
"rev": "ad8a719fa97b26dfc0b3b6f0ba0f468036c549e1",
"type": "github"
},
"original": {
"owner": "ihaveamac",
"repo": "srcds-nix",
"type": "github"
}
},
"std": {
"inputs": {
"arion": [
@@ -1427,6 +1463,27 @@
"type": "github"
}
},
"treefmt-nix": {
"inputs": {
"nixpkgs": [
"srcds-nix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1738953846,
"narHash": "sha256-yrK3Hjcr8F7qS/j2F+r7C7o010eVWWlm4T1PrbKBOxQ=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "4f09b473c936d41582dd744e19f34ec27592c5fd",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"type": "github"
}
},
"vpn-confinement": {
"locked": {
"lastModified": 1778182451,
+1
View File
@@ -61,6 +61,7 @@
url = "github:lytedev/slippi-nix";
inputs.nixpkgs.follows = "nixpkgs-unstable";
};
srcds-nix.url = "github:ihaveamac/srcds-nix";
};
outputs = {
self,
+5 -5
View File
@@ -17,7 +17,7 @@
../../../modules/system
../../../modules/fileshares/holocron_new
../../../modules/homelab
../../../modules/gameservers/cs2
#../../../modules/gameservers/srcds
#../../../modules/gameservers/minecraft_recpro
#../../../modules/gameservers/minecraft_modded
];
@@ -59,7 +59,7 @@
# network
tailscale.enable = true;
caddy.enable = true;
dnsmasq.enable = false;
dnsmasq.enable = true;
# mediastack
mediastack.enable = true;
qbittorrent.vpn_inf = "enp34s0.69";
@@ -83,9 +83,9 @@
nfs.enable = true;
};
gameservers = {
cs2.enable = true;
};
# gameservers = {
# srcds.enable = true;
# };
# boot (systemd is going on me)
boot.loader.systemd-boot.enable = true; # systemd your pretty cool ya know
@@ -34,7 +34,7 @@ in {
autodetect = true;
defaults.monitored = "-a -o on -s (S/../.././05|L/../01/./05)";
notifications = {
test = true;
test = false;
mail = {
enable = true;
recipient = "blake";
+21 -19
View File
@@ -17,6 +17,10 @@ in {
type = lib.types.int;
default = 27015;
};
tv_port = lib.mkOption {
type = lib.types.int;
default = 27016;
};
hostname = lib.mkOption {
type = lib.types.str;
default = "recoil.pro CS2";
@@ -25,7 +29,7 @@ in {
type = lib.types.str;
default = "de_dust2";
};
maxPlayers = lib.mkOption {
max_players = lib.mkOption {
type = lib.types.int;
default = 10;
};
@@ -51,6 +55,8 @@ in {
environment.systemPackages = with pkgs; [
steamcmd
steam-run
rcon
];
systemd.tmpfiles.rules = [
@@ -61,8 +67,7 @@ in {
environment.etc."cs2/server.cfg".text = ''
hostname "${cfg.hostname}"
sv_lan 0
sv_visiblemaxplayers ${toString cfg.maxPlayers}
rcon_password "$(<${config.sops.secrets.cs2-rcon.path})"
rcon_password "$(<${config.sops.secrets."cs2/rcon".path})"
mp_autoteambalance 1
mp_limitteams 2
'';
@@ -95,22 +100,30 @@ in {
serviceConfig = {
User = "cs2";
Group = "cs2";
WorkingDirectory = "${cfg.data_dir}/server/game/bin/linuxsteamrt64";
WorkingDirectory = "${cfg.data_dir}";
Restart = "always";
ExecStart = pkgs.writeShellScript "cs2-start" ''
export GSLT=$(cat ${config.sops.secrets."cs2/gslt".path})
exec ./cs2.sh \
exec ${pkgs.steam-run}/bin/steam-run -- \
${cfg.data_dir}/server/game/bin/linuxsteamrt64/cs2 \
-dedicated \
-usercon \
-console \
-port ${toString cfg.port} \
-tv_port ${toString cfg.tv_port} \
-maxplayers_override ${toString cfg.max_players} \
+game_type 0 \
+game_mode 1 \
+mapgroup mg_active \
+map ${cfg.map} \
+sv_setsteamaccount "$GSLT" \
+exec server.cfg
+exec /etc/gameserver/cs2/server.cfg
'';
};
};
networking.firewall.allowedTCPPorts = [cfg.port];
networking.firewall.allowedUDPPorts = [cfg.port];
networking.firewall.allowedTCPPorts = [cfg.port cfg.tv_port];
networking.firewall.allowedUDPPorts = [cfg.port cfg.tv_port];
# backups cs2 server with borg!
services.borgbackup.jobs.${service} = {
@@ -134,17 +147,6 @@ in {
};
};
sops.secrets = {
cs2-gslt = {
owner = "cs2";
group = "cs2";
};
cs2-rcon = {
owner = "cs2";
group = "cs2";
};
};
# manage secrets with sops
sops.secrets = {
"${service}/gslt" = {
+162
View File
@@ -0,0 +1,162 @@
{
pkgs,
config,
lib,
...
}: let
service = "cs2";
cfg = config.gameservers.${service};
in {
options.gameservers.${service} = {
enable = lib.mkEnableOption "Counter Strike 2 server";
data_dir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/gameservers/cs2";
};
port = lib.mkOption {
type = lib.types.int;
default = 27015;
};
tv_port = lib.mkOption {
type = lib.types.int;
default = 27016;
};
hostname = lib.mkOption {
type = lib.types.str;
default = "recoil.pro CS2";
};
map = lib.mkOption {
type = lib.types.str;
default = "de_dust2";
};
max_players = lib.mkOption {
type = lib.types.int;
default = 10;
};
backup = lib.mkOption {
type = lib.types.bool;
default = true;
};
backup_repo = lib.mkOption {
type = lib.types.path;
default = "/holocron/archives/gameservers/cs2";
};
};
config = lib.mkIf cfg.enable {
users.users.cs2 = {
isSystemUser = true;
group = "cs2";
home = cfg.data_dir;
createHome = true;
};
users.groups.cs2 = {};
environment.systemPackages = with pkgs; [
steamcmd
steam-run
rcon
];
systemd.tmpfiles.rules = [
"d ${cfg.data_dir} 0770 cs2 cs2 -"
"d ${cfg.data_dir}/server 0770 cs2 cs2 -"
];
environment.etc."cs2/server.cfg".text = ''
hostname "${cfg.hostname}"
sv_lan 0
rcon_password "$(<${config.sops.secrets."cs2/rcon".path})"
mp_autoteambalance 1
mp_limitteams 2
'';
systemd.services.cs2-update = {
description = "Update CS2 server";
serviceConfig = {
Type = "oneshot";
User = "cs2";
};
script = ''
${pkgs.steamcmd}/bin/steamcmd \
+force_install_dir ${cfg.data_dir}/server \
+login anonymous \
+app_update 730 validate \
+quit
'';
};
systemd.services.cs2-server = {
description = "Counter Strike 2 Dedicated Server";
after = [
"network.target"
"cs2-update.service"
];
requires = [
"cs2-update.service"
];
wantedBy = ["multi-user.target"];
serviceConfig = {
User = "cs2";
Group = "cs2";
WorkingDirectory = "${cfg.data_dir}/server";
Restart = "always";
ExecStart = pkgs.writeShellScript "cs2-start" ''
export GSLT=$(cat ${config.sops.secrets."cs2/gslt".path})
exec ${pkgs.steam-run}/bin/steam-run -- \
${cfg.data_dir}/server/game/cs2.sh \
-dedicated \
-usercon \
-console \
-port ${toString cfg.port} \
-tv_port ${toString cfg.tv_port} \
-maxplayers_override ${toString cfg.max_players} \
+game_type 0 \
+game_mode 1 \
+mapgroup mg_active \
+map ${cfg.map} \
+sv_setsteamaccount "$GSLT" \
+exec /etc/gameserver/cs2/server.cfg
'';
};
};
networking.firewall.allowedTCPPorts = [cfg.port cfg.tv_port];
networking.firewall.allowedUDPPorts = [cfg.port cfg.tv_port];
# backups cs2 server with borg!
services.borgbackup.jobs.${service} = {
archiveBaseName = service;
repo = cfg.backup_repo;
paths = cfg.data_dir;
compression = "auto,zstd";
#preHook = "systemctl start mysql-backup.service";
startAt = "*-*-* *:00:00";
group = "archives";
encryption.mode = "repokey-blake2";
encryption.passCommand = "cat ${config.sops.secrets."borg_passwd".path}";
extraArgs = ["--verbose" "--show-rc" "--umask" "0007"];
extraCreateArgs = ["--list" "--stats" "--filter" "AME"];
prune.keep = {
within = "1d"; # Keep all archives from the last day
hourly = 24;
daily = 7;
weekly = 12;
monthly = -1; # Keep at least one archive for each month
};
};
# manage secrets with sops
sops.secrets = {
"${service}/gslt" = {
owner = service;
group = service;
};
"${service}/rcon" = {
owner = service;
group = service;
};
};
};
}
+114
View File
@@ -0,0 +1,114 @@
{
pkgs,
config,
lib,
inputs,
...
}: let
service = "srcds";
cfg = config.gameservers.${service};
in {
imports = [inputs.srcds-nix.nixosModules.default];
options.gameservers.${service} = {
enable = lib.mkEnableOption "Counter Strike 2 server";
data_dir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/gameservers/cs2";
};
port = lib.mkOption {
type = lib.types.int;
default = 27015;
};
tv_port = lib.mkOption {
type = lib.types.int;
default = 27016;
};
hostname = lib.mkOption {
type = lib.types.str;
default = "recoil.pro CS2";
};
map = lib.mkOption {
type = lib.types.str;
default = "de_dust2";
};
max_players = lib.mkOption {
type = lib.types.int;
default = 10;
};
backup = lib.mkOption {
type = lib.types.bool;
default = true;
};
backup_repo = lib.mkOption {
type = lib.types.path;
default = "/holocron/archives/gameservers/cs2";
};
};
config = lib.mkIf cfg.enable {
users.users.cs2 = {
isSystemUser = true;
group = "cs2";
home = cfg.data_dir;
createHome = true;
};
users.groups.cs2 = {};
services.srcds = {
enable = true;
openFirewall = true;
games = {
cs2-server = {
appId = 730;
gamePort = cfg.port;
rcon = {
enable = true;
password = "secretpass";
};
extraArgs = [];
startingMap = cfg.map;
};
};
};
environment.systemPackages = with pkgs; [
rcon
];
# backups cs2 server with borg!
services.borgbackup.jobs.${service} = {
archiveBaseName = service;
repo = cfg.backup_repo;
paths = cfg.data_dir;
compression = "auto,zstd";
#preHook = "systemctl start mysql-backup.service";
startAt = "*-*-* *:00:00";
group = "archives";
encryption.mode = "repokey-blake2";
encryption.passCommand = "cat ${config.sops.secrets."borg_passwd".path}";
extraArgs = ["--verbose" "--show-rc" "--umask" "0007"];
extraCreateArgs = ["--list" "--stats" "--filter" "AME"];
prune.keep = {
within = "1d"; # Keep all archives from the last day
hourly = 24;
daily = 7;
weekly = 12;
monthly = -1; # Keep at least one archive for each month
};
};
# manage secrets with sops
sops.secrets = {
"${service}/gslt" = {
owner = service;
group = service;
};
"${service}/rcon" = {
owner = service;
group = service;
};
};
};
}
+1 -1
View File
@@ -25,7 +25,7 @@ in {
alwaysKeepRunning = true;
settings = {
no-resolv = true;
listen-address = "10.10.0.10"; # your LAN IP
listen-address = "10.10.0.11"; # your LAN IP
#interface = "enp89s0";
bind-interfaces = true;
# address = [