Add automatic NLSR security configuration
refs: #3050
Change-Id: I218f96a2cb11dd35de99c4a9eab056f0fed890aa
diff --git a/ndn/nlsr.py b/ndn/nlsr.py
index 38cda67..da68f76 100644
--- a/ndn/nlsr.py
+++ b/ndn/nlsr.py
@@ -1,8 +1,8 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
-# Copyright (C) 2015 The University of Memphis,
-# Arizona Board of Regents,
-# Regents of the University of California.
+# Copyright (C) 2015-2016, The University of Memphis,
+# Arizona Board of Regents,
+# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
@@ -21,8 +21,14 @@
# along with Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
+from mininet.clean import sh
+
from ndn.ndn_application import NdnApplication
+import os
+import shutil
+import textwrap
+
class Nlsr(NdnApplication):
def __init__(self, node):
NdnApplication.__init__(self, node)
@@ -42,14 +48,71 @@
def start(self):
NdnApplication.start(self, "nlsr -d -f {} &".format(self.confFile))
+ @staticmethod
+ def createKey(host, name, outputFile):
+ host.cmd("ndnsec-keygen {} > {}".format(name, outputFile))
+
+ @staticmethod
+ def createCertificate(host, name, prefix, keyFile, outputFile, signer=None):
+ if signer is None:
+ host.cmd("ndnsec-certgen -N {} -p {} {} > {}".format(name, prefix, keyFile, outputFile))
+ else:
+ host.cmd("ndnsec-certgen -N {} -p {} -s {} {} > {}".format(name, prefix, signer, keyFile, outputFile))
+
+ @staticmethod
+ def createKeysAndCertificates(net, workDir):
+ securityDir = "{}/security".format(workDir)
+
+ if not os.path.exists(securityDir):
+ os.mkdir(securityDir)
+
+ # Create root certificate
+ rootName = "/ndn"
+ sh("ndnsec-keygen {} > {}/root.keys".format(rootName, securityDir))
+ sh("ndnsec-certgen -N {} -p {} {}/root.keys > {}/root.cert".format(rootName, rootName, securityDir, securityDir))
+
+ # Create necessary certificates for each site
+ for host in net.hosts:
+ nodeSecurityFolder = "{}/security".format(host.homeFolder)
+
+ if not os.path.exists(nodeSecurityFolder):
+ os.mkdir(nodeSecurityFolder)
+
+ shutil.copyfile("{}/root.cert".format(securityDir), "{}/root.cert".format(nodeSecurityFolder))
+
+ # Create site certificate
+ siteName = "/ndn/edu"
+ siteKeyFile = "{}/site.keys".format(nodeSecurityFolder)
+ siteCertFile = "{}/site.cert".format(nodeSecurityFolder)
+ Nlsr.createKey(host, siteName, siteKeyFile)
+
+ # Root key is in root namespace, must sign site key and then install on host
+ sh("ndnsec-certgen -N {} -s {} -p {} {} > {}".format(siteName, rootName, siteName, siteKeyFile, siteCertFile))
+ host.cmd("ndnsec-cert-install -f {}".format(siteCertFile))
+
+ # Create operator certificate
+ opName = "{}/%C1.Operator/op".format(siteName)
+ opKeyFile = "{}/op.keys".format(nodeSecurityFolder)
+ opCertFile = "{}/op.cert".format(nodeSecurityFolder)
+ Nlsr.createKey(host, opName, opKeyFile)
+ Nlsr.createCertificate(host, opName, opName, opKeyFile, opCertFile, signer=siteName)
+
+ # Create router certificate
+ routerName = "{}/%C1.Router/cs/{}".format(siteName, host.name)
+ routerKeyFile = "{}/router.keys".format(nodeSecurityFolder)
+ routerCertFile = "{}/router.cert".format(nodeSecurityFolder)
+ Nlsr.createKey(host, routerName, routerKeyFile)
+ Nlsr.createCertificate(host, routerName, routerName, routerKeyFile, routerCertFile, signer=opName)
+
class NlsrConfigGenerator:
ROUTING_LINK_STATE = "ls"
ROUTING_HYPERBOLIC = "hr"
- def __init__(self, node):
+ def __init__(self, node, isSecurityEnabled):
node.cmd("sudo cp /usr/local/etc/mini-ndn/nlsr.conf nlsr.conf")
self.node = node
+ self.isSecurityEnabled = isSecurityEnabled
parameters = node.nlsrParameters
@@ -72,6 +135,7 @@
newContent = newContent.replace("$HYPERBOLIC_SECTION", self.__getHyperbolicSection())
newContent = newContent.replace("$FIB_SECTION", self.__getFibSection())
newContent = newContent.replace("$ADVERTISING_SECTION", self.__getAdvertisingSection())
+ newContent = newContent.replace("$SECURITY_SECTION", self.__getSecuritySection())
configFile = open(filePath, 'w')
configFile.write(newContent)
@@ -162,16 +226,196 @@
return advertising
def __getSecuritySection(self):
+ if self.isSecurityEnabled is False:
+ security = textwrap.dedent("""\
+ security
+ {
+ validator
+ {
+ trust-anchor
+ {
+ type any
+ }
+ }
+ prefix-update-validator
+ {
+ trust-anchor
+ {
+ type any
+ }
+ }
+ }""")
+ else:
+ security = textwrap.dedent("""\
+ security
+ {
+ validator
+ {
+ rule
+ {
+ id "NSLR Hello Rule"
+ for data
+ filter
+ {
+ type name
+ regex ^[^<NLSR><INFO>]*<NLSR><INFO><><>$
+ }
+ checker
+ {
+ type customized
+ sig-type rsa-sha256
+ key-locator
+ {
+ type name
+ hyper-relation
+ {
+ k-regex ^([^<KEY><NLSR>]*)<NLSR><KEY><ksk-.*><ID-CERT>$
+ k-expand \\\\1
+ h-relation equal
+ p-regex ^([^<NLSR><INFO>]*)<NLSR><INFO><><>$
+ p-expand \\\\1
+ }
+ }
+ }
+ }
- security = "security\n"
- security += "{\n"
- security += " validator\n"
- security += " {\n"
- security += " trust-anchor\n"
- security += " {\n"
- security += " type any\n"
- security += " }\n"
- security += " }\n"
- security += "}\n"
+ rule
+ {
+ id "NSLR LSA Rule"
+ for data
+ filter
+ {
+ type name
+ regex ^[^<NLSR><LSA>]*<NLSR><LSA>
+ }
+ checker
+ {
+ type customized
+ sig-type rsa-sha256
+ key-locator
+ {
+ type name
+ hyper-relation
+ {
+ k-regex ^([^<KEY><NLSR>]*)<NLSR><KEY><ksk-.*><ID-CERT>$
+ k-expand \\\\1
+ h-relation equal
+ p-regex ^([^<NLSR><LSA>]*)<NLSR><LSA>(<>*)<><><><>$
+ p-expand \\\\1\\\\2
+ }
+ }
+ }
+ }
+
+ rule
+ {
+ id "NSLR Hierarchy Exception Rule"
+ for data
+ filter
+ {
+ type name
+ regex ^[^<KEY><%C1.Router>]*<%C1.Router>[^<KEY><NLSR>]*<KEY><ksk-.*><ID-CERT><>$
+ }
+ checker
+ {
+ type customized
+ sig-type rsa-sha256
+ key-locator
+ {
+ type name
+ hyper-relation
+ {
+ k-regex ^([^<KEY><%C1.Operator>]*)<%C1.Operator>[^<KEY>]*<KEY><ksk-.*><ID-CERT>$
+ k-expand \\\\1
+ h-relation equal
+ p-regex ^([^<KEY><%C1.Router>]*)<%C1.Router>[^<KEY>]*<KEY><ksk-.*><ID-CERT><>$
+ p-expand \\\\1
+ }
+ }
+ }
+ }
+
+ rule
+ {
+ id "NSLR Hierarchical Rule"
+ for data
+ filter
+ {
+ type name
+ regex ^[^<KEY>]*<KEY><ksk-.*><ID-CERT><>$
+ }
+ checker
+ {
+ type hierarchical
+ sig-type rsa-sha256
+ }
+ }
+
+ trust-anchor
+ {
+ type file
+ file-name "security/root.cert"
+ }
+ }
+
+ prefix-update-validator
+ {
+ rule
+ {
+ id "NLSR ControlCommand Rule"
+ for interest
+ filter
+ {
+ type name
+ regex ^<localhost><nlsr><prefix-update>[<advertise><withdraw>]<>$
+ }
+ checker
+ {
+ type customized
+ sig-type rsa-sha256
+ key-locator
+ {
+ type name
+ regex ^([^<KEY><%C1.Operator>]*)<%C1.Operator>[^<KEY>]*<KEY><ksk-.*><ID-CERT>$
+ }
+ }
+ }
+
+ rule
+ {
+ id "NLSR Hierarchy Rule"
+ for data
+ filter
+ {
+ type name
+ regex ^[^<KEY>]*<KEY><ksk-.*><ID-CERT><>$
+ }
+ checker
+ {
+ type hierarchical
+ sig-type rsa-sha256
+ }
+ }
+
+ trust-anchor
+ {
+ type file
+ file-name "security/site.cert"
+ }
+ }
+ ; cert-to-publish "security/root.cert" ; optional, a file containing the root certificate
+ ; Only the router that is designated to publish the root cert
+ ; needs to specify this
+
+ cert-to-publish "security/site.cert" ; optional, a file containing the site certificate
+ ; Only the router that is designated to publish the site cert
+ ; needs to specify this
+
+ cert-to-publish "security/op.cert" ; optional, a file containing the operator certificate
+ ; Only the router that is designated to publish the operator
+ ; cert needs to specify this
+
+ cert-to-publish "security/router.cert" ; required, a file containing the router certificate.
+ }""")
return security