[Freeipa-devel] [PATCH] 0053..0054 Configure lightweight CA key replication

Fraser Tweedale ftweedal at redhat.com
Thu Apr 14 06:39:37 UTC 2016


Hi all,

The attached patches configure lightweight CA key replication on IPA
CAs, on upgrade and installation.

Patches 0051..0052 from my other mail are also needed for the system
to work, but this patchset does not depend on them and can be
reviewed independently.

There is also no hard dependency on the (unreleased) Dogtag 10.3.0b1
- it just puts the necessary principals/keys/configuration in place.

Cheers,
Fraser
-------------- next part --------------
From aa91bd3c6773d42c864a8f34eabad8b90bb01f8b Mon Sep 17 00:00:00 2001
From: Fraser Tweedale <ftweedal at redhat.com>
Date: Mon, 11 Apr 2016 12:42:35 +1000
Subject: [PATCH 53/54] Optionally add service name to Custodia key DNs

Lightweight CAs support introduces new service principals for
Dogtag, with Custodia keys.  The current Custodia key creation uses
a DN that contains only they key type and the hostname, so keys for
multiple services on the same host cannot be created.

Add the 'generate_keys' method to generate keys for a host or an
arbitrary service.  When a service name is given, include the
service name in the DN.

This change does not affect searching because all searching is done
using the ipaKeyUsage and memberPrincipal attributes.

Part of: https://fedorahosted.org/freeipa/ticket/4559
---
 ipapython/secrets/kem.py | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/ipapython/secrets/kem.py b/ipapython/secrets/kem.py
index 1025ed7980f055c82c602634e8845fa490cf0514..533121779241d30e19fef4c050bb69c55d29ec22 100644
--- a/ipapython/secrets/kem.py
+++ b/ipapython/secrets/kem.py
@@ -105,10 +105,11 @@ class KEMLdap(iSecLdap):
             encoding=serialization.Encoding.DER,
             format=serialization.PublicFormat.SubjectPublicKeyInfo)
 
-    def set_key(self, usage, host, principal, key):
+    def set_key(self, usage, servicename, host, principal, key):
         public_key = self._format_public_key(key)
         conn = self.connect()
