<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">2018-01-16 13:52 GMT+01:00 Daniel Stirnimann <span dir="ltr"><<a href="mailto:daniel.stirnimann@switch.ch" target="_blank">daniel.stirnimann@switch.ch</a>></span>:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hello all,<br>
<br>
Just wondering, if one is already using selinux in enforcing mode, does<br>
systemd hardening provide any additional benefit?<br></blockquote><div><br></div><div>Very good question, I'm not sure at all:</div><div>To my understanding, it might be complementary, at least it's possible in systemd config to apply a SELinux context:</div><div><a href="https://www.freedesktop.org/software/systemd/man/systemd.exec.html#Mandatory%20Access%20Control">https://www.freedesktop.org/software/systemd/man/systemd.exec.html#Mandatory%20Access%20Control</a><br></div><div><br></div><div>It's clearly possible that all options we have put in the systemd config file has an equivalent in SELinux/AppArmor/SMACK and that its propose more security options than systemd. But I have only basic knowledge on these technologies, interested in by feedbacks from a person who has written rules with that.</div><div><br></div><div>The main advantage I see to work on this systemd config file is to increase the default security configuration in major distributions without extra dependencies: 99% of people don't customize the default daemons config setup, and SELinux/AppArmor/SMACK aren't always used.</div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
Daniel<br>
<div><div class="gmail-h5"><br>
On 16.01.18 12:21, Ludovic Gasc wrote:<br>
> Hi,<br>
><br>
> I have merged config files from Tony, Robert, and me.<br>
> I have tried to be the most generic, the result below.<br>
><br>
> It seems to work here without regression, except a warning:<br>
> managed-keys-zone: Unable to fetch DNSKEY set '.': operation canceled<br>
><br>
> But only at the first boot, I don't see the message anymore when I<br>
> restart the daemon.<br>
> Any clue ?<br>
><br>
> Thanks for your feedbacks.<br>
><br>
> [Unit]<br>
> After=network-online.target<br>
><br>
> [Service]<br>
> Type=simple<br>
> TimeoutSec=25<br>
> Restart=always<br>
> RestartSec=1<br>
> User=bind<br>
> Group=bind<br>
> CapabilityBoundingSet=CAP_NET_<wbr>BIND_SERVICE<br>
> AmbientCapabilities=CAP_NET_<wbr>BIND_SERVICE<br>
> SystemCallFilter=~@mount @debug acct modify_ldt add_key adjtimex<br>
> clock_adjtime delete_module fanotify_init finit_module get_mempolicy<br>
> init_module io_destroy io_getevents iopl ioperm io_setup io_submit<br>
> io_cancel kcmp kexec_load keyctl lookup_dcookie migrate_pages move_pages<br>
> open_by_handle_at perf_event_open process_vm_readv process_vm_writev<br>
> ptrace remap_file_pages request_key set_mempolicy swapoff swapon uselib<br>
> vmsplice<br>
><br>
> NoNewPrivileges=true<br>
> PrivateDevices=true<br>
> PrivateTmp=true<br>
> ProtectHome=true<br>
> ProtectSystem=strict<br>
> ProtectKernelModules=true<br>
> ProtectKernelTunables=true<br>
> ProtectControlGroups=true<br>
> InaccessiblePaths=/home<br>
> InaccessiblePaths=/opt<br>
> InaccessiblePaths=/root<br>
> ReadWritePaths=/run/named<br>
> ReadWritePaths=/var/cache/bind<br>
> ReadWritePaths=/var/lib/bind<br>
><br>
><br>
> --<br>
> Ludovic Gasc (GMLudo)<br>
><br>
> 2018-01-15 21:14 GMT+01:00 Robert Edmonds <<a href="mailto:edmonds@mycre.ws">edmonds@mycre.ws</a><br>
</div></div>> <mailto:<a href="mailto:edmonds@mycre.ws">edmonds@mycre.ws</a>>>:<br>
><br>
>     Tony Finch wrote:<br>
<div><div class="gmail-h5">>     > Ludovic Gasc <<a href="mailto:gmludo@gmail.com">gmludo@gmail.com</a> <mailto:<a href="mailto:gmludo@gmail.com">gmludo@gmail.com</a>>> wrote:<br>
>     > ><br>
>     > > 1. The list of minimal capabilities needed for bind to run correctly:<br>
>     > > <a href="http://man7.org/linux/man-pages/man7/capabilities.7.html" rel="noreferrer" target="_blank">http://man7.org/linux/man-<wbr>pages/man7/capabilities.7.html</a><br>
>     <<a href="http://man7.org/linux/man-pages/man7/capabilities.7.html" rel="noreferrer" target="_blank">http://man7.org/linux/man-<wbr>pages/man7/capabilities.7.html</a><wbr>><br>
>     ><br>
>     > named already drops capabilities - have a look at the code around here:<br>
>     > <a href="https://source.isc.org/cgi-bin/gitweb.cgi?p=bind9.git;a=blob;f=bin/named/unix/os.c;hb=v9_11_2#l234" rel="noreferrer" target="_blank">https://source.isc.org/cgi-<wbr>bin/gitweb.cgi?p=bind9.git;a=<wbr>blob;f=bin/named/unix/os.c;hb=<wbr>v9_11_2#l234</a><br>
>     <<a href="https://source.isc.org/cgi-bin/gitweb.cgi?p=bind9.git;a=blob;f=bin/named/unix/os.c;hb=v9_11_2#l234" rel="noreferrer" target="_blank">https://source.isc.org/cgi-<wbr>bin/gitweb.cgi?p=bind9.git;a=<wbr>blob;f=bin/named/unix/os.c;hb=<wbr>v9_11_2#l234</a>><br>
>     ><br>
>     > Note that it's a bit clever - the privileges are dropped in two stages,<br>
>     > right at the start, and after the server has been configured.<br>
><br>
>     I checked just now to see what that code actually ends up doing, and on<br>
>     my system I ended up with:<br>
><br>
>         $ grep -h ^Cap /proc/$(pidof named)/**/status | sort | uniq -c<br>
>               6 CapAmb:     0000000000000000<br>
>               6 CapBnd:     0000003fffffffff<br>
>               6 CapEff:     0000000001000400<br>
>               6 CapInh:     0000000000000000<br>
>               6 CapPrm:     0000000001000400<br>
>         $<br>
><br>
>     That decodes to:<br>
><br>
>      - The effective and permitted capabilities sets were reduced to<br>
>        CAP_NET_BIND_SERVICE and CAP_SYS_RESOURCE.<br>
><br>
>      - The ambient and inheritable capabilities sets were cleared.<br>
><br>
>      - The capability bounding set was left completely open-ended.<br>
><br>
>     It's not clear why CAP_SYS_RESOURCE needs to be retained past startup:<br>
><br>
>             /*<br>
>              * XXX  We might want to add CAP_SYS_RESOURCE, though it's not<br>
>              *      clear it would work right given the way linuxthreads<br>
>     work.<br>
>              * XXXDCL But since we need to be able to set the maximum number<br>
>              * of files, the stack size, data size, and core dump size to<br>
>              * support named.conf options, this is now being added to test.<br>
>              */<br>
>             SET_CAP(CAP_SYS_RESOURCE);<br>
><br>
>     See commits 5e4b7294d88ab58371d8c98e05ea80<wbr>086dcb67cd,<br>
>     108490a7f8529aff50a0ac7897580b<wbr>59a73d9845. "[T]o test"?<br>
><br>
>     CAP_SYS_RESOURCE is documented as permitting:<br>
><br>
>        CAP_SYS_RESOURCE<br>
>               * Use reserved space on ext2 filesystems;<br>
>               * make ioctl(2) calls controlling ext3 journaling;<br>
>               * override disk quota limits;<br>
>               * increase resource limits (see setrlimit(2));<br>
>               * override RLIMIT_NPROC resource limit;<br>
>               * override maximum number of consoles on console allocation;<br>
>               * override maximum number of keymaps;<br>
>               * allow more than 64hz interrupts from the real-time clock;<br>
>               * raise msg_qbytes limit for a System V message queue<br>
>     above  the<br>
>                 limit in /proc/sys/kernel/msgmnb (see msgop(2) and<br>
>     msgctl(2));<br>
>               * allow  the  RLIMIT_NOFILE resource limit on the number<br>
>     of "in-<br>
>                 flight" file descriptors to  be  bypassed  when <br>
>     passing  file<br>
>                 descriptors  to  another process via a UNIX domain<br>
>     socket (see<br>
>                 unix(7));<br>
>               * override the /proc/sys/fs/pipe-size-max limit when<br>
>     setting the<br>
>                 capacity of a pipe using the F_SETPIPE_SZ fcntl(2) command.<br>
>               * use  F_SETPIPE_SZ to increase the capacity of a pipe<br>
>     above the<br>
>                 limit specified by /proc/sys/fs/pipe-max-size;<br>
>               * override /proc/sys/fs/mqueue/queues_<wbr>max  limit  when <br>
>     creating<br>
>                 POSIX message queues (see mq_overview(7));<br>
>               * employ the prctl(2) PR_SET_MM operation;<br>
>               * set  /proc/[pid]/oom_score_adj to a value lower than the<br>
>     value<br>
>                 last set by a process with CAP_SYS_RESOURCE.<br>
><br>
>     I would guess that retaining CAP_NET_BIND_SERVICE and CAP_SYS_RESOURCE<br>
>     during the process runtime permits open-ended reloading of the config at<br>
>     runtime (e.g., binding to a new IP address on port 53 without needing to<br>
>     restart the daemon). So even though BIND drops some capabilities, it's<br>
>     still running with elevated privileges compared to a traditional<br>
>     non-root user.<br>
><br>
>     systemd permits a nice pattern for network daemons that want to run as<br>
>     an unprivileged user, but bind to a privileged port (and without using<br>
>     socket activation), without starting the process as root. Basically, you<br>
>     put something like this in the unit file:<br>
><br>
>         [Service]<br>
>         User=…<br>
>         Group=…<br>
>         CapabilityBoundingSet=CAP_NET_<wbr>BIND_SERVICE CAP_SYS_CHROOT<br>
>     CAP_SETPCAP<br>
>         AmbientCapabilities=CAP_NET_<wbr>BIND_SERVICE CAP_SYS_CHROOT CAP_SETPCAP<br>
>         …<br>
><br>
>     Any needed filesystem directories and permissions need to be set up<br>
>     correctly before hand. The service is started by the init system as the<br>
>     unprivileged User/Group specified in the unit file, so there's no need<br>
>     to change UID/GID. CAP_NET_BIND_SERVICE is then used to bind to a<br>
>     privileged port, CAP_SYS_CHROOT is used to perform the chroot, and<br>
>     CAP_SETPCAP is used to drop all remaining capabilities from the<br>
>     capability sets and the capability bounding set, so you end up with a<br>
>     completely unprivileged process at runtime. (Alternatively you could<br>
>     keep CAP_NET_BIND_SERVICE and drop CAP_SYS_CHROOT and CAP_SETPCAP, if<br>
>     you wanted to retain the capability to perform privileged binds at<br>
>     runtime. Or you could eliminate CAP_SYS_CHROOT and use other systemd<br>
>     functionality to make parts of the filesystem inaccessible, etc.) This<br>
>     pattern might be a bit hard to retrofit into BIND at this point, though,<br>
>     other than by adding more knobs.<br>
><br>
>     --<br>
>     Robert Edmonds<br>
>     ______________________________<wbr>_________________<br>
>     Please visit <a href="https://lists.isc.org/mailman/listinfo/bind-users" rel="noreferrer" target="_blank">https://lists.isc.org/mailman/<wbr>listinfo/bind-users</a><br>
>     <<a href="https://lists.isc.org/mailman/listinfo/bind-users" rel="noreferrer" target="_blank">https://lists.isc.org/<wbr>mailman/listinfo/bind-users</a>> to unsubscribe<br>
>     from this list<br>
><br>
>     bind-users mailing list<br>
</div></div>>     <a href="mailto:bind-users@lists.isc.org">bind-users@lists.isc.org</a> <mailto:<a href="mailto:bind-users@lists.isc.org">bind-users@lists.isc.<wbr>org</a>><br>
>     <a href="https://lists.isc.org/mailman/listinfo/bind-users" rel="noreferrer" target="_blank">https://lists.isc.org/mailman/<wbr>listinfo/bind-users</a><br>
>     <<a href="https://lists.isc.org/mailman/listinfo/bind-users" rel="noreferrer" target="_blank">https://lists.isc.org/<wbr>mailman/listinfo/bind-users</a>><br>
<div class="gmail-HOEnZb"><div class="gmail-h5">><br>
______________________________<wbr>_________________<br>
Please visit <a href="https://lists.isc.org/mailman/listinfo/bind-users" rel="noreferrer" target="_blank">https://lists.isc.org/mailman/<wbr>listinfo/bind-users</a> to unsubscribe from this list<br>
<br>
bind-users mailing list<br>
<a href="mailto:bind-users@lists.isc.org">bind-users@lists.isc.org</a><br>
<a href="https://lists.isc.org/mailman/listinfo/bind-users" rel="noreferrer" target="_blank">https://lists.isc.org/mailman/<wbr>listinfo/bind-users</a></div></div></blockquote></div><br></div></div>