I just noticed I broke gzip(1) by blocking fchown(2). Attached is what I'm using now (see especially SystemCallFilter=).
# FIXME: convince upstream to use logrotate instead of an equivalent sh script! [Service] PrivateNetwork=yes User=ntpsec PrivateUsers=yes PrivateNetwork=yes CapabilityBoundingSet= RestrictAddressFamilies=AF_UNIX PrivateDevices=yes PrivateTmp=yes ProtectHome=yes ProtectControlGroups=yes ProtectKernelModules=yes ProtectKernelTunables=yes ProtectSystem=strict ReadWritePaths=-/var/log/ntpsec/ WorkingDirectory=/var/log/ntpsec IPAddressDeny=any SystemCallArchitectures=native RestrictNamespaces=yes NoNewPrivileges=yes
# This is the conservative baseline suggested by "systemd-analyze security". # It breaks because gzip tries to call fchown(2). #SystemCallFilter=@system-service #SystemCallFilter=~@privileged @resources # This doesn't work because the aliases "overlap" #SystemCallFilter=@system-service @chown #SystemCallFilter=~@privileged @resources # Doing it as "add lots, then remove some, then re-add a little" works. # If that made no sense, try wdiffing before/after of "systemctl show", # to see the exact list of syscalls that end up in the allow list. SystemCallFilter=@system-service SystemCallFilter=~@privileged @resources SystemCallFilter=@chown RestrictRealtime=yes LockPersonality=yes RemoveIPC=yes MemoryDenyWriteExecute=yes # FIXME: ntpsec logs are world-readable. Should we restrict them to e.g. adm group? UMask=022 # Resource exhaustion (i.e. DOS) isn't covered by "systemd-analyze security", but # WE care about it. This is the lowest priority available. # See also logrotate.service. # MemoryHigh= mitigates read-once jobs flushing fscache (see https://github.com/Feh/nocache) # TasksMax= mitigates accidental forkbombs. # CPUQuota=100% limits the slice to equivalent of 100% of a single CPU core # CPUWeight= [Service] Nice=19 CPUSchedulingPolicy=batch IOSchedulingClass=idle MemoryHigh=128M TasksMax=16 CPUQuota=50%
Jun 04 06:25:01 not-omega systemd[1]: cron-sysstat-root-0.service: Succeeded. Jun 04 06:25:01 not-omega systemd[1]: Started [Cron] "5-55/10 * * * * root command -v debian-sa1 > /dev/null && debian-sa1 1 1". Jun 04 06:25:01 not-omega systemd[1]: cron-sysstat-root-0.service: Consumed 2ms CPU time, no IP traffic. Jun 04 06:25:01 not-omega systemd[1]: cron-ntpsec-root-0.service: Succeeded. Jun 04 06:25:01 not-omega systemd[1]: Started [Cron] "25 6 * * * root if [ ! -d /run/systemd/system ] && [ -x /usr/lib/ntp/rotate-stats ]; then /usr/lib/ntp/rotate-stats; fi". Jun 04 06:25:01 not-omega systemd[1]: cron-ntpsec-root-0.service: Consumed 1ms CPU time, no IP traffic. Jun 04 06:25:01 not-omega systemd[1]: cron-daily.service: Succeeded. Jun 04 06:25:01 not-omega systemd[1]: Started systemd-cron daily script service. Jun 04 06:25:01 not-omega systemd[1]: cron-daily.service: Consumed 213ms CPU time, received 3.9K IP traffic, sent 1.0K IP traffic. Jun 04 06:25:01 not-omega systemd[1]: Reached target systemd-cron daily target. Jun 04 06:25:01 not-omega systemd[1]: Stopped target systemd-cron daily target. Jun 04 06:25:01 not-omega rotate-stats[30067]: gzip: loopstats.20190530.gz already exists; not overwritten Jun 04 06:25:01 not-omega rotate-stats[30067]: gzip: loopstats.20190531.gz already exists; not overwritten Jun 04 06:25:01 not-omega rotate-stats[30067]: gzip: loopstats.20190601.gz already exists; not overwritten Jun 04 06:25:01 not-omega audit[30167]: SECCOMP auid=4294967295 uid=107 gid=114 ses=4294967295 subj==unconfined pid=30167 comm="gzip" exe="/usr/bin/gzip" sig=31 arch=c000003e syscall=93 compat Jun 04 06:25:01 not-omega kernel: audit: type=1326 audit(1559593501.751:53): auid=4294967295 uid=107 gid=114 ses=4294967295 subj==unconfined pid=30167 comm="gzip" exe="/usr/bin/gzip" sig=31 ar Jun 04 06:25:01 not-omega systemd[1]: Started Process Core Dump (PID 30168/UID 0). Jun 04 06:25:02 not-omega rotate-stats[30067]: Bad system call (core dumped) Jun 04 06:25:02 not-omega systemd[1]: ntpsec-rotate-stats.service: Main process exited, code=exited, status=159/n/a Jun 04 06:25:02 not-omega systemd[1]: ntpsec-rotate-stats.service: Failed with result 'exit-code'. Jun 04 06:25:02 not-omega systemd[1]: ntpsec-rotate-stats.service: Consumed 61ms CPU time, no IP traffic. Jun 04 06:25:03 not-omega systemd-coredump[30169]: Process 30167 (gzip) of user 107 dumped core. Stack trace of thread 30167: #0 0x00007f61abfab667 fchown (libc.so.6) #1 0x000055ce0462865e n/a (gzip) #2 0x000055ce04624b27 n/a (gzip) #3 0x00007f61abee409b __libc_start_main (libc.so.6) #4 0x000055ce04624cfa n/a (gzip) Jun 04 06:25:03 not-omega systemd[1]: systemd-coredump@4-30168-0.service: Succeeded. Jun 04 06:25:03 not-omega systemd[1]: systemd-coredump@4-30168-0.service: Consumed 129ms CPU time, no IP traffic. Jun 04 06:35:01 not-omega systemd[1]: Starting [Cron] "5-55/10 * * * * root command -v debian-sa1 > /dev/null && debian-sa1 1 1"... Jun 04 06:35:01 not-omega systemd[1]: cron-sysstat-root-0.service: Succeeded. Jun 04 06:35:01 not-omega systemd[1]: Started [Cron] "5-55/10 * * * * root command -v debian-sa1 > /dev/null && debian-sa1 1 1". Jun 04 06:35:01 not-omega systemd[1]: cron-sysstat-root-0.service: Consumed 2ms CPU time, no IP traffic. Jun 04 06:45:01 not-omega systemd[1]: Starting [Cron] "5-55/10 * * * * root command -v debian-sa1 > /dev/null && debian-sa1 1 1"... Jun 04 06:45:01 not-omega systemd[1]: cron-sysstat-root-0.service: Succeeded. Jun 04 06:45:01 not-omega systemd[1]: Started [Cron] "5-55/10 * * * * root command -v debian-sa1 > /dev/null && debian-sa1 1 1". Jun 04 06:45:01 not-omega systemd[1]: cron-sysstat-root-0.service: Consumed 2ms CPU time, no IP traffic. Jun 04 06:55:01 not-omega systemd[1]: Starting [Cron] "5-55/10 * * * * root command -v debian-sa1 > /dev/null && debian-sa1 1 1"... Jun 04 06:55:01 not-omega systemd[1]: cron-sysstat-root-0.service: Succeeded. Jun 04 06:55:01 not-omega systemd[1]: Started [Cron] "5-55/10 * * * * root command -v debian-sa1 > /dev/null && debian-sa1 1 1". Jun 04 06:55:01 not-omega systemd[1]: cron-sysstat-root-0.service: Consumed 2ms CPU time, no IP traffic. Jun 04 07:05:01 not-omega systemd[1]: Starting [Cron] "5-55/10 * * * * root command -v debian-sa1 > /dev/null && debian-sa1 1 1"... Jun 04 07:05:01 not-omega systemd[1]: cron-sysstat-root-0.service: Succeeded. Jun 04 07:05:01 not-omega systemd[1]: Started [Cron] "5-55/10 * * * * root command -v debian-sa1 > /dev/null && debian-sa1 1 1". Jun 04 07:05:01 not-omega systemd[1]: cron-sysstat-root-0.service: Consumed 2ms CPU time, no IP traffic. Jun 04 07:15:01 not-omega systemd[1]: Starting [Cron] "5-55/10 * * * * root command -v debian-sa1 > /dev/null && debian-sa1 1 1"... Jun 04 07:15:01 not-omega systemd[1]: cron-sysstat-root-0.service: Succeeded. Jun 04 07:15:01 not-omega systemd[1]: Started [Cron] "5-55/10 * * * * root command -v debian-sa1 > /dev/null && debian-sa1 1 1". Jun 04 07:15:01 not-omega systemd[1]: cron-sysstat-root-0.service: Consumed 2ms CPU time, no IP traffic. Jun 04 07:17:01 not-omega systemd[1]: Condition check resulted in systemd-cron hourly script service being skipped. lines 208-259