Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nixos/rspamd: add sandbox #93293

Merged
merged 3 commits into from Dec 1, 2020
Merged

nixos/rspamd: add sandbox #93293

merged 3 commits into from Dec 1, 2020

Conversation

tnias
Copy link
Contributor

@tnias tnias commented Jul 16, 2020

Motivation for this change

Better systemd service sandboxing.

Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS linux)
  • Built on platform(s)
    • NixOS
    • macOS
    • other Linux distributions
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Determined the impact on package closure size (by running nix path-info -S before and after)
  • Ensured that relevant documentation is up to date
  • Fits CONTRIBUTING.md.

cc rspamd maintainers @avnik @fpletz @globin

@tnias tnias requested a review from peti as a code owner July 16, 2020 19:10
Drop preStart script in favour of systemd StateDirectory parameter.
Copy link
Member

@peti peti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a bunch of DKIM signing keys in /etc/pki/dkim. Can rspamd still read those after those changes take effect?

@Mic92
Copy link
Member

Mic92 commented Jul 17, 2020

I have a bunch of DKIM signing keys in /etc/pki/dkim. Can rspamd still read those after those changes take effect?

They need to be readable by the rspamd user. Maybe this should be mentioned in the changelog.

@peti
Copy link
Member

peti commented Jul 17, 2020

They need to be readable by the rspamd user.

Is that a new requirement created by this PR? I was under the impression that it needs to be this way since, like, forever.

@tnias
Copy link
Contributor Author

tnias commented Jul 17, 2020

ProtectSystem=strict mounts / as ro, so reading something in /etc should work as before.

@peti
Copy link
Member

peti commented Jul 17, 2020

That sounds good. In that case, I am basically in favor of this change. I do think it's necessary to do a good deal of testing before it's merged, though, because the consequences of accidentally breaking the mail system are really bad.

@Mic92
Copy link
Member

Mic92 commented Jul 18, 2020

They need to be readable by the rspamd user.

Is that a new requirement created by this PR? I was under the impression that it needs to be this way since, like, forever.

I have not tested but I saw that this pr changes from letting the service them-self dropping privileges to starting as a user in the first place. Some services take the opportunity to read secret files before dropping privileges. If that is not the case ignore my comment.

@Mic92
Copy link
Member

Mic92 commented Jul 18, 2020

Regarding testing, I suggest to add those hardening options to https://github.com/rspamd/rspamd/blob/master/rspamd.service as well and let the rspamd maintainers have a look at it in a pr. We don't need to wait from them to merge it, but they usually have better ideas about the internals. We did something similar for netdata: netdata/netdata#9234
If they merge it we can take it from there and they hopefully update & maintain it according to the privileges rspamd needs.

@tnias
Copy link
Contributor Author

tnias commented Jul 18, 2020

Cosmetics fixed. I will create an upstream PR for the hardening options.

@aanderse
Copy link
Member

Some services take the opportunity to read secret files before dropping privileges.

From my experience this was a common pattern in software developed back in the 90s-2000s which start as root and then drop privileges, so a very relevant comment 👍

@Mic92
Copy link
Member

Mic92 commented Jul 28, 2020

@tnias remind if in a few days. If upstream does not want to review it, we just go ahead.


preStart = ''
${pkgs.coreutils}/bin/mkdir -p /var/lib/rspamd
${pkgs.coreutils}/bin/chown ${cfg.user}:${cfg.group} /var/lib/rspamd
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just applied to to my server but when upgrading. I noticed that some files
include /var/lib/rspam/rspamd.sock where still owned by root. It looks like StateDirectory is not applied recursively if /var/lib/rspamd is owned by rspamd.

I would add a ExecStartPre that with mkIf versionOlder stateVersion "20.09" that does

ExecStartPre = "+${pkgs.coreutils}/bin/chown -R ${cfg.user}:${cfg.group} /var/lib/rspamd";

@Mic92
Copy link
Member

Mic92 commented Jul 30, 2020

Someone also tested this on archlinux according to the thread.
@dasJ did you had another rspamd instance to test this on?

@dasJ
Copy link
Member

dasJ commented Jul 30, 2020

@Mic92 I didn't really look over this PR, but my setup runs pretty well with #87661 and these additional overrides:

