diff --git a/modules/nixos/caddy/default.nix b/modules/nixos/caddy/default.nix index f9c50bca..8600f77d 100644 --- a/modules/nixos/caddy/default.nix +++ b/modules/nixos/caddy/default.nix @@ -4,10 +4,7 @@ pkgs, ... }: - -with lib; - -let +with lib; let cfg = config.services.caddy; certs = config.security.acme.certs; @@ -17,67 +14,63 @@ let dependentCertNames = filter (cert: certs.${cert}.dnsProvider == null) vhostCertNames; # those that might depend on the HTTP server independentCertNames = filter (cert: certs.${cert}.dnsProvider != null) vhostCertNames; # those that don't depend on the HTTP server - mkVHostConf = - hostOpts: - let - sslCertDir = config.security.acme.certs.${hostOpts.useACMEHost}.directory; - in - '' - ${hostOpts.hostName} ${concatStringsSep " " hostOpts.serverAliases} { - ${optionalString ( - hostOpts.listenAddresses != [ ] - ) "bind ${concatStringsSep " " hostOpts.listenAddresses}"} - ${optionalString ( - hostOpts.useACMEHost != null - ) "tls ${sslCertDir}/cert.pem ${sslCertDir}/key.pem"} - log { - ${hostOpts.logFormat} - } - - ${hostOpts.extraConfig} + mkVHostConf = hostOpts: let + sslCertDir = config.security.acme.certs.${hostOpts.useACMEHost}.directory; + in '' + ${hostOpts.hostName} ${concatStringsSep " " hostOpts.serverAliases} { + ${optionalString ( + hostOpts.listenAddresses != [] + ) "bind ${concatStringsSep " " hostOpts.listenAddresses}"} + ${optionalString ( + hostOpts.useACMEHost != null + ) "tls ${sslCertDir}/cert.pem ${sslCertDir}/key.pem"} + log { + ${hostOpts.logFormat} } - ''; - settingsFormat = pkgs.formats.json { }; + ${hostOpts.extraConfig} + } + ''; + + settingsFormat = pkgs.formats.json {}; configFile = - if cfg.settings != { } then - settingsFormat.generate "caddy.json" cfg.settings - else - let - Caddyfile = pkgs.writeTextDir "Caddyfile" '' - { - ${cfg.globalConfig} - } - ${cfg.extraConfig} - ${concatMapStringsSep "\n" mkVHostConf virtualHosts} - ''; + if cfg.settings != {} + then settingsFormat.generate "caddy.json" cfg.settings + else let + Caddyfile = pkgs.writeTextDir "Caddyfile" '' + { + ${cfg.globalConfig} + } + ${cfg.extraConfig} + ${concatMapStringsSep "\n" mkVHostConf virtualHosts} + ''; - Caddyfile-formatted = pkgs.runCommand "Caddyfile-formatted" { } '' - mkdir -p $out - cp --no-preserve=mode ${Caddyfile}/Caddyfile $out/Caddyfile - ${lib.getExe cfg.package} fmt --overwrite $out/Caddyfile - ''; - in - "${ - if pkgs.stdenv.buildPlatform == pkgs.stdenv.hostPlatform then Caddyfile-formatted else Caddyfile - }/Caddyfile"; + Caddyfile-formatted = pkgs.runCommand "Caddyfile-formatted" {} '' + mkdir -p $out + cp --no-preserve=mode ${Caddyfile}/Caddyfile $out/Caddyfile + ${lib.getExe cfg.package} fmt --overwrite $out/Caddyfile + ''; + in "${ + if pkgs.stdenv.buildPlatform == pkgs.stdenv.hostPlatform + then Caddyfile-formatted + else Caddyfile + }/Caddyfile"; etcConfigFile = "caddy/caddy_config"; configPath = "/etc/${etcConfigFile}"; mkCertOwnershipAssertion = import ../../../security/acme/mk-cert-ownership-assertion.nix lib; -in -{ +in { imports = [ (mkRemovedOptionModule [ "services" "caddy" "agree" ] "this option is no longer necessary for Caddy 2") - (mkRenamedOptionModule [ "services" "caddy" "ca" ] [ "services" "caddy" "acmeCA" ]) - (mkRenamedOptionModule [ "services" "caddy" "config" ] [ "services" "caddy" "extraConfig" ]) + (mkRenamedOptionModule ["services" "caddy" "ca"] ["services" "caddy" "acmeCA"]) + (mkRenamedOptionModule ["services" "caddy" "config"] ["services" "caddy" "extraConfig"]) ]; # interface @@ -112,7 +105,7 @@ in ''; }; - package = mkPackageOption pkgs "caddy" { }; + package = mkPackageOption pkgs "caddy" {}; dataDir = mkOption { type = types.path; @@ -183,10 +176,9 @@ in adapter = mkOption { default = - if ((cfg.configFile != configFile) || (builtins.baseNameOf cfg.configFile) == "Caddyfile") then - "caddyfile" - else - null; + if ((cfg.configFile != configFile) || (builtins.baseNameOf cfg.configFile) == "Caddyfile") + then "caddyfile" + else null; defaultText = literalExpression '' if ((cfg.configFile != configFile) || (builtins.baseNameOf cfg.configFile) == "Caddyfile") then "caddyfile" else null ''; @@ -256,8 +248,8 @@ in }; virtualHosts = mkOption { - type = with types; attrsOf (submodule (import ./vhost-options.nix { inherit cfg; })); - default = { }; + type = with types; attrsOf (submodule (import ./vhost-options.nix {inherit cfg;})); + default = {}; example = literalExpression '' { "hydra.example.com" = { @@ -323,7 +315,7 @@ in settings = mkOption { type = settingsFormat.type; - default = { }; + default = {}; description = '' Structured configuration for Caddy to generate a Caddy JSON configuration file. See for available options. @@ -380,21 +372,22 @@ in # implementation config = mkIf cfg.enable { - - assertions = [ - { - assertion = cfg.configFile == configFile -> cfg.adapter == "caddyfile" || cfg.adapter == null; - message = "To specify an adapter other than 'caddyfile' please provide your own configuration via `services.caddy.configFile`"; - } - ] - ++ map ( - name: - mkCertOwnershipAssertion { - cert = config.security.acme.certs.${name}; - groups = config.users.groups; - services = [ config.systemd.services.caddy ]; - } - ) vhostCertNames; + assertions = + [ + { + assertion = cfg.configFile == configFile -> cfg.adapter == "caddyfile" || cfg.adapter == null; + message = "To specify an adapter other than 'caddyfile' please provide your own configuration via `services.caddy.configFile`"; + } + ] + ++ map ( + name: + mkCertOwnershipAssertion { + cert = config.security.acme.certs.${name}; + groups = config.users.groups; + services = [config.systemd.services.caddy]; + } + ) + vhostCertNames; services.caddy.globalConfig = '' ${optionalString (cfg.email != null) "email ${cfg.email}"} @@ -408,7 +401,7 @@ in boot.kernel.sysctl."net.core.rmem_max" = mkDefault 2500000; boot.kernel.sysctl."net.core.wmem_max" = mkDefault 2500000; - systemd.packages = [ cfg.package ]; + systemd.packages = [cfg.package]; systemd.services.caddy = { wants = map (certName: "acme-finished-${certName}.target") vhostCertNames; after = @@ -416,46 +409,45 @@ in ++ map (certName: "acme-${certName}.service") independentCertNames; # avoid loading self-signed key w/ real cert, or vice-versa before = map (certName: "acme-${certName}.service") dependentCertNames; - wantedBy = [ "multi-user.target" ]; + wantedBy = ["multi-user.target"]; startLimitIntervalSec = 14400; startLimitBurst = 10; reloadTriggers = optional cfg.enableReload cfg.configFile; restartTriggers = optional (!cfg.enableReload) cfg.configFile; - serviceConfig = - let - runOptions = ''--config ${configPath} ${ + serviceConfig = let + runOptions = ''--config ${configPath} ${ optionalString (cfg.adapter != null) "--adapter ${cfg.adapter}" }''; - in - { - # Override the `ExecStart` line from upstream's systemd unit file by our own: - # https://www.freedesktop.org/software/systemd/man/systemd.service.html#ExecStart= - # If the empty string is assigned to this option, the list of commands to start is reset, prior assignments of this option will have no effect. - ExecStart = [ - "" - ''${lib.getExe cfg.package} run ${runOptions} ${optionalString cfg.resume "--resume"}'' - ]; - # Validating the configuration before applying it ensures we’ll get a proper error that will be reported when switching to the configuration - ExecReload = [ + in { + # Override the `ExecStart` line from upstream's systemd unit file by our own: + # https://www.freedesktop.org/software/systemd/man/systemd.service.html#ExecStart= + # If the empty string is assigned to this option, the list of commands to start is reset, prior assignments of this option will have no effect. + ExecStart = [ + "" + ''${lib.getExe cfg.package} run ${runOptions} ${optionalString cfg.resume "--resume"}'' + ]; + # Validating the configuration before applying it ensures we’ll get a proper error that will be reported when switching to the configuration + ExecReload = + [ "" ] ++ lib.optional cfg.enableReload "${lib.getExe cfg.package} reload ${runOptions} --force"; - User = cfg.user; - Group = cfg.group; - ReadWritePaths = [ cfg.dataDir ]; - StateDirectory = mkIf (cfg.dataDir == "/var/lib/caddy") [ "caddy" ]; - LogsDirectory = mkIf (cfg.logDir == "/var/log/caddy") [ "caddy" ]; - Restart = "on-failure"; - RestartPreventExitStatus = 1; - RestartSec = "5s"; - EnvironmentFile = optional (cfg.environmentFile != null) cfg.environmentFile; + User = cfg.user; + Group = cfg.group; + ReadWritePaths = [cfg.dataDir]; + StateDirectory = mkIf (cfg.dataDir == "/var/lib/caddy") ["caddy"]; + LogsDirectory = mkIf (cfg.logDir == "/var/log/caddy") ["caddy"]; + Restart = "on-failure"; + RestartPreventExitStatus = 1; + RestartSec = "5s"; + EnvironmentFile = optional (cfg.environmentFile != null) cfg.environmentFile; - # TODO: attempt to upstream these options - NoNewPrivileges = true; - PrivateDevices = true; - ProtectHome = true; - }; + # TODO: attempt to upstream these options + NoNewPrivileges = true; + PrivateDevices = true; + ProtectHome = true; + }; }; users.users = optionalAttrs (cfg.user == "caddy") { @@ -470,16 +462,17 @@ in caddy.gid = config.ids.gids.caddy; }; - security.acme.certs = - let - certCfg = map ( + security.acme.certs = let + certCfg = + map ( certName: - nameValuePair certName { - group = mkDefault cfg.group; - reloadServices = [ "caddy.service" ]; - } - ) vhostCertNames; - in + nameValuePair certName { + group = mkDefault cfg.group; + reloadServices = ["caddy.service"]; + } + ) + vhostCertNames; + in listToAttrs certCfg; environment.etc.${etcConfigFile}.source = cfg.configFile; diff --git a/modules/nixos/caddy/vhost-options.nix b/modules/nixos/caddy/vhost-options.nix index 73ef4b87..19fc3b05 100644 --- a/modules/nixos/caddy/vhost-options.nix +++ b/modules/nixos/caddy/vhost-options.nix @@ -1,16 +1,12 @@ -{ cfg }: -{ +{cfg}: { config, lib, name, ... -}: -let +}: let inherit (lib) literalExpression mkOption types; -in -{ +in { options = { - hostName = mkOption { type = types.str; default = name; @@ -19,7 +15,7 @@ in serverAliases = mkOption { type = with types; listOf str; - default = [ ]; + default = []; example = [ "www.example.org" "example.org" @@ -34,7 +30,7 @@ in description = '' A list of host interfaces to bind to for this virtual host. ''; - default = [ ]; + default = []; example = [ "127.0.0.1" "::1" @@ -58,7 +54,7 @@ in logFormat = mkOption { type = types.lines; default = '' - output file ${cfg.logDir}/access-${lib.replaceStrings [ "/" " " ] [ "_" "_" ] config.hostName}.log + output file ${cfg.logDir}/access-${lib.replaceStrings ["/" " "] ["_" "_"] config.hostName}.log ''; defaultText = '' output file ''${config.services.caddy.logDir}/access-''${hostName}.log @@ -83,6 +79,5 @@ in automatically generated `Caddyfile`. ''; }; - }; } diff --git a/modules/nixos/satisfactory.nix b/modules/nixos/satisfactory.nix index 99d64bd0..8a7a280b 100644 --- a/modules/nixos/satisfactory.nix +++ b/modules/nixos/satisfactory.nix @@ -1,13 +1,16 @@ -{config, pkgs, lib, ...}: -let - cfg = config.services.satisfactory; -in { + config, + pkgs, + lib, + ... +}: let + cfg = config.services.satisfactory; +in { options.services.satisfactory = { enable = lib.mkEnableOption "Enable Satisfactory Dedicated Server"; beta = lib.mkOption { - type = lib.types.enum [ "public" "experimental" ]; + type = lib.types.enum ["public" "experimental"]; default = "public"; description = "Beta channel to follow"; }; @@ -55,14 +58,19 @@ in networking = { firewall = { - allowedUDPPorts = [ 15777 15000 7777 27015 ]; - allowedUDPPortRanges = [ { from = 27031; to = 27036; } ]; - allowedTCPPorts = [ 27015 27036 ]; + allowedUDPPorts = [15777 15000 7777 27015]; + allowedUDPPortRanges = [ + { + from = 27031; + to = 27036; + } + ]; + allowedTCPPorts = [27015 27036]; }; }; systemd.services.satisfactory = { - wantedBy = [ "multi-user.target" ]; + wantedBy = ["multi-user.target"]; preStart = '' ${pkgs.steamcmd}/bin/steamcmd \ +force_install_dir /var/lib/satisfactory/SatisfactoryDedicatedServer \ @@ -76,8 +84,16 @@ in ln -sfv /var/lib/satisfactory/.steam/steam/linux64 /var/lib/satisfactory/.steam/sdk64 mkdir -p /var/lib/satisfactory/SatisfactoryDedicatedServer/FactoryGame/Saved/Config/LinuxServer ${pkgs.crudini}/bin/crudini --set /var/lib/satisfactory/SatisfactoryDedicatedServer/FactoryGame/Saved/Config/LinuxServer/Game.ini '/Script/Engine.GameSession' MaxPlayers ${toString cfg.maxPlayers} - ${pkgs.crudini}/bin/crudini --set /var/lib/satisfactory/SatisfactoryDedicatedServer/FactoryGame/Saved/Config/LinuxServer/ServerSettings.ini '/Script/FactoryGame.FGServerSubsystem' mAutoPause ${if cfg.autoPause then "True" else "False"} - ${pkgs.crudini}/bin/crudini --set /var/lib/satisfactory/SatisfactoryDedicatedServer/FactoryGame/Saved/Config/LinuxServer/ServerSettings.ini '/Script/FactoryGame.FGServerSubsystem' mAutoSaveOnDisconnect ${if cfg.autoSaveOnDisconnect then "True" else "False"} + ${pkgs.crudini}/bin/crudini --set /var/lib/satisfactory/SatisfactoryDedicatedServer/FactoryGame/Saved/Config/LinuxServer/ServerSettings.ini '/Script/FactoryGame.FGServerSubsystem' mAutoPause ${ + if cfg.autoPause + then "True" + else "False" + } + ${pkgs.crudini}/bin/crudini --set /var/lib/satisfactory/SatisfactoryDedicatedServer/FactoryGame/Saved/Config/LinuxServer/ServerSettings.ini '/Script/FactoryGame.FGServerSubsystem' mAutoSaveOnDisconnect ${ + if cfg.autoSaveOnDisconnect + then "True" + else "False" + } ''; script = '' /var/lib/satisfactory/SatisfactoryDedicatedServer/Engine/Binaries/Linux/UnrealServer-Linux-Shipping FactoryGame -multihome=${cfg.address} @@ -89,7 +105,7 @@ in WorkingDirectory = "/var/lib/satisfactory"; }; environment = { - LD_LIBRARY_PATH="SatisfactoryDedicatedServer/linux64:SatisfactoryDedicatedServer/Engine/Binaries/Linux:SatisfactoryDedicatedServer/Engine/Binaries/ThirdParty/PhysX3/Linux/x86_64-unknown-linux-gnu"; + LD_LIBRARY_PATH = "SatisfactoryDedicatedServer/linux64:SatisfactoryDedicatedServer/Engine/Binaries/Linux:SatisfactoryDedicatedServer/Engine/Binaries/ThirdParty/PhysX3/Linux/x86_64-unknown-linux-gnu"; }; }; }; diff --git a/nixos/ryu/configuration.nix b/nixos/ryu/configuration.nix index b426553a..37190e52 100644 --- a/nixos/ryu/configuration.nix +++ b/nixos/ryu/configuration.nix @@ -12,12 +12,6 @@ ./apps ]; - # sops = { - # defaultSopsFile = ../../secrets/secrets.yaml; - # defaultSopsFormat = "yaml"; - # age.keyFile = "/home/${device.user}/.config/sops/age/keys.txt"; - # }; - security.tpm2 = { enable = true; pkcs11.enable = true;