diff options
author | Rob Austein <sra@hactrn.net> | 2016-05-05 06:23:24 +0000 |
---|---|---|
committer | Rob Austein <sra@hactrn.net> | 2016-05-05 06:23:24 +0000 |
commit | 628fac246498569c4ceed6a2d4a033d9254befb0 (patch) | |
tree | e02601efadb22aff1ac1a66e50c7dae5df08e3b6 | |
parent | 74609ee8900501784f7f1a3f568a42503e3a1f86 (diff) |
rootd migration finally working right. I think. Could stand more testing.
svn path=/branches/tk705/; revision=6421
-rwxr-xr-x | potpourri/ca-unpickle.py | 91 | ||||
-rw-r--r-- | rpki/irdbd.py | 10 | ||||
-rw-r--r-- | rpki/rpkic.py | 14 | ||||
-rw-r--r-- | rpki/rpkidb/models.py | 8 |
4 files changed, 105 insertions, 18 deletions
diff --git a/potpourri/ca-unpickle.py b/potpourri/ca-unpickle.py index b2889d1d..9fa30bed 100755 --- a/potpourri/ca-unpickle.py +++ b/potpourri/ca-unpickle.py @@ -277,6 +277,16 @@ class Root(object): now = rpki.sundial.now() + crl_interval = cfg.getint(section = "myrpki", + option = "tenant_crl_interval", + default = 6 * 60 * 60) + + regen_margin = cfg.getint(section = "myrpki", + option = "tenant_regen_margin", + default = 14 * 24 * 60 * 60 + 2 * 60) + + # Whole lota new BPKI glorp. + root_resourceholderca_serial = 1 root_resourceholderca_key = rpki.x509.RSA.generate() root_resourceholderca_cer = rpki.x509.X509.bpki_self_certify( @@ -362,11 +372,14 @@ class Root(object): pathLenConstraint = 0) serverca.next_serial += 1 + # Various contact URIs. + root_up_down_path = "/up-down/{root}/{work}".format( root = root_handle, work = work_resourceholderca.handle) - root_up_down_uri = fixuri.rpkid(root_up_down_path) + root_loopback_uri = fixuri.rpkid("/up-down/{root}/{root}".format( + root = root_handle)) root_publication_control_uri = fixuri.pubd("/client/{root}".format( root = root_handle)) @@ -375,6 +388,14 @@ class Root(object): module = cfg.get(section = "myrpki", option = "publication_rsync_module"), handle = root_handle)) + rpki_root_cer_uri = fixuri.rsyncd("/{module}/{gski}.cer".format( + module = cfg.get(section = "myrpki", option = "publication_rsync_module"), + gski = rpki_root_key.gSKI())) + + rpki_root_crl_uri = root_rsync_uri + rpki_root_key.gSKI() + ".crl" + + rpki_root_mft_uri = root_rsync_uri + rpki_root_key.gSKI() + ".mft" + rrdp_notification_uri = cfg.get(section = "myrpki", option = "publication_rrdp_notification_uri") @@ -406,6 +427,53 @@ class Root(object): port = world.cfg.rootd.server_port): raise RuntimeError("Pickled Rootd service_uri does not match pickled configuration") + # Updated RPKI root certificate, CRL and manifest. + # The root certificate URI here isn't really right, but it's (probably) harmless. + + rpki_root_last_serial += 1 + rpki_root_cer = rpki.x509.X509.self_certify( + keypair = rpki_root_key, + subject_key = rpki_root_key.get_public(), + serial = rpki_root_last_serial, + sia = (root_rsync_uri, rpki_root_mft_uri, None, rrdp_notification_uri), + notAfter = rpki_root_resources.valid_until, + resources = rpki_root_resources) + + rpki_root_last_crl_manifest_number += 1 + + root_rpki_crl = rpki.x509.CRL.generate( + keypair = rpki_root_key, + issuer = rpki_root_cer, + serial = rpki_root_last_crl_manifest_number, + thisUpdate = now, + nextUpdate = now + rpki.sundial.timedelta(seconds = crl_interval), + revokedCertificates = ()) + + rpki_root_last_serial += 1 + mft_cer = rpki_root_cer.issue( + keypair = rpki_root_key, + subject_key = rpki_root_mft_key.get_public(), + serial = rpki_root_last_serial, + sia = (None, None, rpki_root_mft_uri, rrdp_notification_uri), + resources = rpki.resource_set.resource_bag.from_inheritance(), + aia = rpki_root_cer_uri, + crldp = rpki_root_crl_uri, + notBefore = now, + notAfter = rpki_root_cer.getNotAfter(), + is_ca = False) + + rpki_root_mft_objs = [ + (rpki_root_key.gSKI() + ".crl", root_rpki_crl), + (work_resourceholderca_cer.gSKI() + ".cer", work_resourceholderca_cer)] + + rpki_root_mft = rpki.x509.SignedManifest.build( + keypair = rpki_root_mft_key, + certs = mft_cer, + serial = rpki_root_last_crl_manifest_number, + thisUpdate = now, + nextUpdate = now + rpki.sundial.timedelta(seconds = crl_interval), + names_and_objs = rpki_root_mft_objs) + # Adjust saved working CA's parent object to point at new root. # We supply just the path portion of the URI here, to avoid confusing fixuri.rpkid() later. # @@ -426,7 +494,7 @@ class Root(object): certificate = root_hostedca_cer, handle = root_handle, ta = root_resourceholderca_cer, - service_uri = root_up_down_uri, + service_uri = fixuri.rpkid(root_up_down_path), parent_handle = root_handle, child_handle = work_rpkid_parent.sender_name, repository_type = "none", @@ -458,7 +526,7 @@ class Root(object): certificate = root_parent_bpki_cer, handle = root_handle, ta = root_resourceholderca_cer, - service_uri = root_up_down_uri, + service_uri = root_loopback_uri, parent_handle = root_handle, child_handle = root_handle, repository_type = "none", @@ -535,12 +603,8 @@ class Root(object): self.rpkid_root_Tenant = dict( tenant_handle = root_handle, use_hsm = False, - crl_interval = cfg.getint(section = "myrpki", - option = "tenant_crl_interval", - default = 6 * 60 * 60), - regen_margin = cfg.getint(section = "myrpki", - option = "tenant_regen_margin", - default = 14 * 24 * 60 * 60 + 2 * 60), + crl_interval = crl_interval, + regen_margin = regen_margin, bpki_cert = root_hostedca_cer, bpki_glue = None, ) @@ -557,6 +621,7 @@ class Root(object): self.rpkid_root_Repository = dict( repository_handle = root_handle, peer_contact_uri = root_publication_control_uri, + rrdp_notification_uri = rrdp_notification_uri, bpki_cert = root_repository_bpki_cer, bpki_glue = None, last_cms_timestamp = None, @@ -567,7 +632,7 @@ class Root(object): parent_handle = root_handle, bpki_cert = root_parent_bpki_cer, bpki_glue = None, - peer_contact_uri = root_up_down_uri, + peer_contact_uri = root_loopback_uri, sia_base = root_rsync_uri, sender_name = root_handle, recipient_name = root_handle, @@ -589,15 +654,15 @@ class Root(object): self.rpkid_root_CADetail = dict( public_key = rpki_root_key.get_public(), private_key_id = rpki_root_key, - latest_crl = None, + latest_crl = rpki_root_crl, crl_published = None, latest_ca_cert = rpki_root_cer, manifest_private_key_id = rpki_root_mft_key, manifest_public_key = rpki_root_mft_key.get_public(), - latest_manifest = None, + latest_manifest = rpki_root_mft, manifest_published = None, state = "active", - ca_cert_uri = root_rsync_uri + rpki_root_key.gSKI() + ".cer", + ca_cert_uri = rpki_root_cer_uri, # Foreign keys: ca ) diff --git a/rpki/irdbd.py b/rpki/irdbd.py index 7a2c4606..98fe83ea 100644 --- a/rpki/irdbd.py +++ b/rpki/irdbd.py @@ -35,12 +35,16 @@ import rpki.log import rpki.x509 import rpki.daemonize -from lxml.etree import Element, SubElement +from lxml.etree import Element, SubElement, tostring as ElementToString logger = logging.getLogger(__name__) class main(object): + # Whether to drop XMl into the log + + debug = False + def handle_list_resources(self, q_pdu, r_msg): tenant_handle = q_pdu.get("tenant_handle") child_handle = q_pdu.get("child_handle") @@ -117,6 +121,8 @@ class main(object): q_cms = rpki.left_right.cms_msg(DER = q_der) q_msg = q_cms.unwrap((serverCA.certificate, rpkid.certificate)) self.cms_timestamp = q_cms.check_replay(self.cms_timestamp, request.path) + if self.debug: + logger.debug("Received: %s", ElementToString(q_msg)) if q_msg.get("type") != "query": raise rpki.exceptions.BadQuery("Message type is {}, expected query".format( q_msg.get("type"))) @@ -134,6 +140,8 @@ class main(object): if q_pdu.get("tag") is not None: r_pdu.set("tag", q_pdu.get("tag")) + if self.debug: + logger.debug("Sending: %s", ElementToString(r_msg)) request.send_cms_response(rpki.left_right.cms_msg().wrap( r_msg, irdbd.private_key, irdbd.certificate)) diff --git a/rpki/rpkic.py b/rpki/rpkic.py index d90ad690..5e0efe0f 100644 --- a/rpki/rpkic.py +++ b/rpki/rpkic.py @@ -868,6 +868,20 @@ class main(Cmd): @parsecmd(argsubparsers) + def do_force_run_now(self, args): + """ + Force rpkid to run periodic tasks for this Tenant immediately. + + This is not usually necessary, as rpkid runs all of these + tasks on a regular schedule, but this command can be useful + occasionally when configuration change is taking a long time + to percolate through a series of parent/child exchanges. + """ + + self.zoo.run_rpkid_now() + + + @parsecmd(argsubparsers) def do_up_down_rekey(self, args): """ Initiate a "rekey" operation. diff --git a/rpki/rpkidb/models.py b/rpki/rpkidb/models.py index 31c367ba..3021a0d4 100644 --- a/rpki/rpkidb/models.py +++ b/rpki/rpkidb/models.py @@ -748,6 +748,7 @@ class Parent(models.Model): @tornado.gen.coroutine def query_up_down(self, rpkid, q_msg): trace_call_chain() + #logger.debug("%r query_up_down(): %s", self, ElementToString(q_msg)) if self.root_asn_resources or self.root_ipv4_resources or self.root_ipv6_resources: r_msg = yield self.query_up_down_root(rpkid, q_msg) elif self.bsc is None: @@ -773,6 +774,7 @@ class Parent(models.Model): self.tenant.bpki_cert, self.tenant.bpki_glue, self.bpki_cert, self.bpki_glue)) r_cms.check_replay_sql(self, self.peer_contact_uri) + #logger.debug("%r query_up_down(): %s", self, ElementToString(r_msg)) rpki.up_down.check_response(r_msg, q_msg.get("type")) raise tornado.gen.Return(r_msg) @@ -798,8 +800,6 @@ class Parent(models.Model): trace_call_chain() publisher = rpki.rpkid.publication_queue(rpkid = rpkid) - #logger.debug("%r query_up_down_root(): %s", self, ElementToString(q_msg)) - r_msg = Element(rpki.up_down.tag_message, nsmap = rpki.up_down.nsmap, version = rpki.up_down.version, @@ -915,8 +915,6 @@ class Parent(models.Model): r_msg.set("type", "error_response") SubElement(r_msg, rpki.up_down.tag_status).text = "2001" - #logger.debug("%r query_up_down_root(): %s", self, ElementToString(r_msg)) - raise tornado.gen.Return(r_msg) @@ -1875,6 +1873,8 @@ class ChildCert(models.Model): resources = old_resources if sia is None: sia = old_sia + if len(sia) < 4 or not sia[3]: + sia = (sia[0], sia[1], sia[2], ca_detail.ca.parent.repository.rrdp_notification_uri) assert resources.valid_until is not None and old_resources.valid_until is not None if resources.asn != old_resources.asn or resources.v4 != old_resources.v4 or resources.v6 != old_resources.v6: logger.debug("Resources changed for %r: old %s new %s", self, old_resources, resources) |