{
      serviceConfig = {
        ExecStart = "${pkgs.rspamd}/bin/rspamd ${optionalString cfg.debug "-d"} -c /etc/rspamd/rspamd.conf -f";
        Restart = "always";

        User = "rspamd";
        Group = "rspamd";

        StateDirectory = "rspamd";
        RuntimeDirectory = "rspamd";

        MemoryDenyWriteExecute = false;
        SystemCallFilter = "@basic-io @file-system @network-io @system-service"; # @system-service is **probably** enough
        PrivateNetwork = false;
        RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6";
      };
}

@Mic92
Copy link
Member

Mic92 commented Jul 30, 2020

@Mic92 I didn't really look over this PR, but my setup runs pretty well with #87661 and these additional overrides:

{
      serviceConfig = {
        ExecStart = "${pkgs.rspamd}/bin/rspamd ${optionalString cfg.debug "-d"} -c /etc/rspamd/rspamd.conf -f";
        Restart = "always";

        User = "rspamd";
        Group = "rspamd";

        StateDirectory = "rspamd";
        RuntimeDirectory = "rspamd";

        MemoryDenyWriteExecute = false;
        SystemCallFilter = "@basic-io @file-system @network-io @system-service"; # @system-service is **probably** enough

@System-service includes the other 3.

    PrivateNetwork = false;
    RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6";
  };

}

@@ -394,16 +394,43 @@ in
restartTriggers = [ rspamdDir ];

serviceConfig = {
ExecStart = "${pkgs.rspamd}/bin/rspamd ${optionalString cfg.debug "-d"} --user=${cfg.user} --group=${cfg.group} --pid=/run/rspamd.pid -c /etc/rspamd/rspamd.conf -f";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just noticed one regression, when postfix.enable = true, then the rspamd socket is chowned to postfix. However this no longer works if rspamd is started as rspamd user right away because of lacking permissions.

@Mic92
Copy link
Member

Mic92 commented Aug 1, 2020

@GrahamcOfBorg test rspamd

@Mic92
Copy link
Member

Mic92 commented Aug 1, 2020

The postfixIntegration test broke with this PR.

@symphorien symphorien mentioned this pull request Aug 26, 2020
11 tasks
@Mic92
Copy link
Member

Mic92 commented Sep 19, 2020

@tnias are you still interested in fixing postfix integration?

@tnias
Copy link
Contributor Author

tnias commented Sep 19, 2020

@Mic92 I have not yet found a way I really like. I think in my current setup the socket is accessible to world, but that is not really an elegant solution.

If anyone has ideas or a patches I'd be happy to see and integrate those. Or if anyone wants to take over I would be good with that, too. :)

@Mic92
Copy link
Member

Mic92 commented Sep 20, 2020

@Mic92 I have not yet found a way I really like. I think in my current setup the socket is accessible to world, but that is not really an elegant solution.

If anyone has ideas or a patches I'd be happy to see and integrate those. Or if anyone wants to take over I would be good with that, too. :)

acl might be able to solve this, but this might not work on all filesystems, we support.

@mweinelt
Copy link
Member

As the upstream seems unwilling to move forward, what needs to be resolved to merger this downstream?

@Mic92
Copy link
Member

Mic92 commented Nov 23, 2020

@mweinelt postfix integration needs to be fixed #93293 (comment)

@Mic92
Copy link
Member

Mic92 commented Nov 29, 2020

I fixed postfix integration.

@Mic92
Copy link
Member

Mic92 commented Nov 29, 2020

Some of the other nixos tests are still broken.

@Mic92
Copy link
Member

Mic92 commented Nov 30, 2020

All tests are fixed now.

@tnias
Copy link
Contributor Author

tnias commented Nov 30, 2020

Thx 😍

@symphorien
Copy link
Member

Simple nixos mailserver tests still pass.

@symphorien
Copy link
Member

For some reason I cannot merge this

image

@Mic92 Mic92 merged commit b1ed5ff into NixOS:master Dec 1, 2020
@Mic92
Copy link
Member

Mic92 commented Dec 1, 2020

For some reason I cannot merge this

image

Usually a reload helps. It happens when someone else has merged something just before you and github has not yet checked if the code can be merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants