[Freeipa-devel] [PATCH] 1059 single CRL generator

Rob Crittenden rcritten at redhat.com
Wed Oct 10 16:41:42 UTC 2012


Martin Kosek wrote:
> On 10/10/2012 05:29 PM, Rob Crittenden wrote:
>> Martin Kosek wrote:
>>> On 10/10/2012 04:12 PM, Rob Crittenden wrote:
>>>> Martin Kosek wrote:
>>>>> On 10/10/2012 12:46 AM, Rob Crittenden wrote:
>>>>>> Rob Crittenden wrote:
>>>>>>> Martin Kosek wrote:
>>>>>>>> On 10/09/2012 04:43 PM, Rob Crittenden wrote:
>>>>>>>>> Martin Kosek wrote:
>>>>>>>>>> On 10/04/2012 06:17 PM, Rob Crittenden wrote:
>>>>>>>>>>> This changes the way IPA generates CRLs for new installs only.
>>>>>>>>>>>
>>>>>>>>>>> The first master installed is configured as the CRL generator. An
>>>>>>>>>>> entry is
>>>>>>>>>>> added to cn=masters that designates it.
>>>>>>>>>>>
>>>>>>>>>>> When a replica is installed it queries this entry so it knows where
>>>>>>>>>>> to forward
>>>>>>>>>>> CRL requests. CRL files are not available on cloned CAs (so
>>>>>>>>>>> /ipa/crl will
>>>>>>>>>>> return not found). It is possible to get a CRL directly from the
>>>>>>>>>>> clone CA via
>>>>>>>>>>> http://<hostname>:9180/ca/ee/ca/getCRL?op=getCRL&crlIssuingPoint=MasterCRL
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> rob
>>>>>>>>>>
>>>>>>>>>> I tested new IPA server + replica with your patch and the CRL was
>>>>>>>>>> now generated
>>>>>>>>>> only on the CRL master. I also tried OCSP (though this may not be
>>>>>>>>>> relevant) and
>>>>>>>>>> it worked for me too.
>>>>>>>>>>
>>>>>>>>>> 1) I do not understand the following block in set_crl_master(self,
>>>>>>>>>> suffix):
>>>>>>>>>>
>>>>>>>>>> +        try:
>>>>>>>>>> +            self.admin_conn.addEntry(entry)
>>>>>>>>>> +        except ldap.ALREADY_EXISTS, e:
>>>>>>>>>> +            root_logger.debug("failed to set CA as CRL generator")
>>>>>>>>>> +            raise e
>>>>>>>>>>
>>>>>>>>>> - when we hit ldap.ALREADY_EXISTS, we are actually OK because cn=CRL
>>>>>>>>>> is set,
>>>>>>>>>> right?
>>>>>>>>>> - AFAIK, addEntry should  return our errors, i.e. errors.DuplicateEntry
>>>>>>>>>> - s/raise e/raise/
>>>>>>>>>>
>>>>>>>>>> I think you may have wanted to rather catch for more general LDAP
>>>>>>>>>> error and
>>>>>>>>>> then report a real error and not just a debug note.
>>>>>>>>>>
>>>>>>>>>> 2) In get_crl_master:
>>>>>>>>>>
>>>>>>>>>> +        except Exception, e:
>>>>>>>>>> +            root_logger.debug("Could not connect to the Directory
>>>>>>>>>> Server on
>>>>>>>>>> %s: %s" % (master_host, str(e)))
>>>>>>>>>> +            raise e
>>>>>>>>>>
>>>>>>>>>> s/raise e/raise/
>>>>>>>>>>
>>>>>>>>>> +        except errors.NotFound, e:
>>>>>>>>>> +            root_logger.debug("failed to find CA CRL generator")
>>>>>>>>>> +            self.crl_master = None
>>>>>>>>>>
>>>>>>>>>> - e is actually not used, "except errors.NotFound" would be enough
>>>>>>>>>>
>>>>>>>>>> 3) Majorish issue I hit with the actual CRL publishing on our server
>>>>>>>>>> (F17). I
>>>>>>>>>> always get 403 Forbidden error when trying to download CRL from the
>>>>>>>>>> CRL master:
>>>>>>>>>>
>>>>>>>>>> # wget --ca-certificate /etc/ipa/ca.crt
>>>>>>>>>> https://`hostname`/ipa/crl/MasterCRL.bin
>>>>>>>>>> --2012-10-05 03:32:58--
>>>>>>>>>> https://vm-120.idm.lab.bos.redhat.com/ipa/crl/MasterCRL.bin
>>>>>>>>>> Resolving vm-120.idm.lab.bos.redhat.com... 10.16.78.120
>>>>>>>>>> Connecting to vm-120.idm.lab.bos.redhat.com|10.16.78.120|:443...
>>>>>>>>>> connected.
>>>>>>>>>> HTTP request sent, awaiting response... 403 Forbidden
>>>>>>>>>> 2012-10-05 03:32:58 ERROR 403: Forbidden.
>>>>>>>>>>
>>>>>>>>>> I tracked the problem down to too strict permission on /var/lib/pki-ca
>>>>>>>>>> directory which is being published by httpd which does not have
>>>>>>>>>> access to it:
>>>>>>>>>>
>>>>>>>>>> # ll /var/lib/pki-ca
>>>>>>>>>>
>>>>>>>>>> drwxrwx---. 11 pkiuser pkiuser 4096 Oct  5 03:00 pki-ca
>>>>>>>>>>
>>>>>>>>>> When I fixed the permission:
>>>>>>>>>> # chmod o+x /var/lib/pki-ca/
>>>>>>>>>>
>>>>>>>>>> I was able to get pass the Forbidden error and actually retrieved
>>>>>>>>>> the CRL.
>>>>>>>>>> Adding Ade on CC list to follow on this permission issue.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> I was thinking about usability of this new approach, we may want to
>>>>>>>>>> make user
>>>>>>>>>> life easier in a perspective of CRL master managing. I have following
>>>>>>>>>> enhancements in mind:
>>>>>>>>>>
>>>>>>>>>> - mark CRL master in ipa-replica-manage list, or
>>>>>>>>>> ipa-csreplica-manage list:
>>>>>>>>>>
>>>>>>>>>> # ipa-csreplica-manage list
>>>>>>>>>> Directory Manager password:
>>>>>>>>>>
>>>>>>>>>> vm-065.idm.lab.bos.redhat.com: master [CRL]
>>>>>>>>>> vm-120.idm.lab.bos.redhat.com: master
>>>>>>>>>>
>>>>>>>>>> - when removing master with CRL by "ipa-replica-manage del" we
>>>>>>>>>> should warn user
>>>>>>>>>> and inform him what he should do next to amend the situation. I am
>>>>>>>>>> thinking
>>>>>>>>>> about 2 new commands for ipa-csreplica-manage:
>>>>>>>>>>
>>>>>>>>>> * ipa-csreplica-manage crl-promote
>>>>>>>>>>        - promote current master as the new CRL master, enable CRL
>>>>>>>>>> generation in
>>>>>>>>>> CS.cfg, mark master as the new CRL master in cn=masters
>>>>>>>>>> * ipa-csreplica-manage crl-update
>>>>>>>>>>        - update CS.cfg of current CA replica and point
>>>>>>>>>> master.ca.agent.* to current
>>>>>>>>>> CRL master
>>>>>>>>>>
>>>>>>>>>> I can work on those enhancements if we agree on them.
>>>>>>>>>>
>>>>>>>>>> Martin
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Andrew provided some feedback out-of-band and my solution was overly
>>>>>>>>> complex.
>>>>>>>>> Here is a much simpler patch which does away with all the hand-waving
>>>>>>>>> around
>>>>>>>>> knowing who the CRL generator is.
>>>>>>>>>
>>>>>>>>> rob
>>>>>>>>
>>>>>>>> This looks OK code-wise, I will wait for dogtag guys to confirm that
>>>>>>>> this is
>>>>>>>> the right approach.
>>>>>>>>
>>>>>>>> Btw. I think we may want to file a RFE to implement some command to
>>>>>>>> promote a
>>>>>>>> replica to CRL master (like "ipa-csreplica-manage crl-promote" proposed
>>>>>>>> earlier). Users may want to promote a replica when the master crashes
>>>>>>>> or is to
>>>>>>>> be replaced. Some way to migrate CRL list (if not replicated already)
>>>>>>>> to the
>>>>>>>> promoted replica would also be needed.
>>>>>>>>
>>>>>>>> Martin
>>>>>>>>
>>>>>>>
>>>>>>> Andrew suggested I specify that we do not monitor cloned revocations on
>>>>>>> the server not generating CRLs, so I added that.
>>>>>>>
>>>>>>> The last question is what we do about redirecting users on the
>>>>>>> non-generating masters.
>>>>>>>
>>>>>>> We can do it easily with a line like this in Apache:
>>>>>>>
>>>>>>> RewriteRule ^/ipa/crl/MasterCRL.bin
>>>>>>> https://$FQDN:9444/ca/ee/ca/getCRL?op=getCRL&crlIssuingPoint=MasterCRL
>>>>>>> [L,R=301,NC]
>>>>>>>
>>>>>>> The tricky part is writing this properly. The CA can be added
>>>>>>> post-install so I don't think simply adding this to ipa-rewrite.conf
>>>>>>> will work well. Is adding another template configuration file for Apache
>>>>>>> overkill?
>>>>>>>
>>>>>>> rob
>>>>>>
>>>>>> Here is my WIP for auto-configuring redirect on clones. It works ok for me
>>>>>> and
>>>>>> isn't too invasive IMHO. The basic idea is to allow proxying of the getCRL
>>>>>> servlet and redirect to that on requests to the clone server.
>>>>>>
>>>>>> Browsing won't work, but you can fetch the MasterCRL.bin with:
>>>>>>
>>>>>> # wget --ca-certificate=/etc/ipa/ca.crt
>>>>>> http://replica.example.com/ipa/crl/MasterCRL.bin
>>>>>>
>>>>>> diff --git a/install/conf/ipa-pki-proxy.conf
>>>>>> b/install/conf/ipa-pki-proxy.conf
>>>>>> index 20c0921..8c4f3a9 100644
>>>>>> --- a/install/conf/ipa-pki-proxy.conf
>>>>>> +++ b/install/conf/ipa-pki-proxy.conf
>>>>>> @@ -3,7 +3,7 @@
>>>>>>     ProxyRequests Off
>>>>>>
>>>>>>     # matches for ee port
>>>>>> -<LocationMatch
>>>>>> "^/ca/ee/ca/checkRequest|^/ca/ee/ca/getCertChain|^/ca/ee/ca/getTokenInfo|^/ca/ee/ca/tokenAuthenticate|^/ca/ocsp|^/ca/ee/ca/updateNumberRange">
>>>>>>
>>>>>>
>>>>>>
>>>>>> +<LocationMatch
>>>>>> "^/ca/ee/ca/checkRequest|^/ca/ee/ca/getCertChain|^/ca/ee/ca/getTokenInfo|^/ca/ee/ca/tokenAuthenticate|^/ca/ocsp|^/ca/ee/ca/updateNumberRange|^/ca/ee/ca/getCRL">
>>>>>>
>>>>>>
>>>>>>
>>>>>>         NSSOptions +StdEnvVars +ExportCertData +StrictRequire +OptRenegotiate
>>>>>>         NSSVerifyClient none
>>>>>>         ProxyPassMatch ajp://localhost:$DOGTAG_PORT
>>>>>> @@ -25,3 +25,6 @@ ProxyRequests Off
>>>>>>         ProxyPassMatch ajp://localhost:$DOGTAG_PORT
>>>>>>         ProxyPassReverse ajp://localhost:$DOGTAG_PORT
>>>>>>     </LocationMatch>
>>>>>> +
>>>>>> +# Only enable this on servers that are not generating a CRL
>>>>>> +${CLONE}RewriteRule ^/ipa/crl/MasterCRL.bin
>>>>>> https://$FQDN/ca/ee/ca/getCRL?op=getCRL&crlIssuingPoint=MasterCRL
>>>>>> [L,R=301,NC]
>>>>>> diff --git a/ipaserver/install/cainstance.py
>>>>>> b/ipaserver/install/cainstance.py
>>>>>> index 0ac895e..aabbba3 100644
>>>>>> --- a/ipaserver/install/cainstance.py
>>>>>> +++ b/ipaserver/install/cainstance.py
>>>>>> @@ -1304,7 +1304,11 @@ class CAInstance(service.Service):
>>>>>>
>>>>>>         def __http_proxy(self):
>>>>>>             template_filename = ipautil.SHARE_DIR + "ipa-pki-proxy.conf"
>>>>>> -        sub_dict = dict(DOGTAG_PORT=self.dogtag_constants.AJP_PORT)
>>>>>> +        sub_dict = dict(
>>>>>> +            DOGTAG_PORT=self.dogtag_constants.AJP_PORT,
>>>>>> +            CLONE='' if self.clone else '#',
>>>>>> +            FQDN=self.fqdn,
>>>>>> +        )
>>>>>>             template = ipautil.template_file(template_filename, sub_dict)
>>>>>>             with open(HTTPD_CONFD + "ipa-pki-proxy.conf", "w") as fd:
>>>>>>                 fd.write(template)
>>>>>
>>>>> The approach looks OK, just please do not forget to also add CLONE to sub_dict
>>>>> in ipa-upgradeconfig, it just crashed when I was testing the change:
>>>>>
>>>>> CRL tree already moved
>>>>>      File "/usr/lib/python2.7/site-packages/ipaserver/install/installutils.py",
>>>>> line 614, in run_script
>>>>>        return_value = main_function()
>>>>>
>>>>>      File "/sbin/ipa-upgradeconfig", line 601, in main
>>>>>        upgrade(sub_dict, "/etc/httpd/conf.d/ipa-pki-proxy.conf",
>>>>> ipautil.SHARE_DIR
>>>>> + "ipa-pki-proxy.conf", add=True)
>>>>>
>>>>>      File "/sbin/ipa-upgradeconfig", line 187, in upgrade
>>>>>        update_conf(sub_dict, filename, template)
>>>>>
>>>>>      File "/sbin/ipa-upgradeconfig", line 110, in update_conf
>>>>>        template = ipautil.template_file(template_filename, sub_dict)
>>>>>
>>>>>      File "/usr/lib/python2.7/site-packages/ipapython/ipautil.py", line 228, in
>>>>> template_file
>>>>>        return template_str(f.read(), vars)
>>>>>
>>>>>      File "/usr/lib/python2.7/site-packages/ipapython/ipautil.py", line 215, in
>>>>> template_str
>>>>>        val = string.Template(txt).substitute(vars)
>>>>>
>>>>>      File "/usr/lib64/python2.7/string.py", line 172, in substitute
>>>>>        return self.pattern.sub(convert, self.template)
>>>>>
>>>>>      File "/usr/lib64/python2.7/string.py", line 162, in convert
>>>>>        val = mapping[named]
>>>>>
>>>>> The ipa-upgradeconfig command failed, exception: KeyError: 'CLONE'
>>>>> Unexpected error
>>>>> KeyError: 'CLONE'
>>>>>
>>>>> Martin
>>>>>
>>>>
>>>> Fixed and merged into a single patch.
>>>>
>>>> rob
>>>
>>> This will crash when upgrading a replica without a CA or server with self-sign:
>>>
>>> +
>>> +    crl = installutils.get_directive(configured_constants.CS_CFG_PATH,
>>> +                                     'ca.crl.MasterCRL.enableCRLUpdates', '=')
>>>
>>> This line can be run only when CA is actually configured.
>>>
>>> Martin
>>>
>>
>> Right you are. Fixed.
>>
>> rob
>
> ACK. Works fine, I was able to get MasterCRL.bin on both master and replica.
>
>
> Please just amend the block below a bit:
>
>       # migrate CRL publish dir before the location in ipa.conf is updated
>       ca = cainstance.CAInstance(api.env.realm, certs.NSS_DIR)
> +    if ca.is_configured():
> +        crl = installutils.get_directive(configured_constants.CS_CFG_PATH,
> +                                         'ca.crl.MasterCRL.enableCRLUpdates',
> +                                         '=')
> +        sub_dict['CLONE']='#' if crl.lower() == 'true' else ''
>       ca_restart = migrate_crl_publish_dir(ca)
>
> "ca_restart = migrate_crl_publish_dir(ca)" should be closer to the comment
> above, otherwise it may be confusing.
>
> Martin
>

fixed and pushed to master and ipa-3-0

rob




More information about the Freeipa-devel mailing list