121 lines
		
	
	
	
		
			4.2 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
			
		
		
	
	
			121 lines
		
	
	
	
		
			4.2 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
| {
 | |
|   pkgs,
 | |
|   lib,
 | |
|   ...
 | |
| }: let
 | |
|   inherit (lib) concatStringsSep;
 | |
| in {
 | |
|   # Sadly, steam-run requires some X libs
 | |
|   environment.noXlibs = false;
 | |
| 
 | |
|   systemd.services.starbound = {
 | |
|     description = "Starbound";
 | |
|     after = ["network.target"];
 | |
| 
 | |
|     serviceConfig = {
 | |
|       ExecStart = "${pkgs.local.starbound}/bin/launch-starbound ${./configs/starbound.json}";
 | |
| 
 | |
|       Type = "simple";
 | |
| 
 | |
|       # Credential loading for steam auth (if necessary; prefer
 | |
|       # anonymous login wherever possible).
 | |
|       LoadCredential = "steam:/run/secrets/steam/tlater";
 | |
| 
 | |
|       # Security settings
 | |
|       DynamicUser = true;
 | |
| 
 | |
|       # This is where the StateDirectory ends up
 | |
|       WorkingDirectory = "/var/lib/starbound";
 | |
|       # Creates /var/lib/starbound (or rather, a symlink there to
 | |
|       # /var/lib/private/starbound), and sets it up to be writeable to
 | |
|       # by the dynamic user.
 | |
|       StateDirectory = "starbound";
 | |
| 
 | |
|       # Note some settings below are basically tautologous with
 | |
|       # `NoNewPrivileges`, but they all work slightly differently so
 | |
|       # add additional layers in case of bugs.
 | |
| 
 | |
|       ## THESE SETTINGS ARE A GOOD IDEA BUT THE STEAM CLIENT IS
 | |
|       ## REALLY, REALLY BAD, AND FOR SOME REASON I NEED TO USE IT TO
 | |
|       ## DOWNLOAD GAME SERVERS AS WELL:
 | |
|       ##
 | |
|       # To guarantee the above (only permits 64-bit syscalls, 32-bit
 | |
|       # syscalls can circumvent the above restrictions).
 | |
|       #
 | |
|       # Obviously, if running a 32 bit game server, change this.
 | |
|       # SystemCallArchitectures = "native";
 | |
|       # Game servers shouldn't need to create new namespaces ever.
 | |
|       #
 | |
|       # TODO: Since steam uses namespaces for things *entirely
 | |
|       # unrelated* to installing game servers, we need to allow
 | |
|       # namespace access. Ideally I'd instead do this in an
 | |
|       # ExecStartPre, but alas, this isn't possible because of
 | |
|       # https://github.com/systemd/systemd/issues/19604.
 | |
|       #
 | |
|       # RestrictNamespaces = true;
 | |
| 
 | |
|       # Don't need to let the game server see other user accounts
 | |
|       PrivateUsers = true;
 | |
|       # *Probably* not harmful for game servers, which probably don't update dynamically
 | |
|       ProtectHostname = true;
 | |
|       # Yeah, if a game server tries to edit the hardware clock something's fishy
 | |
|       ProtectClock = true;
 | |
|       # Don't let game servers modify kernel settings, duh
 | |
|       ProtectKernelTunables = true;
 | |
|       ProtectKernelModules = true;
 | |
|       ProtectKernelLogs = true;
 | |
|       # Game servers shouldn't use cgroups themselves either
 | |
|       ProtectControlGroups = true;
 | |
|       # Most game servers will never need other socket types
 | |
|       RestrictAddressFamilies = ["AF_UNIX AF_INET AF_INET6"];
 | |
|       # Also a no-brainer, no game server should ever need this
 | |
|       LockPersonality = true;
 | |
|       # Some game servers will probably try to set this, but they
 | |
|       # don't need it. It's only required for audio processing and
 | |
|       # such, which the server end doesn't need to do.
 | |
|       RestrictRealtime = true;
 | |
|       # Don't allow a variety of syscalls that gameservers have no
 | |
|       # business using anyway
 | |
|       SystemCallFilter =
 | |
|         "~"
 | |
|         + (concatStringsSep " " [
 | |
|           "@clock"
 | |
|           "@cpu-emulation"
 | |
|           "@debug"
 | |
|           "@keyring"
 | |
|           "@memlock"
 | |
|           "@module"
 | |
|           # "@mount"  TODO: Consider adding when steamcmd is run in ExecStartPre
 | |
|           "@obsolete"
 | |
|           "@raw-io"
 | |
|           "@reboot"
 | |
|           # "@resources" TODO: Ditto
 | |
|           "@setuid"
 | |
|           "@swap"
 | |
|         ]);
 | |
|       # Normally only "read-only", but steamcmd will puke if there is
 | |
|       # no home directory to write to (though the nix package will
 | |
|       # implicitly symlink to the path that we set in its override, so
 | |
|       # no actual files are created, besides a symlink).
 | |
|       ProtectHome = "tmpfs";
 | |
| 
 | |
|       # Implied by DynamicUser anyway, but it doesn't hurt to add
 | |
|       # these explicitly, at least for reference.
 | |
|       RemoveIPC = true;
 | |
|       PrivateTmp = true;
 | |
|       PrivateDevices = true;
 | |
|       NoNewPrivileges = true;
 | |
|       RestrictSUIDSGID = true;
 | |
|       ProtectSystem = "strict";
 | |
|       # ProtectHome = "read-only"; # See further up
 | |
|     };
 | |
|   };
 | |
| 
 | |
|   services.backups.starbound = {
 | |
|     user = "root";
 | |
|     paths = [
 | |
|       "/var/lib/private/starbound/storage/universe/"
 | |
|     ];
 | |
|     pauseServices = ["starbound.service"];
 | |
|   };
 | |
| }
 |