Hardening systemd services

I think it’s vague, a network-service class could have programs such as

  • unbound
  • nsd
  • samba

you can’t really have the same hardening for them, unbound could work without persistent data requirement, nsd could use only an user defined configuration, samba would need to access the filesystem.

I don’t think classes of this kind could be used.

Using systemd-analyze security is the way to see how a service is hardened, so you don’t have to dig in nixpkgs :slight_smile:

1 Like

Emphasis on default - nix allows overriding these things really easily for the specific service you need already. This proposal just reduces boilerplate, makes it easier for contributors with less experience to know what they should be setting, and advertises that these things are possible to those who don’t know yet.

Your mixins-alike approach is similar, and probably matches the underlying setting types better, but this one fits better within the existing nixpkgs module system. I think both are good suggestions.

only works if I have the service already installed, which if I’m considering whether I should be using one I probably don’t - and installing it for the sake of checking is about as much effort as looking at its module (perhaps less, considering download times vs my existing local copy of nixpkgs).

But yes, systemd-analyze security is very handy for checking the state of my running system :slight_smile:

3 Likes

Indeed, I didn’t think about the case in which you would want to know about the service without installing it.

There is a bunch of good practices and code examples about how to
securize systemd services in nix-bitcoin project:

Nginx has a bunch of recommended* options around security. These options set the defaults for other options. Maybe such a scheme is applicable to systems services as well?

systemd.services.<name>.recommendedHardening or splitting it up into multiple recommendations. Because this only sets defaults of other options, you can still easily override it for a specific service.

1 Like

Are there any general hardening guidelines after all? I don’t really like how many services run as root with full privileges…

saw wiki - it’s something, but not much after all.

Also the idea of having to harden all/most services from nixpkgs frustrates me as a beginner

4 Likes

I had an idea for something similar in form of additional attrset within systemd service specification:

harden = {
  basic = true; # basic setup, like RPC, no SUID, etc. 
  execOnlyNix = true; # allow executing only binaries from `/nix/store`
  protectKernel = true; # disable access to kernel logs, modules and tunables
  proc = true; # limit unit view into `/proc`
  systemCall = true; # limit system calls and allow only native system call facilities (important on x86-64
  onlyLocalhost = true; # allow listening only on localhost
}

I am not 100% sure about the naming of the hardening parts, but the idea is there to discuss.

I have created draft PR with implementation of such options

1 Like

That’s a lot better than my idea. And you even have a prototype!

What I find critical is that it’s opt-in rather than opt-out. I think it should be the other way around. Rather than enumerating the things it shouldn’t do, you should enumerate the things the service depends on for its function and block everything else by default.

Your “basic” set of hardening allows networking and unix sockets for instance but some services shouldn’t even have access to that. It’d be great if I could declare such a service simply by saying harden.enable = true;.

If I had a similarly basic service but it needs network access, I would then be able to say:

{
  ...service.harden = {
    enable = true;
    networking = true;
  };
}

which would set RestrictAddressFamilies = [ AF_INET" "AF_INET6" ];

Yes, but I wanted to start without breaking everything in this PR, as for example sshd in most cases will require almost all of these options disabled.

EDIT: I got what you meant. I have changed the PR to address that and now it uses harden.enable to enable everything and then you can opt-out of some hardening options.

Yeah, but I am still learning Nixpkgs modules type system and I haven’t yet checked if this accepts sum types like that.

Yeah, that would be reasonable. And by default we could allow only AF_UNIX sockets or none at all.