Add automatic NLSR security configuration
refs: #3050
Change-Id: I218f96a2cb11dd35de99c4a9eab056f0fed890aa
diff --git a/bin/minindn b/bin/minindn
index a9f0e9c..d70cc2f 100755
--- a/bin/minindn
+++ b/bin/minindn
@@ -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.
@@ -104,6 +104,7 @@
self.templateFile = "minindn.conf"
self.hr = False
self.isCliEnabled = True
+ self.nlsrSecurity = False
self.nPings = 300
self.testbed = False
self.workDir = "/tmp"
@@ -161,6 +162,9 @@
parser.add_option("--nPings", action="store", dest="nPings", type="int", default=300,
help="Number of pings to perform between each node in the experiment")
+ parser.add_option("--nlsr-security", action="store_true", dest="nlsrSecurity", default=False,
+ help="Enables NLSR security")
+
parser.add_option("-t", "--testbed", action="store_true", dest="testbed", default=False,
help="instantiates NDN Testbed")
@@ -184,7 +188,9 @@
options.nFaces = args.faces
options.hr = args.hr
options.isCliEnabled = args.isCliEnabled
+ options.nlsrSecurity = args.nlsrSecurity
options.nPings = args.nPings
+
options.testbed = args.testbed
options.workDir = args.workDir
options.resultDir = args.resultDir
@@ -308,6 +314,10 @@
nodes = "" # Used later to check prefix name in checkFIB
+ # NLSR Security
+ if options.nlsrSecurity is True:
+ Nlsr.createKeysAndCertificates(net, options.workDir)
+
# NLSR initialization
for host in net.hosts:
nodes += str(host.name) + ","
@@ -322,7 +332,7 @@
host.nlsrParameters["hyperbolic-state"] = "on"
# Generate NLSR configuration file
- configGenerator = NlsrConfigGenerator(host)
+ configGenerator = NlsrConfigGenerator(host, options.nlsrSecurity)
configGenerator.createConfigFile()
# Start NLSR
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
diff --git a/ndn_utils/nlsr.conf b/ndn_utils/nlsr.conf
index 1eb56de..492ee0d 100644
--- a/ndn_utils/nlsr.conf
+++ b/ndn_utils/nlsr.conf
@@ -21,174 +21,4 @@
$ADVERTISING_SECTION
-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
- }
- }
- }
- }
-
- 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 any
- file-name "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 any
- file-name "site.cert"
- }
- }
-
- ; cert-to-publish "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 "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 "operator.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 "router.cert" ; required, a file containing the router certificate.
-}
+$SECURITY_SECTION