diff --git a/NDprotector/.gitignore b/NDprotector/.gitignore new file mode 100644 index 0000000..18161b0 --- /dev/null +++ b/NDprotector/.gitignore @@ -0,0 +1,5 @@ +# Ignore +*.pyc + +# Keep +!.gitignore diff --git a/NDprotector/Address.py b/NDprotector/Address.py index d0a6ec7..ba8c1f2 100644 --- a/NDprotector/Address.py +++ b/NDprotector/Address.py @@ -233,6 +233,7 @@ def __init__(self,interface=None,\ self.__sec = ord(socket.inet_pton(\ socket.AF_INET6,self.__address)[8]) >> 5 + print "About to invoke CGAverify in Address.py, check 1" # jochoi: debug if not CGAverify(self.__address, CGAParams(modifier=modifier, prefix=self.__prefix, \ ccount = self.__collcount, pubkey = self.__pubkey, \ ext = ext)): @@ -341,6 +342,7 @@ def do_dad(self): if packet.haslayer(ICMPv6ND_NS) and address == "::": address = packet.tgt # CGA address check + print "About to invoke CGAverify in Address.py, check 2" # jochoi: debug if not CGAverify(address,packet[CGAParams]): warn("one packet with an invalid CGA address was received during the DAD procedure\n") continue diff --git a/NDprotector/Config.py b/NDprotector/Config.py index d1e5420..a9ad868 100644 --- a/NDprotector/Config.py +++ b/NDprotector/Config.py @@ -4,6 +4,7 @@ load_plugins, \ find_plugins from NDprotector.Log import warn +from NDprotector.Address import Address def readconfig(config_file): diff --git a/NDprotector/In.py b/NDprotector/In.py index 230540c..eed39fa 100644 --- a/NDprotector/In.py +++ b/NDprotector/In.py @@ -1,6 +1,10 @@ """this module processes all the in-going packets by using nfqueue""" from socket import AF_INET6 import sys +import ctypes # jochoi: import to use if_indextoname +import ctypes.util # jochoi: import to use if_indextoname + +libc = ctypes.CDLL(ctypes.util.find_library('c')) # jochoi: needed for if_indextoname from NDprotector.Log import warn @@ -21,6 +25,18 @@ except ImportError: pass +# jochoi: begin if_indextoname to replace get_if_list function +def if_indextoname(index): + if not isinstance(index, int): + raise TypeError ('provided index should be an int value'); + libc.if_indextoname.argtypes = [ctypes.c_uint32, ctypes.c_char_p] + libc.if_indextoname.restype = ctypes.c_char_p + ifname = ctypes.create_string_buffer(32) + ifname = libc.if_indextoname (index, ifname) + if not ifname: + raise RuntimeError ("Invalid index") + return ifname +# jochoi: end if_indextoname def callback(i, payload): """a callback function called on each ingoing packets""" @@ -36,21 +52,36 @@ def callback(i, payload): signalgs = [] verifalgs = [] + print "In.py | Interface index is : %s" % payload.get_indev() # jochoi: debug + print "In.py | Interface name is : %s" % if_indextoname(payload.get_indev()) # jochoi: debug + # may be buggy due to the order of get_if_list() # (in that case, we could use the if_nametoindex() ) - interface = get_if_list()[ payload.get_indev() - 1] + # interface = get_if_list()[ payload.get_indev() - 1] + interface = if_indextoname(payload.get_indev()) # jochoi: edit nc = NeighCache() if packet.haslayer(ICMPv6ND_NS) \ or packet.haslayer(ICMPv6ND_NA): + # jochoi: begin debug to match arpsec02 printout + if packet.haslayer(ICMPv6ND_NS): + print "In.py | Received NS message" + else: + print "In.py | Received NA message" + + print "In.py | Source address: %s" % packet[IPv6].src + print "In.py | Target address: %s" % packet[IPv6].tgt + # jochoi: end debug to match arpsec02 + secured = False try: address = packet[IPv6].src # we can receive messages from other node performing a DAD if address == "::": address = packet.tgt + print "In.py | About to invoke CGAverify, check 1" # jochoi: debug cga_prop = CGAverify(address,packet.getlayer(CGAParams)) if not cga_prop: warn("an ingoing packet has failed CGA verification test\n") @@ -60,6 +91,7 @@ def callback(i, payload): # Timestamp and Nonce verification are performed in the NC # FIXME: this is not "good", we are subject to a DoS attack here + print "In.py | CGAverify successful" # jochoi: debug list_of_pubkeys = CGAPKExtListtoPubKeyList(packet[CGAParams].ext) list_of_pubkeys.insert(0,packet[CGAParams].pubkey) pubkey = list_of_pubkeys[packet[ICMPv6NDOptUSSig].pos] @@ -79,6 +111,7 @@ def callback(i, payload): warn("an ingoing packet has failed Universal Signature verification\n") else: secured = True + print "In.py | Set secured to TRUE" # jochoi: debug except AttributeError: warn("An unsecured packet passed\n") @@ -200,7 +233,8 @@ def callback(i, payload): and pubkey.modulusLen <= NDprotector.max_RSA_key_size))\ or\ (NDprotector.ECCsupport and isinstance(pubkey, ECCkey)): - + + print "About to invoke CGAverify in In.py, check 2" # jochoi: debug if CGAverify(packet[IPv6].src,packet.getlayer(CGAParams)) and \ packet[ICMPv6NDOptUSSig].keyh == pkhash and \ packet[ICMPv6NDOptUSSig].verify_sig(pubkey): diff --git a/NDprotector/Out.py b/NDprotector/Out.py index 426462e..e555750 100644 --- a/NDprotector/Out.py +++ b/NDprotector/Out.py @@ -31,25 +31,33 @@ def callback(i,payload): or packet.haslayer(ICMPv6ND_NA): for addr in configured_addresses: + print "Out.py | addr in config %s" % str(addr) # jochoi: debug + print "Out.py | source address %s" % packet[IPv6].src # jochoi: debug if str(addr) == packet[IPv6].src: + print "Out.py | addr in config matches packet source address" # jochoi: debug if packet.haslayer(ICMPv6ND_NS): nonce = "".join([ chr(random.randrange(255)) for i in range(6)]) nc.record_nonce_out(packet[IPv6].src,packet[IPv6].dst,nonce) else: nonce = nc.pop_nonce_out(packet[IPv6].src,packet[IPv6].dst) data = addr.sign(data,nonce=nonce) - warn("signing a NS or NA message\n") + # jochoi: split warning for NS and NA messages + # warn("signing a NS or NA message\n") + if packet.haslayer(ICMPv6ND_NS): + warn("signing a NS message\n") + else: + warn("signing a NA message\n") payload.set_verdict_modified(nfqueue.NF_ACCEPT,str(data),len(str(data))) return 0 - else: - if NDprotector.mixed_mode: - warn("letting go one outgoing unsecured packet\n") - payload.set_verdict(nfqueue.NF_ACCEPT) - return else: - warn("dropping one unsecured packet\n") - payload.set_verdict(nfqueue.NF_DROP) - return 0 + if NDprotector.mixed_mode: + warn("letting go one outgoing unsecured packet\n") + payload.set_verdict(nfqueue.NF_ACCEPT) + return 0 # added return 0 + else: + warn("dropping one unsecured packet\n") + payload.set_verdict(nfqueue.NF_DROP) + return 0 elif packet.haslayer(ICMPv6ND_RS): if NDprotector.is_router == False: if packet[IPv6].src == "::" : @@ -69,15 +77,15 @@ def callback(i,payload): data = addr.sign(data,nonce=nonce) payload.set_verdict_modified(nfqueue.NF_ACCEPT, str(data), len(str(data))) return 0 - else: - if NDprotector.mixed_mode: - warn("letting go one outgoing unsecure RS packet\n") - payload.set_verdict(nfqueue.NF_ACCEPT) - return 0 else: - warn("dropping one unsecure RS packet\n") - payload.set_verdict(nfqueue.NF_DROP) - return 0 + if NDprotector.mixed_mode: + warn("letting go one outgoing unsecure RS packet\n") + payload.set_verdict(nfqueue.NF_ACCEPT) + return 0 + else: + warn("dropping one unsecure RS packet\n") + payload.set_verdict(nfqueue.NF_DROP) + return 0 else: # a router does not send this kind of messages payload.set_verdict(nfqueue.NF_DROP) @@ -97,15 +105,15 @@ def callback(i,payload): data = addr.sign(data,nonce=nonce) payload.set_verdict_modified(nfqueue.NF_ACCEPT,str(data),len(str(data))) return 0 - else: - if NDprotector.mixed_mode: - warn("letting go one outgoing unsecure RA packet\n") - payload.set_verdict(nfqueue.NF_ACCEPT) - return 0 else: - warn("dropping one unsecure RA packet\n") - payload.set_verdict(nfqueue.NF_DROP) - return 0 + if NDprotector.mixed_mode: + warn("letting go one outgoing unsecure RA packet\n") + payload.set_verdict(nfqueue.NF_ACCEPT) + return 0 + else: + warn("dropping one unsecure RA packet\n") + payload.set_verdict(nfqueue.NF_DROP) + return 0 else: # a host does not send RA messages payload.set_verdict(nfqueue.NF_DROP) diff --git a/bench/benchCGA.py b/bench/benchCGA.py index 1fe1647..eb8cff7 100755 --- a/bench/benchCGA.py +++ b/bench/benchCGA.py @@ -15,10 +15,12 @@ from scapy6send.cert import * from scapy6send.scapy6 import * from NDprotector.Tool import PubKeyListtoCGAPKExtList +from math import * # cynthiao sigtypeID = 9 extrakeynum =3 +key_gen_time = [] cga_gen_time = [] cga_verif_time = [] sign_gen_time = [] @@ -73,15 +75,21 @@ def signature_verify(data,k): return IPv6(data)[ICMPv6NDOptUSSig].verify_sig(k) def compute_key(): - return ECCkey(NID_secp256k1) + return ECCkey(NID_secp256k1) # jochoi: (observation) key is being generated with 256 bits? def gen_cga(key): return CGAgen("fe80::", key, 1, ext = PubKeyListtoCGAPKExtList([ key for i in range(extrakeynum)]) ) def bench_single_ecc(): - for i in range(10000): + for i in range(100): + before = time.time() k = compute_key() + # print "key computed, %s" % k # jochoi: debug / should time tthe key generation + after = time.time() + # print "key generation took: %s" % str(after - before) + key_gen_time.append(after - before) + # computes a CGA address before = time.time() (address, params) = gen_cga(k) @@ -109,6 +117,16 @@ def bench_single_ecc(): print "loop #%d computed, message size: %d" % (i, len(m)) +def computeMdev(data, avg): + ''' + Compute the mean deviation given the list and the average value + ''' + num = len(data) + sum = 0.0 + for d in data: + sum += abs(d - avg) + + return(sum/num) if __name__ == "__main__": @@ -121,17 +139,85 @@ def bench_single_ecc(): f = open("%d-key-ecc-duration" % extrakeynum, "w") + f.write("key_gen_time = " + repr(key_gen_time) + "\n") f.write("cga_gen_time = " + repr(cga_gen_time) + "\n") f.write("cga_verif_time = " + repr(cga_verif_time) + "\n") f.write("sign_gen_time = " + repr(sign_gen_time) + "\n") f.write("sign_verif_time = " + repr(sign_verif_time) + "\n") f.close() - + # cynthiao additions :: added min, max, standard deviation + + print "==KEY GENERATION TIMES==" + print "min KEY Generation time: " + str(min(key_gen_time)) + print "max KEY generation time: " + str(max(key_gen_time)) + print "mean KEY generation time: " + str(sum(key_gen_time) / len(key_gen_time)) + + def average(key_gen_time): return sum(key_gen_time) * 1.0 / len(key_gen_time) + avg = average(key_gen_time) + variance = map(lambda x: (x - avg)**2, key_gen_time) + average(variance) + stdGenDev = math.sqrt(average(variance)) + print "deviation of KEY generation time: " + str(stdGenDev) + mdev = computeMdev(key_gen_time, avg) + print "mean deviation of KEY generation time: " + str(mdev) + + print "==CGA GENERATION TIMES==" + print "min CGA generation time: " + str(min(cga_gen_time)) + print "max CGA generation time: " + str(max(cga_gen_time)) print "mean CGA generation time: " + str(sum(cga_gen_time) / len(cga_gen_time)) + + def average(cga_gen_time): return sum(cga_gen_time) * 1.0 / len(cga_gen_time) + avg = average(cga_gen_time) + variance = map(lambda x: (x - avg)**2, cga_gen_time) + average(variance) + stdGenDev = math.sqrt(average(variance)) + print "deviation of CGA generation time: " + str(stdGenDev) + mdev = computeMdev(cga_gen_time, avg) + print "mean deviation of KEY generation time: " + str(mdev) + + print "==CGA VERIFICATION TIMES==" + print "min CGA verification time: " + str(min(cga_verif_time)) + print "max CGA verification time: " + str(max(cga_verif_time)) print "mean CGA verification time: " + str(sum(cga_verif_time) / len(cga_verif_time)) + + def average(cga_verif_time): return sum(cga_verif_time) * 1.0 / len(cga_verif_time) + avg = average(cga_verif_time) + variance = map(lambda x: (x - avg)**2, cga_verif_time) + average(variance) + stdVerDev = math.sqrt(average(variance)) + print "deviation of CGA verification time: " + str(stdVerDev) + mdev = computeMdev(cga_verif_time, avg) + print "mean deviation of KEY generation time: " + str(mdev) + + print "==SIGNATURE GENERATION TIMES==" + print "min Signature generation time: " + str(min(sign_gen_time)) + print "max Signature generation time: " + str(max(sign_gen_time)) print "mean Signature generation time: " + str(sum(sign_gen_time) / len(sign_gen_time)) + + def average(sign_gen_time): return sum(sign_gen_time) * 1.0 / len(sign_gen_time) + avg = average(sign_gen_time) + variance = map(lambda x: (x - avg)**2, sign_gen_time) + average(variance) + stdSigDev = math.sqrt(average(variance)) + print "deviation of Signature generation time: " + str(stdSigDev) + mdev = computeMdev(sign_gen_time, avg) + print "mean deviation of KEY generation time: " + str(mdev) + + print "==SIGNATURE VERIFICATION TIMES==" + print "min Signature verification time: " + str(min(sign_verif_time)) + print "max Signature verification time: " + str(max(sign_verif_time)) print "mean Signature verification time: " + str(sum(sign_verif_time) / len(sign_verif_time)) + + def average(sign_verif_time): return sum(sign_verif_time) * 1.0 / len(sign_verif_time) + avg = average(sign_verif_time) + variance = map(lambda x: (x - avg)**2, sign_verif_time) + average(variance) + stdSigVerDev = math.sqrt(average(variance)) + print "deviation of Signature verification time: " + str(stdSigVerDev) + mdev = computeMdev(sign_verif_time, avg) + print "mean deviation of KEY generation time: " + str(mdev) + # prof = cProfile.run("bench_single_ecc()","%d-key-ecc.prof" % extrakeynum) diff --git a/examples/sendd.conf.host b/examples/sendd.conf.host index 1a0290e..d8b3822 100644 --- a/examples/sendd.conf.host +++ b/examples/sendd.conf.host @@ -35,7 +35,7 @@ NDprotector.mixed_mode = False # allow NDprotector to flush all the IPv6 addresses on all interfaces # (so that only CGA are on the interfaces) -NDprotector.flush_interfaces = True +NDprotector.flush_interfaces = False # /!\ Beware: # force test on X.509 IP Address extension @@ -53,7 +53,7 @@ NDprotector.default_sec_value = 1 # If True, the programm automotaticlally assign addresses on the interfaces # the program will also clean up and destroy unused addresses # If set to False, the user must to the address assignement manually -NDprotector.assign_addresses = True +NDprotector.assign_addresses = False # Default key size for RSA keys @@ -70,7 +70,7 @@ NDprotector.max_RSA_key_size = 2048 # Path to the default Public Key used for Stateless Address Autoconfiguration # if None is provided, generate a new RSA Public Key for new addresses -NDprotector.default_publickey = None +NDprotector.default_publickey = "/root/git/NDprotector/publicKeyB.pem" # NDprotector.default_publickey = "/etc/NDprotector/mypublickey.pem" # Path to the trust anchor @@ -107,9 +107,11 @@ NDprotector.configured_addresses = \ # ext = None ), # list of configured prefixes where autoconfiguration will be applied - Address(interface = "eth0", - prefix = "fe80::", - key = "/etc/NDprotector/key.pem"), # if ommited, uses the key pointed by default_publickey + # Address(interface = "eth0", + Address(interface = "eth1", + prefix = "2001:db8:0:100::", + key = "/root/git/NDprotector/privateKeyB.pem", + modifier = 50), # if ommited, uses the key pointed by default_publickey # or fallback (when default_publickey is None) and the program will compute a new RSA key # Address(interface = "eth0", # for example this one will build it's own key # prefix = "2001::", diff --git a/examples/sendd.conf.router b/examples/sendd.conf.router index ff43c6e..2966845 100644 --- a/examples/sendd.conf.router +++ b/examples/sendd.conf.router @@ -104,7 +104,7 @@ NDprotector.configured_addresses = \ # ext = None ), # list of configured prefixes where autoconfiguration will be applied - Address(interface = "eth0", + NDprotector.Address(interface = "eth0", prefix = "fe80::", # must correspond to the public key linked to cert path1-level1.pem and path2-level1.pem key = "/etc/NDprotector/router_pk.pem"), # if ommited, uses the key pointed by default_publickey diff --git a/genCGA.py b/genCGA.py index f0d7407..e2a8025 100755 --- a/genCGA.py +++ b/genCGA.py @@ -1,4 +1,4 @@ -#!/bin/env python +#!/usr/bin/python """a small tool to generate configuration file for CGA addresses""" import warnings diff --git a/ndprotector.py b/ndprotector.py index abb470a..d01a277 100755 --- a/ndprotector.py +++ b/ndprotector.py @@ -1,4 +1,4 @@ -#!/usr/bin/python2.6 +#!/usr/bin/python # author: Tony Cheneau '''This program protects incomimg and outgoing NDP packets with the SEND diff --git a/scapy6send/.gitignore b/scapy6send/.gitignore new file mode 100644 index 0000000..18161b0 --- /dev/null +++ b/scapy6send/.gitignore @@ -0,0 +1,5 @@ +# Ignore +*.pyc + +# Keep +!.gitignore diff --git a/scapy6send/scapy6.py b/scapy6send/scapy6.py index 4b85c46..1f27401 100755 --- a/scapy6send/scapy6.py +++ b/scapy6send/scapy6.py @@ -5879,10 +5879,17 @@ def hash2(self): Return the 112-bits Hash2 value as described in section 3 of RFC 3972. """ + ''' + daveti: this is NOT Hash2 used in the CGA verification tmp = self.copy() tmp.prefix = "::" tmp.ccount = 0 - s = SHA.new(str(tmp)).digest() + ''' + # Hash2 based on CGA verification + ext_str = "".join(map(lambda x: str(x), self.ext)) + key_str = str(self.pubkey) + s = "".join((self.modifier, '\x00\x00\x00\x00\x00\x00\x00\x00\x00', key_str, ext_str)) + s = SHA.new(str(s)).digest() return s[:14] def CGAgen1(prefix,key,sec,ext=[],modifier=None,ccount=None): @@ -5919,8 +5926,13 @@ class ECCkey(): # 2, 3 # we skip 2 and 3 if the modifier is fixed during the call + # daveti: The RFC says that we could skip 2-3 if sec=0 rather than a fixed modifier. + # Even if the modifier is fixed, as long as sec!=0, we need to update the modifier. + # The implication seems that the fixed modifier should only be used with sec=0 if we + # want the modifier to be fixed! key_str = str(key) - if not modifier: + #if not modifier: + if sec != 0: while True: # TC: seems more optimized # s = m + '\x00'*9 + key_str + ext_str diff --git a/workingconf/sendd.conf.host01 b/workingconf/sendd.conf.host01 new file mode 100644 index 0000000..d8b3822 --- /dev/null +++ b/workingconf/sendd.conf.host01 @@ -0,0 +1,133 @@ +# default sendd config file + +# DO NOT CHANGE theses values unless you know what you're doing +NDprotector.retrans_timer = 1 +# timestamp verification algorithm variables +NDprotector.ts_delta = 300 +NDprotector.ts_fuzz = 1 +NDprotector.ts_drift = 0.01 + +# indicate which signature algorithm is supported, order matters +NDprotector.SignatureAlgorithms = \ + SigTypeID.keys() # we authorize all the supported keys + +# you can edit the rest of the file :) + + + +# path to the plugin directory +NDprotector.pluginpath = "NDprotector/plugins" + +# plugins that could be loaded +NDprotector.plugins = [] +# available plugin +# NDprotector.plugins = [ 'ephemeraladdress' ] + +# if the node is a router: +# - it does not interpret RA messages +# - it interperts CPS and answers CPA +NDprotector.is_router = False + +# mixed mode indicates if the daemon is configured to accept both secured and +# unsecured NDP messages (an unseccured message will not ovewrite a secured +# entry though) +NDprotector.mixed_mode = False + +# allow NDprotector to flush all the IPv6 addresses on all interfaces +# (so that only CGA are on the interfaces) +NDprotector.flush_interfaces = False + +# /!\ Beware: +# force test on X.509 IP Address extension +# (only used when is_router is set to False) +# by default, the extensions are checked against, however, it needs +# OpenSSL to have been compiled with the -enable-rfc3779 flag +NDprotector.x509_ipextension = True + + +# default sec value used for address creation +# (value higher than 1, while totally conform to RFC 3971/3972, +# are not recommanded as they require a lot of processing power) +NDprotector.default_sec_value = 1 + +# If True, the programm automotaticlally assign addresses on the interfaces +# the program will also clean up and destroy unused addresses +# If set to False, the user must to the address assignement manually +NDprotector.assign_addresses = False + + +# Default key size for RSA keys +NDprotector.rsa_key_size = 1024 + +# Minimum (RSA) key size for ingoing messages +# when the key is bellow this value, the message is considered insecure +NDprotector.min_RSA_key_size = 384 + +# Maximum size of a (RSA) key +# key whose length exceed this value are ignored +NDprotector.max_RSA_key_size = 2048 + + +# Path to the default Public Key used for Stateless Address Autoconfiguration +# if None is provided, generate a new RSA Public Key for new addresses +NDprotector.default_publickey = "/root/git/NDprotector/publicKeyB.pem" +# NDprotector.default_publickey = "/etc/NDprotector/mypublickey.pem" + +# Path to the trust anchor +# For host it is [ TA1, TA2 ] +# For router, this is empty ( [] ) +NDprotector.trustanchors = [ "/etc/NDprotector/ta1.pem", + "/etc/NDprotector/ta2.pem" ] + +# Certification path +# Order matters (first certificate is the CA, then level1, etc. +# For routers it is [ [C1,C2,C3], ..., [C1',C2',C3'] ] +# For host, this is empty ( [] ) +# Ex: here, there is two paths +NDprotector.certification_path = [] + +# list of configured addresses +# (you must at least configure a Link-Local address +# for each interface you want this daemon to listen on) +NDprotector.configured_addresses = \ + [ \ + # Address(interface = "eth0", # can be omitted if only one outgoing interface is available + # address = "fe80::3062:ca0b:e098:91ec", # can not work, for demonstration purposes + # key = "test_key.pem", + # modifier = 36147483618661711768276696653219369138L, # should be set to the modifier value + # sec = 1, + # collcount = 0, + # ext = None ), + # Address(interface = "eth0", # can be omitted if only one outgoing interface is available + # address = "fe80::38d4:a8ac:f9c:8a52", # can not work, for demonstration purposes + # key = "test_key.pem", + # modifier = 36147483618661711768276696653219369138L, # should be set to the modifier value + # sec = 1, + # collcount = 1, + # ext = None ), + + # list of configured prefixes where autoconfiguration will be applied + # Address(interface = "eth0", + Address(interface = "eth1", + prefix = "2001:db8:0:100::", + key = "/root/git/NDprotector/privateKeyB.pem", + modifier = 50), # if ommited, uses the key pointed by default_publickey + # or fallback (when default_publickey is None) and the program will compute a new RSA key + # Address(interface = "eth0", # for example this one will build it's own key + # prefix = "2001::", + # sec=0) + + + # this configuration exemple applies to nodes willing to share an address + # each one as its Private key and the Public key of the others + # Multiple Public Keys are stored in the CGA PDS + # + # exemple of configuration for the first node + # Address(interface = "eth0", sec = 0, key = "/etc/NDprotector/first-key.pem", + # ext = PubKeyListtoCGAPKExtList("/etc/NDprotector/second-key.pem"), prefix = "fe80::" , modifier = 0, dad=False) + # + # keypos indicates the position of the Public Key bound to the Private Key the node will sign with + # Address(interface = "eth0", sec=0, key="/etc/NDprotector/second-key.pem", publickey="/etc/NDprotector/first-key.pem", + # ext = PubKeyListtoCGAPKExtList( [ "/etc/NDprotector/second-key.pem" ]), prefix= "fe80::" , keypos = 1, modifier = 0, dad= False) + ] + diff --git a/workingconf/sendd.conf.host02 b/workingconf/sendd.conf.host02 new file mode 100644 index 0000000..a528de6 --- /dev/null +++ b/workingconf/sendd.conf.host02 @@ -0,0 +1,133 @@ +# default sendd config file + +# DO NOT CHANGE theses values unless you know what you're doing +NDprotector.retrans_timer = 1 +# timestamp verification algorithm variables +NDprotector.ts_delta = 300 +NDprotector.ts_fuzz = 1 +NDprotector.ts_drift = 0.01 + +# indicate which signature algorithm is supported, order matters +NDprotector.SignatureAlgorithms = \ + SigTypeID.keys() # we authorize all the supported keys + +# you can edit the rest of the file :) + + + +# path to the plugin directory +NDprotector.pluginpath = "NDprotector/plugins" + +# plugins that could be loaded +NDprotector.plugins = [] +# available plugin +# NDprotector.plugins = [ 'ephemeraladdress' ] + +# if the node is a router: +# - it does not interpret RA messages +# - it interperts CPS and answers CPA +NDprotector.is_router = False + +# mixed mode indicates if the daemon is configured to accept both secured and +# unsecured NDP messages (an unseccured message will not ovewrite a secured +# entry though) +NDprotector.mixed_mode = False + +# allow NDprotector to flush all the IPv6 addresses on all interfaces +# (so that only CGA are on the interfaces) +NDprotector.flush_interfaces = False + +# /!\ Beware: +# force test on X.509 IP Address extension +# (only used when is_router is set to False) +# by default, the extensions are checked against, however, it needs +# OpenSSL to have been compiled with the -enable-rfc3779 flag +NDprotector.x509_ipextension = True + + +# default sec value used for address creation +# (value higher than 1, while totally conform to RFC 3971/3972, +# are not recommanded as they require a lot of processing power) +NDprotector.default_sec_value = 1 + +# If True, the programm automotaticlally assign addresses on the interfaces +# the program will also clean up and destroy unused addresses +# If set to False, the user must to the address assignement manually +NDprotector.assign_addresses = False + + +# Default key size for RSA keys +NDprotector.rsa_key_size = 1024 + +# Minimum (RSA) key size for ingoing messages +# when the key is bellow this value, the message is considered insecure +NDprotector.min_RSA_key_size = 384 + +# Maximum size of a (RSA) key +# key whose length exceed this value are ignored +NDprotector.max_RSA_key_size = 2048 + + +# Path to the default Public Key used for Stateless Address Autoconfiguration +# if None is provided, generate a new RSA Public Key for new addresses +NDprotector.default_publickey = "/root/git/NDprotector/publicKeyA.pem" +# NDprotector.default_publickey = "/etc/NDprotector/mypublickey.pem" + +# Path to the trust anchor +# For host it is [ TA1, TA2 ] +# For router, this is empty ( [] ) +NDprotector.trustanchors = [ "/etc/NDprotector/ta1.pem", + "/etc/NDprotector/ta2.pem" ] + +# Certification path +# Order matters (first certificate is the CA, then level1, etc. +# For routers it is [ [C1,C2,C3], ..., [C1',C2',C3'] ] +# For host, this is empty ( [] ) +# Ex: here, there is two paths +NDprotector.certification_path = ( [] ) + +# list of configured addresses +# (you must at least configure a Link-Local address +# for each interface you want this daemon to listen on) +NDprotector.configured_addresses = \ + [ \ + # Address(interface = "eth0", # can be omitted if only one outgoing interface is available + # address = "fe80::3062:ca0b:e098:91ec", # can not work, for demonstration purposes + # key = "test_key.pem", + # modifier = 36147483618661711768276696653219369138L, # should be set to the modifier value + # sec = 1, + # collcount = 0, + # ext = None ), + # Address(interface = "eth0", # can be omitted if only one outgoing interface is available + # address = "fe80::38d4:a8ac:f9c:8a52", # can not work, for demonstration purposes + # key = "test_key.pem", + # modifier = 36147483618661711768276696653219369138L, # should be set to the modifier value + # sec = 1, + # collcount = 1, + # ext = None ), + + # list of configured prefixes where autoconfiguration will be applied + # NDprotector.Address.Address(interface = "eth0", + Address(interface = "eth1", + prefix = "2001:db8:0:100::", + key = "/root/git/NDprotector/privateKeyA.pem", + modifier = 77) + # or fallback (when default_publickey is None) and the program will compute a new RSA key + # Address(interface = "eth0", # for example this one will build it's own key + # prefix = "2001::", + # sec=0) + + + # this configuration exemple applies to nodes willing to share an address + # each one as its Private key and the Public key of the others + # Multiple Public Keys are stored in the CGA PDS + # + # exemple of configuration for the first node + # Address(interface = "eth0", sec = 0, key = "/etc/NDprotector/first-key.pem", + # ext = PubKeyListtoCGAPKExtList("/etc/NDprotector/second-key.pem"), prefix = "fe80::" , modifier = 0, dad=False) + # + # keypos indicates the position of the Public Key bound to the Private Key the node will sign with + # Address(interface = "eth0", sec=0, key="/etc/NDprotector/second-key.pem", publickey="/etc/NDprotector/first-key.pem", + # ext = PubKeyListtoCGAPKExtList( [ "/etc/NDprotector/second-key.pem" ]), prefix= "fe80::" , keypos = 1, modifier = 0, dad= False) + ] +