-        name = '%s/%s' % (KEY_USAGE_MAP[usage], host)
+        service_segment = '~' + servicename if servicename else ''
+        name = '%s%s/%s' % (KEY_USAGE_MAP[usage], service_segment, host)
         dn = 'cn=%s,%s' % (name, self.keysbase)
         try:
             mods = [('objectClass', ['nsContainer',
@@ -170,15 +171,18 @@ class IPAKEMKeys(KEMKeysStore):
         return conn.get_key(usage, kid)
 
     def generate_server_keys(self):
-        principal = 'host/%s@%s' % (self.host, self.realm)
+        self.generate_keys()
+
+    def generate_keys(self, servicename=None):
+        principal = '%s/%s@%s' % (servicename or 'host', self.host, self.realm)
         # Neutralize the key with read if any
         self._server_keys = None
         # Generate private key and store it
         pubkeys = newServerKeys(self.config['server_keys'], principal)
         # Store public key in LDAP
         ldapconn = KEMLdap(self.ldap_uri)
-        ldapconn.set_key(KEY_USAGE_SIG, self.host, principal, pubkeys[0])
-        ldapconn.set_key(KEY_USAGE_ENC, self.host, principal, pubkeys[1])
+        ldapconn.set_key(KEY_USAGE_SIG, servicename, self.host, principal, pubkeys[0])
+        ldapconn.set_key(KEY_USAGE_ENC, servicename, self.host, principal, pubkeys[1])
 
     @property
     def server_keys(self):
-- 
2.5.5

-------------- next part --------------
From cf452abcf309ce3cded3eeef70b07f108d9eb92d Mon Sep 17 00:00:00 2001
From: Fraser Tweedale <ftweedal at redhat.com>
Date: Mon, 11 Apr 2016 16:47:33 +1000
Subject: [PATCH 54/54] Setup lightweight CA key retrieval on install/upgrade

To configure Dogtag lightweight CA key replication on installation
and upgrade:

- add the 'dogtag-ipa-custodia/$HOSTNAME' service principal
- create Custodia keys
- retrieve keytab
- configure the IPACustodiaKeyRetriever in CS.cfg

Part of: https://fedorahosted.org/freeipa/ticket/4559
---
 install/tools/ipa-ca-install        |  4 ++++
 ipaserver/install/cainstance.py     | 43 +++++++++++++++++++++++++++++++++++++
 ipaserver/install/server/install.py |  8 ++++++-
 ipaserver/install/server/upgrade.py |  6 +++++-
 4 files changed, 59 insertions(+), 2 deletions(-)

diff --git a/install/tools/ipa-ca-install b/install/tools/ipa-ca-install
index 1bc5def03bf687a1e4f9fb38a54363b5429c8fc4..0af5b39116b4649423ed2a51579e2adc767d802b 100755
--- a/install/tools/ipa-ca-install
+++ b/install/tools/ipa-ca-install
@@ -226,6 +226,10 @@ def install_master(safe_options, options):
     ca.install_check(True, None, options)
     ca.install(True, None, options)
 
+    CA = cainstance.CAInstance(
+            api.env.realm, certs.NSS_DIR, host_name=api.env.host)
+    CA.setup_lightweight_ca_key_retrieval()
+
 
 def install(safe_options, options, filename):
     options.promote = False
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index a21f7d2671461dfb99797d39fc7ee5706317241f..08d0ec661a5b0a95cfc4f8ac8ccc1476d86e6ea0 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -59,6 +59,7 @@ from ipapython.certdb import get_ca_nickname
 from ipapython.dn import DN
 from ipapython.ipa_log_manager import log_mgr,\
     standard_logging_setup, root_logger
+from ipapython.secrets.kem import IPAKEMKeys
 
 from ipaserver.install import certs
 from ipaserver.install import dsinstance
@@ -66,6 +67,7 @@ from ipaserver.install import installutils
 from ipaserver.install import ldapupdate
 from ipaserver.install import replication
 from ipaserver.install import service
+from ipaserver.install import sysupgrade
 from ipaserver.install.dogtaginstance import (export_kra_agent_pem,
                                               DogtagInstance)
 from ipaserver.plugins import ldap2
@@ -1356,11 +1358,52 @@ class CAInstance(DogtagInstance):
         self.step("updating IPA configuration", update_ipa_conf)
         self.step("Restart HTTP server to pick up changes",
                   self.__restart_http_instance)
+        self.step("Configure lightweight CA key retrieval",
+                  self.setup_lightweight_ca_key_retrieval)
 
         self.step("enabling CA instance", self.__enable_instance)
 
         self.start_creation(runtime=210)
 
+    def setup_lightweight_ca_key_retrieval(self):
+        if sysupgrade.get_upgrade_state('dogtag', 'setup_lwca_key_retrieval'):
+            return
+
+        root_logger.info('[Set up lightweight CA key retrieval]')
+
+        service = 'dogtag-ipa-custodia'
+        principal = '{}/{}@{}'.format(service, api.env.host, self.realm)
+        pent = pwd.getpwnam(constants.PKI_USER)
+
+        root_logger.info('Creating principal')
+        installutils.kadmin_addprinc(principal)
+        self.suffix = ipautil.realm_to_suffix(self.realm)
+        if not self.admin_conn:
+            self.ldap_connect()
+        self.move_service(principal)
+
+        root_logger.info('Retrieving keytab')
+        keytab = os.path.join(paths.PKI_TOMCAT, 'dogtag-ipa-custodia.keytab')
+        installutils.create_keytab(keytab, principal)
+        os.chmod(keytab, 0o600)
+        os.chown(keytab, pent.pw_uid, pent.pw_gid)
+
+        root_logger.info('Creating Custodia keys')
+        keyfile = os.path.join(paths.PKI_TOMCAT, 'dogtag-ipa-custodia.keys')
+        keystore = IPAKEMKeys({'server_keys': keyfile})
+        keystore.generate_keys(service)
+        os.chmod(keyfile, 0o600)
+        os.chown(keyfile, pent.pw_uid, pent.pw_gid)
+
+        root_logger.info('Configuring key retriever')
+        installutils.set_directive(
+            paths.CA_CS_CFG_PATH,
+            'features.authority.keyRetrieverClass',
+            'com.netscape.ca.IPACustodiaKeyRetriever',
+            quotes=False, separator='=')
+
+        sysupgrade.set_upgrade_state('dogtag', 'setup_lwca_key_retieval', True)
+
 
 def replica_ca_install_check(config):
     if not config.setup_ca:
diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
index f01022c4c3a056513db47f70727aa48157a8c6f2..d9fcd7e6098c1bdd7647c300695f583f43bde9e5 100644
--- a/ipaserver/install/server/install.py
+++ b/ipaserver/install/server/install.py
@@ -892,7 +892,8 @@ def install(installer):
         ca.install_step_0(False, None, options)
 
         # Now put the CA cert where other instances exepct it
-        ca_instance = cainstance.CAInstance(realm_name, certs.NSS_DIR)
+        ca_instance = cainstance.CAInstance(
+            realm_name, certs.NSS_DIR, host_name=host_name)
         ca_instance.publish_ca_cert(CACERT)
     else:
         # Put the CA cert where other instances expect it
@@ -922,6 +923,11 @@ def install(installer):
     # generated
     ds.add_cert_to_service()
 
+    if setup_ca:
+        # CA was configured before Kerberos;
+        # add Custodia client princ and keys now
+        ca_instance.setup_lightweight_ca_key_retrieval()
+
     memcache = memcacheinstance.MemcacheInstance()
     memcache.create_instance('MEMCACHE', host_name, dm_password,
                              ipautil.realm_to_suffix(realm_name))
diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
index 3e60cfd3630c359268cf16219527088b5c63ba86..cc003c7146d547b5778f4d5d8d1c4f7eedc69ec7 100644
--- a/ipaserver/install/server/upgrade.py
+++ b/ipaserver/install/server/upgrade.py
@@ -1463,7 +1463,8 @@ def upgrade_configuration():
     if subject_base:
         sub_dict['SUBJECT_BASE'] = subject_base
 
-    ca = cainstance.CAInstance(api.env.realm, certs.NSS_DIR)
+    ca = cainstance.CAInstance(
+            api.env.realm, certs.NSS_DIR, host_name=api.env.host)
 
     with installutils.stopped_service('pki-tomcatd', 'pki-tomcat'):
         # Dogtag must be stopped to be able to backup CS.cfg config
@@ -1658,6 +1659,9 @@ def upgrade_configuration():
     ca_import_included_profiles(ca)
     add_default_caacl(ca)
 
+    if ca.is_configured():
+        ca.setup_lightweight_ca_key_retrieval()
+
     set_sssd_domain_option('ipa_server_mode', 'True')
 
     if ds_running and not ds.is_running():
-- 
2.5.5



More information about the Freeipa-devel mailing list