|
|
7bbb43 |
From 11e597217fe6f1dcee3a918eef0bc3a0d2928e6d Mon Sep 17 00:00:00 2001
|
|
|
7bbb43 |
From: Christian Heimes <cheimes@redhat.com>
|
|
|
7bbb43 |
Date: Thu, 26 Apr 2018 12:06:36 +0200
|
|
|
7bbb43 |
Subject: [PATCH] Use single Custodia instance in installers
|
|
|
7bbb43 |
|
|
|
7bbb43 |
Installers now pass a single CustodiaInstance object around, instead of
|
|
|
7bbb43 |
creating new instances on demand. In case of replica promotion with CA,
|
|
|
7bbb43 |
the instance gets all secrets from a master with CA present. Before, an
|
|
|
7bbb43 |
installer created multiple instances and may have requested CA key
|
|
|
7bbb43 |
material from a different machine than DM password hash.
|
|
|
7bbb43 |
|
|
|
7bbb43 |
In case of Domain Level 1 and replica promotion, the CustodiaInstance no
|
|
|
7bbb43 |
longer adds the keys to the local instance and waits for replication to
|
|
|
7bbb43 |
other replica. Instead the installer directly uploads the new public
|
|
|
7bbb43 |
keys to the remote 389-DS instance.
|
|
|
7bbb43 |
|
|
|
7bbb43 |
Without promotion, new Custodia public keys are still added to local
|
|
|
7bbb43 |
389-DS over LDAPI.
|
|
|
7bbb43 |
|
|
|
7bbb43 |
Fixes: https://pagure.io/freeipa/issue/7518
|
|
|
7bbb43 |
Signed-off-by: Christian Heimes <cheimes@redhat.com>
|
|
|
7bbb43 |
Reviewed-By: Simo Sorce <ssorce@redhat.com>
|
|
|
7bbb43 |
Reviewed-By: Simo Sorce <ssorce@redhat.com>
|
|
|
7bbb43 |
---
|
|
|
7bbb43 |
install/tools/ipa-ca-install | 13 ++-
|
|
|
7bbb43 |
ipaserver/install/ca.py | 26 +++--
|
|
|
7bbb43 |
ipaserver/install/cainstance.py | 9 +-
|
|
|
7bbb43 |
ipaserver/install/custodiainstance.py | 150 ++++++++++++++++++++++-------
|
|
|
7bbb43 |
ipaserver/install/ipa_kra_install.py | 10 +-
|
|
|
7bbb43 |
ipaserver/install/kra.py | 6 +-
|
|
|
7bbb43 |
ipaserver/install/server/install.py | 14 +--
|
|
|
7bbb43 |
ipaserver/install/server/replicainstall.py | 15 +--
|
|
|
7bbb43 |
8 files changed, 165 insertions(+), 78 deletions(-)
|
|
|
7bbb43 |
|
|
|
7bbb43 |
diff --git a/install/tools/ipa-ca-install b/install/tools/ipa-ca-install
|
|
|
7bbb43 |
index f84b4749a3e2a80aca002a2aa057b200e6187f18..a3694007e5815d1c44f642057c749879d336dfc5 100755
|
|
|
7bbb43 |
--- a/install/tools/ipa-ca-install
|
|
|
7bbb43 |
+++ b/install/tools/ipa-ca-install
|
|
|
7bbb43 |
@@ -31,6 +31,7 @@ from ipaserver.install.installutils import create_replica_config
|
|
|
7bbb43 |
from ipaserver.install.installutils import check_creds, ReplicaConfig
|
|
|
7bbb43 |
from ipaserver.install import dsinstance, ca
|
|
|
7bbb43 |
from ipaserver.install import cainstance, service
|
|
|
7bbb43 |
+from ipaserver.install import custodiainstance
|
|
|
7bbb43 |
from ipapython import version
|
|
|
7bbb43 |
from ipalib import api
|
|
|
7bbb43 |
from ipalib.constants import DOMAIN_LEVEL_0
|
|
|
7bbb43 |
@@ -193,13 +194,17 @@ def install_replica(safe_options, options, filename):
|
|
|
7bbb43 |
options.domain_name = config.domain_name
|
|
|
7bbb43 |
options.dm_password = config.dirman_password
|
|
|
7bbb43 |
options.host_name = config.host_name
|
|
|
7bbb43 |
+ options.ca_host_name = config.ca_host_name
|
|
|
7bbb43 |
if os.path.exists(cafile):
|
|
|
7bbb43 |
options.ca_cert_file = cafile
|
|
|
7bbb43 |
else:
|
|
|
7bbb43 |
options.ca_cert_file = None
|
|
|
7bbb43 |
|
|
|
7bbb43 |
ca.install_check(True, config, options)
|
|
|
7bbb43 |
- ca.install(True, config, options)
|
|
|
7bbb43 |
+
|
|
|
7bbb43 |
+ custodia = custodiainstance.get_custodia_instance(
|
|
|
7bbb43 |
+ options, custodiainstance.CustodiaModes.CA_PEER)
|
|
|
7bbb43 |
+ ca.install(True, config, options, custodia=custodia)
|
|
|
7bbb43 |
|
|
|
7bbb43 |
|
|
|
7bbb43 |
def install_master(safe_options, options):
|
|
|
7bbb43 |
@@ -228,7 +233,11 @@ def install_master(safe_options, options):
|
|
|
7bbb43 |
sys.exit("CA subject: {}".format(e.message))
|
|
|
7bbb43 |
|
|
|
7bbb43 |
ca.install_check(True, None, options)
|
|
|
7bbb43 |
- ca.install(True, None, options)
|
|
|
7bbb43 |
+
|
|
|
7bbb43 |
+ # No CA peer available yet.
|
|
|
7bbb43 |
+ custodia = custodiainstance.get_custodia_instance(
|
|
|
7bbb43 |
+ options, custodiainstance.CustodiaModes.STANDALONE)
|
|
|
7bbb43 |
+ ca.install(True, None, options, custodia=custodia)
|
|
|
7bbb43 |
|
|
|
7bbb43 |
|
|
|
7bbb43 |
def install(safe_options, options, filename):
|
|
|
7bbb43 |
diff --git a/ipaserver/install/ca.py b/ipaserver/install/ca.py
|
|
|
7bbb43 |
index 52cb20f1cb3612394544a6a41f10e9e939bc0657..2ac4382ccd24d217832950b94baddd113f7a8930 100644
|
|
|
7bbb43 |
--- a/ipaserver/install/ca.py
|
|
|
7bbb43 |
+++ b/ipaserver/install/ca.py
|
|
|
7bbb43 |
@@ -19,10 +19,7 @@ from ipalib.install.service import enroll_only, master_install_only, replica_ins
|
|
|
7bbb43 |
from ipaserver.install import sysupgrade
|
|
|
7bbb43 |
from ipapython.install import typing
|
|
|
7bbb43 |
from ipapython.install.core import group, knob, extend_knob
|
|
|
7bbb43 |
-from ipaserver.install import (cainstance,
|
|
|
7bbb43 |
- custodiainstance,
|
|
|
7bbb43 |
- dsinstance,
|
|
|
7bbb43 |
- bindinstance)
|
|
|
7bbb43 |
+from ipaserver.install import cainstance, bindinstance, dsinstance
|
|
|
7bbb43 |
from ipapython import ipautil, certdb
|
|
|
7bbb43 |
from ipapython.admintool import ScriptError
|
|
|
7bbb43 |
from ipaplatform import services
|
|
|
7bbb43 |
@@ -201,12 +198,12 @@ def install_check(standalone, replica_config, options):
|
|
|
7bbb43 |
"cannot continue." % (subject, db.secdir))
|
|
|
7bbb43 |
|
|
|
7bbb43 |
|
|
|
7bbb43 |
-def install(standalone, replica_config, options):
|
|
|
7bbb43 |
- install_step_0(standalone, replica_config, options)
|
|
|
7bbb43 |
- install_step_1(standalone, replica_config, options)
|
|
|
7bbb43 |
+def install(standalone, replica_config, options, custodia):
|
|
|
7bbb43 |
+ install_step_0(standalone, replica_config, options, custodia=custodia)
|
|
|
7bbb43 |
+ install_step_1(standalone, replica_config, options, custodia=custodia)
|
|
|
7bbb43 |
|
|
|
7bbb43 |
|
|
|
7bbb43 |
-def install_step_0(standalone, replica_config, options):
|
|
|
7bbb43 |
+def install_step_0(standalone, replica_config, options, custodia):
|
|
|
7bbb43 |
realm_name = options.realm_name
|
|
|
7bbb43 |
dm_password = options.dm_password
|
|
|
7bbb43 |
host_name = options.host_name
|
|
|
7bbb43 |
@@ -237,9 +234,6 @@ def install_step_0(standalone, replica_config, options):
|
|
|
7bbb43 |
else:
|
|
|
7bbb43 |
cafile = os.path.join(replica_config.dir, 'cacert.p12')
|
|
|
7bbb43 |
if options.promote:
|
|
|
7bbb43 |
- custodia = custodiainstance.CustodiaInstance(
|
|
|
7bbb43 |
- replica_config.host_name,
|
|
|
7bbb43 |
- replica_config.realm_name)
|
|
|
7bbb43 |
custodia.get_ca_keys(
|
|
|
7bbb43 |
replica_config.ca_host_name,
|
|
|
7bbb43 |
cafile,
|
|
|
7bbb43 |
@@ -266,7 +260,9 @@ def install_step_0(standalone, replica_config, options):
|
|
|
7bbb43 |
'certmap.conf', 'subject_base', str(subject_base))
|
|
|
7bbb43 |
dsinstance.write_certmap_conf(realm_name, ca_subject)
|
|
|
7bbb43 |
|
|
|
7bbb43 |
- ca = cainstance.CAInstance(realm_name, host_name=host_name)
|
|
|
7bbb43 |
+ ca = cainstance.CAInstance(
|
|
|
7bbb43 |
+ realm=realm_name, host_name=host_name, custodia=custodia
|
|
|
7bbb43 |
+ )
|
|
|
7bbb43 |
ca.configure_instance(host_name, dm_password, dm_password,
|
|
|
7bbb43 |
subject_base=subject_base,
|
|
|
7bbb43 |
ca_subject=ca_subject,
|
|
|
7bbb43 |
@@ -284,7 +280,7 @@ def install_step_0(standalone, replica_config, options):
|
|
|
7bbb43 |
use_ldaps=standalone)
|
|
|
7bbb43 |
|
|
|
7bbb43 |
|
|
|
7bbb43 |
-def install_step_1(standalone, replica_config, options):
|
|
|
7bbb43 |
+def install_step_1(standalone, replica_config, options, custodia):
|
|
|
7bbb43 |
if replica_config is not None and not replica_config.setup_ca:
|
|
|
7bbb43 |
return
|
|
|
7bbb43 |
|
|
|
7bbb43 |
@@ -293,7 +289,9 @@ def install_step_1(standalone, replica_config, options):
|
|
|
7bbb43 |
subject_base = options._subject_base
|
|
|
7bbb43 |
basedn = ipautil.realm_to_suffix(realm_name)
|
|
|
7bbb43 |
|
|
|
7bbb43 |
- ca = cainstance.CAInstance(realm_name, host_name=host_name)
|
|
|
7bbb43 |
+ ca = cainstance.CAInstance(
|
|
|
7bbb43 |
+ realm=realm_name, host_name=host_name, custodia=custodia
|
|
|
7bbb43 |
+ )
|
|
|
7bbb43 |
|
|
|
7bbb43 |
ca.stop('pki-tomcat')
|
|
|
7bbb43 |
|
|
|
7bbb43 |
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
|
|
|
7bbb43 |
index 20635eae22268ff72de73b8b9c430050114bb45b..eefc30b6e01dcf744703b8607cbe169fbec5d859 100644
|
|
|
7bbb43 |
--- a/ipaserver/install/cainstance.py
|
|
|
7bbb43 |
+++ b/ipaserver/install/cainstance.py
|
|
|
7bbb43 |
@@ -59,7 +59,6 @@ from ipapython.ipa_log_manager import log_mgr,\
|
|
|
7bbb43 |
from ipaserver.secrets.kem import IPAKEMKeys
|
|
|
7bbb43 |
|
|
|
7bbb43 |
from ipaserver.install import certs
|
|
|
7bbb43 |
-from ipaserver.install import custodiainstance
|
|
|
7bbb43 |
from ipaserver.install import dsinstance
|
|
|
7bbb43 |
from ipaserver.install import installutils
|
|
|
7bbb43 |
from ipaserver.install import ldapupdate
|
|
|
7bbb43 |
@@ -285,7 +284,7 @@ class CAInstance(DogtagInstance):
|
|
|
7bbb43 |
'caSigningCert cert-pki-ca')
|
|
|
7bbb43 |
server_cert_name = 'Server-Cert cert-pki-ca'
|
|
|
7bbb43 |
|
|
|
7bbb43 |
- def __init__(self, realm=None, host_name=None):
|
|
|
7bbb43 |
+ def __init__(self, realm=None, host_name=None, custodia=None):
|
|
|
7bbb43 |
super(CAInstance, self).__init__(
|
|
|
7bbb43 |
realm=realm,
|
|
|
7bbb43 |
subsystem="CA",
|
|
|
7bbb43 |
@@ -310,6 +309,8 @@ class CAInstance(DogtagInstance):
|
|
|
7bbb43 |
self.no_db_setup = False
|
|
|
7bbb43 |
self.keytab = os.path.join(
|
|
|
7bbb43 |
paths.PKI_TOMCAT, self.service_prefix + '.keytab')
|
|
|
7bbb43 |
+ # Custodia instance for RA key retrieval
|
|
|
7bbb43 |
+ self._custodia = custodia
|
|
|
7bbb43 |
|
|
|
7bbb43 |
def configure_instance(self, host_name, dm_password, admin_password,
|
|
|
7bbb43 |
pkcs12_info=None, master_host=None, csr_file=None,
|
|
|
7bbb43 |
@@ -711,9 +712,7 @@ class CAInstance(DogtagInstance):
|
|
|
7bbb43 |
self.configure_agent_renewal()
|
|
|
7bbb43 |
|
|
|
7bbb43 |
def __import_ra_key(self):
|
|
|
7bbb43 |
- custodia = custodiainstance.CustodiaInstance(host_name=self.fqdn,
|
|
|
7bbb43 |
- realm=self.realm)
|
|
|
7bbb43 |
- custodia.import_ra_key(self.master_host)
|
|
|
7bbb43 |
+ self._custodia.import_ra_key(self.master_host)
|
|
|
7bbb43 |
self.__set_ra_cert_perms()
|
|
|
7bbb43 |
|
|
|
7bbb43 |
self.configure_agent_renewal()
|
|
|
7bbb43 |
diff --git a/ipaserver/install/custodiainstance.py b/ipaserver/install/custodiainstance.py
|
|
|
7bbb43 |
index 0a90bb3954486b9773e3553e9981d2a8d0d4e44a..262ae5857c64719ff5cebde31b4b107e1245d458 100644
|
|
|
7bbb43 |
--- a/ipaserver/install/custodiainstance.py
|
|
|
7bbb43 |
+++ b/ipaserver/install/custodiainstance.py
|
|
|
7bbb43 |
@@ -1,5 +1,9 @@
|
|
|
7bbb43 |
# Copyright (C) 2015 FreeIPa Project Contributors, see 'COPYING' for license.
|
|
|
7bbb43 |
|
|
|
7bbb43 |
+from __future__ import print_function, absolute_import
|
|
|
7bbb43 |
+
|
|
|
7bbb43 |
+import enum
|
|
|
7bbb43 |
+
|
|
|
7bbb43 |
from ipaserver.secrets.kem import IPAKEMKeys, KEMLdap
|
|
|
7bbb43 |
from ipaserver.secrets.client import CustodiaClient
|
|
|
7bbb43 |
from ipaplatform.paths import paths
|
|
|
7bbb43 |
@@ -21,12 +25,84 @@ import time
|
|
|
7bbb43 |
import pwd
|
|
|
7bbb43 |
|
|
|
7bbb43 |
|
|
|
7bbb43 |
+class CustodiaModes(enum.Enum):
|
|
|
7bbb43 |
+ # peer must have a CA
|
|
|
7bbb43 |
+ CA_PEER = 'Custodia CA peer'
|
|
|
7bbb43 |
+ # peer must have a CA, KRA preferred
|
|
|
7bbb43 |
+ KRA_PEER = 'Custodia KRA peer'
|
|
|
7bbb43 |
+ # any master will do
|
|
|
7bbb43 |
+ MASTER_PEER = 'Custodia master peer'
|
|
|
7bbb43 |
+ # standalone / local instance
|
|
|
7bbb43 |
+ STANDALONE = 'Custodia standalone'
|
|
|
7bbb43 |
+
|
|
|
7bbb43 |
+
|
|
|
7bbb43 |
+def get_custodia_instance(config, mode):
|
|
|
7bbb43 |
+ """Create Custodia instance
|
|
|
7bbb43 |
+
|
|
|
7bbb43 |
+ :param config: configuration/installer object
|
|
|
7bbb43 |
+ :param mode: CustodiaModes member
|
|
|
7bbb43 |
+ :return: CustodiaInstance object
|
|
|
7bbb43 |
+
|
|
|
7bbb43 |
+ The config object must have the following attribute
|
|
|
7bbb43 |
+
|
|
|
7bbb43 |
+ *host_name*
|
|
|
7bbb43 |
+ FQDN of the new replica/master
|
|
|
7bbb43 |
+ *realm_name*
|
|
|
7bbb43 |
+ Kerberos realm
|
|
|
7bbb43 |
+ *promote*
|
|
|
7bbb43 |
+ True, when instance will be promoted from client to replica
|
|
|
7bbb43 |
+ *master_host_name* (for *CustodiaModes.MASTER_PEER*)
|
|
|
7bbb43 |
+ hostname of a master (may not have a CA)
|
|
|
7bbb43 |
+ *ca_host_name* (for *CustodiaModes.CA_PEER*)
|
|
|
7bbb43 |
+ hostname of a master with CA
|
|
|
7bbb43 |
+ *kra_host_name* (for *CustodiaModes.KRA_PEER*)
|
|
|
7bbb43 |
+ hostname of a master with KRA or CA
|
|
|
7bbb43 |
+
|
|
|
7bbb43 |
+ For promotion, the instance will upload new keys and retrieve secrets
|
|
|
7bbb43 |
+ from the same host. Therefore it uses *ca_host_name* instead of
|
|
|
7bbb43 |
+ *master_host_name* to create a replica with CA.
|
|
|
7bbb43 |
+ """
|
|
|
7bbb43 |
+ assert isinstance(mode, CustodiaModes)
|
|
|
7bbb43 |
+ root_logger.info(
|
|
|
7bbb43 |
+ "Custodia client for '%r' with promotion %s.",
|
|
|
7bbb43 |
+ mode, 'yes' if config.promote else 'no'
|
|
|
7bbb43 |
+ )
|
|
|
7bbb43 |
+ if config.promote:
|
|
|
7bbb43 |
+ if mode == CustodiaModes.CA_PEER:
|
|
|
7bbb43 |
+ # In case we install replica with CA, prefer CA host as source for
|
|
|
7bbb43 |
+ # all Custodia secret material.
|
|
|
7bbb43 |
+ custodia_master = config.ca_host_name
|
|
|
7bbb43 |
+ elif mode == CustodiaModes.KRA_PEER:
|
|
|
7bbb43 |
+ custodia_master = config.kra_host_name
|
|
|
7bbb43 |
+ elif mode == CustodiaModes.MASTER_PEER:
|
|
|
7bbb43 |
+ custodia_master = config.master_host_name
|
|
|
7bbb43 |
+ elif mode == CustodiaModes.STANDALONE:
|
|
|
7bbb43 |
+ custodia_master = None
|
|
|
7bbb43 |
+ else:
|
|
|
7bbb43 |
+ custodia_master = None
|
|
|
7bbb43 |
+
|
|
|
7bbb43 |
+ if custodia_master is None:
|
|
|
7bbb43 |
+ # use ldapi with local dirsrv instance
|
|
|
7bbb43 |
+ root_logger.info("Custodia uses LDAPI.")
|
|
|
7bbb43 |
+ ldap_uri = None
|
|
|
7bbb43 |
+ else:
|
|
|
7bbb43 |
+ root_logger.info("Custodia uses '%s' as master peer.",
|
|
|
7bbb43 |
+ custodia_master)
|
|
|
7bbb43 |
+ ldap_uri = 'ldap://{}'.format(custodia_master)
|
|
|
7bbb43 |
+
|
|
|
7bbb43 |
+ return CustodiaInstance(
|
|
|
7bbb43 |
+ host_name=config.host_name,
|
|
|
7bbb43 |
+ realm=config.realm_name,
|
|
|
7bbb43 |
+ ldap_uri=ldap_uri
|
|
|
7bbb43 |
+ )
|
|
|
7bbb43 |
+
|
|
|
7bbb43 |
+
|
|
|
7bbb43 |
class CustodiaInstance(SimpleServiceInstance):
|
|
|
7bbb43 |
- def __init__(self, host_name=None, realm=None):
|
|
|
7bbb43 |
+ def __init__(self, host_name=None, realm=None, ldap_uri=None):
|
|
|
7bbb43 |
super(CustodiaInstance, self).__init__("ipa-custodia")
|
|
|
7bbb43 |
self.config_file = paths.IPA_CUSTODIA_CONF
|
|
|
7bbb43 |
self.server_keys = paths.IPA_CUSTODIA_KEYS
|
|
|
7bbb43 |
- self.ldap_uri = None
|
|
|
7bbb43 |
+ self.ldap_uri = ldap_uri
|
|
|
7bbb43 |
self.fqdn = host_name
|
|
|
7bbb43 |
self.realm = realm
|
|
|
7bbb43 |
|
|
|
7bbb43 |
@@ -49,14 +125,19 @@ class CustodiaInstance(SimpleServiceInstance):
|
|
|
7bbb43 |
ipautil.flush_sync(f)
|
|
|
7bbb43 |
|
|
|
7bbb43 |
def create_instance(self):
|
|
|
7bbb43 |
- suffix = ipautil.realm_to_suffix(self.realm)
|
|
|
7bbb43 |
+ if self.ldap_uri is None or self.ldap_uri.startswith('ldapi://'):
|
|
|
7bbb43 |
+ # local case, ensure container exists
|
|
|
7bbb43 |
+ self.step("Making sure custodia container exists",
|
|
|
7bbb43 |
+ self.__create_container)
|
|
|
7bbb43 |
+
|
|
|
7bbb43 |
self.step("Generating ipa-custodia config file", self.__config_file)
|
|
|
7bbb43 |
- self.step("Making sure custodia container exists", self.__create_container)
|
|
|
7bbb43 |
self.step("Generating ipa-custodia keys", self.__gen_keys)
|
|
|
7bbb43 |
- super(CustodiaInstance, self).create_instance(gensvc_name='KEYS',
|
|
|
7bbb43 |
- fqdn=self.fqdn,
|
|
|
7bbb43 |
- ldap_suffix=suffix,
|
|
|
7bbb43 |
- realm=self.realm)
|
|
|
7bbb43 |
+ super(CustodiaInstance, self).create_instance(
|
|
|
7bbb43 |
+ gensvc_name='KEYS',
|
|
|
7bbb43 |
+ fqdn=self.fqdn,
|
|
|
7bbb43 |
+ ldap_suffix=ipautil.realm_to_suffix(self.realm),
|
|
|
7bbb43 |
+ realm=self.realm
|
|
|
7bbb43 |
+ )
|
|
|
7bbb43 |
sysupgrade.set_upgrade_state('custodia', 'installed', True)
|
|
|
7bbb43 |
|
|
|
7bbb43 |
def __gen_keys(self):
|
|
|
7bbb43 |
@@ -81,18 +162,6 @@ class CustodiaInstance(SimpleServiceInstance):
|
|
|
7bbb43 |
root_logger.info("Secure server.keys mode")
|
|
|
7bbb43 |
os.chmod(self.server_keys, 0o600)
|
|
|
7bbb43 |
|
|
|
7bbb43 |
- def create_replica(self, master_host_name):
|
|
|
7bbb43 |
- suffix = ipautil.realm_to_suffix(self.realm)
|
|
|
7bbb43 |
- self.ldap_uri = 'ldap://%s' % master_host_name
|
|
|
7bbb43 |
- self.master_host_name = master_host_name
|
|
|
7bbb43 |
-
|
|
|
7bbb43 |
- self.step("Generating ipa-custodia config file", self.__config_file)
|
|
|
7bbb43 |
- self.step("Generating ipa-custodia keys", self.__gen_keys)
|
|
|
7bbb43 |
- super(CustodiaInstance, self).create_instance(gensvc_name='KEYS',
|
|
|
7bbb43 |
- fqdn=self.fqdn,
|
|
|
7bbb43 |
- ldap_suffix=suffix,
|
|
|
7bbb43 |
- realm=self.realm)
|
|
|
7bbb43 |
-
|
|
|
7bbb43 |
def __create_container(self):
|
|
|
7bbb43 |
"""
|
|
|
7bbb43 |
Runs the custodia update file to ensure custodia container is present.
|
|
|
7bbb43 |
@@ -106,7 +175,7 @@ class CustodiaInstance(SimpleServiceInstance):
|
|
|
7bbb43 |
updater.update([os.path.join(paths.UPDATES_DIR, '73-custodia.update')])
|
|
|
7bbb43 |
|
|
|
7bbb43 |
def import_ra_key(self, master_host_name):
|
|
|
7bbb43 |
- cli = self.__CustodiaClient(server=master_host_name)
|
|
|
7bbb43 |
+ cli = self._get_custodia_client(server=master_host_name)
|
|
|
7bbb43 |
# please note that ipaCert part has to stay here for historical
|
|
|
7bbb43 |
# reasons (old servers expect you to ask for ra/ipaCert during
|
|
|
7bbb43 |
# replication as they store the RA agent cert in an NSS database
|
|
|
7bbb43 |
@@ -114,14 +183,14 @@ class CustodiaInstance(SimpleServiceInstance):
|
|
|
7bbb43 |
cli.fetch_key('ra/ipaCert')
|
|
|
7bbb43 |
|
|
|
7bbb43 |
def import_dm_password(self, master_host_name):
|
|
|
7bbb43 |
- cli = self.__CustodiaClient(server=master_host_name)
|
|
|
7bbb43 |
+ cli = self._get_custodia_client(server=master_host_name)
|
|
|
7bbb43 |
cli.fetch_key('dm/DMHash')
|
|
|
7bbb43 |
|
|
|
7bbb43 |
- def __wait_keys(self, host, timeout=300):
|
|
|
7bbb43 |
+ def _wait_keys(self, host, timeout=300):
|
|
|
7bbb43 |
ldap_uri = 'ldap://%s' % host
|
|
|
7bbb43 |
deadline = int(time.time()) + timeout
|
|
|
7bbb43 |
- root_logger.info("Waiting up to {} seconds to see our keys "
|
|
|
7bbb43 |
- "appear on host: {}".format(timeout, host))
|
|
|
7bbb43 |
+ root_logger.info("Waiting up to %s seconds to see our keys "
|
|
|
7bbb43 |
+ "appear on host: %s", timeout, host)
|
|
|
7bbb43 |
|
|
|
7bbb43 |
konn = KEMLdap(ldap_uri)
|
|
|
7bbb43 |
saved_e = None
|
|
|
7bbb43 |
@@ -129,6 +198,12 @@ class CustodiaInstance(SimpleServiceInstance):
|
|
|
7bbb43 |
try:
|
|
|
7bbb43 |
return konn.check_host_keys(self.fqdn)
|
|
|
7bbb43 |
except Exception as e:
|
|
|
7bbb43 |
+ # Print message to console only once for first error.
|
|
|
7bbb43 |
+ if saved_e is None:
|
|
|
7bbb43 |
+ # FIXME: Change once there's better way to show this
|
|
|
7bbb43 |
+ # message in installer output,
|
|
|
7bbb43 |
+ print(" Waiting for keys to appear on host: {}, please "
|
|
|
7bbb43 |
+ "wait until this has completed.".format(host))
|
|
|
7bbb43 |
# log only once for the same error
|
|
|
7bbb43 |
if not isinstance(e, type(saved_e)):
|
|
|
7bbb43 |
root_logger.debug(
|
|
|
7bbb43 |
@@ -138,22 +213,23 @@ class CustodiaInstance(SimpleServiceInstance):
|
|
|
7bbb43 |
raise RuntimeError("Timed out trying to obtain keys.")
|
|
|
7bbb43 |
time.sleep(1)
|
|
|
7bbb43 |
|
|
|
7bbb43 |
- def __CustodiaClient(self, server):
|
|
|
7bbb43 |
+ def _get_custodia_client(self, server):
|
|
|
7bbb43 |
# Before we attempt to fetch keys from this host, make sure our public
|
|
|
7bbb43 |
# keys have been replicated there.
|
|
|
7bbb43 |
- self.__wait_keys(server)
|
|
|
7bbb43 |
-
|
|
|
7bbb43 |
- return CustodiaClient('host@%s' % self.fqdn, self.server_keys,
|
|
|
7bbb43 |
- paths.KRB5_KEYTAB, server, realm=self.realm)
|
|
|
7bbb43 |
+ self._wait_keys(server)
|
|
|
7bbb43 |
|
|
|
7bbb43 |
- def __get_keys(self, ca_host, cacerts_file, cacerts_pwd, data):
|
|
|
7bbb43 |
- # Fecth all needed certs one by one, then combine them in a single
|
|
|
7bbb43 |
- # p12 file
|
|
|
7bbb43 |
+ return CustodiaClient(
|
|
|
7bbb43 |
+ client_service='host@{}'.format(self.fqdn),
|
|
|
7bbb43 |
+ keyfile=self.server_keys, keytab=paths.KRB5_KEYTAB,
|
|
|
7bbb43 |
+ server=server, realm=self.realm
|
|
|
7bbb43 |
+ )
|
|
|
7bbb43 |
|
|
|
7bbb43 |
+ def _get_keys(self, ca_host, cacerts_file, cacerts_pwd, data):
|
|
|
7bbb43 |
+ # Fetch all needed certs one by one, then combine them in a single
|
|
|
7bbb43 |
+ # PKCS12 file
|
|
|
7bbb43 |
prefix = data['prefix']
|
|
|
7bbb43 |
certlist = data['list']
|
|
|
7bbb43 |
-
|
|
|
7bbb43 |
- cli = self.__CustodiaClient(server=ca_host)
|
|
|
7bbb43 |
+ cli = self._get_custodia_client(server=ca_host)
|
|
|
7bbb43 |
|
|
|
7bbb43 |
# Temporary nssdb
|
|
|
7bbb43 |
tmpnssdir = tempfile.mkdtemp(dir=paths.TMP)
|
|
|
7bbb43 |
@@ -203,7 +279,7 @@ class CustodiaInstance(SimpleServiceInstance):
|
|
|
7bbb43 |
'subsystemCert cert-pki-ca']
|
|
|
7bbb43 |
data = {'prefix': 'ca',
|
|
|
7bbb43 |
'list': certlist}
|
|
|
7bbb43 |
- self.__get_keys(ca_host, cacerts_file, cacerts_pwd, data)
|
|
|
7bbb43 |
+ self._get_keys(ca_host, cacerts_file, cacerts_pwd, data)
|
|
|
7bbb43 |
|
|
|
7bbb43 |
def get_kra_keys(self, ca_host, cacerts_file, cacerts_pwd):
|
|
|
7bbb43 |
certlist = ['auditSigningCert cert-pki-kra',
|
|
|
7bbb43 |
@@ -212,7 +288,7 @@ class CustodiaInstance(SimpleServiceInstance):
|
|
|
7bbb43 |
'transportCert cert-pki-kra']
|
|
|
7bbb43 |
data = {'prefix': 'ca',
|
|
|
7bbb43 |
'list': certlist}
|
|
|
7bbb43 |
- self.__get_keys(ca_host, cacerts_file, cacerts_pwd, data)
|
|
|
7bbb43 |
+ self._get_keys(ca_host, cacerts_file, cacerts_pwd, data)
|
|
|
7bbb43 |
|
|
|
7bbb43 |
def __start(self):
|
|
|
7bbb43 |
super(CustodiaInstance, self).__start()
|
|
|
7bbb43 |
diff --git a/ipaserver/install/ipa_kra_install.py b/ipaserver/install/ipa_kra_install.py
|
|
|
7bbb43 |
index 3e08f4da94651b49876e1427daddbd957f0027ae..9ebabe057513141ee76d238a3f20e76a27dd932e 100644
|
|
|
7bbb43 |
--- a/ipaserver/install/ipa_kra_install.py
|
|
|
7bbb43 |
+++ b/ipaserver/install/ipa_kra_install.py
|
|
|
7bbb43 |
@@ -32,6 +32,7 @@ from ipapython import admintool
|
|
|
7bbb43 |
from ipapython import ipautil
|
|
|
7bbb43 |
from ipaserver.install import service
|
|
|
7bbb43 |
from ipaserver.install import cainstance
|
|
|
7bbb43 |
+from ipaserver.install import custodiainstance
|
|
|
7bbb43 |
from ipaserver.install import krainstance
|
|
|
7bbb43 |
from ipaserver.install import dsinstance
|
|
|
7bbb43 |
from ipaserver.install import installutils
|
|
|
7bbb43 |
@@ -176,7 +177,6 @@ class KRAInstaller(KRAInstall):
|
|
|
7bbb43 |
|
|
|
7bbb43 |
api.Backend.ldap2.connect()
|
|
|
7bbb43 |
|
|
|
7bbb43 |
- config = None
|
|
|
7bbb43 |
if self.installing_replica:
|
|
|
7bbb43 |
if self.options.promote:
|
|
|
7bbb43 |
config = ReplicaConfig()
|
|
|
7bbb43 |
@@ -196,6 +196,7 @@ class KRAInstaller(KRAInstall):
|
|
|
7bbb43 |
config.kra_host_name = config.master_host_name
|
|
|
7bbb43 |
|
|
|
7bbb43 |
config.setup_kra = True
|
|
|
7bbb43 |
+ config.promote = self.options.promote
|
|
|
7bbb43 |
|
|
|
7bbb43 |
if config.subject_base is None:
|
|
|
7bbb43 |
attrs = api.Backend.ldap2.get_ipa_config()
|
|
|
7bbb43 |
@@ -204,6 +205,11 @@ class KRAInstaller(KRAInstall):
|
|
|
7bbb43 |
if config.kra_host_name is None:
|
|
|
7bbb43 |
config.kra_host_name = service.find_providing_server(
|
|
|
7bbb43 |
'KRA', api.Backend.ldap2, api.env.ca_host)
|
|
|
7bbb43 |
+ custodia = custodiainstance.get_custodia_instance(
|
|
|
7bbb43 |
+ config, custodiainstance.CustodiaModes.KRA_PEER)
|
|
|
7bbb43 |
+ else:
|
|
|
7bbb43 |
+ config = None
|
|
|
7bbb43 |
+ custodia = None
|
|
|
7bbb43 |
|
|
|
7bbb43 |
try:
|
|
|
7bbb43 |
kra.install_check(api, config, self.options)
|
|
|
7bbb43 |
@@ -213,7 +219,7 @@ class KRAInstaller(KRAInstall):
|
|
|
7bbb43 |
print(dedent(self.INSTALLER_START_MESSAGE))
|
|
|
7bbb43 |
|
|
|
7bbb43 |
try:
|
|
|
7bbb43 |
- kra.install(api, config, self.options)
|
|
|
7bbb43 |
+ kra.install(api, config, self.options, custodia=custodia)
|
|
|
7bbb43 |
except:
|
|
|
7bbb43 |
self.log.error(dedent(self.FAIL_MESSAGE))
|
|
|
7bbb43 |
raise
|
|
|
7bbb43 |
diff --git a/ipaserver/install/kra.py b/ipaserver/install/kra.py
|
|
|
7bbb43 |
index 3545b301a977f4b7e7801ca1ef87d594bb3ba54f..3333970e8af9e36d6b7614286cc1e774f6eb9b25 100644
|
|
|
7bbb43 |
--- a/ipaserver/install/kra.py
|
|
|
7bbb43 |
+++ b/ipaserver/install/kra.py
|
|
|
7bbb43 |
@@ -16,7 +16,6 @@ from ipaplatform.paths import paths
|
|
|
7bbb43 |
from ipapython import certdb
|
|
|
7bbb43 |
from ipapython import ipautil
|
|
|
7bbb43 |
from ipapython.install.core import group
|
|
|
7bbb43 |
-from ipaserver.install import custodiainstance
|
|
|
7bbb43 |
from ipaserver.install import cainstance
|
|
|
7bbb43 |
from ipaserver.install import krainstance
|
|
|
7bbb43 |
from ipaserver.install import dsinstance
|
|
|
7bbb43 |
@@ -68,7 +67,7 @@ def install_check(api, replica_config, options):
|
|
|
7bbb43 |
"new replica file.")
|
|
|
7bbb43 |
|
|
|
7bbb43 |
|
|
|
7bbb43 |
-def install(api, replica_config, options):
|
|
|
7bbb43 |
+def install(api, replica_config, options, custodia):
|
|
|
7bbb43 |
if replica_config is None:
|
|
|
7bbb43 |
if not options.setup_kra:
|
|
|
7bbb43 |
return
|
|
|
7bbb43 |
@@ -91,9 +90,6 @@ def install(api, replica_config, options):
|
|
|
7bbb43 |
'host/{env.host}@{env.realm}'.format(env=api.env),
|
|
|
7bbb43 |
paths.KRB5_KEYTAB,
|
|
|
7bbb43 |
ccache)
|
|
|
7bbb43 |
- custodia = custodiainstance.CustodiaInstance(
|
|
|
7bbb43 |
- replica_config.host_name,
|
|
|
7bbb43 |
- replica_config.realm_name)
|
|
|
7bbb43 |
custodia.get_kra_keys(
|
|
|
7bbb43 |
replica_config.kra_host_name,
|
|
|
7bbb43 |
krafile,
|
|
|
7bbb43 |
diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
|
|
|
7bbb43 |
index 422474fa915b4876530f304ef9424f6b31cf26cc..f4338ed0428f7f44decd004f6a183258bef7f795 100644
|
|
|
7bbb43 |
--- a/ipaserver/install/server/install.py
|
|
|
7bbb43 |
+++ b/ipaserver/install/server/install.py
|
|
|
7bbb43 |
@@ -709,6 +709,7 @@ def install(installer):
|
|
|
7bbb43 |
host_name = options.host_name
|
|
|
7bbb43 |
ip_addresses = options.ip_addresses
|
|
|
7bbb43 |
setup_ca = options.setup_ca
|
|
|
7bbb43 |
+ options.promote = False # first master, no promotion
|
|
|
7bbb43 |
|
|
|
7bbb43 |
# Installation has started. No IPA sysrestore items are restored in case of
|
|
|
7bbb43 |
# failure to enable root cause investigation
|
|
|
7bbb43 |
@@ -789,6 +790,10 @@ def install(installer):
|
|
|
7bbb43 |
setup_pkinit=not options.no_pkinit,
|
|
|
7bbb43 |
subject_base=options.subject_base)
|
|
|
7bbb43 |
|
|
|
7bbb43 |
+ custodia = custodiainstance.get_custodia_instance(
|
|
|
7bbb43 |
+ options, custodiainstance.CustodiaModes.MASTER_PEER)
|
|
|
7bbb43 |
+ custodia.create_instance()
|
|
|
7bbb43 |
+
|
|
|
7bbb43 |
if setup_ca:
|
|
|
7bbb43 |
if not options.external_cert_files and options.external_ca:
|
|
|
7bbb43 |
# stage 1 of external CA installation
|
|
|
7bbb43 |
@@ -803,7 +808,7 @@ def install(installer):
|
|
|
7bbb43 |
if n in options.__dict__}
|
|
|
7bbb43 |
write_cache(cache_vars)
|
|
|
7bbb43 |
|
|
|
7bbb43 |
- ca.install_step_0(False, None, options)
|
|
|
7bbb43 |
+ ca.install_step_0(False, None, options, custodia=custodia)
|
|
|
7bbb43 |
else:
|
|
|
7bbb43 |
# Put the CA cert where other instances expect it
|
|
|
7bbb43 |
x509.write_certificate(http_ca_cert, paths.IPA_CA_CRT)
|
|
|
7bbb43 |
@@ -823,15 +828,12 @@ def install(installer):
|
|
|
7bbb43 |
ds.enable_ssl()
|
|
|
7bbb43 |
|
|
|
7bbb43 |
if setup_ca:
|
|
|
7bbb43 |
- ca.install_step_1(False, None, options)
|
|
|
7bbb43 |
+ ca.install_step_1(False, None, options, custodia=custodia)
|
|
|
7bbb43 |
|
|
|
7bbb43 |
otpd = otpdinstance.OtpdInstance()
|
|
|
7bbb43 |
otpd.create_instance('OTPD', host_name,
|
|
|
7bbb43 |
ipautil.realm_to_suffix(realm_name))
|
|
|
7bbb43 |
|
|
|
7bbb43 |
- custodia = custodiainstance.CustodiaInstance(host_name, realm_name)
|
|
|
7bbb43 |
- custodia.create_instance()
|
|
|
7bbb43 |
-
|
|
|
7bbb43 |
# Create a HTTP instance
|
|
|
7bbb43 |
http = httpinstance.HTTPInstance(fstore)
|
|
|
7bbb43 |
if options.http_cert_files:
|
|
|
7bbb43 |
@@ -863,7 +865,7 @@ def install(installer):
|
|
|
7bbb43 |
krb.restart()
|
|
|
7bbb43 |
|
|
|
7bbb43 |
if options.setup_kra:
|
|
|
7bbb43 |
- kra.install(api, None, options)
|
|
|
7bbb43 |
+ kra.install(api, None, options, custodia=custodia)
|
|
|
7bbb43 |
|
|
|
7bbb43 |
if options.setup_dns:
|
|
|
7bbb43 |
dns.install(False, False, options)
|
|
|
7bbb43 |
diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
|
|
|
7bbb43 |
index 42e4615ad2dc1f604f5d8d14f8e57e3e4674bcb9..2ecc0abe0c5918cf5aefccc1bd6f09e70503baab 100644
|
|
|
7bbb43 |
--- a/ipaserver/install/server/replicainstall.py
|
|
|
7bbb43 |
+++ b/ipaserver/install/server/replicainstall.py
|
|
|
7bbb43 |
@@ -1357,6 +1357,7 @@ def install(installer):
|
|
|
7bbb43 |
fstore = installer._fstore
|
|
|
7bbb43 |
sstore = installer._sstore
|
|
|
7bbb43 |
config = installer._config
|
|
|
7bbb43 |
+ config.promote = installer.promote
|
|
|
7bbb43 |
promote = installer.promote
|
|
|
7bbb43 |
cafile = installer._ca_file
|
|
|
7bbb43 |
dirsrv_pkcs12_info = installer._dirsrv_pkcs12_info
|
|
|
7bbb43 |
@@ -1483,19 +1484,19 @@ def install(installer):
|
|
|
7bbb43 |
otpd.create_instance('OTPD', config.host_name,
|
|
|
7bbb43 |
ipautil.realm_to_suffix(config.realm_name))
|
|
|
7bbb43 |
|
|
|
7bbb43 |
- custodia = custodiainstance.CustodiaInstance(config.host_name,
|
|
|
7bbb43 |
- config.realm_name)
|
|
|
7bbb43 |
- if promote:
|
|
|
7bbb43 |
- custodia.create_replica(config.master_host_name)
|
|
|
7bbb43 |
+ if ca_enabled:
|
|
|
7bbb43 |
+ mode = custodiainstance.CustodiaModes.CA_PEER
|
|
|
7bbb43 |
else:
|
|
|
7bbb43 |
- custodia.create_instance()
|
|
|
7bbb43 |
+ mode = custodiainstance.CustodiaModes.MASTER_PEER
|
|
|
7bbb43 |
+ custodia = custodiainstance.get_custodia_instance(config, mode)
|
|
|
7bbb43 |
+ custodia.create_instance()
|
|
|
7bbb43 |
|
|
|
7bbb43 |
if ca_enabled:
|
|
|
7bbb43 |
options.realm_name = config.realm_name
|
|
|
7bbb43 |
options.domain_name = config.domain_name
|
|
|
7bbb43 |
options.host_name = config.host_name
|
|
|
7bbb43 |
options.dm_password = config.dirman_password
|
|
|
7bbb43 |
- ca.install(False, config, options)
|
|
|
7bbb43 |
+ ca.install(False, config, options, custodia=custodia)
|
|
|
7bbb43 |
|
|
|
7bbb43 |
# configure PKINIT now that all required services are in place
|
|
|
7bbb43 |
krb.enable_ssl()
|
|
|
7bbb43 |
@@ -1505,7 +1506,7 @@ def install(installer):
|
|
|
7bbb43 |
ds.apply_updates()
|
|
|
7bbb43 |
|
|
|
7bbb43 |
if kra_enabled:
|
|
|
7bbb43 |
- kra.install(api, config, options)
|
|
|
7bbb43 |
+ kra.install(api, config, options, custodia=custodia)
|
|
|
7bbb43 |
|
|
|
7bbb43 |
service.print_msg("Restarting the KDC")
|
|
|
7bbb43 |
krb.restart()
|
|
|
7bbb43 |
--
|
|
|
7bbb43 |
2.14.3
|
|
|
7bbb43 |
|