diff --git a/roles/server/default.nix b/roles/server/default.nix index 44f1b3c..6ffed7e 100755 --- a/roles/server/default.nix +++ b/roles/server/default.nix @@ -21,5 +21,6 @@ ./copyparty.nix ./beets.nix ./navidrome.nix + ./minecraft.nix ]; } diff --git a/roles/server/minecraft.nix b/roles/server/minecraft.nix new file mode 100644 index 0000000..138c379 --- /dev/null +++ b/roles/server/minecraft.nix @@ -0,0 +1,99 @@ +{ + pkgs, + config, + ... +}: let + stopScript = pkgs.writeShellScript "minecraft-server-stop" '' + echo stop > ${config.systemd.sockets.minecraft-server-sf5.socketConfig.ListenFIFO} + + # Wait for the PID of the minecraft server to disappear before + # returning, so systemd doesn't attempt to SIGKILL it. + while kill -0 "$1" 2> /dev/null; do + sleep 1s + done + ''; +in { + fileSystems = { + "/var/lib/minecraft" = { + device = "/dev/disk/by-uuid/5322c217-b87b-4150-8b4c-a8fa17a899bf"; + fsType = "btrfs"; + options = ["subvol=@minecraft"]; + }; + }; + users.users.sf5 = { + isSystemUser = true; + group = "sf5"; + }; + users.groups.sf5 = {}; + systemd.tmpfiles.settings = { + music."/var/lib/minecraft/sf5" = { + d = { + age = "-"; + user = "sf5"; + group = "sf5"; + mode = "0755"; + }; + }; + }; + networking.firewall.allowedTCPPorts = [25565]; + systemd.sockets.minecraft-server-sf5 = { + bindsTo = ["minecraft-server-sf5.service"]; + socketConfig = { + ListenFIFO = "/run/minecraft-server-sf5.stdin"; + SocketMode = "0660"; + SocketUser = "sf5"; + SocketGroup = "sf5"; + RemoveOnStop = true; + FlushPending = true; + }; + }; + systemd.services.minecraft-server-sf5 = { + description = "Minecraft Server (Sky Factory 5)"; + wantedBy = ["multi-user.target"]; + requires = ["minecraft-server-sf5.socket"]; + after = [ + "network.target" + "minecraft-server-sf5.socket" + ]; + + path = [pkgs.jdk17 pkgs.bash]; + + serviceConfig = { + ExecStart = "/var/lib/minecraft/sf5/run.sh"; + ExecStop = "${stopScript} $MAINPID"; + Restart = "always"; + User = "sf5"; + WorkingDirectory = "/var/lib/minecraft/sf5"; + + StandardInput = "socket"; + StandardOutput = "journal"; + StandardError = "journal"; + + # Hardening + CapabilityBoundingSet = [""]; + DeviceAllow = [""]; + LockPersonality = true; + PrivateDevices = true; + PrivateTmp = true; + PrivateUsers = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectProc = "invisible"; + RestrictAddressFamilies = [ + "AF_INET" + "AF_INET6" + ]; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + SystemCallArchitectures = "native"; + UMask = "0077"; + }; + }; + programs.rust-motd.settings.service_status."Minecraft (SkyFactory 5)"= "minecraft-server-sf5"; +}