Jump to content

Systemd/Hardening: Difference between revisions

From Official NixOS Wiki
First time editing the wiki, apologies if I did anything wrong! I didn't want to remove the tmux stuff added by others, so I kept my changes to a sentence or two inserted before it
RossSmyth (talk | contribs)
Add Navidrome to the "good" links
Line 98: Line 98:
<translate>
<translate>
<!--T:18-->
<!--T:18-->
* Navidrome: https://github.com/NixOS/nixpkgs/blob/445d861c6d31b4af0c79d8d4be2331f762a361d7/nixos/modules/services/audio/navidrome.nix#L167-L225
* Chrony: https://github.com/NixOS/nixpkgs/pull/104944/files
* Chrony: https://github.com/NixOS/nixpkgs/pull/104944/files
* Isso: https://github.com/NixOS/nixpkgs/pull/140840/files
* Isso: https://github.com/NixOS/nixpkgs/pull/140840/files
Line 109: Line 110:
<translate>
<translate>
<!--T:20-->
<!--T:20-->
* SHH, systemd hardening helper:  [https://www.synacktiv.com/en/publications/systemd-hardening-made-easy-with-shh systemd hardening made easy with SHH]
* SHH, systemd hardening helper, note this tool is not exhaustive and is just a good first-step:  [https://www.synacktiv.com/en/publications/systemd-hardening-made-easy-with-shh systemd hardening made easy with SHH]
</translate>
</translate>



Revision as of 18:58, 6 August 2026

Systemd's service options are quite lax by default, and so it is often desirable to look at ways to harden systemd services. A good way to get started on a given service is to look at the output of the command systemd-analyze security myService. From there, you can look at the documentation for the options you see in the output, often in man systemd.exec or man systemd.resource-control, and set the appropriate options for your service.

Accessing the network with a different RootDirectory

To be able to access the network while having a RootDirectory specified, you need to give access to /etc/ssl, /etc/static/ssl and /etc/resolv.conf. The simplest way of doing this is by simply putting /etc in the BindReadOnlyPaths option. A more granular way, would be to put these 3 paths into BindReadOnlyPaths, and wait for the creation of /etc/resolv.conf through a systemd.path unit.

Dropping a shell inside a systemd service

While hardening a service, it often happens that you want a shell inside a hardened systemd unit, for example to check access to files, or check the network connectivity. Since systemd v258, one may run systemd-analyze unit-shell <service> to accomplish this. Note that this currently only works for running services. Alternatively, one might use tmux to create a session inside the service, and attaching to it outside of the service. Simple example:

{ pkgs, ... }:
{
  systemd.services.myService = {
    serviceConfig = {
      ExecStart = "${pkgs.tmux}/bin/tmux -S /tmp/tmux.socket new-session -s my-session -d";
      ExecStop = "${pkgs.tmux}/bin/tmux -S /tmp/tmux.socket kill-session -t my-session";
      Type = "forking";

      # ...
    };
  };
}

Example with a RootDirectory specified:

{ pkgs }:
{
  systemd.services.myService = {
    serviceConfig = {
      ExecStart = "${pkgs.tmux}/bin/tmux -S /run/myService/tmux.socket new-session -s my-session -d";
      ExecStop = "${pkgs.tmux}/bin/tmux -S /run/myService/tmux.socket kill-session -t my-session";
      Type = "forking";

      # Used as root directory
      RuntimeDirectory = "myService";
      RootDirectory = "/run/myService";

      BindReadOnlyPaths = [
        "/nix/store"

        # So tmux uses /bin/sh as shell
        "/bin"
      ];

      # This sets up a private /dev/tty
      # The tmux server would crash without this
      # since there would be nothing in /dev
      PrivateDevices = true;
    };
  };
}

To attach to the shell, simply execute tmux -S /path/to/tmux.socket attach.

Hardening examples

This list contains proposed hardening options that are not yet upstreamed. Please use with caution, and please notify the author of the change if something breaks: