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/postfix: systemd sandbox #93305
base: master
Are you sure you want to change the base?
Conversation
ln -sf /var/spool/mail /var/ | ||
|
||
#Finally delegate to postfix checking remain directories in /var/lib/postfix and set permissions on them | ||
${pkgs.postfix}/bin/postfix set-permissions config_directory=/var/lib/postfix/conf |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The sandbox is incomplete here. This will still run postfix
as root, although I don't know whether there is a way around it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assumed it is acceptable to have no sandbox for the prepare script, because it does not run as a network daemon.
Should put it in a sandbox as well?
To my knowledge the "main daemon" has to be run as root. It drops privileges for it's children, but there is no tight systemd integration. I am open for suggestions. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. In that case I'm not sure whether there is any benefit from running postfix set-permission
in the sandbox.
PrivateTmp = true; | ||
ProtectClock = true; | ||
ProtectControlGroups = true; | ||
ProtectHome = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Won’t this break .forward, or delivering mail to a local user’s home directory?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. Replacing ProtectHome=true
by ReadOnlyPaths=/home
would allow to read .forward. For delivery to the home directory this has to be disabled entirely.
Should this be behind an option? If yes, how whould an option look like?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would suggest you don't put this behind an option - don't include it at all. It isn't a reasonable default for a mail server. Add documentation so users who can and wish to will know how to add it.
It's probably a good idea to also discuss this with the people from simple-nixos-mailserver @r-raymond |
@hmenke thanks for the heads up, I'll ping the current maintainers. |
Thanks for the heads up, and thanks for these patches! I really like this idea;) Did you run the nixos-mailserver tests with your patches? I will do it this WE. |
I have not yet run any of the official tests. Just tested my usecase for now. |
wantedBy = [ "multi-user.target" ]; | ||
before = [ "postifx.service" ]; | ||
serviceConfig = { | ||
ExecStart = preparePostfixScript; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't you run this in the original service as an ExecStartPre
with the +
prefix?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, the +
prefix looks good. I will fix my patches.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How is this kind of sandboxing going to interact with non-trivial Postfix installations that run, say a mailing list server or reflector scripts or any other mail service that needs resources other than Postfix itself?
Running the daemon in a sandbox feels like a rather intrusive change. This should definitely be opt-in.
I will try to do something like services.nginx.enableSandbox. |
@Mic92 given @tnias I'm not in favor of module randomly adding
|
The fixup changes loosen up rules to allow more general actions.
|
Rules systemd.tmpfiles can be taken from here - #76604 |
3e7b9c7
to
a4f4dd2
Compare
I used @Izorkin's tmpfiles patch and addded some (hopefully) reasonable sandboxing options. |
There are some permission/ownership issues in the /var/lib/postfix directory. |
@tnias nixos-mailserver tests passed with this patchset. |
@nlewo I just cleared my /var/lib/postfix directory and now it works just fine. I probably messed up the permissions at some point. ¯_(ツ)_/¯ |
I ran into the |
3276da3
to
7b285fb
Compare
ProtectKernelLogs = true; | ||
ProtectKernelModules = true; | ||
ProtectKernelTunables = true; | ||
ProtectSystem = "full"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this still allow other milters? I know that our rspamd integration for postfix for example creates a socket in /run/rspamd/rspamd-milter.sock
, opendkim might be similar.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIUC, the full
value still allows RW accesses to /run
.
Also, I've run the nixos-mailserver tests (rspamd, opendkim, dovecot,...) on top of this patch and tests passed.
@GrahamcOfBorg test rspamd |
Still any blocker on this? |
And here I was thinking it would be really nice to not have this in |
I would also say to have it tested in unstable for a bit longer and merge it after the branch-off. Postfix itself already does quite a bit of privilege separation so these sandboxes would not improve too much in terms of security. |
Due to the use of
Such option merging conflict happens regularly to me and others #97371 |
Was this closed on purpose? |
@Mic92 There seemed to be little action around it and in the spirit of reducing the number of open PRs I closed it. We can also keep it open if you prefer. |
@tnias I think it just take some time to make sure that postfix does not break. |
/marvin opt-in |
We're roughly 4-5 months away from a new release. This change presents high enough risk that I would love to see it merged very soon. 4-5 months sounds like a long enough time to break and fix enough machines that we don't have to worry when this goes stable. Just a thought... |
|
||
ReadWritePaths = [ "/var/lib/postfix" "/var/spool/mail" ]; | ||
|
||
CapabilityBoundingSet = [ "CAP_DAC_OVERRIDE" "CAP_NET_BIND_SERVICE" "CAP_SETGID" "CAP_SETUID" ]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tnias Have you checked if postfix drops these capabilities for its less-privileged childs?
Otherwise it might make postfix less secure than it was before (those capabilities allow to read/write arbitrary files and change to different users/groups).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Before this update
Master process:
CapInh: 0000000000000000
CapPrm: 000001ffffffffff
CapEff: 000001ffffffffff
CapBnd: 000001ffffffffff
CapAmb: 0000000000000000
Slave process:
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: 000001ffffffffff
CapAmb: 0000000000000000
0x000001ffffffffff=cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,cap_audit_read,cap_perfmon,cap_bpf,cap_checkpoint_restore
After this update:
Master process:
CapInh: 0000000000000000
CapPrm: 00000000000004c2
CapEff: 00000000000004c2
CapBnd: 00000000000004c2
CapAmb: 0000000000000000
Slave process:
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: 00000000000004c2
CapAmb: 0000000000000000
0x00000000000004c2=cap_dac_override,cap_setgid,cap_setuid,cap_net_bind_service
I marked this as stale due to inactivity. → More info |
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/hardening-systemd-services/17147/7 |
FWIW, I've proposed a smaller set of hardening directives in #255227, inspired by Gentoo's. |
Motivation for this change
Add systemd service sandbox features.
Things done
sandbox
innix.conf
on non-NixOS linux)nix-shell -p nixpkgs-review --run "nixpkgs-review wip"
./result/bin/
)nix path-info -S
before and after)cc: postfix maintainers @rickynils @globin