All the certs are pretty critical in certificate renewal but the agent
cert has the distinction of having to be updated in multiple places. It
needs to exist in both LDAP servers.
It is possible that one or both of these servers may be down briefly
during renewal so we need to be a bit more robust in our handling. This
will wait up to 5 minutes per server to try to update things, and syslog
when failures occur.
It is now also safe to re-run this in case something catastrophic
happens. One would just need to manually run this to load the required
data into LDAP.
rob
>From fc0bbe5a25012e920920aa6824fa4d45be45855e Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcrit...@redhat.com>
Date: Tue, 23 Oct 2012 14:07:13 -0400
Subject: [PATCH] Wait for the directory server to come up when updating the
agent certificate.
It is possible that either or both of the LDAP instances are being restarted
during the renewal process. Make the script retry if this is the case.
It is also safe to re-run this script if it fails. It will take the current
ipaCert certificate and attempt to update the agent information in LDAP.
https://fedorahosted.org/freeipa/ticket/3179
---
install/restart_scripts/renew_ra_cert | 97 ++++++++++++++++++++++++-----------
1 file changed, 66 insertions(+), 31 deletions(-)
diff --git a/install/restart_scripts/renew_ra_cert b/install/restart_scripts/renew_ra_cert
index 14cbc114ca9d38697cdb2a24b41ccf2ac2c66389..8146955c250d28a7557be981d512ddcdb70a5c4d 100644
--- a/install/restart_scripts/renew_ra_cert
+++ b/install/restart_scripts/renew_ra_cert
@@ -23,6 +23,7 @@ import sys
import shutil
import tempfile
import syslog
+import time
from ipapython import services as ipaservices
from ipapython.certmonger import get_pin
from ipapython import ipautil
@@ -33,6 +34,7 @@ from ipapython.dn import DN
from ipalib import x509
from ipalib import errors
from ipaserver.plugins.ldap2 import ldap2
+import ldap as _ldap
api.bootstrap(context='restart')
api.finalize()
@@ -53,41 +55,74 @@ except IOError, e:
syslog.syslog(syslog.LOG_ERR, 'Unable to determine PIN for CA instance: %s' % e)
sys.exit(1)
-try:
- conn = ldap2(shared_instance=False, ldap_uri='ldap://localhost:%d' % DEFAULT_DSPORT)
- conn.connect(bind_dn=DN(('cn', 'directory manager')), bind_pw=dm_password)
- (entry_dn, entry_attrs) = conn.get_entry(dn, ['usercertificate'], normalize=False)
- entry_attrs['usercertificate'].append(cert)
- entry_attrs['description'] = '2;%d;%s;%s' % (serial_number, issuer, subject)
- conn.update_entry(dn, entry_attrs, normalize=False)
- conn.disconnect()
-except Exception, e:
- syslog.syslog(syslog.LOG_ERR, 'Updating agent entry failed: %s' % e)
- sys.exit(1)
+attempts = 0
+dogtag_uri='ldap://localhost:%d' % DEFAULT_DSPORT
+updated = False
-# Store it in the IPA LDAP server
-tmpdir = tempfile.mkdtemp(prefix = "tmp-")
-try:
- dn = DN(('cn','ipaCert'), ('cn', 'ca_renewal'), ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn)
- principal = str('host/%s@%s' % (api.env.host, api.env.realm))
- ccache = ipautil.kinit_hostprincipal('/etc/krb5.keytab', tmpdir, principal)
- conn = ldap2(shared_instance=False, ldap_uri=api.env.ldap_uri)
- conn.connect(ccache=ccache)
+while attempts < 10:
try:
- (entry_dn, entry_attrs) = conn.get_entry(dn, ['usercertificate'])
- entry_attrs['usercertificate'] = cert
+ conn = ldap2(shared_instance=False, ldap_uri=dogtag_uri)
+ conn.connect(bind_dn=DN(('cn', 'directory manager')), bind_pw=dm_password)
+ (entry_dn, entry_attrs) = conn.get_entry(dn, ['usercertificate'], normalize=False)
+ entry_attrs['usercertificate'].append(cert)
+ entry_attrs['description'] = '2;%d;%s;%s' % (serial_number, issuer, subject)
conn.update_entry(dn, entry_attrs, normalize=False)
- except errors.NotFound:
- entry_attrs = dict(objectclass=['top', 'pkiuser', 'nscontainer'],
- usercertificate=cert)
- conn.add_entry(dn, entry_attrs, normalize=False)
+ updated = True
+ except errors.NetworkError:
+ syslog.syslog(syslog.LOG_ERR, 'Connection to %s failed, sleeping 30' % dogtag_uri)
+ time.sleep(30)
+ attempts += 1
+ continue
except errors.EmptyModlist:
- pass
- conn.disconnect()
-except Exception, e:
- syslog.syslog(syslog.LOG_ERR, 'Updating renewal certificate failed: %s' % e)
-finally:
- shutil.rmtree(tmpdir)
+ updated = True
+ break
+ except Exception, e:
+ syslog.syslog(syslog.LOG_ERR, 'Updating agent entry failed: %s' % e)
+ break
+ finally:
+ if conn.isconnected():
+ conn.disconnect()
+
+if not updated:
+ syslog.syslog(syslog.LOG_ERR, 'Giving up. This script may be safely re-executed.')
+ sys.exit(1)
+
+attempts = 0
+updated = False
+
+# Store it in the IPA LDAP server
+while attempts < 10:
+ try:
+ tmpdir = tempfile.mkdtemp(prefix = "tmp-")
+ dn = DN(('cn','ipaCert'), ('cn', 'ca_renewal'), ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn)
+ principal = str('host/%s@%s' % (api.env.host, api.env.realm))
+ ccache = ipautil.kinit_hostprincipal('/etc/krb5.keytab', tmpdir, principal)
+ conn = ldap2(shared_instance=False, ldap_uri=api.env.ldap_uri)
+ conn.connect(ccache=ccache)
+ try:
+ (entry_dn, entry_attrs) = conn.get_entry(dn, ['usercertificate'])
+ entry_attrs['usercertificate'] = cert
+ conn.update_entry(dn, entry_attrs, normalize=False)
+ except errors.NotFound:
+ entry_attrs = dict(objectclass=['top', 'pkiuser', 'nscontainer'],
+ usercertificate=cert)
+ conn.add_entry(dn, entry_attrs, normalize=False)
+ except errors.EmptyModlist:
+ pass
+ updated = True
+ break
+ except Exception, e:
+ syslog.syslog(syslog.LOG_ERR, 'Updating renewal certificate failed: %s' % e)
+ time.sleep(30)
+ attempts += 1
+ finally:
+ if conn.isconnected():
+ conn.disconnect()
+ shutil.rmtree(tmpdir)
+
+if not updated:
+ syslog.syslog(syslog.LOG_ERR, 'Giving up. This script may be safely re-executed.')
+ sys.exit(1)
# Now restart Apache so the new certificate is available
try:
--
1.7.11.4
_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel