From 57ac7d3d91963f033190c6a369232686476910a6 Mon Sep 17 00:00:00 2001 From: Fabiano FidĂȘncio Date: Apr 18 2017 14:07:35 +0000 Subject: Add socket_activatable_responders design page Signed-off-by: Fabiano FidĂȘncio --- diff --git a/design_pages/index.rst b/design_pages/index.rst index 1bb7ce8..ff5e638 100644 --- a/design_pages/index.rst +++ b/design_pages/index.rst @@ -16,4 +16,5 @@ When writing a design page, please start from the blank template. kcm non_posix_support shortnames + systemd_activatable_responders blank_template diff --git a/design_pages/systemd_activatable_responders.rst b/design_pages/systemd_activatable_responders.rst new file mode 100644 index 0000000..3c8b421 --- /dev/null +++ b/design_pages/systemd_activatable_responders.rst @@ -0,0 +1,287 @@ +.. highlight:: none + +Systemd Activatable Responders +============================== + +Related ticket(s): +------------------ + * https://pagure.io/SSSD/sssd/issue/2243 + * https://pagure.io/SSSD/sssd/issue/3129 + * https://pagure.io/SSSD/sssd/issue/3245 + +Problem statement +----------------- +SSSD has some responders which don't have to be running all the time, but could +be ``socket-activated`` or ``dbus-activated`` instead on platforms where it's +supported. That's the case, for instance, for the ``IFP``, ``SSH`` and ``Sudo`` +responders. + +Making these responders socket-activated or dbus-activated would provide a +better user experience, as these services could be started on-demand when a +client needs them and exit after a period of inactivity. + +Currently, the Administrator has to explicitly list all the services that might +be potentially needed in the ``services`` line of ``[sssd]`` section and those +processes will be running all the time. + +Use cases +--------- + * sssctl: As more and more features had been added depending on the ``IFP`` + responder being activated, leaving this responder to be started on-demand + instead of having the admins explicitly setting them up is desired; + + * KCM: The KCM responder is only seldom needed, when libkrb5 needs to access + the credentials store. At the same time, the KCM responder must be running + if Kerberos credentials cache defaults to KCM. Socket-activating this + responder would solve both of the cases; + + * AutoFS: The AutoFS responder is typically needed only when a shared + directory is about to be mounted. + +Overview of the solution +------------------------ +The solution agreed on the mailing list is to add a new unit file for each one +of the responders. Once a responder is started, it will communicated to the +monitor in order to let the monitor know that it's up and then the monitor will +take care of registering the responder, which basically consists in marking the +service as started, increasing the services' counter, getting the responders' +configuration and finally adding the responder to the services' list. A +configurable idle timeout will be implemented the responders, in order to +shut the process down in case it becomes idle. + +Implementation details +---------------------- +In order to achieve our goal we will need some small modifications in the +responders' common code to make those ready for socket-activation, add a +systemd unit file for each of the responders, add a new binary file to ensure +that the Administrator won't mix up those two methods of starting services +(for the very same service) and finally do some changes in the +monitor code for managing the socket-activated service. + +The change in the responders' common code is quite trivial and goes towards +calling ``activate_unix_sockets()`` function instead of ``set_unix_socket()``. +The important part around this change is to avoid the responders' file +descriptors to be set as -1 in all cases as it would cause the socket to be +unreachable in case the Administrator decides to move back from using the +socket-activated services to the default way. + +The systemd units for the responders will look like: + * NSS responder: NSS is a really special case as it cannot have be run as + unprivileged user. It happens because libc does initgroups on pretty much + any account and initgroups checks all NSS modules in order to be precise, + causing ``nss_sss`` to trigger the ``NSS responder`` ... so a cycle + dependency would happen. + + * sssd-nss.service:: + + [Unit] + Description=SSSD NSS Service responder + Documentation=man:sssd.conf(5) + After=sssd.service + BindsTo=sssd.service + RefuseManualStart=true + + [Install] + Also=sssd-nss.socket + + [Service] + ExecStart=@libexecdir@/sssd/sssd_nss --debug-to-files --socket-activated + Restart=on-failure + + * sssd-nss.socket:: + + [Unit] + Description=SSSD NSS Service responder socket + Documentation=man:sssd.conf(5) + After=sssd.service + BindsTo=sssd.service + Before=sssd-autofs.socket sssd-pac.socket sssd-pam.socket sssd-ssh.socket sssd-sudo.socket + DefaultDependencies=no + Conflicts=shutdown.target + + [Socket] + ExecStartPre=@libexecdir@/sssd/sssd_check_socket_activated_responders -r nss + ListenStream=@pipepath@/nss + + [Install] + WantedBy=sssd.service + + * PAM responder: PAM is a little bit special as it has two sockets associated + to itself. + + * sssd-pam.service:: + + [Unit] + Description=SSSD PAM Service responder + Documentation=man:sssd.conf(5) + After=sssd.service + BindsTo=sssd.service + RefuseManualStart=true + + [Install] + Also=sssd-pam.socket sssd-pam-priv.socket + + [Service] + ExecStartPre=-/bin/chown @SSSD_USER@:@SSSD_USER@ @logpath@/sssd_pam.log + ExecStart=@libexecdir@/sssd/sssd_pam --debug-to-files --socket-activated + Restart=on-failure + User=@SSSD_USER@ + Group=@SSSD_USER@ + PermissionsStartOnly=true + + * sssd-pam.socket:: + + [Unit] + Description=SSSD PAM Service responder socket + Documentation=man:sssd.conf(5) + After=sssd.service + BindsTo=sssd.service + BindsTo=sssd-pam-priv.socket + DefaultDependencies=no + Conflicts=shutdown.target + + [Socket] + ExecStartPre=@libexecdir@/sssd/sssd_check_socket_activated_responders -r pam + ListenStream=@pipepath@/pam + SocketUser=root + SocketGroup=root + + [Install] + WantedBy=sssd.service + + * sssd-pam-private.socket:: + + [Unit] + Description=SSSD PAM Service responder private socket + Documentation=man:sssd.conf(5) + After=sssd.service + BindsTo=sssd.service + BindsTo=sssd-pam.socket + DefaultDependencies=no + Conflicts=shutdown.target + + [Socket] + ExecStartPre=@libexecdir@/sssd/sssd_check_socket_activated_responders -r pam + Service=sssd-pam.service + ListenStream=@pipepath@/private/pam + SocketUser=root + SocketGroup=root + SocketMode=0600 + + [Install] + WantedBy=sssd.service + + * AutoFS, PAC, Ssh and Sudo responders: + + * sssd-@responder@.service:: + + [Unit] + Description=SSSD @responder@ Service responder + Documentation=man:sssd.conf(5) + After=sssd.service + BindsTo=sssd.service + RefuseManualStart=true + + [Install] + Also=sssd-@responder@.socket + + [Service] + ExecStartPre=-/bin/chown @SSSD_USER@:@SSSD_USER@ @logpath@/sssd_autofs.log + ExecStart=@libexecdir@/sssd/sssd_@responder@ --debug-to-files --socket-activated + Restart=on-failure + User=@SSSD_USER@ + Group=@SSSD_USER@ + PermissionsStartOnly=true + + * sssd-@responder@.socket:: + + [Unit] + Description=SSSD @responder@ Service responder socket + Documentation=man:sssd.conf(5) + After=sssd.service + BindsTo=sssd.service + DefaultDependencies=no + Conflicts=shutdown.target + + [Socket] + ExecStartPre=@libexecdir@/sssd/sssd_check_socket_activated_responders -r @responder@ + ListenStream=@pipepath@/@responder@ + SocketUser=@SSSD_USER@ + SocketGroup=@SSSD_USER@ + + [Install] + WantedBy=sssd.service + + * IFP responder: While the other responders are going to be socket-activated, + IFP will be dbus-activated: + + * sssd-ifp.service:: + + [Unit] + Description=SSSD IFP Service responder + Documentation=man:sssd-ifp(5) + After=sssd.service + BindsTo=sssd.service + + [Service] + Type=dbus + BusName=org.freedesktop.sssd.infopipe + ExecStart=@libexecdir@/sssd/sssd_ifp --uid 0 --gid 0 --debug-to-files --dbus-activated + Restart=on-failure + + +The newly added binary does nothing but check in the config files whether the +responder that is about to be activated is also listed in the ``services`` of +the configuration file. In case it's there, the services' socket is not +started, fallbacking to the default way. + +And, finally, the code on the monitor side will have to have some adjustments +in order to properly deal with an empty list of services and, also, to register +the service when it is stated. + +As just the responders will be socket-activated (for now), the service type +will have to be exposed and passed through sbus when calling the +``RegistrationService`` method and then the monitor will properly do the +services' registration when the method's callback is triggered. As mentioned +before, the registration that has to be done consists in: + + * Marking the service as started; + * Increasing the services' counter; + * Getting the services' configuration; + * Setting the services' restart number; + * Adding the service to the services' list; + +Unregistering a socket-activated responder will also be done by the monitor +when the connection between the service and the monitor is closed. + +Configuration changes +--------------------- +After this design is implemented, the ``services`` line in ``sssd.conf`` will +become optional for platforms where systemd is present. Note that in order to +keep backward compatibility, if the ``services`` line is present, the services +will behave exactly as they did before these changes. + +How To Test +----------- +The easiest way to test is removing the service from sssd,conf's ``services`` +line, enabling the service's socket and trying to use SSSD normally. + +See below an example of how to enable NSS and PAM sockets:: + + # systemctl enable sssd-nss.socket sssd-pam.socket + # systemctl start sssd-nss.socket sssd-pam.socket + +Using sssctl tool without having the IFP responder set in the ``services`` line +is another way to test. + +How To Debug +------------ +The easiest way to debug this new feature is taking a look on the responders' +common initialization code and in the monitors' client registration code. + +Is worth to mention that disabling the systemd's sockets will prevent the +responders' services to be started. + +Authors +------- +Fabiano Fidencio