From c6644b8566f747fa80e2c1925b79bad9f8c92bd7 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Thu, 19 Nov 2020 16:29:05 -0500 Subject: [PATCH] Generate a unique cache for each connection Rather than having a shared ccache per user, configure mod_auth_gssapi to create a unique one. This requires cleanup to remove expired caches. A new script is added, ipa-ccache-sweeper to do this. It will be invoked by a new service, ipa-ccache-sweep, which will be executed every 12 hours by an equally-named timer. https://pagure.io/freeipa/issue/8589 Signed-off-by: Rob Crittenden Reviewed-By: Alexander Bokovoy Reviewed-By: Francois Cami --- freeipa.spec.in | 3 ++ init/systemd/Makefile.am | 4 ++ init/systemd/ipa-ccache-sweep.service.in | 12 +++++ init/systemd/ipa-ccache-sweep.timer.in | 8 +++ install/share/ipa.conf.template | 4 +- install/tools/Makefile.am | 2 + install/tools/ipa-ccache-sweeper.in | 67 ++++++++++++++++++++++++ 7 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 init/systemd/ipa-ccache-sweep.service.in create mode 100644 init/systemd/ipa-ccache-sweep.timer.in create mode 100644 install/tools/ipa-ccache-sweeper.in diff --git a/freeipa.spec.in b/freeipa.spec.in index dc24e9751..5d5b91990 100755 --- a/freeipa.spec.in +++ b/freeipa.spec.in @@ -1314,6 +1314,7 @@ fi %{_libexecdir}/certmonger/dogtag-ipa-ca-renew-agent-submit %{_libexecdir}/certmonger/ipa-server-guard %dir %{_libexecdir}/ipa +%{_libexecdir}/ipa/ipa-ccache-sweeper %{_libexecdir}/ipa/ipa-custodia %{_libexecdir}/ipa/ipa-custodia-check %{_libexecdir}/ipa/ipa-httpd-kdcproxy @@ -1338,6 +1339,8 @@ fi %attr(644,root,root) %{_unitdir}/ipa.service %attr(644,root,root) %{_unitdir}/ipa-otpd.socket %attr(644,root,root) %{_unitdir}/ipa-otpd@.service +%attr(644,root,root) %{_unitdir}/ipa-ccache-sweep.service +%attr(644,root,root) %{_unitdir}/ipa-ccache-sweep.timer # END %attr(755,root,root) %{plugin_dir}/libipa_pwd_extop.so %attr(755,root,root) %{plugin_dir}/libipa_enrollment_extop.so diff --git a/init/systemd/Makefile.am b/init/systemd/Makefile.am index 175178787..8236075a2 100644 --- a/init/systemd/Makefile.am +++ b/init/systemd/Makefile.am @@ -7,11 +7,15 @@ NULL = dist_noinst_DATA = \ ipa-custodia.service.in \ ipa.service.in \ + ipa-ccache-sweep.service.in \ + ipa-ccache-sweep.timer.in \ $(NULL) systemdsystemunit_DATA = \ ipa-custodia.service \ ipa.service \ + ipa-ccache-sweep.service \ + ipa-ccache-sweep.timer \ $(NULL) CLEANFILES = $(systemdsystemunit_DATA) diff --git a/init/systemd/ipa-ccache-sweep.service.in b/init/systemd/ipa-ccache-sweep.service.in new file mode 100644 index 000000000..0ba2661f9 --- /dev/null +++ b/init/systemd/ipa-ccache-sweep.service.in @@ -0,0 +1,12 @@ +[Unit] +Description=IPA Kerberos Ccache Sweeper Service +Wants=gssproxy.service + +[Service] +Type=simple +ExecStart=@libexecdir@/ipa/ipa-ccache-sweeper +PrivateTmp=yes +User=ipaapi + +[Install] +WantedBy=multi-user.target diff --git a/init/systemd/ipa-ccache-sweep.timer.in b/init/systemd/ipa-ccache-sweep.timer.in new file mode 100644 index 000000000..84fe6e383 --- /dev/null +++ b/init/systemd/ipa-ccache-sweep.timer.in @@ -0,0 +1,8 @@ +[Unit] +Description=Remove Expired Kerberos Credential Caches + +[Timer] +OnUnitActiveSec=12h + +[Install] +WantedBy=timers.target diff --git a/install/share/ipa.conf.template b/install/share/ipa.conf.template index 07f39516d..ca51d2ea3 100644 --- a/install/share/ipa.conf.template +++ b/install/share/ipa.conf.template @@ -1,5 +1,5 @@ # -# VERSION 31 - DO NOT REMOVE THIS LINE +# VERSION 32 - DO NOT REMOVE THIS LINE # # This file may be overwritten on upgrades. # @@ -76,6 +76,7 @@ WSGIScriptReloading Off GssapiImpersonate On GssapiDelegCcacheDir $IPA_CCACHES GssapiDelegCcachePerms mode:0660 gid:ipaapi + GssapiDelegCcacheUnique On GssapiUseS4U2Proxy on GssapiAllowedMech krb5 Require valid-user @@ -117,6 +118,7 @@ Alias /ipa/session/cookie "/usr/share/ipa/gssapi.login" AuthType none GssapiDelegCcacheDir $IPA_CCACHES GssapiDelegCcachePerms mode:0660 gid:ipaapi + GssapiDelegCcacheUnique On SSLVerifyClient require SSLUserName SSL_CLIENT_CERT LookupUserByCertificate On diff --git a/install/tools/Makefile.am b/install/tools/Makefile.am index bcf45fd20..d6fbf9e3b 100644 --- a/install/tools/Makefile.am +++ b/install/tools/Makefile.am @@ -6,6 +6,7 @@ SUBDIRS = \ dist_noinst_DATA = \ ipa-ca-install.in \ + ipa-ccache-sweeper.in \ ipa-dns-install.in \ ipa-kra-install.in \ ipa-server-install.in \ @@ -70,6 +71,7 @@ nodist_sbin_SCRIPTS = \ appdir = $(libexecdir)/ipa/ nodist_app_SCRIPTS = \ + ipa-ccache-sweeper \ ipa-custodia \ ipa-custodia-check \ ipa-httpd-kdcproxy \ diff --git a/install/tools/ipa-ccache-sweeper.in b/install/tools/ipa-ccache-sweeper.in new file mode 100644 index 000000000..33bd5f7fe --- /dev/null +++ b/install/tools/ipa-ccache-sweeper.in @@ -0,0 +1,67 @@ +#!/usr/bin/env python3 + +# Based heavily on +# https://github.com/gssapi/mod_auth_gssapi/blob/master/contrib/sweeper.py + +# Copyright (C) 2016 mod_auth_gssapi contributors - See COPYING for (C) terms + +# If one uses both sessions and unique ccache names, then the filesystem will +# become littered with ccache files unless the accessed application cleans +# them up itself. This script will minimize ccache file proliferation by +# removing any ccaches that have expired from the filesystem, and serves as an +# example of how this cleaning can be performed. + +import argparse +import os +import stat +import sys +import time + +from gssapi.raw import acquire_cred_from +from ipaplatform.paths import paths + + +# process file as a ccache and indicate whether it is expired +def should_delete(fname, t, minlife): + try: + # skip directories and other non-files + st = os.stat(fname) + if not stat.S_ISREG(st.st_mode): + return False + + # ignore files that are newer than minlife minutes + if t - st.st_mtime < minlife * 60: + return False + + creds = acquire_cred_from({b"ccache": fname.encode("UTF-8")}) + except FileNotFoundError: + # someone else did the work for us + return False + except Exception as e: + print("Not deleting %s due to error %s" % (fname, e)) + return False + + return creds.lifetime == 0 + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Sweep expired ccaches") + parser.add_argument("-m", dest="minlife", type=int, + help="ignore newer files than this (default: 30)", + default=30) + args = parser.parse_args() + + os.environ["GSS_USE_PROXY"] = "yes" + os.environ["GSSPROXY_BEHAVIOR"] = "REMOTE_FIRST" + + print("Running sweeper...") + + t = time.time() + + os.chdir(paths.IPA_CCACHES) + for fname in os.listdir(paths.IPA_CCACHES): + if should_delete(fname, t, args.minlife): + os.unlink(fname) + + print("Sweeper finished successfully!") + sys.exit(0)