class Network: def __init__(self, config): self.config = config self.keepalived = Keepalived(self.config) self.conntrackd = Conntrackd(self.config) self.firewall = Firewall(self.config) self.password_service = PasswordService(self.config) self.metadata_service = MetadataService(self.config) self.metadata_vm = MetadataVm(self.config) self.dhcp_service = DhcpService(self.config) self.dhcp_vm = DhcpVm(self.config) self.vpn = Vpn(self.config) self.rsyslog = Rsyslog(self.config) def sync(self): logging.debug("Starting sync of network!") logging.debug(self.config.dbag_network_overview) self.keepalived.sync() self.conntrackd.sync() self.firewall.sync() self.password_service.sync() self.metadata_service.sync() self.metadata_vm.sync() self.dhcp_service.sync() self.dhcp_vm.sync() self.vpn.sync() self.rsyslog.sync()
def on_accept(self): clientsock, clientaddr = self.server.accept() forward= clientsock.recv(buffer_size) print "Message received from Client:", forward try: destination_ip = forward except socket.gaierror: #could not resolve print 'Hostname could not be resolved. Exiting' sys.exit() fire=Firewall('blackList.txt','whitelist.txt') reply=fire.input_ip(destination_ip) print "SEEMA REPLY" print reply if reply == "no" : #scloud.close() print "BLOCKED!!!!!!!" sys.exit() server_host = '172.31.39.102' server_port = 8888 server_ip=socket.gethostbyname(server_host) print server_ip forward = Forward().start(server_ip,server_port) if forward: print clientaddr, "has connected" self.input_list.append(clientsock) self.input_list.append(forward) self.channel[clientsock] = forward self.channel[forward] = clientsock else: print "Can't establish connection with remote server.", print "Closing connection with client side", clientaddr clientsock.close()
def testAcceptPacketFalse(self): firewall = Firewall('allow_rules.csv') self.assertEqual( firewall.accept_packet("inbound", "tcp", 81, "192.168.1.2"), False) self.assertEqual( firewall.accept_packet("inbound", "udp", 24, "52.12.48.92"), False)
def on_accept(self): clientsock, clientaddr = self.server.accept() forward = clientsock.recv(buffer_size) print "Message received from Client:", forward try: destination_ip = forward except socket.gaierror: #could not resolve print 'Hostname could not be resolved. Exiting' sys.exit() fire = Firewall('blackList.txt', 'whitelist.txt') reply = fire.input_ip(destination_ip) print "SEEMA REPLY" print reply if reply == "no": #scloud.close() print "BLOCKED!!!!!!!" sys.exit() server_host = '172.31.39.102' server_port = 8888 server_ip = socket.gethostbyname(server_host) print server_ip forward = Forward().start(server_ip, server_port) if forward: print clientaddr, "has connected" self.input_list.append(clientsock) self.input_list.append(forward) self.channel[clientsock] = forward self.channel[forward] = clientsock else: print "Can't establish connection with remote server.", print "Closing connection with client side", clientaddr clientsock.close()
def common_cases(): f = Firewall('test_input.csv') assert f.accept_packet("inbound", "tcp", 80, "192.168.1.2") assert f.accept_packet("inbound", "udp", 53, "192.168.2.1") assert not f.accept_packet("inbound", "tcp", 81, "192.168.1.2") assert not f.accept_packet("inbound", "udp", 24, "52.12.48.92") print('Base Cases Passed')
def test_udp(self): path = "rules.csv" firewall = Firewall(path) assert firewall.accept_packet("inbound", "udp", 53, "192.168.2.1") == True assert firewall.accept_packet("inbound", "udp", 24, "52.12.48.92") == False assert firewall.accept_packet("inbound", "udp", 57, "192.168.1.1") == False assert firewall.accept_packet("outbound", "udp", 1000, "52.12.48.92") == True assert firewall.accept_packet("outbound", "udp", 1500, "52.12.48.93") == False
def test_smoke_safe_path(self): layers = {0: 3, 1: 2, 4: 4, 6: 4} firewall = Firewall(layers) offset = firewall.get_safe_path() self.assertEqual(offset, 10)
def test_smoke_severity(self): layers = {0: 3, 1: 2, 4: 4, 6: 4} firewall = Firewall(layers) severity = firewall.calculate_severity() self.assertEqual(severity, 24) # 0*3 + 6*4
def process_warden(): # update tables by life_time fw = Firewall() removed = fw.refresh() if len(removed) > 0: print removed fw.close_connection()
def do_ipconfig(self): setting = HSMSettings.IP_ADDRESS_SETTINGS dhcp_or_static = self.settings.get_setting(setting) if(dhcp_or_static == 'STATIC_IP'): self.startstatic_ip() else: self.startdhcp() Firewall.generate_firewall_rules(self.settings, self.tmp)
def large_set(): f = Firewall('large_set.csv') start = time.time() # test overlap in part of ip range does not affect port validity for i in range(100): assert not f.accept_packet('inbound','tcp',1,'192.168.1.2') end = time.time() assert end-start<TIME_REQ print('Large Set Passed')
def __init__(self, config): self.config = config self.keepalived = Keepalived(self.config) self.conntrackd = Conntrackd(self.config) self.firewall = Firewall(self.config) self.password_service = PasswordService(self.config) self.metadata_service = MetadataService(self.config) self.metadata_vm = MetadataVm(self.config) self.dhcp_service = DhcpService(self.config) self.dhcp_vm = DhcpVm(self.config) self.vpn = Vpn(self.config) self.rsyslog = Rsyslog(self.config)
def main(): depths = [] ranges = [] line = f.readline().rstrip() while line: parts = line.split(': ') depths.append(int(parts[0])) ranges.append(int(parts[1])) line = f.readline().rstrip() firewall = Firewall(depths, ranges) firewall.run() print(firewall.totalSeverity)
def test_firewall_allow_packet(self): """Verify firewall allows a packet that matches a rule.""" fw = Firewall() fw.add_fw_rule( FirewallRule(direction="inbound", protocol="tcp", port="80", ip_address="192.168.1.2")) self.assertTrue( fw.accept_packet(direction="inbound", protocol="tcp", port=80, ip_address="192.168.1.2"))
def test_firewall_block_packet(self): """Verify firewall blocks a packet that doesn't match a rule.""" fw = Firewall() fw.add_fw_rule( FirewallRule(direction="inbound", protocol="tcp", port="80", ip_address="192.168.1.2")) self.assertFalse( fw.accept_packet(direction="outbound", protocol="tcp", port=80, ip_address="192.168.1.2")) self.assertFalse( fw.accept_packet(direction="inbound", protocol="udp", port=80, ip_address="192.168.1.2")) self.assertFalse( fw.accept_packet(direction="inbound", protocol="udp", port=81, ip_address="192.168.1.2")) self.assertFalse( fw.accept_packet(direction="outbound", protocol="tcp", port=80, ip_address="192.168.1.3"))
def clientthread(conn): #Sending message to connected client conn.send('Welcome to the server. Type something and hit enter\n') #send only takes string #infinite loop so that function do not terminate and thread do not end. #Receiving from client data = conn.recv(1024) print("Data Received Starts") print(data) print("Data Ends") fire=Firewall('blackList.txt','whitelist.txt') reply=fire.input(data) print("Reply", reply) conn.sendall(reply) #came out of loop conn.close()
def __init__(self, con=None): self._con = con self._dns = DNS(self) self._dhcp = DHCP(self) self._ftp = PureFTP(self) self._network = Network(self) self._firewall = Firewall(self)
def clientthread(conn): #Sending message to connected client conn.send('Welcome to the server. Type something and hit enter\n' ) #send only takes string #infinite loop so that function do not terminate and thread do not end. #Receiving from client data = conn.recv(1024) print("Data Received Starts") print(data) print("Data Ends") fire = Firewall('blackList.txt', 'whitelist.txt') reply = fire.input(data) print("Reply", reply) conn.sendall(reply) #came out of loop conn.close()
def test_firewall_allow_range_port_packet(self): """ Verify firewall allows a packet that matches a rule with ranged port numbers. """ fw = Firewall() fw.add_fw_rule( FirewallRule(direction="inbound", protocol="tcp", port="1-65535", ip_address="192.168.1.2")) self.assertTrue( fw.accept_packet(direction="inbound", protocol="tcp", port=1, ip_address="192.168.1.2")) self.assertTrue( fw.accept_packet(direction="inbound", protocol="tcp", port=65535, ip_address="192.168.1.2")) self.assertTrue( fw.accept_packet(direction="inbound", protocol="tcp", port=30000, ip_address="192.168.1.2"))
def _handle_reg(event): if event.name == "gateway": try: from firewall import Firewall global fw fw = Firewall() event.component.addListeners(fw) except: fw_log.exception("Couldn't load firewall.py")
def test_tcp(self): path = "rules.csv" firewall = Firewall(path) assert firewall.accept_packet("inbound", "tcp", 80, "192.168.1.2") == True assert firewall.accept_packet("outbound", "tcp", 10234, "192.168.10.11") == True assert firewall.accept_packet("inbound", "tcp", 81, "192.168.1.2") == False assert firewall.accept_packet("outbound", "tcp", 20000, "192.168.10.11") == True assert firewall.accept_packet("inbound", "tcp", 800, "192.168.1.2") == False
def on_accept(self): clientsock, clientaddr = self.server.accept() print clientaddr[0] fire = Firewall('blackList.txt', 'whitelist.txt') reply = fire.input_ip(clientaddr[0]) if reply == 'no': #192.168.239.128': print "Sorry" sys.exit(1) forward = Forward().start(forward_to[0], forward_to[1]) if forward: print clientaddr, "has connected" self.input_list.append(clientsock) self.input_list.append(forward) self.channel[clientsock] = forward self.channel[forward] = clientsock else: print "Can't establish connection with remote server.", print "Closing connection with client side", clientaddr clientsock.close()
def on_accept(self): clientsock, clientaddr = self.server.accept() print clientaddr[0] fire=Firewall('blackList.txt','whitelist.txt') reply=fire.input_ip(clientaddr[0]) if reply == 'no' :#192.168.239.128': print "Sorry" sys.exit(1) forward = Forward().start(forward_to[0], forward_to[1]) if forward: print clientaddr, "has connected" self.input_list.append(clientsock) self.input_list.append(forward) self.channel[clientsock] = forward self.channel[forward] = clientsock else: print "Can't establish connection with remote server.", print "Closing connection with client side", clientaddr clientsock.close()
def __init__(self, net): self.net = net self.intf_list = net.interfaces() self.interface = {} self.devInterface = {} self.ipToEth = {} self.frdtable = [] self.pktQueue = [] self.fw = Firewall() # Build a forwarding table f = open("forwarding_table.txt", "r") for line in f: linelst = line.split() linelst[0] = IPAddr(linelst[0]) linelst[1] = IPAddr(linelst[1]) linelst[2] = IPAddr(linelst[2]) self.frdtable.append(linelst) # Cache ip address to Eth address using net.interface() for intf in self.intf_list: self.frdtable.append([intf.ipaddr, intf.netmask, IPAddr("0"), intf.name]) self.interface[intf.ipaddr] = [intf.netmask, intf.name, intf.ethaddr] self.devInterface[intf.name] = [intf.ethaddr, intf.ipaddr]
def test_sample_small(): print('Test firewall with', sample_small) fw = Firewall(sample_small) print(fw.accept_packet("inbound", "tcp", 80, "192.168.1.2") == True) print(fw.accept_packet("inbound", "udp", 53, "192.168.2.1") == True) print(fw.accept_packet("outbound", "tcp", 10234, "192.168.10.11") == True) print(fw.accept_packet("inbound", "tcp", 81, "192.168.1.2") == False) print(fw.accept_packet("inbound", "udp", 24, "52.12.48.92") == False) print(fw.accept_packet("inbound", "tcp", 80, "192.168.1.3") == False)
class TestFirewall(unittest.TestCase): fw = Firewall('fw.csv') def test0(self): self.assertTrue(self.fw.accept_packet("inbound", "tcp", 80, "192.168.1.2"), "Rule not found, permission denied") def test1(self): self.assertTrue(self.fw.accept_packet("inbound", "udp", 53, "192.168.2.1"), "Rule not found, permission denied") def test2(self): self.assertTrue(self.fw.accept_packet("outbound", "tcp", 10234, "192.168.10.11"), "Rule not found, permission denied") def test3(self): self.assertFalse(self.fw.accept_packet("inbound", "tcp", 81, "192.168.1.2"), "Rule not found, permission denied") def test4(self): self.assertFalse(self.fw.accept_packet("inbound", "udp", 24, "52.12.48.92"), "Rule not found, permission denied")
def edge_cases(): f = Firewall('edge_case.csv') # test overlap in part of ip range does not affect port validity assert not f.accept_packet("inbound", "tcp", 89, "192.168.2.3") # test present ip range overlap does not affect port validity assert f.accept_packet("inbound", "tcp", 80, "192.168.1.9") # test port range is inclusive assert f.accept_packet("inbound", "tcp", 53, "192.168.1.2") assert f.accept_packet("inbound", "tcp", 79, "192.168.1.2") # test ip address range is inclusive assert f.accept_packet("inbound", "tcp", 80, "192.168.2.5") assert f.accept_packet("inbound", "tcp", 80, "192.168.1.1") # test out of ip range by one. assert not f.accept_packet("inbound", "tcp", 88, "192.168.2.0") # test packet is only tested against applicable rules assert not f.accept_packet("outbound", "tcp", 80, "192.168.2.0") print('Edge Cases Passed')
def _handle_ConnectionUp(self,event): dpid = event.dpid #log.debug("Switch %s has come up.", dpid_to_str(dpid)) #LearningSwitch(event.connection,False) # switch sw1 and sw3 are regular learning switch if dpid == 1 or dpid ==3: log.debug("Switch %s has come up.", dpid_to_str(dpid)) LearningSwitch(event.connection,False) # firewall elif dpid == 6: log.debug("Firewall %s has come up.", dpid_to_str(dpid)) Firewall(event.connection)
def testAcceptPacketTrue(self): firewall = Firewall('allow_rules.csv') self.assertEqual( firewall.accept_packet("inbound", "udp", 53, "192.168.2.5"), True) self.assertEqual( firewall.accept_packet("inbound", "tcp", 20, "192.168.1.101"), True) self.assertEqual( firewall.accept_packet("inbound", "udp", 53, "192.168.2.1"), True) self.assertEqual( firewall.accept_packet("outbound", "tcp", 10234, "192.168.10.11"), True)
def main(self): # solicitar nombre del archivo (debe estar en el misma carpeta) print('\nWrite the file name with extension (e.g. rules.txt):\n') filename = input() # obtener direccion absoluta del archivo: # https://stackoverflow.com/questions/12201928/python-open-gives-ioerror-errno-2-no-such-file-or-directory script_location = Path(__file__).absolute().parent file_location = script_location / filename # print(file_location) # si el archivo existe la ejecución continúa # https://stackoverflow.com/questions/82831/how-do-i-check-whether-a-file-exists-without-exceptions if (os.path.exists(file_location) == True): # leer expresión según el archivo de reglas reader = FileReader() expression, instruction = reader.readRules(file_location) # validar que se haya encontrado expresión e instrucción a realizar if (expression == None or instruction == None): print("\nThere was a problem with the file text") else: print("\nExpression to filter: " + expression) # hacer lo nuestro firewall = Firewall(expression) validation = firewall.validateExpression() if (validation == "No error"): # la expresión es correcta if (instruction == "allow" ): # se permite tráfico específico firewall.allowTraffic() elif (instruction == "block" ): # se bloquean tráfico especifico firewall.blockTraffic() else: # la expresión es errónea de acuerdo con reglas de librería WinDivert print( "The expression is wrong according to WinDivert rules") else: # si el archivo no existe se termina la ejecución print("The file doesn't exist")
def test_no_add_duplicate_ipaddr_rules(self): """Verify that duplicate range IP address rules cannot be added.""" fw = Firewall() fw.add_fw_rule( FirewallRule(direction="inbound", protocol="tcp", port="80", ip_address="192.168.1.2-192.168.2.2")) bucket_num = 80 // fw.num_ports_bucket self.assertEqual(len(fw.fw_rules["inbound"]["tcp"][bucket_num]), 1) fw.add_fw_rule( FirewallRule(direction="inbound", protocol="tcp", port="80", ip_address="192.168.1.2-192.168.2.2")) self.assertEqual(len(fw.fw_rules["inbound"]["tcp"][bucket_num]), 1)
def __init__(s, nodename): Thread.__init__(s) # Init logger s.log = logging.getLogger('Connector-{0}'.format(s.name)) # Init new database session s._sess = s.Session() # Init firewall tables s.f = Firewall(s.log, s._sess) # Init DNS daemon s.dns = DNSDaemon(s.log, s._sess) # Init database connection status table s.connections = ConnectionStatus(s.log, s._sess, nodename) # Make inotify watcher wm = WatchManager() ## OpenVPN status update handler class PUpdateStatus(ProcessEvent): ## Close file event method def process_IN_MODIFY(self, event): # Update status and firewall rules s.updateStatus() # Make notificator s.notifier = Notifier(wm, PUpdateStatus()) # Add OpenVPN status file watcher wm.watch_transient_file(OPENVPN_STATUS_FILE, IN_MODIFY, PUpdateStatus) s._sess.close()
def test_no_add_duplicate_range_port_rules(self): """Verify that duplicate range port rules cannot be added.""" fw = Firewall() fw.add_fw_rule( FirewallRule(direction="inbound", protocol="tcp", port="50-2000", ip_address="192.168.1.2")) start_bucket = 50 // fw.num_ports_bucket end_bucket = 2000 // fw.num_ports_bucket for bucket_num in range(start_bucket, end_bucket + 1): self.assertEqual(len(fw.fw_rules["inbound"]["tcp"][bucket_num]), 1) fw.add_fw_rule( FirewallRule(direction="inbound", protocol="tcp", port="50-2000", ip_address="192.168.1.2")) for bucket_num in range(start_bucket, end_bucket + 1): self.assertEqual(len(fw.fw_rules["inbound"]["tcp"][bucket_num]), 1)
def router_main(self): self.arp_ip = {} #Empty dict for IP's we're waiting for ARPs on #Dict because it's faster than queue and we don't care about order self.firewall = Firewall() #New line while True: try: self.examineStalled() #deal with stalled that are waiting on ARPs dev,ts,pkt = self.net.recv_packet(timeout=0.5) #Chnged/new lines for Firewall self.firewall.update_token_buckets() payload = pkt.payload if pkt.type == pkt.ARP_TYPE: #Is an ARP src_ip = payload.protosrc dst_ip = payload.protodst src_eth = payload.hwsrc #no dst self.ip_to_ether[src_ip] = src_eth #Add to map from IP's to eth if payload.opcode == arp.REQUEST: if dst_ip in self.ip_to_ether: hwdst = self.ip_to_ether[dst_ip] reply = self.makeReply(dst_ip, src_ip, hwdst, src_eth) self.net.send_packet(dev, reply) #send it off #Do nothing otherwise else: #ARP_REPLY self.ip_to_ether[src_ip] = src_eth #Sending dealt with in examineStalled(.) elif pkt.type == pkt.IP_TYPE: if self.firewall.allow(payload): #Change for Firewall if payload.dstip in self.my_interfaces: #Sent to us inner = payload.payload if inner.find("icmp") and inner.type == pktlib.TYPE_ECHO_REQUEST: icmp_reply = self.makeEcho(inner.payload) # make ICMP header ip_reply = self.makeIP(icmp_reply, payload.srcip, self.nameMap[dev][1]) # make IP header pkt.payload = ip_reply # put it in the packet to be sent forward payload = pkt.payload else: icmp_error = self.makeICMP(pktlib.TYPE_DEST_UNREACH, pktlib.CODE_UNREACH_PORT, payload) # make ICMP error ip_reply = self.makeIP(icmp_error, payload.srcip, self.nameMap[dev][1]) # make IP header pkt.payload = ip_reply # put it in the packet to be sent forward payload = pkt.payload payload.ttl -= 1 if payload.ttl == 0: icmp_error = self.makeICMP(pktlib.TYPE_TIME_EXCEED, 0, payload) # make ICMP error ip_reply = self.makeIP(icmp_error, payload.srcip, self.nameMap[dev][1]) # wrap it in IP pkt.payload = ip_reply # send it off payload = pkt.payload self.forward_packet(pkt, dev) #Drop elsewise except SrpyNoPackets: # log_debug("Timeout waiting for packets") continue except SrpyShutdown: return
def handle_start_firewall_method(self): firewall = Firewall() firewall.start()
def handle_stop_firewall_method(self): firewall = Firewall() firewall.stop()
class Router(object): def __init__(self, net): self.net = net self.intf_list = net.interfaces() self.interface = {} self.devInterface = {} self.ipToEth = {} self.frdtable = [] self.pktQueue = [] self.fw = Firewall() # Build a forwarding table f = open("forwarding_table.txt", "r") for line in f: linelst = line.split() linelst[0] = IPAddr(linelst[0]) linelst[1] = IPAddr(linelst[1]) linelst[2] = IPAddr(linelst[2]) self.frdtable.append(linelst) # Cache ip address to Eth address using net.interface() for intf in self.intf_list: self.frdtable.append([intf.ipaddr, intf.netmask, IPAddr("0"), intf.name]) self.interface[intf.ipaddr] = [intf.netmask, intf.name, intf.ethaddr] self.devInterface[intf.name] = [intf.ethaddr, intf.ipaddr] def router_main(self): while True: try: dev,ts,pkt = self.net.recv_packet(timeout=1.0) self.pktQueue.append(packt(pkt)) for i in self.pktQueue: # ARP REQ -> ARP REPLY if (i.pktElem.type == i.pktElem.ARP_TYPE): if (i.pktElem.dst == pktlib.ETHER_BROADCAST): self.arpReply(i.pktElem.payload) self.pktQueue.remove(i) # IP PKT -> ARP REQUEST if (i.pktElem.type == i.pktElem.IP_TYPE): print time.time() if (self.fw.mainframe(i.pktElem.payload,time.time())): self.addFinder(i.pktElem, i.retries) self.pktQueue.remove(i) except SrpyNoPackets: # log_debug("Timeout waiting for packets") continue except SrpyShutdown: return def arpReply(self, e): ''' This method builds and sends ARP reply in response to ARP Request. e = payload of original IP packet received ''' # Create ARP reply header (Ethernet) if (e.protodst in self.interface): dev = self.interface[e.protodst][1] ethpkt = pktlib.ethernet() ethpkt.src = self.interface[e.protodst][2] ethpkt.dst = e.hwsrc ethpkt.type = ethpkt.ARP_TYPE arp_rep = pktlib.arp() arp_rep.opcode = pktlib.arp.REPLY arp_rep.protosrc = e.protodst arp_rep.protodst = e.protosrc arp_rep.hwsrc = self.interface[e.protodst][2] arp_rep.hwdst = e.hwsrc # Encapsulate eth packet ethpkt.set_payload(arp_rep) # Send it back to the src address self.net.send_packet(dev,ethpkt) return def addFinder(self, pkt, retries): ''' This method looks up destination ip addresses in the forwarding table and net.interfaces dictionary and forwards packets or calls ARP Request ''' e=pkt.find('ipv4') longest = 0 i = 0 ind = -1 # Check ARP, then check frdtable for line in (self.frdtable): mask = netmask_to_cidr(line[1]) dstIpUns = e.dstip.toUnsigned() pktprefix = (dstIpUns>>(32-mask))<<(32-mask) unsigned = str(line[0].toUnsigned()) intfmask = netmask_to_cidr(line[1]) masked = (int(unsigned)>>(32-intfmask))<<(32-intfmask) if (int(pktprefix) == masked): if (pktprefix>longest): longest = pktprefix nxthop = line[2] ind = i i = i+1 dev = self.frdtable[ind][3] drop = False if e.dstip in self.interface: drop = True if (ind!=-1) and not (drop): if dev in self.devInterface: seth = self.devInterface[dev][0] srcip = self.devInterface[dev][1] else: pass if e.dstip in (self.ipToEth): self.forwarding(dev, seth, self.ipToEth[e.dstip],pkt) else: self.arpBuilder(dev, pkt, nxthop, retries)
from firewall import Firewall f = open ("file you store the exactly hex packet") firewallTest = Firewall(None, None, None) firewallTest.handpacket(OUting, )
def main(): """ Main method. :return None """ firewall = Firewall() print("Welcome to the Firewall Shell Program!") print("WARNING: This program deals with IP Tables and WILL overwrite existing iptable rules.") cont = raw_input("Do you still wish to proceed? [Y/N]") if cont.lower() == "n": print("Terminating Program. Good-Bye.") sys.exit() elif cont.lower() != "n" and cont.lower() != "y": print("Invalid Option! \nTerminating Program!") sys.exit() else: cont = True print("Starting firewall shell....") firewall.start() print("Firewall shell is now running.....") while cont: print("Do you wish to....") print( "display tables[dispaly]\nblock port 25[block]\naccept forward[forward]\naccept icmp[icmp]\naccept input[input]\naccept protocol[protocol]\nredirect http[http]\nsource nat[nat]\nclose shell[close]\nrestart shell[restart]\ncommit[commit]\nclear[clear]") user_input = raw_input("Command: ") if user_input.lower() == "forward": question = raw_input("Do you wish to add an in and out interface? [Y/N]\n") if question.lower() == "y": in_interface = raw_input("In Interface: ") out_interface = raw_input("Out Interface: ") else: in_interface = None out_interface = None firewall.accept_forward(in_interface, out_interface) elif user_input.lower() == "icmp": question = raw_input("Do you wish to add an interface? [Y/N]\n") if question.lower() == "y": interface = raw_input("Interface: ") else: interface = None firewall.accept_icmp(interface) elif user_input.lower() == "input": question = raw_input("Do you wish to add an interface? [Y/N]\n") if question.lower() == "y": interface = raw_input("Interface: ") else: interface = None firewall.accept_input(interface) elif user_input.lower() == "protocol": interface = raw_input("Interface: ") port = raw_input("Port: ") question = raw_input("Do you wish to add an destination and source? [Y/N]\n") if question.lower() == "y": dest = raw_input("Destination: ") src = raw_input("Source: ") else: dest = None src = None firewall.accept_protocol(interface, port, dest, src) elif user_input.lower() == "http": interface = raw_input("Interface: ") proxy_port = raw_input("Proxy Port: ") firewall.redirect_http(interface, proxy_port) elif user_input.lower() == "display": print os.system("iptables -L -n") elif user_input.lower() == "block": print os.system("iptables -A OUTPUT -p tcp --dport 25 -j DROP") print "Port 25 Blocked for OUTGOING connections" print os.system("service iptables save") elif user_input.lower() == "nat": interface = raw_input("Interface: ") firewall.source_nat(interface) elif user_input.lower() == "close": print("Terminating shell....") firewall.stop() sys.exit() elif user_input.lower() == "restart": print("Restarting shell....") firewall.stop() firewall.start() elif user_input.lower() == "commit": print("Commiting changes...."), firewall.commit() print("Done") elif user_input.lower() == "clear": print("Clearing changes...."), firewall.clear() print("Done") else: print("INVALID OPTION!") qcont = raw_input("Do you wish to continue?[Y/N]\n") if qcont.lower() == "n": cont = False else: pass
class Router(object): def __init__(self, net): self.net = net self.ip_to_ether = {} #Empty dict to store mappings self.my_interfaces = Set() #Set of ip's for this router's interfaces self.forwardingTable = {} self.nameMap = {} #Maps from intf names to ip and eth addresses self.buildMappings() def makeReply(self, dst_ip, src_ip, hwdst, src_eth): ''' Creates an ARP reply packet given IP source and destination, Ethernet source and destination ''' arp_rep = arp() #Build up packet arp_rep.opcode = arp.REPLY arp_rep.protosrc = dst_ip arp_rep.protodst = src_ip arp_rep.hwsrc = hwdst #Matching ethernet asked for in initial request arp_rep.hwdst = src_eth ether = ethernet() #wrap in ether ether.type = ether.ARP_TYPE ether.set_payload(arp_rep) ether.src = hwdst ether.dst = src_eth return ether def makeRequest(self, dst_ip, src_ip, src_eth): ''' Creates an ARP request packet -Of same structure as makeReply, but distinct enough that it's worth having different functions that lay it all out ''' arp_req = arp() arp_req.opcode = arp.REQUEST arp_req.protosrc = src_ip arp_req.protodst = dst_ip arp_req.hwsrc = src_eth arp_req.hwdst = ETHER_BROADCAST ether = ethernet() #wrap in ether ether.type = ether.ARP_TYPE ether.set_payload(arp_req) ether.src = src_eth ether.dst = ETHER_BROADCAST return ether def makeEcho(self, request): icmppkt = pktlib.icmp() icmppkt.type = pktlib.TYPE_ECHO_REPLY reply = pktlib.echo() reply.id = request.id reply.seq = request.seq reply.payload = request.payload icmppkt.payload = reply return icmppkt def makeICMP(self, errorType, codeType, ippkt): icmppkt = pktlib.icmp() icmppkt.type = errorType icmppkt.code = codeType icmppkt.payload = pktlib.unreach() icmppkt.payload.payload = ippkt.dump()[:28] return icmppkt def makeIP(self, icmppkt, ipsrc, ipdest): ippkt = pktlib.ipv4() ippkt.srcip = ipdest ippkt.dstip = ipsrc ippkt.ttl = 64 # a reasonable initial TTL value ippkt.protocol = ippkt.ICMP_PROTOCOL ippkt.payload = icmppkt return ippkt def buildMappings(self): ''' Creates a Forwarding Table for the router, as well as establishing mappings from names to eth and ip, storing a list of ip's associated with my interfaces, and initializing the table of mappings from ip to eth addresses Addresses in forwarding table are stored in binary for easy bitwise operations ''' #Obtain routes from net.interfaces for intf in self.net.interfaces(): prefix = intf.ipaddr.toUnsigned() & intf.netmask.toUnsigned() # network prefix mask = intf.netmask # network mask nexthop = None # next hop name = intf.name # interface name self.forwardingTable[prefix] = tuple([mask, nexthop, name]) self.nameMap[name] = (intf.ethaddr, intf.ipaddr) self.my_interfaces.add(intf.ipaddr) self.ip_to_ether[intf.ipaddr] = intf.ethaddr #Obtain routes from forwarding_table.txt forTable = open("forwarding_table.txt", "r") for line in forTable: parsedLine = line.split(" ") prefix = IPAddr(parsedLine[0]).toUnsigned() # network prefix mask = IPAddr(parsedLine[1]) # network mask nexthop = IPAddr(parsedLine[2]) # next hop name = parsedLine[3][0:-1] # interface name self.forwardingTable[prefix] = tuple([mask, nexthop, name]) def matchPrefix(self, dstip): best_prefix = None best_match = -1 for prefix in self.forwardingTable: netmask = self.forwardingTable[prefix][0] # 0 is the netmask if prefix == (dstip.toUnsigned() & netmask.toUnsigned()): if best_match ==-1 or best_match < netmask_to_cidr(netmask): best_prefix = prefix best_match = netmask_to_cidr(netmask) if best_prefix == None: #No matches at all return None return self.forwardingTable[best_prefix] #Index 1 is the nexthop def forward_packet(self, pkt, dev): payload = pkt.payload match = self.matchPrefix(payload.dstip) if match == None: #No entry on table matched icmp_error = self.makeICMP(pktlib.TYPE_DEST_UNREACH, pktlib.CODE_UNREACH_NET, payload) # make ICMP error ip_reply = self.makeIP(icmp_error, payload.srcip, self.nameMap[dev][1]) # wrap it in IP pkt.payload = ip_reply # send it off payload = pkt.payload match = self.matchPrefix(payload.dstip) next_hop = match[1] #Ease of use name = match[2] if next_hop == None: #No next hop, directly connected to our port nxt_ip = payload.dstip else: nxt_ip = next_hop src_eth = self.nameMap[name][0] #Pull ip/eth corresponding to this interface src_ip = self.nameMap[name][1] ether = ethernet() #wrap ip in ether ether.type = ether.IP_TYPE ether.set_payload(payload) ether.src = src_eth if nxt_ip in self.ip_to_ether: #We have the mapping nxt_ip->eth ether.dst = self.ip_to_ether[nxt_ip] self.net.send_packet(name, ether) #Send packet on its way else: if nxt_ip in self.arp_ip: #Already waiting on ARP for this self.arp_ip[nxt_ip].addPacket(ether) else: #New IP to ARP at request = self.makeRequest(nxt_ip, src_ip, src_eth) #create ARP req waiter = arpWaiter(name, request, ether, dev) self.arp_ip[nxt_ip] = waiter self.net.send_packet(name, request) #Send ARP request def examineStalled(self): keys = self.arp_ip.keys() #Can/will lose keys during iteration for dst in keys: stalled = self.arp_ip.pop(dst) if dst in self.ip_to_ether: #We've since figured this one out dst_eth = self.ip_to_ether[dst] for ether_pkt in stalled.getList(): #Send out all the waiting packets ether_pkt.dst = dst_eth self.net.send_packet(stalled.intf_name, ether_pkt) else: difference = time.time() - stalled.start_time sentICMP = False if difference/stalled.tries > 1: if stalled.tries >=5: #Timeout, send ICMP timeout ether = stalled.packet_list[0] # one of the ethernet packets that are queued up is all we need to get IP info icmp_error = self.makeICMP(pktlib.TYPE_DEST_UNREACH, pktlib.CODE_UNREACH_HOST, ether.payload) ip_reply = self.makeIP(icmp_error, ether.payload.srcip, self.nameMap[stalled.dev][1]) ether = ethernet() #wrap ip in ether because forward_packet uses ethernet packets ether.type = ether.IP_TYPE ether.set_payload(ip_reply) self.forward_packet(ether, stalled.intf_name) sentICMP = True else: self.net.send_packet(stalled.intf_name, stalled.arp_req) #Send ARP again stalled.tries += 1 if not sentICMP: self.arp_ip[dst] = stalled #Add stalled back to the dict def router_main(self): self.arp_ip = {} #Empty dict for IP's we're waiting for ARPs on #Dict because it's faster than queue and we don't care about order self.firewall = Firewall() #New line while True: try: self.examineStalled() #deal with stalled that are waiting on ARPs dev,ts,pkt = self.net.recv_packet(timeout=0.5) #Chnged/new lines for Firewall self.firewall.update_token_buckets() payload = pkt.payload if pkt.type == pkt.ARP_TYPE: #Is an ARP src_ip = payload.protosrc dst_ip = payload.protodst src_eth = payload.hwsrc #no dst self.ip_to_ether[src_ip] = src_eth #Add to map from IP's to eth if payload.opcode == arp.REQUEST: if dst_ip in self.ip_to_ether: hwdst = self.ip_to_ether[dst_ip] reply = self.makeReply(dst_ip, src_ip, hwdst, src_eth) self.net.send_packet(dev, reply) #send it off #Do nothing otherwise else: #ARP_REPLY self.ip_to_ether[src_ip] = src_eth #Sending dealt with in examineStalled(.) elif pkt.type == pkt.IP_TYPE: if self.firewall.allow(payload): #Change for Firewall if payload.dstip in self.my_interfaces: #Sent to us inner = payload.payload if inner.find("icmp") and inner.type == pktlib.TYPE_ECHO_REQUEST: icmp_reply = self.makeEcho(inner.payload) # make ICMP header ip_reply = self.makeIP(icmp_reply, payload.srcip, self.nameMap[dev][1]) # make IP header pkt.payload = ip_reply # put it in the packet to be sent forward payload = pkt.payload else: icmp_error = self.makeICMP(pktlib.TYPE_DEST_UNREACH, pktlib.CODE_UNREACH_PORT, payload) # make ICMP error ip_reply = self.makeIP(icmp_error, payload.srcip, self.nameMap[dev][1]) # make IP header pkt.payload = ip_reply # put it in the packet to be sent forward payload = pkt.payload payload.ttl -= 1 if payload.ttl == 0: icmp_error = self.makeICMP(pktlib.TYPE_TIME_EXCEED, 0, payload) # make ICMP error ip_reply = self.makeIP(icmp_error, payload.srcip, self.nameMap[dev][1]) # wrap it in IP pkt.payload = ip_reply # send it off payload = pkt.payload self.forward_packet(pkt, dev) #Drop elsewise except SrpyNoPackets: # log_debug("Timeout waiting for packets") continue except SrpyShutdown: return
from firewall import Firewall single = Firewall() single.policy(single.INPUT,single.DROP) single.policy(single.OUTPUT,single.ACCEPT) single.policy(single.FORWARD,single.DROP) single.input().protocol('icmp').drop() single.input().protocol('tcp').dport(('3389','5900')).accept() single.input().protocol('tcp').dport(('137','138','139','145')).accept() single.show() #single.run() #single.list()
f = None os_name = os.uname()[0] # Get OS if os_name == 'Darwin': f = os.open(TUNPATH, os.O_RDWR) else: # Linux f = os.open('/dev/net/tun', os.O_RDWR) ifr = struct.pack('16sH', TUNPATH, IFF_TAP | IFF_NO_PI) fcntl.ioctl(f, TUNSETIFF, ifr) # fcntl.ioctl(tun, TUNSETOWNER, 1000) # Assign an IP to tun/tap device device_name = TUNPATH.split('/')[-1] subprocess.check_call('ifconfig '+device_name+' '+device_ip, shell=True) firewall = Firewall() s = socket(AF_INET, SOCK_DGRAM) # maybe set it to O_NONBLOCK try: if MODE == 1: s.bind(("", PORT)) while 1: word,peer = s.recvfrom(1500) if word == MAGIC_WORD: break print "Bad magic word for %s:%i" % peer s.sendto(MAGIC_WORD, peer) else: s.sendto(MAGIC_WORD, peer)