aboutsummaryrefslogtreecommitdiff
path: root/potpourri
diff options
context:
space:
mode:
Diffstat (limited to 'potpourri')
-rw-r--r--potpourri/analyze-rcynic-history.py7
-rwxr-xr-xpotpourri/generate-root-certificate62
-rw-r--r--potpourri/roa-to-irr.py96
3 files changed, 115 insertions, 50 deletions
diff --git a/potpourri/analyze-rcynic-history.py b/potpourri/analyze-rcynic-history.py
index b72d0741..648538cc 100644
--- a/potpourri/analyze-rcynic-history.py
+++ b/potpourri/analyze-rcynic-history.py
@@ -243,6 +243,7 @@ for i, key in enumerate(mb.iterkeys(), 1):
session = shelf[key]
else:
+ sys.stderr.write("%s..." % key)
assert not mb[key].is_multipart()
input = ElementTreeFromString(mb[key].get_payload())
date = input.get("date")
@@ -276,9 +277,9 @@ if plot_all_hosts:
set()))
else:
- hostnames = ("rpki.apnic.net", "rpki.ripe.net", "localcert.ripe.net",
- "repository.lacnic.net", "rpki.afrinic.net", "rpki.arin.net",
- "arin.rpki.net", "repo0.rpki.net", "rgnet.rpki.net")
+ hostnames = ("rpki.apnic.net", "rpki.ripe.net", "repository.lacnic.net", "rpki.afrinic.net", "rpki.arin.net",
+ #"localcert.ripe.net", "arin.rpki.net", "repo0.rpki.net", "rgnet.rpki.net",
+ "ca0.rpki.net")
plot_hosts(hostnames, [fmt.attr for fmt in Host.format if fmt.attr != "hostname"])
diff --git a/potpourri/generate-root-certificate b/potpourri/generate-root-certificate
new file mode 100755
index 00000000..31647d5f
--- /dev/null
+++ b/potpourri/generate-root-certificate
@@ -0,0 +1,62 @@
+#!/usr/bin/env python
+
+"""
+Generate an RPKI root certificate for rootd. In most cases you should
+not need to do this; see caveats in the manual about running rootd if
+you think you need this. This script does nothing that can't also be
+done with the OpenSSL command line tool, but on some platforms the
+installed copy of openssl doesn't understand the RFC 3779 extensions.
+"""
+
+import os
+import sys
+import time
+import argparse
+import rpki.x509
+import rpki.config
+import rpki.sundial
+import rpki.resource_set
+
+os.environ["TZ"] = "UTC"
+time.tzset()
+
+parser = argparse.ArgumentParser(description = __doc__)
+parser.add_argument("-c", "--config", help = "configuration file")
+parser.add_argument("-a", "--asns", default = "0-4294967295", help = "ASN resources")
+parser.add_argument("-4", "--ipv4", default = "0.0.0.0/0", help = "IPv4 resources")
+parser.add_argument("-6", "--ipv6", default = "::/0", help = "IPv6 resources")
+parser.add_argument("--certificate", default = "root.cer", help = "certificate file")
+parser.add_argument("--key", default = "root.key", help = "key file")
+parser.add_argument("--tal", default = "root.tal", help = "TAL file")
+args = parser.parse_args()
+
+cfg = rpki.config.parser(args.config, "rootd")
+
+resources = rpki.resource_set.resource_bag(
+ asn = rpki.resource_set.resource_set_as(args.asns),
+ v4 = rpki.resource_set.resource_set_ipv4(args.ipv4),
+ v6 = rpki.resource_set.resource_set_ipv6(args.ipv6))
+
+keypair = rpki.x509.RSA.generate(quiet = True)
+
+sia = cfg.get("rpki-base-uri")
+sia = (sia, sia + "root.mft", None)
+
+uri = cfg.get("rpki-root-cert-uri")
+
+cert = rpki.x509.X509.self_certify(
+ keypair = keypair,
+ subject_key = keypair.get_public(),
+ serial = 1,
+ sia = sia,
+ notAfter = rpki.sundial.now() + rpki.sundial.timedelta(days = 365),
+ resources = resources)
+
+with open(args.certificate, "wb") as f:
+ f.write(cert.get_DER())
+
+with open(args.key, "wb") as f:
+ f.write(keypair.get_DER())
+
+with open(args.tal, "w") as f:
+ f.write(uri + "\n\n" + keypair.get_public().get_Base64())
diff --git a/potpourri/roa-to-irr.py b/potpourri/roa-to-irr.py
index 01b2aac8..500596f8 100644
--- a/potpourri/roa-to-irr.py
+++ b/potpourri/roa-to-irr.py
@@ -21,13 +21,16 @@ Generate IRR route and route6 objects from ROAs.
"""
import os
-import socket
import sys
import argparse
import errno
-import time
+
import rpki.x509
+from socket import gethostname
+from textwrap import dedent
+from time import time, strftime, gmtime, asctime
+
args = None
class route(object):
@@ -57,20 +60,22 @@ class route(object):
return result
def __str__(self):
- lines = (
- "%-14s%s/%s" % (self.label, self.prefix, self.prefixlen),
- "descr: %s/%s-%s" % (self.prefix, self.prefixlen, self.max_prefixlen),
- "origin: AS%d" % self.asn,
- "notify: %s" % args.notify,
- "mnt-by: %s" % args.mnt_by,
- "changed: %s %s" % (args.changed_by, self.date),
- "source: %s" % args.source,
- "override: %s" % args.password if args.password is not None else None,
- "")
- return "\n".join(line for line in lines if line is not None)
+ lines = "\n" if args.email else ""
+ lines += dedent('''\
+ {self.label:<14s}{self.prefix}/{self.prefixlen}
+ descr: {self.prefix}/{self.prefixlen}-{self.max_prefixlen}
+ origin: AS{self.asn:d}
+ notify: {args.notify}
+ mnt-by: {args.mnt_by}
+ changed: {args.changed_by} {self.date}
+ source: {args.source}
+ ''').format(self = self, args = args)
+ if args.password is not None:
+ lines += "override: {}\n".format(args.password)
+ return lines
def write(self, output_directory):
- name = "%s-%s-%s-AS%d-%s" % (self.prefix, self.prefixlen, self.max_prefixlen, self.asn, self.date)
+ name = "{0.prefix}-{0.prefixlen}-{0.max_prefixlen}-AS{0.asn:d}-{0.date}".format(self)
with open(os.path.join(output_directory, name), "w") as f:
f.write(str(self))
@@ -88,7 +93,7 @@ class route_list(list):
uri = "rsync://" + path[len(rcynic_dir):].lstrip("/")
roa = rpki.x509.ROA(DER_file = path)
roa.extract()
- assert roa.get_POW().getVersion() == 0, "ROA version is %d, expected 0" % roa.get_POW().getVersion()
+ assert roa.get_POW().getVersion() == 0, "ROA version is {:d}, expected 0".format(roa.get_POW().getVersion())
asnum = roa.get_POW().getASID()
notBefore = roa.get_POW().certs()[0].getNotBefore().strftime("%Y%m%d")
v4, v6 = roa.get_POW().getPrefixes()
@@ -105,55 +110,52 @@ class route_list(list):
def email_header(f):
if args.email:
- f.write("\n".join((
- "From %s" % args.email_from,
- "Date: %s" % time.strftime("%d %b %Y %T %z"),
- "From: %s" % args.email_from,
- "Subject: Fake email header to make irr_rpsl_submit happy",
- "Message-Id: <%s.%s@%s>" % (os.getpid(), time.time(), socket.gethostname()),
- "", "")))
+ now = time()
+ f.write(dedent('''\
+ From {from_} {ctime}
+ Date: {date}
+ From: {from_}
+ Subject: Fake email header to make irr_rpsl_submit happy
+ Message-Id: <{pid}.{seconds}@{hostname}>
+ ''').format(from_ = args.from_,
+ ctime = asctime(gmtime(now)),
+ date = strftime("%d %b %Y %T %z", gmtime(now)),
+ pid = os.getpid(),
+ seconds = now,
+ hostname = gethostname()))
def main():
global args
- whoami = "%s@%s" % (os.getlogin(), socket.gethostname())
+ whoami = "{}@{}".format(os.getlogin(), gethostname())
parser = argparse.ArgumentParser(description = __doc__)
- parser.add_argument("-c", "--changed_by", default = whoami,
- help = "override \"changed:\" value")
- parser.add_argument("-f", "--from", dest = "email_from", default = whoami,
- help = "override \"from:\" header when using --email")
- parser.add_argument("-m", "--mnt_by", default = "MAINT-RPKI",
- help = "override \"mnt-by:\" value")
- parser.add_argument("-n", "--notify", default = whoami,
- help = "override \"notify:\" value")
- parser.add_argument("-p", "--password",
- help = "specify \"override:\" password")
- parser.add_argument("-s", "--source", default = "RPKI",
- help = "override \"source:\" value")
+ parser.add_argument("-c", "--changed_by", default = whoami, help = "override \"changed:\" value")
+ parser.add_argument("-f", "--from", dest="from_", default = whoami, help = "override \"from:\" header when using --email")
+ parser.add_argument("-m", "--mnt_by", default = "MAINT-RPKI", help = "override \"mnt-by:\" value")
+ parser.add_argument("-n", "--notify", default = whoami, help = "override \"notify:\" value")
+ parser.add_argument("-p", "--password", help = "specify \"override:\" password")
+ parser.add_argument("-s", "--source", default = "RPKI", help = "override \"source:\" value")
group = parser.add_mutually_exclusive_group()
- group.add_argument("-e", "--email", action = "store_true",
- help = "generate fake RFC 822 header suitable for piping to irr_rpsl_submit")
- group.add_argument("-o", "--output",
- help = "write route and route6 objects to directory OUTPUT, one object per file")
- parser.add_argument("authenticated_directory",
- help = "directory tree containing authenticated rcynic output")
+ group.add_argument("-e", "--email", action = "store_true", help = "generate fake RFC 822 header suitable for piping to irr_rpsl_submit")
+ group.add_argument("-d", "--output-directory", help = "write route and route6 objects to directory OUTPUT, one object per file")
+ parser.add_argument("authenticated_directory", help = "directory tree containing authenticated rcynic output")
args = parser.parse_args()
if not os.path.isdir(args.authenticated_directory):
- sys.exit("\"%s\" is not a directory" % args.authenticated_directory)
+ sys.exit('"{}" is not a directory'.format(args.authenticated_directory))
routes = route_list(args.authenticated_directory)
- if args.output:
- if not os.path.isdir(args.output):
- os.makedirs(args.output)
+ if args.output_directory:
+ if not os.path.isdir(args.output_directory):
+ os.makedirs(args.output_directory)
for r in routes:
- r.write(args.output)
+ r.write(args.output_directory)
else:
email_header(sys.stdout)
for r in routes:
- sys.stdout.write("%s\n" % r)
+ sys.stdout.write(str(r))
if __name__ == "__main__":
main()