summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFraser Tweedale <ftweedal@redhat.com>2016-06-01 08:07:33 +1000
committerJan Cholasta <jcholast@redhat.com>2016-06-09 09:04:27 +0200
commitb0d9a4728f0dc78e2bbde344beac17ae50b847a9 (patch)
treeb5cca38aa8795073de92776942be6e6fe63b2479
parent0d37d230c066f9eb703c81e0e21b1b6738703b41 (diff)
downloadfreeipa-b0d9a4728f0dc78e2bbde344beac17ae50b847a9.tar.gz
freeipa-b0d9a4728f0dc78e2bbde344beac17ae50b847a9.tar.xz
freeipa-b0d9a4728f0dc78e2bbde344beac17ae50b847a9.zip
Setup lightweight CA key retrieval on install/upgrade
Add the ipa-pki-retrieve-key helper program and configure lightweight CA key replication on installation and upgrade. The specific configuration steps are: - Add the 'dogtag/$HOSTNAME' service principal - Create the pricipal's Custodia keys - Retrieve the principal's keytab - Configure Dogtag's CS.cfg to use ExternalProcessKeyRetriever to invoke ipa-pki-retrieve-key for key retrieval Also bump the minimum version of Dogtag to 10.3.2. Part of: https://fedorahosted.org/freeipa/ticket/4559 Reviewed-By: Jan Cholasta <jcholast@redhat.com>
-rw-r--r--freeipa.spec.in7
-rw-r--r--install/share/bootstrap-template.ldif6
-rw-r--r--install/tools/Makefile.am1
-rwxr-xr-xinstall/tools/ipa-pki-retrieve-key32
-rw-r--r--install/updates/73-custodia.update5
-rw-r--r--ipalib/constants.py1
-rw-r--r--ipaserver/install/ca.py9
-rw-r--r--ipaserver/install/cainstance.py56
-rw-r--r--ipaserver/install/server/install.py6
-rw-r--r--ipaserver/install/server/upgrade.py4
10 files changed, 119 insertions, 8 deletions
diff --git a/freeipa.spec.in b/freeipa.spec.in
index d5d78f806..8eb3bd5fc 100644
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -94,7 +94,7 @@ BuildRequires: libunistring-devel
BuildRequires: python-lesscpy
BuildRequires: python-yubico >= 1.2.3
BuildRequires: openssl-devel
-BuildRequires: pki-base >= 10.2.6
+BuildRequires: pki-base >= 10.3.2
BuildRequires: python-pytest-multihost >= 0.5
BuildRequires: python-pytest-sourceorder
BuildRequires: python-kdcproxy >= 0.3
@@ -155,8 +155,8 @@ Requires(post): systemd-units
Requires: selinux-policy >= %{selinux_policy_version}
Requires(post): selinux-policy-base >= %{selinux_policy_version}
Requires: slapi-nis >= 0.55-1
-Requires: pki-ca >= 10.2.6-19
-Requires: pki-kra >= 10.2.6-19
+Requires: pki-ca >= 10.3.2
+Requires: pki-kra >= 10.3.2
Requires(preun): python systemd-units
Requires(postun): python systemd-units
Requires: zip
@@ -1074,6 +1074,7 @@ fi
%{_libexecdir}/ipa/ipa-dnskeysync-replica
%{_libexecdir}/ipa/ipa-ods-exporter
%{_libexecdir}/ipa/ipa-httpd-kdcproxy
+%{_libexecdir}/ipa/ipa-pki-retrieve-key
%dir %{_libexecdir}/ipa/oddjob
%attr(0755,root,root) %{_libexecdir}/ipa/oddjob/org.freeipa.server.conncheck
%config(noreplace) %{_sysconfdir}/dbus-1/system.d/org.freeipa.server.conf
diff --git a/install/share/bootstrap-template.ldif b/install/share/bootstrap-template.ldif
index 83be43995..f6ab35495 100644
--- a/install/share/bootstrap-template.ldif
+++ b/install/share/bootstrap-template.ldif
@@ -179,6 +179,12 @@ objectClass: nsContainer
objectClass: top
cn: custodia
+dn: cn=dogtag,cn=custodia,cn=ipa,cn=etc,$SUFFIX
+changetype: add
+objectClass: nsContainer
+objectClass: top
+cn: dogtag
+
dn: cn=s4u2proxy,cn=etc,$SUFFIX
changetype: add
objectClass: nsContainer
diff --git a/install/tools/Makefile.am b/install/tools/Makefile.am
index 7212dabdb..2866a30b2 100644
--- a/install/tools/Makefile.am
+++ b/install/tools/Makefile.am
@@ -39,6 +39,7 @@ EXTRA_DIST = \
appdir = $(libexecdir)/ipa/
app_SCRIPTS = \
ipa-httpd-kdcproxy \
+ ipa-pki-retrieve-key \
$(NULL)
MAINTAINERCLEANFILES = \
diff --git a/install/tools/ipa-pki-retrieve-key b/install/tools/ipa-pki-retrieve-key
new file mode 100755
index 000000000..740e799d2
--- /dev/null
+++ b/install/tools/ipa-pki-retrieve-key
@@ -0,0 +1,32 @@
+#!/usr/bin/python2
+
+from __future__ import print_function
+
+import os
+import sys
+
+from ipalib import constants
+from ipalib.config import Env
+from ipaplatform.paths import paths
+from ipapython.secrets.client import CustodiaClient
+
+env = Env()
+env._finalize()
+
+keyname = "ca_wrapped/" + sys.argv[1]
+servername = sys.argv[2]
+
+service = constants.PKI_GSSAPI_SERVICE_NAME
+client_keyfile = os.path.join(paths.PKI_TOMCAT, service + '.keys')
+client_keytab = os.path.join(paths.PKI_TOMCAT, service + '.keytab')
+
+# pylint: disable=no-member
+client = CustodiaClient(
+ client_service='%s@%s' % (service, env.host), server=servername,
+ realm=env.realm, ldap_uri="ldaps://" + env.host,
+ keyfile=client_keyfile, keytab=client_keytab,
+ )
+
+# Print the response JSON to stdout; it is already in the format
+# that Dogtag's ExternalProcessKeyRetriever expects
+print(client.fetch_key(keyname, store=False))
diff --git a/install/updates/73-custodia.update b/install/updates/73-custodia.update
index f6520fb2e..60f805ab8 100644
--- a/install/updates/73-custodia.update
+++ b/install/updates/73-custodia.update
@@ -2,3 +2,8 @@ dn: cn=custodia,cn=ipa,cn=etc,$SUFFIX
default: objectClass: top
default: objectClass: nsContainer
default: cn: custodia
+
+dn: cn=dogtag,cn=custodia,cn=ipa,cn=etc,$SUFFIX
+default: objectClass: top
+default: objectClass: nsContainer
+default: cn: dogtag
diff --git a/ipalib/constants.py b/ipalib/constants.py
index a2cbfdbcd..97dff1d80 100644
--- a/ipalib/constants.py
+++ b/ipalib/constants.py
@@ -264,3 +264,4 @@ REPL_AGMT_STRIP_ATTRS = ('modifiersName',
DOMAIN_SUFFIX_NAME = 'domain'
CA_SUFFIX_NAME = 'ca'
+PKI_GSSAPI_SERVICE_NAME = 'dogtag'
diff --git a/ipaserver/install/ca.py b/ipaserver/install/ca.py
index 3a827aee8..ac72c7688 100644
--- a/ipaserver/install/ca.py
+++ b/ipaserver/install/ca.py
@@ -182,7 +182,7 @@ def install_step_1(standalone, replica_config, options):
basedn = ipautil.realm_to_suffix(realm_name)
- ca = cainstance.CAInstance(realm_name, certs.NSS_DIR)
+ ca = cainstance.CAInstance(realm_name, certs.NSS_DIR, host_name=host_name)
if standalone:
ca.stop('pki-tomcat')
@@ -197,6 +197,13 @@ def install_step_1(standalone, replica_config, options):
# This is done within stopped_service context, which restarts CA
ca.enable_client_auth_to_db(paths.CA_CS_CFG_PATH)
+ # Lightweight CA key retrieval is configured in step 1 instead
+ # of CAInstance.configure_instance (which is invoked from step
+ # 0) because kadmin_addprinc fails until krb5.conf is installed
+ # by krb.create_instance.
+ #
+ ca.setup_lightweight_ca_key_retrieval()
+
if standalone and replica_config is None:
serverid = installutils.realm_to_serverid(realm_name)
dirname = dsinstance.config_dirname(serverid)
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index 475e74d7f..9f6a5037f 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -45,6 +45,7 @@ from six.moves.configparser import ConfigParser, RawConfigParser
from ipalib import api
from ipalib import pkcs10, x509
from ipalib import errors
+import ipalib.constants
from ipaplatform import services
from ipaplatform.constants import constants
@@ -59,6 +60,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 +68,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 +1359,64 @@ 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]')
+
+ self.__setup_lightweight_ca_key_retrieval_kerberos()
+ self.__setup_lightweight_ca_key_retrieval_custodia()
+
+ root_logger.info('Configuring key retriever')
+ directives = [
+ ('features.authority.keyRetrieverClass',
+ 'com.netscape.ca.ExternalProcessKeyRetriever'),
+ ('features.authority.keyRetrieverConfig.executable',
+ '/usr/libexec/ipa/ipa-pki-retrieve-key'),
+ ]
+ for k, v in directives:
+ installutils.set_directive(
+ paths.CA_CS_CFG_PATH, k, v, quotes=False, separator='=')
+
+ sysupgrade.set_upgrade_state('dogtag', 'setup_lwca_key_retieval', True)
+
+ def __setup_lightweight_ca_key_retrieval_kerberos(self):
+ service = ipalib.constants.PKI_GSSAPI_SERVICE_NAME
+ 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, service + '.keytab')
+ installutils.create_keytab(keytab, principal)
+ os.chmod(keytab, 0o600)
+ os.chown(keytab, pent.pw_uid, pent.pw_gid)
+
+ def __setup_lightweight_ca_key_retrieval_custodia(self):
+ service = ipalib.constants.PKI_GSSAPI_SERVICE_NAME
+ pent = pwd.getpwnam(constants.PKI_USER)
+
+ root_logger.info('Creating Custodia keys')
+ keyfile = os.path.join(paths.PKI_TOMCAT, service + '.keys')
+ keystore = IPAKEMKeys({'server_keys': keyfile})
+ keystore.generate_keys(service)
+ os.chmod(keyfile, 0o600)
+ os.chown(keyfile, pent.pw_uid, pent.pw_gid)
+
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 4b8ef0486..e8d4db878 100644
--- a/ipaserver/install/server/install.py
+++ b/ipaserver/install/server/install.py
@@ -891,9 +891,6 @@ def install(installer):
# we now need to enable ssl on the ds
ds.enable_ssl()
- if setup_ca:
- ca.install_step_1(False, None, options)
-
krb = krbinstance.KrbInstance(fstore)
if options.pkinit_cert_files:
krb.create_instance(realm_name, host_name, domain_name,
@@ -907,6 +904,9 @@ def install(installer):
setup_pkinit=not options.no_pkinit,
subject_base=options.subject)
+ if setup_ca:
+ ca.install_step_1(False, None, options)
+
# The DS instance is created before the keytab, add the SSL cert we
# generated
ds.add_cert_to_service()
diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
index 2398aea90..1a1090f0c 100644
--- a/ipaserver/install/server/upgrade.py
+++ b/ipaserver/install/server/upgrade.py
@@ -1492,7 +1492,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)
ca_running = ca.is_running()
with installutils.stopped_service('pki-tomcatd', 'pki-tomcat'):
@@ -1697,6 +1698,7 @@ def upgrade_configuration():
if ca.is_configured():
cainstance.repair_profile_caIPAserviceCert()
+ ca.setup_lightweight_ca_key_retrieval()
set_sssd_domain_option('ipa_server_mode', 'True')