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
>From fccd77499d0a84eb0f55710b38d15515c95d7583 Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcrit...@redhat.com>
Date: Tue, 9 Oct 2012 10:40:20 -0400
Subject: [PATCH] Configure the initial CA as the CRL generator.

Any installed clones will have CRL generation explicitly disabled.
It is a manual process to make a different CA the CRL generator.
There should be only one.

https://fedorahosted.org/freeipa/ticket/3051
---
 install/conf/ipa-pki-proxy.conf |  5 ++++-
 install/tools/ipa-upgradeconfig |  6 ++++++
 ipaserver/install/cainstance.py | 19 ++++++++++++++++++-
 3 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/install/conf/ipa-pki-proxy.conf b/install/conf/ipa-pki-proxy.conf
index 20c09217adc0bf2c536b6d30f83ac939291d8aff..8c4f3a9b68f2f16036310bb28661159e7acb06d0 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/install/tools/ipa-upgradeconfig b/install/tools/ipa-upgradeconfig
index 51e5b1d5939758bff508e92186d25b2798e889d6..5a54bf351f5fdf141e12b9011cc78c8d951e34f0 100644
--- a/install/tools/ipa-upgradeconfig
+++ b/install/tools/ipa-upgradeconfig
@@ -600,11 +600,17 @@ def main():
         AUTOREDIR='' if auto_redirect else '#',
         CRL_PUBLISH_PATH=configured_constants.CRL_PUBLISH_PATH,
         DOGTAG_PORT=configured_constants.AJP_PORT,
+        CLONE='#'
     )
 
 
     # 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)
 
     upgrade(sub_dict, "/etc/httpd/conf.d/ipa.conf", ipautil.SHARE_DIR + "ipa.conf")
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index a64fe6f03d25380ae0629df51087ddb599b1a034..aabbba39de95937153ebebef79bf8b9082d2e46e 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -1239,6 +1239,19 @@ class CAInstance(service.Service):
             '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:
+            # These next two are defaults, but I want to be explicit that the
+            # initial master is the CRL generator.
+            installutils.set_directive(caconfig, 'ca.crl.MasterCRL.enableCRLCache', 'true', quotes=False, separator='=')
+            installutils.set_directive(caconfig, 'ca.crl.MasterCRL.enableCRLUpdates', 'true', quotes=False, separator='=')
+            installutils.set_directive(caconfig, 'ca.listenToCloneModifications', 'true', quotes=False, separator='=')
+        else:
+            installutils.set_directive(caconfig, 'ca.crl.MasterCRL.enableCRLCache', 'false', quotes=False, separator='=')
+            installutils.set_directive(caconfig, 'ca.crl.MasterCRL.enableCRLUpdates', 'false', quotes=False, separator='=')
+            installutils.set_directive(caconfig, 'ca.listenToCloneModifications', 'false', quotes=False, separator='=')
+
     def __set_subject_in_config(self):
         # dogtag ships with an IPA-specific profile that forces a subject
         # format. We need to update that template with our base subject
@@ -1291,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)
-- 
1.7.11.4

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to