From 439cf7e389d8a15232ea7675677b22288e1c6f4b Mon Sep 17 00:00:00 2001 From: DM Date: Sat, 1 Jul 2023 23:57:08 +0100 Subject: [PATCH] Pushing existing code --- README.md | 32 +- client | 119 ++++++++ dhcp/.DS_Store | Bin 0 -> 6148 bytes dhcp/midasd.py | 375 ++++++++++++++++++++++++ dhcp/packet_examples/.DS_Store | Bin 0 -> 6148 bytes dhcp/packet_examples/cisco_ios/Ack | 1 + dhcp/packet_examples/cisco_ios/Discover | 1 + dhcp/packet_examples/cisco_ios/Offer | 1 + dhcp/packet_examples/cisco_ios/Release | 1 + dhcp/packet_examples/cisco_ios/Request | 1 + dhcp/packet_examples/junos/Ack | 1 + dhcp/packet_examples/junos/Discover | 1 + dhcp/packet_examples/junos/Offer | 1 + dhcp/packet_examples/junos/Release | 1 + dhcp/packet_examples/junos/Request | 1 + dhcp/settings.yaml | 2 + logs/Cisco and Juniper.log | Bin 0 -> 9055 bytes logs/Cisco.log | Bin 0 -> 5793 bytes logs/Juniper.log | 57 ++++ logs/midas_2023-04-08_14:16:10.log | 11 + midas | 25 ++ provisioning/.DS_Store | Bin 0 -> 6148 bytes provisioning/midasp.py | 35 +++ provisioning/templates/cisco_ios.j2 | 199 +++++++++++++ provisioning/templates/junos.j2 | 280 ++++++++++++++++++ provisioning/vars/LAB-897VA.yaml | 3 + provisioning/vars/LAB-SRX300.yaml | 3 + topology/midast.py | 87 ++++++ topology/topology.png | Bin 0 -> 83525 bytes topology/topology.yaml | 54 ++++ utils/log.py | 63 ++++ 31 files changed, 1354 insertions(+), 1 deletion(-) create mode 100755 client create mode 100644 dhcp/.DS_Store create mode 100644 dhcp/midasd.py create mode 100644 dhcp/packet_examples/.DS_Store create mode 100644 dhcp/packet_examples/cisco_ios/Ack create mode 100644 dhcp/packet_examples/cisco_ios/Discover create mode 100644 dhcp/packet_examples/cisco_ios/Offer create mode 100644 dhcp/packet_examples/cisco_ios/Release create mode 100644 dhcp/packet_examples/cisco_ios/Request create mode 100644 dhcp/packet_examples/junos/Ack create mode 100644 dhcp/packet_examples/junos/Discover create mode 100644 dhcp/packet_examples/junos/Offer create mode 100644 dhcp/packet_examples/junos/Release create mode 100644 dhcp/packet_examples/junos/Request create mode 100644 dhcp/settings.yaml create mode 100644 logs/Cisco and Juniper.log create mode 100644 logs/Cisco.log create mode 100644 logs/Juniper.log create mode 100644 logs/midas_2023-04-08_14:16:10.log create mode 100755 midas create mode 100644 provisioning/.DS_Store create mode 100644 provisioning/midasp.py create mode 100644 provisioning/templates/cisco_ios.j2 create mode 100644 provisioning/templates/junos.j2 create mode 100644 provisioning/vars/LAB-897VA.yaml create mode 100644 provisioning/vars/LAB-SRX300.yaml create mode 100644 topology/midast.py create mode 100644 topology/topology.png create mode 100644 topology/topology.yaml create mode 100644 utils/log.py diff --git a/README.md b/README.md index feec9d0..7e0f8cc 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,32 @@ -# Midas +# midas +A topology aware zero touch provisioning (ZTP) tool for network devices. +##Β Supported operating systems: + - Juniper Junos + - Cisco IOS + +## Modules +### midasd +The socket DHCP portion of midas. + +### midast +The networkx topology portion of midas. + +### midasp +The YAML/Jinja provisioning portion of midas. + +## Installation / usage +``` + $ cd midas + $ chmod +x midas + $ sudo ./midas +``` + +## Tips + - When building your topology.yaml the visualisation builds top to bottom, arrange your nodes and edges in such a way that they correspond to the correct side of the graph, for neatness. + +## Dependencies + - networkx + - pygraphviz + - yaml + - jinja2 diff --git a/client b/client new file mode 100755 index 0000000..251594d --- /dev/null +++ b/client @@ -0,0 +1,119 @@ +#!/usr/bin/env python3 + +import socket, sys + +MAX_BYTES = 1024 +ServerPort = 67 +ClientPort = 68 + +class DHCPClient(): + def client(self): + print("DHCP client is starting...\n") + dest = ('', ServerPort) + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) + s.bind(('0.0.0.0', ServerPort)) + + print("Sending Juniper DHCP discovery.") + packet = DHCPClient.mock_juniper_packet() + s.sendto(packet, dest) + + def mock_juniper_packet(): + return b'\x01\x01\x06\x01O\x00\xe0\xa1\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x94\xbf\x94\xb3n\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00c\x82Sc5\x01\x013\x04\x00\x01Q\x80\x0c\nLAB-SRX300\xff\x00' + + def craft_discover_packet(): + OP = bytes([0x01]) + HTYPE = bytes([0x01]) + HLEN = bytes([0x06]) + HOPS = bytes([0x00]) + XID = bytes([0x39, 0x03, 0xF3, 0x26]) + SECS = bytes([0x00, 0x00]) + FLAGS = bytes([0x00, 0x00]) + CIADDR = bytes([0x00, 0x00, 0x00, 0x00]) + YIADDR = bytes([0x00, 0x00, 0x00, 0x00]) + SIADDR = bytes([0x00, 0x00, 0x00, 0x00]) + GIADDR = bytes([0x00, 0x00, 0x00, 0x00]) + CHADDR1 = bytes([0x00, 0x05, 0x3C, 0x04]) + CHADDR2 = bytes([0x8D, 0x59, 0x00, 0x00]) + CHADDR3 = bytes([0x00, 0x00, 0x00, 0x00]) + CHADDR4 = bytes([0x00, 0x00, 0x00, 0x00]) + CHADDR5 = bytes(192) + Magiccookie = bytes([0x63, 0x82, 0x53, 0x63]) + DHCPOptions1 = bytes([53, 1, 1]) #DHCP Discover (value = 1) + DHCPOptions2 = bytes([50, 4, 0xC0, 0xA8, 0x01, 0x64]) + + packet = ( + OP + + HTYPE + + HLEN + + HOPS + + XID + + SECS + + FLAGS + + CIADDR + + YIADDR + + SIADDR + + GIADDR + + CHADDR1 + + CHADDR2 + + CHADDR3 + + CHADDR4 + + CHADDR5 + + Magiccookie + + DHCPOptions1 + + DHCPOptions2 + ) + + return packet + + def craft_request_packet(): + OP = bytes([0x01]) + HTYPE = bytes([0x01]) + HLEN = bytes([0x06]) + HOPS = bytes([0x00]) + XID = bytes([0x39, 0x03, 0xF3, 0x26]) + SECS = bytes([0x00, 0x00]) + FLAGS = bytes([0x00, 0x00]) + CIADDR = bytes([0x00, 0x00, 0x00, 0x00]) + YIADDR = bytes([0x00, 0x00, 0x00, 0x00]) + SIADDR = bytes([0x00, 0x00, 0x00, 0x00]) + GIADDR = bytes([0x00, 0x00, 0x00, 0x00]) + CHADDR1 = bytes([0x00, 0x0C, 0x29, 0xDD]) + CHADDR2 = bytes([0x5C, 0xA7, 0x00, 0x00]) + CHADDR3 = bytes([0x00, 0x00, 0x00, 0x00]) + CHADDR4 = bytes([0x00, 0x00, 0x00, 0x00]) + CHADDR5 = bytes(192) + Magiccookie = bytes([0x63, 0x82, 0x53, 0x63]) + DHCPOptions1 = bytes([53, 1, 3]) #DHCP Discover (value = 3) + DHCPOptions2 = bytes([50, 4, 0xC0, 0xA8, 0x01, 0x64]) + DHCPOptions3 = bytes([54, 4, 0xC0, 0xA8, 0x01, 0x01]) + + packet = ( + OP + + HTYPE + + HLEN + + HOPS + + XID + + SECS + + FLAGS + + CIADDR + + YIADDR + + SIADDR + + GIADDR + + CHADDR1 + + CHADDR2 + + CHADDR3 + + CHADDR4 + + CHADDR5 + + Magiccookie + + DHCPOptions1 + + DHCPOptions2 + + DHCPOptions3 + ) + + return packet + +if __name__ == '__main__': + dhcp_client = DHCPClient() + dhcp_client.client() \ No newline at end of file diff --git a/dhcp/.DS_Store b/dhcp/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..c279a360af04a079fce131e1b93e0d5ba8e3903e GIT binary patch literal 6148 zcmeHKOHRW;47H()N-XG-9dm`=Ag$69^Z-E93M3LG5+HS%J8&U3thf~Kjm;+_0>lC# zWJ@#8?BrI?WG8#M7+L5qnwa~s zbjY`oYh?bGe*@HduMjs3W149N5Z8+oo zzrrswTI3HyViXJn1OJQxos{cxiI4KT^~2}!u1#p?XcYSOR3Oj?j{ppKj-2F4n@`l? YS2*^DT!r==4vdFDCM3FG;1?Kp21)TaV*mgE literal 0 HcmV?d00001 diff --git a/dhcp/midasd.py b/dhcp/midasd.py new file mode 100644 index 0000000..d921f74 --- /dev/null +++ b/dhcp/midasd.py @@ -0,0 +1,375 @@ +import socket +import struct + +from dataclasses import dataclass +from datetime import datetime +from utils.log import log + +# Reference docs +# https://docs.microsoft.com/en-us/windows-server/troubleshoot/dynamic-host-configuration-protocol-basics + +FORMAT_STRING = ( + "!" # Specifies network byte order + "s" # OP: 1 byte + "s" # HTYPE: 1 byte + "s" # HLEN: 1 byte + "s" # HOPS: 1 byte + "4s" # XID: 4 bytes + "2s" # SECS: 2 bytes + "2s" # FLAGS: 2 bytes + "4s" # CIADDR: 4 bytes + "4s" # YIADDR: 4 bytes + "4s" # SIADDR: 4 bytes + "4s" # GIADDR: 4 bytes + "6s" # CHADDR: 6 bytes + "10s" # CHADDR: 10 bytes + "192s" # OVERFLOW: 192 bytes + "4s" # MAGICCOOKIE: 4 bytes +) # 240 bytes total + +OPTION_DESCRIPTIONS = { + 1: 'Subnet Mask', + 3: 'Default Gateway', + 12: 'Hostname', + 43: 'Vendor Specific Information', + 50: 'Requested IP Address', + 51: 'IP Address Lease Time', + 53: 'DHCP Message Type', + 54: 'DHCP Server IP Address', + 55: 'Parameter Request List', + 57: 'DHCP Maximum Message Size', + 60: 'Class Identifier', + 61: 'Client Identifier', + 67: 'Boot File Name', + 150: 'TFTP Server IP Address', +} + +@dataclass() +class DHCPPacket: + # Based on DHCP Discovery packet header from: https://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol + #Β Packet header field byte sizing: https://support.huawei.com/enterprise/en/doc/EDOC1100058931/25cd2dfc/dhcp-messages + # DHCP packet types: https://www.omnisecu.com/tcpip/dhcp-dynamic-host-configuration-protocol-message-options.php + + OP: bytes + HTYPE: bytes + HLEN: bytes + HOPS: bytes + XID: bytes + SECS: bytes + FLAGS: bytes + CIADDR: bytes # Client IP address + YIADDR: bytes # DHCP Server IP address + SIADDR: bytes # Server IP address + GIADDR: bytes # Gateway IP address + CHADDR: bytes # Client hardware address + CHADDR_PADDING: bytes + OVERFLOW: bytes # Overflow space for BOOTP legacy + MCOOKIE: bytes + OPTIONS: bytes + END: bytes = bytes([0xFF]) + +class Packet(): + @staticmethod + def construct_tlv(_type, value): + ''' + Summary: + Constructs a DHCP TLV - Type | Length | Value. + + Takes: + _type: typically the DHCP option number + value: value of the TLV, can be text or integer + + Returns: + A bytes object TLV + ''' + if isinstance(value, str): + value = str.encode(value) + return bytes([_type, len(value)]) + value + + @staticmethod + def construct_junos_suboptions(config_filename): + ''' + Summary: + Constructs Junos specific suboptions required for Zero Touch Provisioning to work. + + 0: firmware file + 1: configuration file + 3: transfer mode + + Additional options are available, see: + https://www.juniper.net/documentation/us/en/software/junos/junos-install-upgrade/topics/topic-map/zero-touch-provision.html#id-zero-touch-provisioning-using-dhcp-options + + Takes: + config_filename: filename and path of the configuration file to be retrieved and applied to the client + + Returns: + A bytes object consisting of multiple TLVs + ''' + return Packet.construct_tlv( + _type=43, + value=b''.join( + [ + #Packet.construct_tlv(0, '/path/to/junosimage.tgz'), # Image filename and path, for upgrading firmware + Packet.construct_tlv(1, config_filename), # Configuration filename and path + Packet.construct_tlv(3, 'tftp'), # Transfer mode + ] + ) + ) + + @staticmethod + def construct_reply_packet(reference_packet, _type, source_ip, topology): + ''' + Summary: + Constructs a DHCP packet of type Offer or Ack, modelled from a received packet with some options changed/added. + Ack packets are the exact same as Offer packets, just with the packet type TLV adjusted. + Different options are changed/added based on client operating system extracted from the networkx Graph object. + + Takes: + reference_packet: received DHCP packet to model the reply packet from + _type: type of packet to construct, Offer or Ack + source_ip: IP address that the DHCP packet was received from + topology: networkx Graph object detailing the network topology + + Returns: + DHCP packet of type Offer or Ack + ''' + packet_data = struct.unpack(FORMAT_STRING, reference_packet[:240]) + reply_packet_object = DHCPPacket(*packet_data, OPTIONS=reference_packet[240:len(reference_packet)]) + + giaddr, yiaddr = Packet.process_giaddr(source_ip) + client_device_name, client_device_os = topology.get_client_calling_for_ip(source_ip, _type) + + reply_packet_object.OP = bytes([0x02]) + reply_packet_object.YIADDR = bytes([yiaddr[0], yiaddr[1], yiaddr[2], yiaddr[3]]) # Client IP + reply_packet_object.SIADDR = bytes([172, 16, 0, 200]) # Server IP: 172.16.0.200 + + if _type == 'offer': + packet_type = bytes([53, 1, 2]) # DHCP offer packet + elif _type == 'ack': + packet_type = bytes([53, 1, 5]) # DHCP ack packet + + if client_device_os == 'junos': + reply_packet_object.OPTIONS = b"".join( + [ + packet_type, + bytes([54, 4, 172, 16, 0, 200]), # Server identifier: 172.16.0.200 + bytes([51, 4, 0x00, 0x01, 0x51, 0x80]), # Lease time: 86400 + bytes([1, 4, 255, 255, 255, 254]), # Subnet mask: 255.255.255.254 + bytes([3, 4, giaddr[0], giaddr[1], giaddr[2], giaddr[3]]), # Default gateway + bytes([150, 4, 172, 16, 0, 200]), # TFTP server: 172.16.0.200 + Packet.construct_junos_suboptions(f'/configs/{client_device_name}.conf'), # Juniper specific suboptions + ] + ) + elif client_device_os == 'cisco_ios': + reply_packet_object.OPTIONS = b"".join( + [ + packet_type, + bytes([54, 4, 172, 16, 0, 200]), # Server identifier: 172.16.0.200 + bytes([51, 4, 0x00, 0x01, 0x51, 0x80]), # Lease time: 86400 + bytes([1, 4, 255, 255, 255, 254]), # Subnet mask: 255.255.255.254 + bytes([3, 4, giaddr[0], giaddr[1], giaddr[2], giaddr[3]]), # Default gateway + bytes([150, 4, 172, 16, 0, 200]), # TFTP server: 172.16.0.200 + Packet.construct_tlv(67, f'/configs/{client_device_name}.conf'), # Cisco specific bootfile + ] + ) + + reply_packet_list = [] + + for field, byte_value in reply_packet_object.__dict__.items(): + reply_packet_list.append(byte_value) + + reply_packet = b''.join(value for value in reply_packet_list) + + return reply_packet + + @staticmethod + def examine_packet(raw_packet): + ''' + Summary: + Examines a DHCP packet and splits it into packet data and DHCP options. + It's expected that DHCP packet length after 240 will be DHCP options. + + Takes: + raw_packet: raw DHCP packet to examine + + Returns: + packet: DHCP packet data minus options + options: DHCP packet options + options_descriptions: DHCP packet options descriptions + ''' + packet_data = struct.unpack(FORMAT_STRING, raw_packet[:240]) + packet = DHCPPacket(*packet_data, OPTIONS=raw_packet[240:len(raw_packet)]) + + options, options_descriptions = Packet.extract_options(packet.OPTIONS) + + return packet, options, options_descriptions + + @staticmethod + def extract_options(packet_data): + ''' + Summary: + Extracts DHCP options from a given raw DHCP packet. + + Takes: + packet_data: DHCP packet as raw bytes + + Returns: + option_dict: dictionairy of DHCP options extracted from a packet + option_description_dict: dictionairy of DHCP option descriptions that were found in a packet + ''' + option_dict = {} + option_description_dict = {} + + index = 0 + while index < len(packet_data): + option_number = packet_data[index] + if option_number == 255: + break + option_length = packet_data[index + 1] + option_value, option_description = Packet.make_human_readable(option_number, packet_data[index + 2 : index + 2 + option_length]) + + option_dict[option_number] = option_value + option_description_dict[option_number] = option_description + index += 2 + option_length + + + return option_dict, option_description_dict + + @staticmethod + def make_human_readable(option_number, raw_value): + ''' + Summary: + Takes a raw DHCP option and makes it human readable. + + DHCP options: + https://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xhtml + + Takes: + option_number: DHCP option number + raw_value: raw bytes value received with the option number + + Returns: + option_value: human readable value of the option number + option_description: description of the option + ''' + if option_number in [1, 3, 50, 54, 150]: + octets = list(raw_value) + option_value = f'{octets[0]}.{octets[1]}.{octets[2]}.{octets[3]}' + elif option_number in [50, 55]: + option_value = list(raw_value) + elif option_number == 53: + option_value = list(raw_value)[0] + elif option_number in [60, 12, 61, 67, 43]: + option_value = raw_value.decode() + elif option_number in [51, 57]: + option_value = int.from_bytes(raw_value, byteorder='big') + else: + option_value = raw_value + + if option_number in OPTION_DESCRIPTIONS: + option_description = OPTION_DESCRIPTIONS[option_number] + else: + option_description = 'Unknown' + + return option_value, option_description + + @staticmethod + def process_giaddr(giaddr): + ''' + Summary: + Calculates IP address to offer the client and turns string giaddr into a list of 4 integers. + + Takes: + giaddr: gateway or relay IP that the DHCP packet was received from (string) + + Returns: + giaddr: gateway or relay IP that the DHCP packet was received from (list of 4 integers) + yiaddr: IP to offer the client (list of 4 integers) + ''' + octets = giaddr.split('.') + last_octet = int(octets[3]) + giaddr = [int(octets[0]), int(octets[1]), int(octets[2]), int(octets[3])] + + if last_octet % 2 == 0: + yiaddr = [int(octets[0]), int(octets[1]), int(octets[2]), int(last_octet + 1)] + else: + yiaddr = [int(octets[0]), int(octets[1]), int(octets[2]), int(last_octet - 1)] + + return giaddr, yiaddr + +class DHCPServer(): + MAX_BYTES = 1024 + SERVER_IP = '172.16.0.200' + PORT = 67 + + def create_socket(self): + ''' + Summary: + Creates a socket to allow the DHCP server to send and receive data to/from. + + Socket characteristics: + AF_INET: type of socket, address format (host, port) + SOCK_DGRAM: socket protocol, UDP + SOL_SOCKET (socket options): + SO_REUSEADDR: socket address and port can be reused + SO_BROADCAST: datagrams can be broadcast from this socket + + Socket bound to: + SERVER_IP + PORT + ''' + _socket=socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + _socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1) + _socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST,1) + _socket.bind((self.SERVER_IP, self.PORT)) + + return _socket + + def run(self, topology): + ''' + Summary: + Runs the DHCP server allowing packets to be sent and received through the created socket. + + Takes: + topology: networkx Graph object detailing the network topology + ''' + log('DHCP server is starting...', 'info') + socket = self.create_socket() + + while True: + try: + log('Waiting for DHCP packets...', 'info') + received_packet, (source_address, source_port) = socket.recvfrom(self.MAX_BYTES) + log(f'DHCP packet received from IP {source_address} on port {source_port}', 'info') + packet_data, packet_options, option_descriptions = Packet.examine_packet(received_packet) + log(f'Received packet options:', 'info') + for option_number, option_value in packet_options.items(): + log(f'{option_number} [{option_descriptions[option_number]}]: {option_value}', 'info') + + if packet_options[53] == 1: + log('Received DHCP discover packet', 'info') + offer_packet = Packet.construct_reply_packet(received_packet, 'offer', source_address, topology) + log('Constructing DHCP offer packet...', 'info') + packet_data, packet_options, option_descriptions = Packet.examine_packet(offer_packet) + log(f'Offer packet options:', 'info') + for option_number, option_value in packet_options.items(): + log(f'{option_number} [{option_descriptions[option_number]}]: {option_value}', 'info') + socket.sendto(offer_packet, (source_address, self.PORT)) + + elif packet_options[53] == 3: + log('Received DHCP request packet', 'info') + ack_packet = Packet.construct_reply_packet(offer_packet, 'ack', source_address, topology) + log('Constructing DHCP ack packet...', 'info') + packet_data, packet_options, option_descriptions = Packet.examine_packet(ack_packet) + log(f'Ack packet options:', 'info') + for option_number, option_value in packet_options.items(): + log(f'{option_number} [{option_descriptions[option_number]}]: {option_value}', 'info') + socket.sendto(ack_packet, (source_address, self.PORT)) + + elif packet_options[53] == 7: + log('Received DHCP release packet', 'info') + log('See you around, partner\U0001F920', 'info') + + except KeyboardInterrupt: + log('Exiting...', 'info') + break diff --git a/dhcp/packet_examples/.DS_Store b/dhcp/packet_examples/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..1036a0f1733d8336fec43d08888cb01f794adaf2 GIT binary patch literal 6148 zcmeHKOKQVF43&};61vGEi|#sC$PL`!?h83UOC0EjI1>oj`%Jk*S3N`T(x;IKV{AiL zr34A2H`Yiq<2S*Ih=^CG?UHCtL{q5XXa>_GGB4VZk$Gg2(;AVU>761Scdwmjcl<{N z+dR`U7Xvq1Lw)|>)3maETU(BIfIKc;0!ne*Tev7w#f8W(XBJ!3^)T92ITt?pn`>A zqnJJ&FsTIqPT)?0vGfv>6ATN(MiDa*)>NRTvb7kj>F@`OD-0V&O((YIgKcNF4u#Y1 zSU;q2;zH4_GvExg85ry1Ta7% z4lQqpvuz$Z0f^ipRq{Y5B&kMC`iIRr7WsWkJ`5G-)1cllGDup?7c*MZ)@a|hmDT(U z3|`ZGLQA%uw8*E~ebvt3(DFUEH568GSd|Zl^|W3bN{qwvqvL~k7`;0huy@*12~>KX zQ!(O=uYd7udlR6_3h0^Hjbl_>sYS3J;nV{~|?B7DZW; zFv3(zSnql3IPCQbNPIZZ0S$mR?q4nd^tI1b(*2MB*tR5dGM2xY1hDlxStUSc5{ChzCHP`dC!fvk;hqB6r|~AZsWE1D?X6!0RU_4|5AJ55AaTzjKFKpB*0q| z^efx|8%oD65Ma$V(%{l7cZHIW%aulbjV*BU-E0=}|~=X|`nskx*D*A-r+I zhd^>Rfl&||EG@ywze(9ld61?s(?ryr4qPWl4qj(5u1krliEe$sy)Kr}E)20)U+jEk zZZXhXcvBHAhP4#vD5Ax{KUdww_q4VmGsT<1Eb(NPz%;)`0AK$i*Tx5lg6q9e1mBk} z1G&IpWwa{x)`6U#L)$r1+k7*R^OS$h^qE{f54R89`?t*G5(lq+rige~}ckh?Pz`=OGB` zxF~9Jn$0MAD~_;hL%8_{MMC0j?CkU*HjS5YdbYH+wKjFVlhbQsfJxrkq$zlb@X@Zn z(?@vdeIcihw2J9FfypJ~%3&wS&11faJX}0zyx!DveC&Z-w?jJ^j%>$@)me%&wM#qjo(F$ztd+2R+kpsYR<_nn zO!C%lzh%58$G%=G@vtoS?gd=d}Ft>GMB$u$Bn>Nzu1#?dtmlq{v{g78-W8OeU}{7LK>RixgQr_W0gTEAr9K zv@an=$Wy!3?k+`!f`^=jY}s13NRdHc!n;Y4A>gX&=8B=^Xjc6KQe?13cD75Ah2x>4 zixgQr_KAI@2zZXx(BO@|?nFT13>Q~ycPTOy%vMJ!G6*cBZc+pU&C_<5qUVn6$O=8Y zj9sMYm>cv87HgqlXR{P#xb_)NUn#BdaMAB7?NvP9DRhJ}eonlKH`1})w5ztgiAVwk?Hsu))a)|&zHnW&b zu8|xjC&&>}-J&R}$d*J)fgwW@P_L_Azj{>^vl;K%ZqE+DafhxuWZZK3DLh=gzr1;b zf4~0rH~b3ci+DDUlPMHwmd?`YOTXX$mbHbRdL;C|jDRGZiy>TxPlmt&34D`>A9o+= zT8`tA$m+;3LL?T*@L7x@l*20hld6s^nYQGkP<<2XlOhA6be_#bAq>%V2LD0^??f^d zxvD2hlSw?4?F{0<9YMgd0@e+0boUdt z?QMW{zEy%3x+2JHC2r#;2-XSx`3J_od3$jSQsmDfhggCv!n{DHj0^=eay7t@VXOjR zlIBaWEQ~&gqK)HV$Zd-aY9*{wSVmzTk%*OICV4uCt6OmFzWQU3CXl6h0e(QKE@5k$ z(Xe+bs1iEOia1T=&=6j00UfTSpvieBqztD5?q4$TI0UCX{?sPKddT!LKKvBV7jszQ zjN;E4huO9PswNtpitoU~#Vi&{0as)EA5UVDV=CW7v5eAQ6ghrB5Ny(Cju-a6j|T?a znz%Ktg9p7$Wue>w;qKB!A#y`3W!FQmxearS#2D>yHIGzQr zYXQek0e)oo7T-IbjohJ=dovn>PWk6Jm4+BvIrg_K@pqt{iIQsR_c*85 zeYjS=fjpP$bpQFo-3IahvqeLDkMvqeJy>1k!ePW}o*Np<765D+g_>|#;MuAU9 zrGM}!PzW1Tbs7b@=GpjoyNR&RDB$abzh#|Ou#FX`YOkH6K!-QB6m@y(X=t^mmkWQ( z^M;P6RUII0jYlWj5$1uyZEgo$y-cG}nO0<%UN+N9n90jD1l8t92zW^s5a#J38C&RL zd69_xpD({R%|ruG#=9wzSx)02?FdR#utsurD^Z2hx=be9rbK4p-c0)I5G5)++8M`C zqQa##b$+Vz6bc?=MgC#O2$ORw?g2I+9e)TpSjfz`v65f1d*|IHBAr#F> zvu{109s8~2@e)zkz8yD2Ya&`g85b)I6T*Jhku1!@&LC@4bWgAJKrhwfDB2DGkpbSj zmF!tfE%o+qvpY0(tG9ghJsnjyWx21KJ-ocm;p_7AW-jvh%gFYrU-=r#Q9 z>ig)U@0+=oF1Kzb@1XM!>qf5Y;tV(g&cLZMfS%2=JXiG58E^)ifsO(GK13*EGR%td z>A)aI0AK;L2tA6y ge-0/0/1 LAB-SRX300" + switchport access vlan 20 + no ip address +! +interface GigabitEthernet2 + description "{{ hostname }} gigabitEthernet2 <--> ge-0/0/2 LAB-SRX300" + switchport access vlan 30 + no ip address +! +interface GigabitEthernet3 + no ip address +! +interface GigabitEthernet4 + no ip address +! +interface GigabitEthernet5 + no ip address +! +interface GigabitEthernet6 + no ip address +! +interface GigabitEthernet7 + no ip address +! +interface GigabitEthernet8 + description "{{ hostname }} gigabitEthernet2 <--> gigabitEthernet1 LAB-RELAY" + ip address 10.0.0.3 255.255.255.254 + duplex auto + speed auto + no shut +! +interface Vlan1 + no ip address +! +interface Vlan10 + ip address {{ management_ip }} 255.255.255.0 +! +interface Vlan20 + ip address 10.0.0.5 255.255.255.254 + ip ospf authentication message-digest + ip ospf message-digest-key 1 md5 Juniper1 + ip ospf network point-to-point + ip ospf 1 area 0 +! +interface Vlan30 + ip address 10.0.0.7 255.255.255.254 + ip ospf authentication message-digest + ip ospf message-digest-key 1 md5 Juniper1 + ip ospf network point-to-point + ip ospf 1 area 0 +! +router ospf 1 + router-id {{ loopback_ip }} + passive-interface Loopback0 +! +ip forward-protocol nd +no ip http server +no ip http secure-server +! +! +! +! +! +control-plane +! +! +mgcp behavior rsip-range tgcp-only +mgcp behavior comedia-role none +mgcp behavior comedia-check-media-src disable +mgcp behavior comedia-sdp-force disable +! +mgcp profile default +! +! +! +! +! +! +! +line con 0 + login local + no modem enable +line aux 0 +line vty 0 4 + login local + transport input ssh telnet +line vty 5 15 + login local + transport input ssh telnet +! +scheduler allocate 20000 1000 +! +! +! +event manager applet crypto-key + event timer cron cron-entry "@reboot" + action 1.0 cli command "enable" + action 1.1 cli command "config t" + action 1.2 cli command "file prompt quiet" + action 1.3 cli command "crypto key generate rsa modulus 2048" + action 1.4 cli command "no event manager applet crypto-key" + action 1.5 cli command "do wr mem" +! +end \ No newline at end of file diff --git a/provisioning/templates/junos.j2 b/provisioning/templates/junos.j2 new file mode 100644 index 0000000..d61e95c --- /dev/null +++ b/provisioning/templates/junos.j2 @@ -0,0 +1,280 @@ +system { + host-name {{ hostname }}; + root-authentication { + plain-text-password-value "Juniper1"; + } + login { + user datatech { + uid 2001; + class read-only; + authentication { + plain-text-password-value "Juniper1"; + } + } + user neteng { + uid 2000; + class super-user; + authentication { + plain-text-password-value "Juniper1"; + } + } + } + services { + ssh { + root-login allow; + } + netconf { + ssh; + } + } + tacplus-server { + 10.10.10.10 secret "Juniper1"; ## SECRET-DATA + 11.11.11.11 secret "Juniper1"; ## SECRET-DATA + } + syslog { + archive size 100k files 3; + user * { + any emergency; + } + file messages { + any notice; + authorization info; + } + file interactive-commands { + interactive-commands any; + } + } +} +security { + authentication-key-chains { + key-chain BGP-KC-LHR14-R101-NCL62-R2 { + key 1 { + secret "$9$Vyws4JZjq.57-YoZU.m"; ## SECRET-DATA + start-time "2022-7-1.00:00:00 +0000"; + } + key 2 { + secret "$9$0Yfd1clVbs2oJdV69pOSybs2aUj5TF9AuiHP5FnpuNdVbs24aZ"; ## SECRET-DATA + start-time "2023-4-3.15:13:45 +0000"; + } + } + key-chain BGP-KC-NCL62-R2-SC-FW2 { + key 1 { + secret "$9$8x0Xxdws4ZGiKM7Vs2GU"; ## SECRET-DATA + start-time "2022-7-1.00:00:00 +0000"; + } + key 2 { + secret "$9$B74EeW24JikmlKDH.m3n1RhyvWxNV24JikSreKLX7-VYGjzF6"; ## SECRET-DATA + start-time "2023-4-3.15:42:04 +0000"; + } + } + key-chain BRMA-KC-LHR30-R101-NCL60-R1 { + key 1 { + apply-flags omit; + secret "$9$1HCREyeK87NbuOhrKMN-"; ## SECRET-DATA + key-name 4953bd1120ffcc31e1d044870c52d67b215c04f0c2ba1fccc970fa16d18a6b6f; + start-time "2023-3-31.14:22:24 +0000"; + } + } + } + forwarding-options { + family { + mpls { + mode packet-based; + } + } + } + macsec { + connectivity-association BRMA-WAN-LHR30-R101-NCL60-R1 { + security-mode static-cak; + mka { + transmit-interval 6000; + sak-rekey-interval 60; + } + pre-shared-key-chain BRMA-KC-LHR30-R101-NCL60-R1; + } + interfaces { + ge-0/0/7 { + connectivity-association BRMA-WAN-LHR30-R101-NCL60-R1; + } + } + } +} +interfaces { + ge-0/0/0 { + description "{{ hostname }} ge-0/0/0 <--> gigabitEthernet0 LAB-RELAY"; + unit 0 { + family inet { + address 10.0.0.1/31; + } + } + } + ge-0/0/1 { + description "{{ hostname }} ge-0/0/1 <--> gigabitEthernet1 LAB-897VA"; + unit 0 { + family inet { + address 10.0.0.4/31; + } + } + } + ge-0/0/2 { + description "{{ hostname }} ge-0/0/2 <--> gigabitEthernet2 LAB-897VA"; + unit 0 { + family inet { + address 10.0.0.6/31; + } + } + } + ge-0/0/5 { + description "Management Network"; + unit 0 { + family inet { + address {{ management_ip }}/24; + } + } + } + lo0 { + unit 0 { + family inet { + address {{ loopback_ip }}/32; + } + } + } +} +snmp { + v3 { + usm { + local-engine { + user snmp-user { + authentication-sha { + authentication-password "Juniper1"; ## SECRET-DATA + } + privacy-aes128 { + privacy-password "Juniper1"; ## SECRET-DATA + } + } + } + } + } +} +policy-options { + policy-statement BN-10-RMA-EXPORT { + term BGP { + from protocol bgp; + then { + community add BN-10-RMA-TARGET; + accept; + } + } + term OSPF { + from protocol ospf; + then { + community add BN-10-RMA-TARGET; + accept; + } + } + term AGGREGATE { + from protocol aggregate; + then { + community add BN-10-RMA-TARGET; + accept; + } + } + term REJECT-ALL { + then reject; + } + } + policy-statement BN-10-RMA-IMPORT { + term BGP { + from { + protocol bgp; + community BN-10-RMA-TARGET; + } + then accept; + } + term REJECT-ALL { + then reject; + } + } + community BN-10-RMA-TARGET members target:65100:1000; +} +access { + radius-server { + 10.10.10.10 secret "Juniper1"; ## SECRET-DATA + 11.11.11.11 secret "Juniper1"; ## SECRET-DATA + } +} +routing-instances { + BN-10-RMA { + protocols { + bgp { + group SEC-NET-FW { + type external; + description "eBGP to Security Network Firewall"; + local-address 192.168.32.78; + hold-time 30; + peer-as 64900; + neighbor 192.168.32.79 { + description ncl62-sc-fw2; + authentication-key-chain BGP-KC-NCL62-R2-SC-FW2; + } + } + traceoptions { + file bgp.log; + flag state; + } + log-updown; + } + } + instance-type vrf; + route-distinguisher 65100:1000; + vrf-import BN-10-RMA-IMPORT; + vrf-export BN-10-RMA-EXPORT; + vrf-table-label; + } +} +protocols { + ospf { + area 0.0.0.0 { + interface ge-0/0/1.0 { + interface-type p2p; + authentication { + md5 1 key "Juniper1"; ## SECRET-DATA + } + } + interface ge-0/0/2.0 { + interface-type p2p; + authentication { + md5 1 key "Juniper1"; ## SECRET-DATA + } + } + interface lo0.0 { + passive; + } + } + } + bgp { + group IBGP-FULL-MESH { + type internal; + description "IBGP Full Mesh"; + hold-time 30; + multipath { + multiple-as; + } + neighbor 172.17.0.0 { + description lhr14-bn-com-agg-r101; + authentication-key-chain BGP-KC-LHR14-R101-NCL62-R2; + } + } + traceoptions { + file bgp.log; + flag state; + } + log-updown; + } + lldp { + interface all; + } +} +routing-options { + autonomous-system 65100; +} \ No newline at end of file diff --git a/provisioning/vars/LAB-897VA.yaml b/provisioning/vars/LAB-897VA.yaml new file mode 100644 index 0000000..6dd7661 --- /dev/null +++ b/provisioning/vars/LAB-897VA.yaml @@ -0,0 +1,3 @@ +hostname: LAB-897VA +management_ip: 172.16.0.3 +loopback_ip: 2.2.2.2 \ No newline at end of file diff --git a/provisioning/vars/LAB-SRX300.yaml b/provisioning/vars/LAB-SRX300.yaml new file mode 100644 index 0000000..b37f005 --- /dev/null +++ b/provisioning/vars/LAB-SRX300.yaml @@ -0,0 +1,3 @@ +hostname: LAB-SRX300 +management_ip: 172.16.0.1 +loopback_ip: 1.1.1.1 \ No newline at end of file diff --git a/topology/midast.py b/topology/midast.py new file mode 100644 index 0000000..0761206 --- /dev/null +++ b/topology/midast.py @@ -0,0 +1,87 @@ +import networkx as nx +import yaml + +from networkx.drawing.nx_agraph import to_agraph +from utils.log import log + +class Topology(): + def __init__(self): + self.G = nx.MultiGraph() + + def build(self): + ''' + Summary: + Builds a network topology from the topology.yaml file into memory, stored in a networkx Graph object. + Once the networkx Graph object has been built, it's drawn and saved as topology.png. + + Nodes: network devices + Node attributes: dict of attributes assigned to a specific node + Edges: links between network devices + Edge attributes: dict of attributes assigned to a specific edge + ''' + log('Building topology...', 'info') + + topology_data = yaml.load(open('topology/topology.yaml'), Loader=yaml.SafeLoader) + + for topology_name, topology_vars in topology_data.items(): + log(f'Topology name: {topology_name}', 'info') + + for node, node_attributes in topology_vars['nodes'].items(): + self.G.add_node(node) + self.G.nodes[node]['shape'] = 'box' + for attribute_name, attribute_value in node_attributes.items(): + self.G.nodes[node][attribute_name] = attribute_value + + for edge_number, edge_attributes in topology_vars['edges'].items(): + self.G.add_edge(edge_attributes['a_end'], edge_attributes['b_end']) + nx.set_edge_attributes( + self.G, + { + (edge_attributes['a_end'], + edge_attributes['b_end'], + edge_attributes['edge_index']): edge_attributes + } + ) + + for node1, node2, edge_attributes in self.G.edges(data=True): + edge_attributes['label'] = f""" + {edge_attributes['a_end']} ({self.G.nodes[edge_attributes['a_end']]['os']}) + {edge_attributes['a_end_ip']}, {edge_attributes['a_end_interface']}\n + {edge_attributes['b_end']} ({self.G.nodes[edge_attributes['b_end']]['os']}) + {edge_attributes['b_end_ip']}, {edge_attributes['b_end_interface']} + """ + + log('Drawing topology...', 'info') + vis = to_agraph(self.G) + vis.layout('dot') + vis_path = 'topology/topology.png' + vis.draw(vis_path) + + log(f'Topology drawn, saved as: {vis_path}', 'info') + log('Topology build complete', 'info') + + def get_client_calling_for_ip(self, giaddr, _type): + ''' + Summary: + Gets the hostname and operating system of the client calling for an IP from the networkx Graph object. + + Takes: + giaddr: Gateway or relay IP that the DHCP packet was received from + _type: Type of DHCP packet, if type is offer log the client name and OS + + Returns: + client_device_name: hostname of the client device + client_device_os: operating system of the client device + ''' + for node1, node2, edge_attributes in self.G.edges(data=True): + if giaddr in edge_attributes.values(): + if giaddr == edge_attributes['a_end_ip']: + client_device_name, client_device_os = edge_attributes['b_end'], self.G.nodes[edge_attributes['b_end']]['os'] + elif giaddr == edge_attributes['b_end_ip']: + client_device_name, client_device_os = edge_attributes['a_end'], self.G.nodes[edge_attributes['a_end']]['os'] + + if _type == 'offer': + log(f'Saw client: {client_device_name}', 'info') + log(f'OS: {client_device_os}', 'info') + + return client_device_name, client_device_os diff --git a/topology/topology.png b/topology/topology.png new file mode 100644 index 0000000000000000000000000000000000000000..bd16923e982d935e26cf0d18a8fa530b2b3d5122 GIT binary patch literal 83525 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