summaryrefslogtreecommitdiffstats
path: root/ipaserver
diff options
context:
space:
mode:
authorMartin Kosek <mkosek@redhat.com>2012-11-19 10:32:28 -0500
committerRob Crittenden <rcritten@redhat.com>2012-12-07 11:00:17 -0500
commit867f7691e9e8d4dc101d227ca56a94f9b947897f (patch)
treedcd1529b6a530091bdb1f446b34bf71bae3836a9 /ipaserver
parent0d836cd6ee9d7b29808cbf36582eed71a5b6a32a (diff)
downloadfreeipa.git-867f7691e9e8d4dc101d227ca56a94f9b947897f.tar.gz
freeipa.git-867f7691e9e8d4dc101d227ca56a94f9b947897f.tar.xz
freeipa.git-867f7691e9e8d4dc101d227ca56a94f9b947897f.zip
Add OCSP and CRL URIs to certificates
Modify the default IPA CA certificate profile to include CRL and OCSP extensions which will add URIs to IPA CRL&OCSP to published certificates. Both CRL and OCSP extensions have 2 URIs, one pointing directly to the IPA CA which published the certificate and one to a new CNAME ipa-ca.$DOMAIN which was introduced as a general CNAME pointing to all IPA replicas which have CA configured. The new CNAME is added either during new IPA server/replica/CA installation or during upgrade. https://fedorahosted.org/freeipa/ticket/3074 https://fedorahosted.org/freeipa/ticket/1431
Diffstat (limited to 'ipaserver')
-rw-r--r--ipaserver/install/bindinstance.py62
-rw-r--r--ipaserver/install/cainstance.py150
2 files changed, 186 insertions, 26 deletions
diff --git a/ipaserver/install/bindinstance.py b/ipaserver/install/bindinstance.py
index 8a77edfa..a528320c 100644
--- a/ipaserver/install/bindinstance.py
+++ b/ipaserver/install/bindinstance.py
@@ -28,6 +28,7 @@ import ldap
import service
from ipaserver import ipaldap
from ipaserver.install.dsinstance import realm_to_serverid
+from ipaserver.install.cainstance import IPA_CA_CNAME
from ipaserver.install.installutils import resolve_host
from ipapython import sysrestore
from ipapython import ipautil
@@ -330,7 +331,7 @@ def del_rr(zone, name, type, rdata):
delkw = { '%srecord' % str(type.lower()) : unicode(rdata) }
try:
api.Command.dnsrecord_del(unicode(zone), unicode(name), **delkw)
- except (errors.NotFound, errors.EmptyModlist):
+ except (errors.NotFound, errors.AttrValueNotFound, errors.EmptyModlist):
pass
def get_rr(zone, name, type):
@@ -430,7 +431,8 @@ class BindInstance(service.Service):
def setup(self, fqdn, ip_address, realm_name, domain_name, forwarders, ntp,
reverse_zone, named_user="named", zonemgr=None,
- zone_refresh=0, persistent_search=True, serial_autoincrement=True):
+ zone_refresh=0, persistent_search=True, serial_autoincrement=True,
+ ca_configured=None):
self.named_user = named_user
self.fqdn = fqdn
self.ip_address = ip_address
@@ -444,6 +446,7 @@ class BindInstance(service.Service):
self.zone_refresh = zone_refresh
self.persistent_search = persistent_search
self.serial_autoincrement = serial_autoincrement
+ self.ca_configured = ca_configured
if not zonemgr:
self.zonemgr = 'hostmaster.%s' % self.domain
@@ -497,6 +500,7 @@ class BindInstance(service.Service):
if self.reverse_zone is not None:
self.step("setting up reverse zone", self.__setup_reverse_zone)
self.step("setting up our own record", self.__add_self)
+ self.step("setting up CA CNAME record", self.__add_ipa_ca_cname)
self.step("setting up kerberos principal", self.__setup_principal)
self.step("setting up named.conf", self.__setup_named_conf)
@@ -556,6 +560,7 @@ class BindInstance(service.Service):
OPTIONAL_NTP=optional_ntp,
ZONEMGR=self.zonemgr,
ZONE_REFRESH=self.zone_refresh,
+ IPA_CA_CNAME=IPA_CA_CNAME,
PERSISTENT_SEARCH=boolean_var['persistent_search'],
SERIAL_AUTOINCREMENT=boolean_var['serial_autoincrement'],)
@@ -582,6 +587,28 @@ class BindInstance(service.Service):
def __add_self_ns(self):
add_ns_rr(self.domain, api.env.host, self.dns_backup, force=True)
+ def __add_ipa_ca_cname(self):
+ if self.ca_configured is False:
+ root_logger.debug("CA is not configured, skip this step")
+ return
+ elif self.ca_configured is None:
+ # we do not know if CA is configured for this host and we can
+ # add the CA CNAME record. So we need to find out
+ root_logger.debug("Check if CA is enabled for this host")
+ base_dn = DN(('cn', api.env.host), ('cn', 'masters'), ('cn', 'ipa'),
+ ('cn', 'etc'), api.env.basedn)
+ ldap_filter = '(&(objectClass=ipaConfigObject)(cn=CA))'
+ try:
+ api.Backend.ldap2.find_entries(filter=ldap_filter, base_dn=base_dn)
+ except ipalib.errors.NotFound:
+ # CA is not configured
+ root_logger.debug("CA is not configured")
+ return
+ else:
+ root_logger.debug("CA is configured for this host, continue")
+
+ add_rr(self.domain, IPA_CA_CNAME, "CNAME", self.host_in_rr)
+
def __add_self(self):
zone = self.domain
resource_records = (
@@ -681,7 +708,7 @@ class BindInstance(service.Service):
resolv_fd.close()
def add_master_dns_records(self, fqdn, ip_address, realm_name, domain_name,
- reverse_zone, ntp=False):
+ reverse_zone, ntp=False, ca_configured=None):
self.fqdn = fqdn
self.ip_address = ip_address
self.realm = realm_name
@@ -690,23 +717,36 @@ class BindInstance(service.Service):
self.suffix = ipautil.realm_to_suffix(self.realm)
self.ntp = ntp
self.reverse_zone = reverse_zone
+ self.ca_configured = ca_configured
self.__add_self()
+ self.__add_ipa_ca_cname()
+
+ def add_ipa_ca_cname(self, fqdn, domain_name, ca_configured=True):
+ self.host = fqdn.split(".")[0]
+ self.fqdn = fqdn
+ self.domain = domain_name
+ self.ca_configured = ca_configured
+ self.__add_ipa_ca_cname()
def remove_master_dns_records(self, fqdn, realm_name, domain_name):
host = fqdn.split(".")[0]
+ self.host = host
+ self.fqdn = fqdn
+ self.domain = domain_name
suffix = ipautil.realm_to_suffix(realm_name)
zone = domain_name
resource_records = (
- ("_ldap._tcp", "SRV", "0 100 389 %s" % host),
- ("_kerberos._tcp", "SRV", "0 100 88 %s" % host),
- ("_kerberos._udp", "SRV", "0 100 88 %s" % host),
- ("_kerberos-master._tcp", "SRV", "0 100 88 %s" % host),
- ("_kerberos-master._udp", "SRV", "0 100 88 %s" % host),
- ("_kpasswd._tcp", "SRV", "0 100 464 %s" % host),
- ("_kpasswd._udp", "SRV", "0 100 464 %s" % host),
- ("_ntp._udp", "SRV", "0 100 123 %s" % host),
+ ("_ldap._tcp", "SRV", "0 100 389 %s" % self.host_in_rr),
+ ("_kerberos._tcp", "SRV", "0 100 88 %s" % self.host_in_rr),
+ ("_kerberos._udp", "SRV", "0 100 88 %s" % self.host_in_rr),
+ ("_kerberos-master._tcp", "SRV", "0 100 88 %s" % self.host_in_rr),
+ ("_kerberos-master._udp", "SRV", "0 100 88 %s" % self.host_in_rr),
+ ("_kpasswd._tcp", "SRV", "0 100 464 %s" % self.host_in_rr),
+ ("_kpasswd._udp", "SRV", "0 100 464 %s" % self.host_in_rr),
+ ("_ntp._udp", "SRV", "0 100 123 %s" % self.host_in_rr),
+ (IPA_CA_CNAME, "CNAME", self.host_in_rr),
("@", "NS", fqdn+"."),
)
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index 418267f6..18c78776 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -66,6 +66,9 @@ DEFAULT_DSPORT = dogtag.install_constants.DS_PORT
PKI_USER = "pkiuser"
PKI_DS_USER = dogtag.install_constants.DS_USER
+# When IPA is installed with DNS support, this CNAME should hold all IPA
+# replicas with CA configured
+IPA_CA_CNAME = "ipa-ca"
# We need to reset the template because the CA uses the regular boot
# information
@@ -497,6 +500,7 @@ class CAInstance(service.Service):
self.dm_password = None
self.admin_password = None
self.fqdn = None
+ self.domain = None
self.pkcs12_info = None
self.clone = False
@@ -516,7 +520,7 @@ class CAInstance(service.Service):
self.ra_agent_db = ra_db
self.ra_agent_pwd = self.ra_agent_db + "/pwdfile.txt"
self.ds_port = DEFAULT_DSPORT
- self.domain_name = "IPA"
+ self.security_domain_name = "IPA"
self.server_root = dogtag_constants.SERVER_ROOT
self.ra_cert = None
self.requestId = None
@@ -534,7 +538,7 @@ class CAInstance(service.Service):
return os.path.exists(os.path.join(
self.server_root, self.dogtag_constants.PKI_INSTANCE_NAME))
- def configure_instance(self, host_name, dm_password,
+ def configure_instance(self, host_name, domain, dm_password,
admin_password, ds_port=DEFAULT_DSPORT,
pkcs12_info=None, master_host=None, csr_file=None,
cert_file=None, cert_chain_file=None,
@@ -552,6 +556,7 @@ class CAInstance(service.Service):
csr_file. For step 2 set cert_file and cert_chain_file.
"""
self.fqdn = host_name
+ self.domain = domain
self.dm_password = dm_password
self.admin_password = admin_password
self.ds_port = ds_port
@@ -596,6 +601,7 @@ class CAInstance(service.Service):
self.step("set up CRL publishing", self.__enable_crl_publish)
self.step("set certificate subject base", self.__set_subject_in_config)
self.step("enabling Subject Key Identifier", self.enable_subject_key_identifier)
+ self.step("enabling CRL and OCSP extensions for certificates", self.__set_crl_ocsp_extensions)
self.step("setting audit signing renewal to 2 years", self.set_audit_renewal)
self.step("configuring certificate server to start on boot", self.__enable)
if not self.clone:
@@ -633,7 +639,7 @@ class CAInstance(service.Service):
"pki_client_database_password": self.admin_password,
"pki_client_database_purge": "False",
"pki_client_pkcs12_password": self.admin_password,
- "pki_security_domain_name": self.domain_name,
+ "pki_security_domain_name": self.security_domain_name,
"pki_admin_name": "admin",
"pki_admin_uid": "admin",
"pki_admin_email": "root@localhost",
@@ -800,7 +806,7 @@ class CAInstance(service.Service):
"-client_certdb_dir", self.ca_agent_db,
"-client_certdb_pwd", self.admin_password,
"-preop_pin" , preop_pin,
- "-domain_name", self.domain_name,
+ "-domain_name", self.security_domain_name,
"-admin_user", "admin",
"-admin_email", "root@localhost",
"-admin_password", self.admin_password,
@@ -1239,6 +1245,124 @@ class CAInstance(service.Service):
return publishdir
+ def __set_crl_ocsp_extensions(self):
+ self.set_crl_ocsp_extensions(self.domain, self.fqdn)
+
+ def set_crl_ocsp_extensions(self, domain, fqdn):
+ """
+ Configure CRL and OCSP extensions in default IPA certificate profile
+ if not done already.
+ """
+ changed = False
+
+ # OCSP extension
+ ocsp_location_0 = installutils.get_directive(
+ self.dogtag_constants.IPA_SERVICE_PROFILE,
+ 'policyset.serverCertSet.5.default.params.authInfoAccessADLocation_0',
+ separator='=')
+
+ if not ocsp_location_0:
+ # Set the first OCSP URI
+ installutils.set_directive(self.dogtag_constants.IPA_SERVICE_PROFILE,
+ 'policyset.serverCertSet.5.default.params.authInfoAccessADLocation_0',
+ 'https://%s.%s/ca/ocsp' % (IPA_CA_CNAME, ipautil.format_netloc(domain)),
+ quotes=False, separator='=')
+ changed = True
+
+ ocsp_profile_count = installutils.get_directive(
+ self.dogtag_constants.IPA_SERVICE_PROFILE,
+ 'policyset.serverCertSet.5.default.params.authInfoAccessNumADs',
+ separator='=')
+
+ if ocsp_profile_count == '1':
+ # add the second OCSP URI
+ installutils.set_directive(self.dogtag_constants.IPA_SERVICE_PROFILE,
+ 'policyset.serverCertSet.5.default.params.authInfoAccessADEnable_1',
+ 'true', quotes=False, separator='=')
+ installutils.set_directive(self.dogtag_constants.IPA_SERVICE_PROFILE,
+ 'policyset.serverCertSet.5.default.params.authInfoAccessADLocationType_1',
+ 'URIName', quotes=False, separator='=')
+ installutils.set_directive(self.dogtag_constants.IPA_SERVICE_PROFILE,
+ 'policyset.serverCertSet.5.default.params.authInfoAccessADLocation_1',
+ 'http://%s/ca/ocsp' % ipautil.format_netloc(fqdn),
+ quotes=False, separator='=')
+ installutils.set_directive(self.dogtag_constants.IPA_SERVICE_PROFILE,
+ 'policyset.serverCertSet.5.default.params.authInfoAccessADMethod_1',
+ '1.3.6.1.5.5.7.48.1', quotes=False, separator='=')
+ installutils.set_directive(self.dogtag_constants.IPA_SERVICE_PROFILE,
+ 'policyset.serverCertSet.5.default.params.authInfoAccessNumADs',
+ '2', quotes=False, separator='=')
+ changed = True
+
+
+ # CRL extension
+ crl_issuer_0 = installutils.get_directive(
+ self.dogtag_constants.IPA_SERVICE_PROFILE,
+ 'policyset.serverCertSet.9.default.params.crlDistPointsIssuerName_0',
+ separator='=')
+
+ if not crl_issuer_0:
+ installutils.set_directive(self.dogtag_constants.IPA_SERVICE_PROFILE,
+ 'policyset.serverCertSet.9.default.params.crlDistPointsIssuerName_0',
+ 'CN=Certificate Authority,o=ipaca', quotes=False, separator='=')
+ installutils.set_directive(self.dogtag_constants.IPA_SERVICE_PROFILE,
+ 'policyset.serverCertSet.9.default.params.crlDistPointsIssuerType_0',
+ 'DirectoryName', quotes=False, separator='=')
+ installutils.set_directive(self.dogtag_constants.IPA_SERVICE_PROFILE,
+ 'policyset.serverCertSet.9.default.params.crlDistPointsPointName_0',
+ 'https://%s.%s/ipa/crl/MasterCRL.bin'% (IPA_CA_CNAME, ipautil.format_netloc(domain)),
+ quotes=False, separator='=')
+ changed = True
+
+ crl_profile_count = installutils.get_directive(
+ self.dogtag_constants.IPA_SERVICE_PROFILE,
+ 'policyset.serverCertSet.9.default.params.crlDistPointsNum',
+ separator='=')
+
+ if crl_profile_count == '1':
+ installutils.set_directive(self.dogtag_constants.IPA_SERVICE_PROFILE,
+ 'policyset.serverCertSet.9.default.params.crlDistPointsEnable_1',
+ 'true', quotes=False, separator='=')
+ installutils.set_directive(self.dogtag_constants.IPA_SERVICE_PROFILE,
+ 'policyset.serverCertSet.9.default.params.crlDistPointsIssuerName_1',
+ 'CN=Certificate Authority,o=ipaca', quotes=False, separator='=')
+ installutils.set_directive(self.dogtag_constants.IPA_SERVICE_PROFILE,
+ 'policyset.serverCertSet.9.default.params.crlDistPointsIssuerType_1',
+ 'DirectoryName', quotes=False, separator='=')
+ installutils.set_directive(self.dogtag_constants.IPA_SERVICE_PROFILE,
+ 'policyset.serverCertSet.9.default.params.crlDistPointsPointName_1',
+ 'https://%s/ipa/crl/MasterCRL.bin' % ipautil.format_netloc(fqdn),
+ quotes=False, separator='=')
+ installutils.set_directive(self.dogtag_constants.IPA_SERVICE_PROFILE,
+ 'policyset.serverCertSet.9.default.params.crlDistPointsPointType_1',
+ 'URIName', quotes=False, separator='=')
+ installutils.set_directive(self.dogtag_constants.IPA_SERVICE_PROFILE,
+ 'policyset.serverCertSet.9.default.params.crlDistPointsReasons_1',
+ '', quotes=False, separator='=')
+ installutils.set_directive(self.dogtag_constants.IPA_SERVICE_PROFILE,
+ 'policyset.serverCertSet.9.default.params.crlDistPointsNum',
+ '2', quotes=False, separator='=')
+ changed = True
+
+ # CRL extension is not enabled by default
+ setlist = installutils.get_directive(self.dogtag_constants.IPA_SERVICE_PROFILE,
+ 'policyset.serverCertSet.list', separator='=')
+ new_set_list = None
+
+ if setlist == '1,2,3,4,5,6,7,8':
+ new_set_list = '1,2,3,4,5,6,7,8,9'
+ elif setlist == '1,2,3,4,5,6,7,8,10':
+ new_set_list = '1,2,3,4,5,6,7,8,9,10'
+
+ if new_set_list:
+ installutils.set_directive(self.dogtag_constants.IPA_SERVICE_PROFILE,
+ 'policyset.serverCertSet.list',
+ new_set_list, quotes=False, separator='=')
+ changed = True
+
+ return changed
+
+
def __enable_crl_publish(self):
"""
Enable file-based CRL publishing and disable LDAP publishing.
@@ -1279,12 +1403,6 @@ class CAInstance(service.Service):
installutils.set_directive(caconfig, 'ca.publish.rule.instance.LdapUserCertRule.enable', 'false', quotes=False, separator='=')
installutils.set_directive(caconfig, 'ca.publish.rule.instance.LdapXCertRule.enable', 'false', quotes=False, separator='=')
- # Fix the CRL URI in the profile
- installutils.set_directive(self.dogtag_constants.IPA_SERVICE_PROFILE,
- 'policyset.serverCertSet.9.default.params.crlDistPointsPointName_0',
- 'https://%s/ipa/crl/MasterCRL.bin' % ipautil.format_netloc(self.fqdn),
- quotes=False, separator='=')
-
# If we are the initial master then we are the CRL generator, otherwise
# we point to that master for CRLs.
if not self.clone:
@@ -1484,11 +1602,12 @@ class CAInstance(service.Service):
# this is the default setting from pki-ca/pki-tomcat. Don't touch it
# if a user has manually modified it.
- if setlist == '1,2,3,4,5,6,7,8':
+ if setlist == '1,2,3,4,5,6,7,8' or setlist == '1,2,3,4,5,6,7,8,9':
+ setlist = setlist + ',10'
installutils.set_directive(
self.dogtag_constants.IPA_SERVICE_PROFILE,
'policyset.serverCertSet.list',
- '1,2,3,4,5,6,7,8,10',
+ setlist,
quotes=False, separator='=')
installutils.set_directive(
self.dogtag_constants.IPA_SERVICE_PROFILE,
@@ -1676,8 +1795,9 @@ def install_replica_ca(config, master_ds_port, postinstall=False):
# If installing this afterward the Apache NSS database already
# exists, don't remove it.
ca.create_ra_agent_db = False
- ca.configure_instance(config.host_name, config.dirman_password,
- config.dirman_password, pkcs12_info=(cafile,),
+ ca.configure_instance(config.host_name, config.domain_name,
+ config.dirman_password, config.dirman_password,
+ pkcs12_info=(cafile,),
master_host=config.master_host_name,
master_replication_port=master_ds_port,
subject_base=config.subject_base)
@@ -1740,4 +1860,4 @@ if __name__ == "__main__":
ds = dsinstance.DsInstance()
ca = CAInstance("EXAMPLE.COM", "/etc/httpd/alias")
- ca.configure_instance("catest.example.com", "password", "password")
+ ca.configure_instance("catest.example.com", "example.com", "password", "password")