# Minecraft gateway only. Secrets stay outside the Nix store. { pkgs, ... }: { systemd.tmpfiles.rules = [ "d /var/lib/minecraft-api-root 0755 root root -" ]; systemd.services.minecraft-api = { description = "Restricted Minecraft-only API for Sol (mesh only)"; wantedBy = [ "multi-user.target" ]; after = [ "network-online.target" "astrnet-mesh0.service" "docker.service" ]; wants = [ "network-online.target" ]; startLimitIntervalSec = 0; serviceConfig = { Type = "simple"; DynamicUser = true; ExecStart = "${pkgs.python3}/bin/python3 -B ${./minecraft-api/server.py}"; Restart = "on-failure"; RestartSec = 10; LoadCredential = "config.json:/var/lib/minecraft-api-secrets/config.json"; StateDirectory = "minecraft-api"; StateDirectoryMode = "0700"; UMask = "0077"; # Only the immutable Nix store, unit credentials and its own queue exist # inside this root. No MC files, home, host /etc or Docker socket. RootDirectory = "/var/lib/minecraft-api-root"; MountAPIVFS = true; BindReadOnlyPaths = [ "/nix/store" ]; ProtectSystem = "strict"; ProtectHome = true; PrivateTmp = true; PrivateDevices = true; ProtectProc = "invisible"; ProcSubset = "pid"; NoNewPrivileges = true; CapabilityBoundingSet = ""; AmbientCapabilities = ""; ProtectKernelTunables = true; ProtectKernelModules = true; ProtectKernelLogs = true; ProtectControlGroups = true; ProtectClock = true; RestrictNamespaces = true; RestrictRealtime = true; RestrictSUIDSGID = true; LockPersonality = true; MemoryDenyWriteExecute = true; SystemCallArchitectures = "native"; SystemCallFilter = [ "@system-service" ]; RestrictAddressFamilies = [ "AF_INET" "AF_UNIX" ]; IPAddressDeny = "any"; IPAddressAllow = [ "10.0.0.0/24" "10.0.1.0/24" "10.0.2.0/24" "10.99.0.0/22" "10.42.0.0/16" ]; SocketBindDeny = "any"; SocketBindAllow = "ipv4:tcp:25580"; MemoryMax = "128M"; CPUQuota = "25%"; TasksMax = 20; LimitNOFILE = 128; }; }; }