diff options
Diffstat (limited to 'nixpkgs/nixos/modules/system/boot')
9 files changed, 481 insertions, 18 deletions
diff --git a/nixpkgs/nixos/modules/system/boot/systemd.nix b/nixpkgs/nixos/modules/system/boot/systemd.nix index 87333999313e..46c3f66f02dc 100644 --- a/nixpkgs/nixos/modules/system/boot/systemd.nix +++ b/nixpkgs/nixos/modules/system/boot/systemd.nix @@ -451,6 +451,21 @@ in cfg.services ); + assertions = concatLists ( + mapAttrsToList + (name: service: + map (message: { + assertion = false; + inherit message; + }) (concatLists [ + (optional ((builtins.elem "network-interfaces.target" service.after) || (builtins.elem "network-interfaces.target" service.wants)) + "Service '${name}.service' is using the deprecated target network-interfaces.target, which no longer exists. Using network.target is recommended instead." + ) + ]) + ) + cfg.services + ); + system.build.units = cfg.units; system.nssModules = [ cfg.package.out ]; @@ -554,6 +569,13 @@ in unitConfig.X-StopOnReconfiguration = true; }; + # This target only exists so that services ordered before sysinit.target + # are restarted in the correct order, notably BEFORE the other services, + # when switching configurations. + systemd.targets.sysinit-reactivation = { + description = "Reactivate sysinit units"; + }; + systemd.units = mapAttrs' (n: v: nameValuePair "${n}.path" (pathToUnit n v)) cfg.paths // mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.services diff --git a/nixpkgs/nixos/modules/system/boot/systemd/journald-gateway.nix b/nixpkgs/nixos/modules/system/boot/systemd/journald-gateway.nix new file mode 100644 index 000000000000..854965282344 --- /dev/null +++ b/nixpkgs/nixos/modules/system/boot/systemd/journald-gateway.nix @@ -0,0 +1,135 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.services.journald.gateway; + + cliArgs = lib.cli.toGNUCommandLineShell { } { + # If either of these are null / false, they are not passed in the command-line + inherit (cfg) cert key trust system user merge; + }; +in +{ + meta.maintainers = [ lib.maintainers.raitobezarius ]; + options.services.journald.gateway = { + enable = lib.mkEnableOption "the HTTP gateway to the journal"; + + port = lib.mkOption { + default = 19531; + type = lib.types.port; + description = '' + The port to listen to. + ''; + }; + + cert = lib.mkOption { + default = null; + type = with lib.types; nullOr str; + description = lib.mdDoc '' + The path to a file or `AF_UNIX` stream socket to read the server + certificate from. + + The certificate must be in PEM format. This option switches + `systemd-journal-gatewayd` into HTTPS mode and must be used together + with {option}`services.journald.gateway.key`. + ''; + }; + + key = lib.mkOption { + default = null; + type = with lib.types; nullOr str; + description = lib.mdDoc '' + Specify the path to a file or `AF_UNIX` stream socket to read the + secret server key corresponding to the certificate specified with + {option}`services.journald.gateway.cert` from. + + The key must be in PEM format. + + This key should not be world-readable, and must be readably by the + `systemd-journal-gateway` user. + ''; + }; + + trust = lib.mkOption { + default = null; + type = with lib.types; nullOr str; + description = lib.mdDoc '' + Specify the path to a file or `AF_UNIX` stream socket to read a CA + certificate from. + + The certificate must be in PEM format. + + Setting this option enforces client certificate checking. + ''; + }; + + system = lib.mkOption { + default = true; + type = lib.types.bool; + description = lib.mdDoc '' + Serve entries from system services and the kernel. + + This has the same meaning as `--system` for {manpage}`journalctl(1)`. + ''; + }; + + user = lib.mkOption { + default = true; + type = lib.types.bool; + description = lib.mdDoc '' + Serve entries from services for the current user. + + This has the same meaning as `--user` for {manpage}`journalctl(1)`. + ''; + }; + + merge = lib.mkOption { + default = false; + type = lib.types.bool; + description = lib.mdDoc '' + Serve entries interleaved from all available journals, including other + machines. + + This has the same meaning as `--merge` option for + {manpage}`journalctl(1)`. + ''; + }; + }; + + config = lib.mkIf cfg.enable { + assertions = [ + { + # This prevents the weird case were disabling "system" and "user" + # actually enables both because the cli flags are not present. + assertion = cfg.system || cfg.user; + message = '' + systemd-journal-gatewayd cannot serve neither "system" nor "user" + journals. + ''; + } + ]; + + systemd.additionalUpstreamSystemUnits = [ + "systemd-journal-gatewayd.socket" + "systemd-journal-gatewayd.service" + ]; + + users.users.systemd-journal-gateway.uid = config.ids.uids.systemd-journal-gateway; + users.users.systemd-journal-gateway.group = "systemd-journal-gateway"; + users.groups.systemd-journal-gateway.gid = config.ids.gids.systemd-journal-gateway; + + systemd.services.systemd-journal-gatewayd.serviceConfig.ExecStart = [ + # Clear the default command line + "" + "${pkgs.systemd}/lib/systemd/systemd-journal-gatewayd ${cliArgs}" + ]; + + systemd.sockets.systemd-journal-gatewayd = { + wantedBy = [ "sockets.target" ]; + listenStreams = [ + # Clear the default port + "" + (toString cfg.port) + ]; + }; + }; +} diff --git a/nixpkgs/nixos/modules/system/boot/systemd/journald-remote.nix b/nixpkgs/nixos/modules/system/boot/systemd/journald-remote.nix new file mode 100644 index 000000000000..57a0a133e1c6 --- /dev/null +++ b/nixpkgs/nixos/modules/system/boot/systemd/journald-remote.nix @@ -0,0 +1,163 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.services.journald.remote; + format = pkgs.formats.systemd; + + cliArgs = lib.cli.toGNUCommandLineShell { } { + inherit (cfg) output; + # "-3" specifies the file descriptor from the .socket unit. + "listen-${cfg.listen}" = "-3"; + }; +in +{ + meta.maintainers = [ lib.maintainers.raitobezarius ]; + options.services.journald.remote = { + enable = lib.mkEnableOption "receiving systemd journals from the network"; + + listen = lib.mkOption { + default = "https"; + type = lib.types.enum [ "https" "http" ]; + description = lib.mdDoc '' + Which protocol to listen to. + ''; + }; + + output = lib.mkOption { + default = "/var/log/journal/remote/"; + type = lib.types.str; + description = lib.mdDoc '' + The location of the output journal. + + In case the output file is not specified, journal files will be created + underneath the selected directory. Files will be called + {file}`remote-hostname.journal`, where the `hostname` part is the + escaped hostname of the source endpoint of the connection, or the + numerical address if the hostname cannot be determined. + ''; + }; + + port = lib.mkOption { + default = 19532; + type = lib.types.port; + description = '' + The port to listen to. + + Note that this option is used only if + {option}`services.journald.upload.listen` is configured to be either + "https" or "http". + ''; + }; + + settings = lib.mkOption { + default = { }; + + description = lib.mdDoc '' + Configuration in the journal-remote configuration file. See + {manpage}`journal-remote.conf(5)` for available options. + ''; + + type = lib.types.submodule { + freeformType = format.type; + + options.Remote = { + Seal = lib.mkOption { + default = false; + example = true; + type = lib.types.bool; + description = '' + Periodically sign the data in the journal using Forward Secure + Sealing. + ''; + }; + + SplitMode = lib.mkOption { + default = "host"; + example = "none"; + type = lib.types.enum [ "host" "none" ]; + description = lib.mdDoc '' + With "host", a separate output file is used, based on the + hostname of the other endpoint of a connection. With "none", only + one output journal file is used. + ''; + }; + + ServerKeyFile = lib.mkOption { + default = "/etc/ssl/private/journal-remote.pem"; + type = lib.types.str; + description = lib.mdDoc '' + A path to a SSL secret key file in PEM format. + + Note that due to security reasons, `systemd-journal-remote` will + refuse files from the world-readable `/nix/store`. This file + should be readable by the "" user. + + This option can be used with `listen = "https"`. If the path + refers to an `AF_UNIX` stream socket in the file system a + connection is made to it and the key read from it. + ''; + }; + + ServerCertificateFile = lib.mkOption { + default = "/etc/ssl/certs/journal-remote.pem"; + type = lib.types.str; + description = lib.mdDoc '' + A path to a SSL certificate file in PEM format. + + This option can be used with `listen = "https"`. If the path + refers to an `AF_UNIX` stream socket in the file system a + connection is made to it and the certificate read from it. + ''; + }; + + TrustedCertificateFile = lib.mkOption { + default = "/etc/ssl/ca/trusted.pem"; + type = lib.types.str; + description = lib.mdDoc '' + A path to a SSL CA certificate file in PEM format, or `all`. + + If `all` is set, then client certificate checking will be + disabled. + + This option can be used with `listen = "https"`. If the path + refers to an `AF_UNIX` stream socket in the file system a + connection is made to it and the certificate read from it. + ''; + }; + }; + }; + }; + }; + + config = lib.mkIf cfg.enable { + systemd.additionalUpstreamSystemUnits = [ + "systemd-journal-remote.service" + "systemd-journal-remote.socket" + ]; + + systemd.services.systemd-journal-remote.serviceConfig.ExecStart = [ + # Clear the default command line + "" + "${pkgs.systemd}/lib/systemd/systemd-journal-remote ${cliArgs}" + ]; + + systemd.sockets.systemd-journal-remote = { + wantedBy = [ "sockets.target" ]; + listenStreams = [ + # Clear the default port + "" + (toString cfg.port) + ]; + }; + + # User and group used by systemd-journal-remote.service + users.groups.systemd-journal-remote = { }; + users.users.systemd-journal-remote = { + isSystemUser = true; + group = "systemd-journal-remote"; + }; + + environment.etc."systemd/journal-remote.conf".source = + format.generate "journal-remote.conf" cfg.settings; + }; +} diff --git a/nixpkgs/nixos/modules/system/boot/systemd/journald-upload.nix b/nixpkgs/nixos/modules/system/boot/systemd/journald-upload.nix new file mode 100644 index 000000000000..6421e5fa486f --- /dev/null +++ b/nixpkgs/nixos/modules/system/boot/systemd/journald-upload.nix @@ -0,0 +1,111 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.services.journald.upload; + format = pkgs.formats.systemd; +in +{ + meta.maintainers = [ lib.maintainers.raitobezarius ]; + options.services.journald.upload = { + enable = lib.mkEnableOption "uploading the systemd journal to a remote server"; + + settings = lib.mkOption { + default = { }; + + description = lib.mdDoc '' + Configuration for journal-upload. See {manpage}`journal-upload.conf(5)` + for available options. + ''; + + type = lib.types.submodule { + freeformType = format.type; + + options.Upload = { + URL = lib.mkOption { + type = lib.types.str; + example = "https://192.168.1.1"; + description = '' + The URL to upload the journal entries to. + + See the description of `--url=` option in + {manpage}`systemd-journal-upload(8)` for the description of + possible values. + ''; + }; + + ServerKeyFile = lib.mkOption { + type = with lib.types; nullOr str; + example = lib.literalExpression "./server-key.pem"; + # Since systemd-journal-upload uses a DynamicUser, permissions must + # be done using groups + description = '' + SSL key in PEM format. + + In contrary to what the name suggests, this option configures the + client private key sent to the remote journal server. + + This key should not be world-readable, and must be readably by + the `systemd-journal` group. + ''; + default = null; + }; + + ServerCertificateFile = lib.mkOption { + type = with lib.types; nullOr str; + example = lib.literalExpression "./server-ca.pem"; + description = '' + SSL CA certificate in PEM format. + + In contrary to what the name suggests, this option configures the + client certificate sent to the remote journal server. + ''; + default = null; + }; + + TrustedCertificateFile = lib.mkOption { + type = with lib.types; nullOr str; + example = lib.literalExpression "./ca"; + description = '' + SSL CA certificate. + + This certificate will be used to check the remote journal HTTPS + server certificate. + ''; + default = null; + }; + + NetworkTimeoutSec = lib.mkOption { + type = with lib.types; nullOr str; + example = "1s"; + description = '' + When network connectivity to the server is lost, this option + configures the time to wait for the connectivity to get restored. + + If the server is not reachable over the network for the + configured time, `systemd-journal-upload` exits. Takes a value in + seconds (or in other time units if suffixed with "ms", "min", + "h", etc). For details, see {manpage}`systemd.time(5)`. + ''; + default = null; + }; + }; + }; + }; + }; + + config = lib.mkIf cfg.enable { + systemd.additionalUpstreamSystemUnits = [ "systemd-journal-upload.service" ]; + + systemd.services."systemd-journal-upload" = { + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + Restart = "always"; + # To prevent flooding the server in case the server is struggling + RestartSec = "3sec"; + }; + }; + + environment.etc."systemd/journal-upload.conf".source = + format.generate "journal-upload.conf" cfg.settings; + }; +} diff --git a/nixpkgs/nixos/modules/system/boot/systemd/journald.nix b/nixpkgs/nixos/modules/system/boot/systemd/journald.nix index 7e62a4c9bfed..9a8e7d592603 100644 --- a/nixpkgs/nixos/modules/system/boot/systemd/journald.nix +++ b/nixpkgs/nixos/modules/system/boot/systemd/journald.nix @@ -5,6 +5,10 @@ with lib; let cfg = config.services.journald; in { + imports = [ + (mkRenamedOptionModule [ "services" "journald" "enableHttpGateway" ] [ "services" "journald" "gateway" "enable" ]) + ]; + options = { services.journald.console = mkOption { default = ""; @@ -71,14 +75,6 @@ in { ''; }; - services.journald.enableHttpGateway = mkOption { - default = false; - type = types.bool; - description = lib.mdDoc '' - Whether to enable the HTTP gateway to the journal. - ''; - }; - services.journald.forwardToSyslog = mkOption { default = config.services.rsyslogd.enable || config.services.syslog-ng.enable; defaultText = literalExpression "services.rsyslogd.enable || services.syslog-ng.enable"; @@ -101,9 +97,6 @@ in { ] ++ (optional (!config.boot.isContainer) "systemd-journald-audit.socket") ++ [ "systemd-journald-dev-log.socket" "syslog.socket" - ] ++ optionals cfg.enableHttpGateway [ - "systemd-journal-gatewayd.socket" - "systemd-journal-gatewayd.service" ]; environment.etc = { @@ -124,12 +117,6 @@ in { }; users.groups.systemd-journal.gid = config.ids.gids.systemd-journal; - users.users.systemd-journal-gateway.uid = config.ids.uids.systemd-journal-gateway; - users.users.systemd-journal-gateway.group = "systemd-journal-gateway"; - users.groups.systemd-journal-gateway.gid = config.ids.gids.systemd-journal-gateway; - - systemd.sockets.systemd-journal-gatewayd.wantedBy = - optional cfg.enableHttpGateway "sockets.target"; systemd.services.systemd-journal-flush.restartIfChanged = false; systemd.services.systemd-journald.restartTriggers = [ config.environment.etc."systemd/journald.conf".source ]; diff --git a/nixpkgs/nixos/modules/system/boot/systemd/repart.nix b/nixpkgs/nixos/modules/system/boot/systemd/repart.nix index 5ac2ace56ba0..3be744acd0b3 100644 --- a/nixpkgs/nixos/modules/system/boot/systemd/repart.nix +++ b/nixpkgs/nixos/modules/system/boot/systemd/repart.nix @@ -83,6 +83,9 @@ in } ]; + # systemd-repart uses loopback devices for partition creation + boot.initrd.availableKernelModules = lib.optional initrdCfg.enable "loop"; + boot.initrd.systemd = lib.mkIf initrdCfg.enable { additionalUpstreamUnits = [ "systemd-repart.service" diff --git a/nixpkgs/nixos/modules/system/boot/systemd/sysupdate.nix b/nixpkgs/nixos/modules/system/boot/systemd/sysupdate.nix index b1914a9c4e76..cab35ddf270c 100644 --- a/nixpkgs/nixos/modules/system/boot/systemd/sysupdate.nix +++ b/nixpkgs/nixos/modules/system/boot/systemd/sysupdate.nix @@ -71,7 +71,7 @@ in type = with lib.types; attrsOf format.type; default = { }; example = { - "10-uki.conf" = { + "10-uki" = { Transfer = { ProtectVersion = "%A"; }; diff --git a/nixpkgs/nixos/modules/system/boot/systemd/tmpfiles.nix b/nixpkgs/nixos/modules/system/boot/systemd/tmpfiles.nix index f7ef45aab3c9..ee06648f568c 100644 --- a/nixpkgs/nixos/modules/system/boot/systemd/tmpfiles.nix +++ b/nixpkgs/nixos/modules/system/boot/systemd/tmpfiles.nix @@ -150,6 +150,41 @@ in "systemd-tmpfiles-setup.service" ]; + # Allow systemd-tmpfiles to be restarted by switch-to-configuration. This + # service is not pulled into the normal boot process. It only exists for + # switch-to-configuration. + # + # This needs to be a separate unit because it does not execute + # systemd-tmpfiles with `--boot` as that is supposed to only be executed + # once at boot time. + # + # Keep this aligned with the upstream `systemd-tmpfiles-setup.service` unit. + systemd.services."systemd-tmpfiles-resetup" = { + description = "Re-setup tmpfiles on a system that is already running."; + + requiredBy = [ "sysinit-reactivation.target" ]; + after = [ "local-fs.target" "systemd-sysusers.service" "systemd-journald.service" ]; + before = [ "sysinit-reactivation.target" "shutdown.target" ]; + conflicts = [ "shutdown.target" ]; + restartTriggers = [ config.environment.etc."tmpfiles.d".source ]; + + unitConfig.DefaultDependencies = false; + + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + ExecStart = "systemd-tmpfiles --create --remove --exclude-prefix=/dev"; + SuccessExitStatus = "DATAERR CANTCREAT"; + ImportCredential = [ + "tmpfiles.*" + "loging.motd" + "login.issue" + "network.hosts" + "ssh.authorized_keys.root" + ]; + }; + }; + environment.etc = { "tmpfiles.d".source = (pkgs.symlinkJoin { name = "tmpfiles.d"; diff --git a/nixpkgs/nixos/modules/system/boot/timesyncd.nix b/nixpkgs/nixos/modules/system/boot/timesyncd.nix index 7487cf97fe53..2666e4cd6b28 100644 --- a/nixpkgs/nixos/modules/system/boot/timesyncd.nix +++ b/nixpkgs/nixos/modules/system/boot/timesyncd.nix @@ -46,6 +46,13 @@ with lib; wantedBy = [ "sysinit.target" ]; aliases = [ "dbus-org.freedesktop.timesync1.service" ]; restartTriggers = [ config.environment.etc."systemd/timesyncd.conf".source ]; + # systemd-timesyncd disables DNSSEC validation in the nss-resolve module by setting SYSTEMD_NSS_RESOLVE_VALIDATE to 0 in the unit file. + # This is required in order to solve the chicken-and-egg problem when DNSSEC validation needs the correct time to work, but to set the + # correct time, we need to connect to an NTP server, which usually requires resolving its hostname. + # In order for nss-resolve to be able to read this environment variable we patch systemd-timesyncd to disable NSCD and use NSS modules directly. + # This means that systemd-timesyncd needs to have NSS modules path in LD_LIBRARY_PATH. When systemd-resolved is disabled we still need to set + # NSS module path so that systemd-timesyncd keeps using other NSS modules that are configured in the system. + environment.LD_LIBRARY_PATH = config.system.nssModules.path; preStart = ( # Ensure that we have some stored time to prevent |