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

Martin Kosek mkosek at redhat.com
Wed Oct 10 16:06:55 UTC 2012


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




More information about the Freeipa-devel mailing list