blob: da68f769504c3d916ef09a50d6bc6384f4421012 [file] [log] [blame]
Vince Lehmanb8b18062015-07-14 13:07:22 -05001# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2#
Vince Lehman5d5a5662015-12-02 12:33:12 -06003# Copyright (C) 2015-2016, The University of Memphis,
4# Arizona Board of Regents,
5# Regents of the University of California.
Vince Lehmanb8b18062015-07-14 13:07:22 -05006#
7# This file is part of Mini-NDN.
8# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
9#
10# Mini-NDN is free software: you can redistribute it and/or modify
11# it under the terms of the GNU General Public License as published by
12# the Free Software Foundation, either version 3 of the License, or
13# (at your option) any later version.
14#
15# Mini-NDN is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18# GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License
21# along with Mini-NDN, e.g., in COPYING.md file.
22# If not, see <http://www.gnu.org/licenses/>.
23
Vince Lehman5d5a5662015-12-02 12:33:12 -060024from mininet.clean import sh
25
Ashlesh Gawande792c6aa2015-07-10 12:18:36 -050026from ndn.ndn_application import NdnApplication
ashuef3490b2015-02-17 11:01:04 -060027
Vince Lehman5d5a5662015-12-02 12:33:12 -060028import os
29import shutil
30import textwrap
31
Ashlesh Gawande792c6aa2015-07-10 12:18:36 -050032class Nlsr(NdnApplication):
ashuef3490b2015-02-17 11:01:04 -060033 def __init__(self, node):
Ashlesh Gawande792c6aa2015-07-10 12:18:36 -050034 NdnApplication.__init__(self, node)
ashuef3490b2015-02-17 11:01:04 -060035 self.routerName = "/%sC1.Router/cs/%s" % ('%', node.name)
Ashlesh Gawande1b663692015-10-14 16:38:10 -050036 self.confFile = "%s/nlsr.conf" % node.homeFolder
ashuef3490b2015-02-17 11:01:04 -060037
38 # Make directory for log file
Ashlesh Gawande1b663692015-10-14 16:38:10 -050039 self.logDir = "%s/log" % node.homeFolder
ashuef3490b2015-02-17 11:01:04 -060040 node.cmd("mkdir %s" % self.logDir)
41
42 # Configure basic router information in nlsr.conf based on host name
43 node.cmd("sudo sed -i 's|router .*|router %s|g' %s" % (self.routerName, self.confFile))
44 node.cmd("sudo sed -i 's|log-dir .*|log-dir %s|g' %s" % (self.logDir, self.confFile))
45 node.cmd("sudo sed -i 's|seq-dir .*|seq-dir %s|g' %s" % (self.logDir, self.confFile))
46 node.cmd("sudo sed -i 's|prefix .*netlab|prefix /ndn/edu/%s|g' %s" % (node.name, self.confFile))
47
48 def start(self):
Yucheng Zhangdd4c6b72016-04-05 17:02:46 -050049 NdnApplication.start(self, "nlsr -d -f {} &".format(self.confFile))
ashuef3490b2015-02-17 11:01:04 -060050
Vince Lehman5d5a5662015-12-02 12:33:12 -060051 @staticmethod
52 def createKey(host, name, outputFile):
53 host.cmd("ndnsec-keygen {} > {}".format(name, outputFile))
54
55 @staticmethod
56 def createCertificate(host, name, prefix, keyFile, outputFile, signer=None):
57 if signer is None:
58 host.cmd("ndnsec-certgen -N {} -p {} {} > {}".format(name, prefix, keyFile, outputFile))
59 else:
60 host.cmd("ndnsec-certgen -N {} -p {} -s {} {} > {}".format(name, prefix, signer, keyFile, outputFile))
61
62 @staticmethod
63 def createKeysAndCertificates(net, workDir):
64 securityDir = "{}/security".format(workDir)
65
66 if not os.path.exists(securityDir):
67 os.mkdir(securityDir)
68
69 # Create root certificate
70 rootName = "/ndn"
71 sh("ndnsec-keygen {} > {}/root.keys".format(rootName, securityDir))
72 sh("ndnsec-certgen -N {} -p {} {}/root.keys > {}/root.cert".format(rootName, rootName, securityDir, securityDir))
73
74 # Create necessary certificates for each site
75 for host in net.hosts:
76 nodeSecurityFolder = "{}/security".format(host.homeFolder)
77
78 if not os.path.exists(nodeSecurityFolder):
79 os.mkdir(nodeSecurityFolder)
80
81 shutil.copyfile("{}/root.cert".format(securityDir), "{}/root.cert".format(nodeSecurityFolder))
82
83 # Create site certificate
84 siteName = "/ndn/edu"
85 siteKeyFile = "{}/site.keys".format(nodeSecurityFolder)
86 siteCertFile = "{}/site.cert".format(nodeSecurityFolder)
87 Nlsr.createKey(host, siteName, siteKeyFile)
88
89 # Root key is in root namespace, must sign site key and then install on host
90 sh("ndnsec-certgen -N {} -s {} -p {} {} > {}".format(siteName, rootName, siteName, siteKeyFile, siteCertFile))
91 host.cmd("ndnsec-cert-install -f {}".format(siteCertFile))
92
93 # Create operator certificate
94 opName = "{}/%C1.Operator/op".format(siteName)
95 opKeyFile = "{}/op.keys".format(nodeSecurityFolder)
96 opCertFile = "{}/op.cert".format(nodeSecurityFolder)
97 Nlsr.createKey(host, opName, opKeyFile)
98 Nlsr.createCertificate(host, opName, opName, opKeyFile, opCertFile, signer=siteName)
99
100 # Create router certificate
101 routerName = "{}/%C1.Router/cs/{}".format(siteName, host.name)
102 routerKeyFile = "{}/router.keys".format(nodeSecurityFolder)
103 routerCertFile = "{}/router.cert".format(nodeSecurityFolder)
104 Nlsr.createKey(host, routerName, routerKeyFile)
105 Nlsr.createCertificate(host, routerName, routerName, routerKeyFile, routerCertFile, signer=opName)
106
ashuef3490b2015-02-17 11:01:04 -0600107class NlsrConfigGenerator:
108
109 ROUTING_LINK_STATE = "ls"
110 ROUTING_HYPERBOLIC = "hr"
111
Vince Lehman5d5a5662015-12-02 12:33:12 -0600112 def __init__(self, node, isSecurityEnabled):
ashu2ad32e22015-05-29 13:37:40 -0500113 node.cmd("sudo cp /usr/local/etc/mini-ndn/nlsr.conf nlsr.conf")
ashuef3490b2015-02-17 11:01:04 -0600114 self.node = node
Vince Lehman5d5a5662015-12-02 12:33:12 -0600115 self.isSecurityEnabled = isSecurityEnabled
ashuef3490b2015-02-17 11:01:04 -0600116
117 parameters = node.nlsrParameters
118
119 self.nFaces = parameters.get("max-faces-per-prefix", 3)
120 self.hyperbolicState = parameters.get("hyperbolic-state", "off")
121 self.hyperRadius = parameters.get("radius", 0.0)
122 self.hyperAngle = parameters.get("angle", 0.0)
Ashlesh Gawandec3ed2b92015-07-01 12:58:08 -0500123 self.logLevel = parameters.get("nlsr-log-level", "DEBUG")
ashuef3490b2015-02-17 11:01:04 -0600124
125 def createConfigFile(self):
126
Ashlesh Gawande1b663692015-10-14 16:38:10 -0500127 filePath = "%s/nlsr.conf" % self.node.homeFolder
ashuef3490b2015-02-17 11:01:04 -0600128
129 configFile = open(filePath, 'r')
130 oldContent = configFile.read()
131 configFile.close()
132
133 newContent = oldContent.replace("$GENERAL_SECTION", self.__getGeneralSection())
134 newContent = newContent.replace("$NEIGHBORS_SECTION", self.__getNeighborsSection())
135 newContent = newContent.replace("$HYPERBOLIC_SECTION", self.__getHyperbolicSection())
136 newContent = newContent.replace("$FIB_SECTION", self.__getFibSection())
137 newContent = newContent.replace("$ADVERTISING_SECTION", self.__getAdvertisingSection())
Vince Lehman5d5a5662015-12-02 12:33:12 -0600138 newContent = newContent.replace("$SECURITY_SECTION", self.__getSecuritySection())
ashuef3490b2015-02-17 11:01:04 -0600139
140 configFile = open(filePath, 'w')
141 configFile.write(newContent)
142 configFile.close()
143
144 def __getConfig(self):
145
146 config = self.__getGeneralSection()
147 config += self.__getNeighborsSection()
148 config += self.__getHyperbolicSection()
149 config += self.__getFibSection()
150 config += self.__getAdvertisingSection()
151 config += self.__getSecuritySection()
152
153 return config
154
155 def __getGeneralSection(self):
156
157 general = "general\n"
158 general += "{\n"
159 general += " network /ndn/\n"
160 general += " site /edu\n"
161 general += " router /%C1.Router/cs/" + self.node.name + "\n"
Ashlesh Gawandec3ed2b92015-07-01 12:58:08 -0500162 general += " log-level " + self.logLevel + "\n"
Ashlesh Gawande1b663692015-10-14 16:38:10 -0500163 general += " log-dir " + self.node.homeFolder + "/log\n"
164 general += " seq-dir " + self.node.homeFolder + "/log\n"
ashuef3490b2015-02-17 11:01:04 -0600165 general += "}\n"
166
167 return general
168
169 def __getNeighborsSection(self):
170
171 neighbors = "neighbors\n"
172 neighbors += "{\n"
173
174 for intf in self.node.intfList():
175 link = intf.link
176 if link:
177 node1, node2 = link.intf1.node, link.intf2.node
178
179 if node1 == self.node:
180 other = node2
181 ip = other.IP(str(link.intf2))
182 else:
183 other = node1
184 ip = other.IP(str(link.intf1))
185
ashu7b6ba182015-04-17 15:02:37 -0500186 linkCost = intf.params.get("delay", "10ms").replace("ms", "")
ashuef3490b2015-02-17 11:01:04 -0600187
188 neighbors += "neighbor\n"
189 neighbors += "{\n"
190 neighbors += " name /ndn/edu/%C1.Router/cs/" + other.name + "\n"
191 neighbors += " face-uri udp://" + str(ip) + "\n"
192 neighbors += " link-cost " + linkCost + "\n"
193 neighbors += "}\n"
194
195 neighbors += "}\n"
196
197 return neighbors
198
199 def __getHyperbolicSection(self):
200
201 hyper = "hyperbolic\n"
202 hyper += "{\n"
203 hyper += "state %s\n" % self.hyperbolicState
204 hyper += "radius " + str(self.hyperRadius) + "\n"
205 hyper += "angle " + str(self.hyperAngle) + "\n"
206 hyper += "}\n"
207
208 return hyper
209
210 def __getFibSection(self):
211
212 fib = "fib\n"
213 fib += "{\n"
214 fib += " max-faces-per-prefix " + str(self.nFaces) + "\n"
215 fib += "}\n"
216
217 return fib
218
219 def __getAdvertisingSection(self):
220
221 advertising = "advertising\n"
222 advertising += "{\n"
223 advertising += " prefix /ndn/edu/" + self.node.name + "\n"
224 advertising += "}\n"
225
226 return advertising
227
228 def __getSecuritySection(self):
Vince Lehman5d5a5662015-12-02 12:33:12 -0600229 if self.isSecurityEnabled is False:
230 security = textwrap.dedent("""\
231 security
232 {
233 validator
234 {
235 trust-anchor
236 {
237 type any
238 }
239 }
240 prefix-update-validator
241 {
242 trust-anchor
243 {
244 type any
245 }
246 }
247 }""")
248 else:
249 security = textwrap.dedent("""\
250 security
251 {
252 validator
253 {
254 rule
255 {
256 id "NSLR Hello Rule"
257 for data
258 filter
259 {
260 type name
261 regex ^[^<NLSR><INFO>]*<NLSR><INFO><><>$
262 }
263 checker
264 {
265 type customized
266 sig-type rsa-sha256
267 key-locator
268 {
269 type name
270 hyper-relation
271 {
272 k-regex ^([^<KEY><NLSR>]*)<NLSR><KEY><ksk-.*><ID-CERT>$
273 k-expand \\\\1
274 h-relation equal
275 p-regex ^([^<NLSR><INFO>]*)<NLSR><INFO><><>$
276 p-expand \\\\1
277 }
278 }
279 }
280 }
ashuef3490b2015-02-17 11:01:04 -0600281
Vince Lehman5d5a5662015-12-02 12:33:12 -0600282 rule
283 {
284 id "NSLR LSA Rule"
285 for data
286 filter
287 {
288 type name
289 regex ^[^<NLSR><LSA>]*<NLSR><LSA>
290 }
291 checker
292 {
293 type customized
294 sig-type rsa-sha256
295 key-locator
296 {
297 type name
298 hyper-relation
299 {
300 k-regex ^([^<KEY><NLSR>]*)<NLSR><KEY><ksk-.*><ID-CERT>$
301 k-expand \\\\1
302 h-relation equal
303 p-regex ^([^<NLSR><LSA>]*)<NLSR><LSA>(<>*)<><><><>$
304 p-expand \\\\1\\\\2
305 }
306 }
307 }
308 }
309
310 rule
311 {
312 id "NSLR Hierarchy Exception Rule"
313 for data
314 filter
315 {
316 type name
317 regex ^[^<KEY><%C1.Router>]*<%C1.Router>[^<KEY><NLSR>]*<KEY><ksk-.*><ID-CERT><>$
318 }
319 checker
320 {
321 type customized
322 sig-type rsa-sha256
323 key-locator
324 {
325 type name
326 hyper-relation
327 {
328 k-regex ^([^<KEY><%C1.Operator>]*)<%C1.Operator>[^<KEY>]*<KEY><ksk-.*><ID-CERT>$
329 k-expand \\\\1
330 h-relation equal
331 p-regex ^([^<KEY><%C1.Router>]*)<%C1.Router>[^<KEY>]*<KEY><ksk-.*><ID-CERT><>$
332 p-expand \\\\1
333 }
334 }
335 }
336 }
337
338 rule
339 {
340 id "NSLR Hierarchical Rule"
341 for data
342 filter
343 {
344 type name
345 regex ^[^<KEY>]*<KEY><ksk-.*><ID-CERT><>$
346 }
347 checker
348 {
349 type hierarchical
350 sig-type rsa-sha256
351 }
352 }
353
354 trust-anchor
355 {
356 type file
357 file-name "security/root.cert"
358 }
359 }
360
361 prefix-update-validator
362 {
363 rule
364 {
365 id "NLSR ControlCommand Rule"
366 for interest
367 filter
368 {
369 type name
370 regex ^<localhost><nlsr><prefix-update>[<advertise><withdraw>]<>$
371 }
372 checker
373 {
374 type customized
375 sig-type rsa-sha256
376 key-locator
377 {
378 type name
379 regex ^([^<KEY><%C1.Operator>]*)<%C1.Operator>[^<KEY>]*<KEY><ksk-.*><ID-CERT>$
380 }
381 }
382 }
383
384 rule
385 {
386 id "NLSR Hierarchy Rule"
387 for data
388 filter
389 {
390 type name
391 regex ^[^<KEY>]*<KEY><ksk-.*><ID-CERT><>$
392 }
393 checker
394 {
395 type hierarchical
396 sig-type rsa-sha256
397 }
398 }
399
400 trust-anchor
401 {
402 type file
403 file-name "security/site.cert"
404 }
405 }
406 ; cert-to-publish "security/root.cert" ; optional, a file containing the root certificate
407 ; Only the router that is designated to publish the root cert
408 ; needs to specify this
409
410 cert-to-publish "security/site.cert" ; optional, a file containing the site certificate
411 ; Only the router that is designated to publish the site cert
412 ; needs to specify this
413
414 cert-to-publish "security/op.cert" ; optional, a file containing the operator certificate
415 ; Only the router that is designated to publish the operator
416 ; cert needs to specify this
417
418 cert-to-publish "security/router.cert" ; required, a file containing the router certificate.
419 }""")
ashuef3490b2015-02-17 11:01:04 -0600420
421 return security