Перенаправление адресов порта / функция Nat In Python 3,7 - PullRequest
1 голос
/ 19 июня 2020

Сейчас я кодирую брандмауэр на python. Этот брандмауэр должен иметь возможность определять из белого списка, разрешено ли прохождение потоку.

Назначение брандмауэра - запросить его через правильный порт, чтобы получить запрошенную услугу. Например, если вы хотите получить доступ к веб-серверу за этим брандмауэром, вам просто нужно запросить брандмауэр на порту 80 или 443, брандмауэр перенаправит пакеты на нужную машину в соответствии с белым списком. Все должно быть прозрачным для пользователя.

В настоящее время для работы над этой темой я использую scapy для прослушивания пакетов и их передачи. Но для простой связи HTTP (в TCP) ничего не работает, то же самое для UDP и ICMP.

Я думаю, что моя проблема связана с тем, что я использую scapy для прослушивания пакетов и их повторной передачи, и что я не использую потоки. Я хотел бы знать, делал ли кто-нибудь что-то подобное и есть ли у вас какие-либо советы по использованию модулей.

Я постараюсь подробно описать свой код, чтобы дать вам представление о том, как он работает.

Сначала у вас есть main (), эта функция обнюхивает пакеты и определяет, приходит ли пакет извне или изнутри. В соответствии с этими параметрами он определяет, какой другой функции отправить пакет для обработки.

def main():

    test = 0
    buffer = []

    # INFINITE LOOPS FOR THE MOMENT #
    while(test<1000):

        # SNIFFING PACKET ON THE EXTERNAL AND INTERNAL INTERFACE #
        packet = sniff(filter="ip",iface=["ens192","InternalInterface"],count=1)

        if(packet):

            PacketContent = packet[0]
            IpDestination = PacketContent[IP].dst
            IpDestination = str(IpDestination)
            IPSource = PacketContent[IP].src
            IPSource = str(IPSource)

    # GETTING THE IP AND MASK OF THE INBOUND PACKET #
            LocalIp = ipaddress.ip_network(IfIp+"/"+Mask,strict = False)
            NetworkIp = ipaddress.ip_network(IpDestination+"/"+Mask,strict = False)

    # GETTING THE IP AND MASK OF THE EXTERNAL NETWORK INTERFACE OF THE FIREWALL #
            IfIp = ni.ifaddresses('ens192')[ni.AF_INET][0]['addr']
            Mask = ni.ifaddresses('ens192')[ni.AF_INET][0]['netmask']

    # GETTING THE IP AND MASK OF THE INTERNAL NETWORK INTERFACE OF THE FIREWALL #
            IfIp2 = ni.ifaddresses('InternalInterface')[ni.AF_INET][0]['addr']
            Mask2 = ni.ifaddresses('InternalInterface')[ni.AF_INET][0]['netmask']

    # GETTING THE NETWORK IP OF PACKET AND OF INTERNAL INTERFACE #
            LocalIp2 = ipaddress.ip_network(IfIp2+"/"+Mask2,strict = False)
            IPSource = ipaddress.ip_network(IPSource+"/"+Mask,strict = False)

    # IF A PACKET IS DESTINATED FOR THE ADDRESS OF THE EXTERNAL FIREWALL INTERFACES #
            if(IfIp == IpDestination):
                if(PacketContent[TCP].dport == 22):
                    main()
                print("Forwarding "+ IpDestination + " to IN")
                buffer =  ForwardingPort(PacketContent,buffer)

    # IF A PACKET IS DESTINATED FOR THE ADDRESS OF THE INTERNAL FIREWALL INTERFACES #
            elif(IPSource == LocalIp2):
                PacketContent.show()
                print("Forwarding  "+ str(IPSource) + " to OUT")
                buffer = BufferPort(PacketContent,buffer)

Затем, если пакет пришел извне, функция ForwardingPort будет вызвана, эта функция также принимает в качестве аргумента полученный пакет. как массив, содержащий списки временных портов клиентов

def ForwardingPort(Packet,buffer):

    # IF THE PACKET TYPE IS 6 IT'S TCP #
    elif(Packet[IP].proto == 6):

        # GETTING THE ASKED SOCKET NUMBER #
        Service = Packet[TCP].dport
        Service = str(Service)

        # OPENING THE FILES THAT CONTAINS SOCKET FORWARDING RULES #
        f = open("/root/ProjetMarsan/Forwading.txt")

        # READING EACH LINE TO FIND THE ASKED SOCKET #

        for li in f.readlines() :

            # IF THE PORT IS AUTHORIZED ON THE FILE #
            if Service in li:

                # GETTING DESTINATION SERVER IP ON THE INTERNAL NETWORK #
                ipDestNat = li.split('=')[1]
                ipDestNat = ipDestNat.replace(" ","")
                ipDestNat = ipDestNat.replace("\n","")

                # REPLACEMENT OF THE ORIGINAL IP WITH THE IP OF THE CORRECT MACHINE CONTAINED IN THE TEXT FILE #
                Packet[IP].dst = ipDestNat

                # BACKUP OF THE TEMPORARY PORT OPENED BY THE CLIENT TO INTEROGATE THE FIREWALL IN A TEXT FILE #
                IpSrcBuff = str(Packet[IP].src)
                SPortBuff = str(Packet[IP].sport)
                buffer.append(SPortBuff + ":" + IpSrcBuff)

                # RECALCULATION OF THE NEW CHECKSUM #
                del Packet[IP].chksum
                del Packet[TCP].chksum
                Packet.show2()

                # SENDING THE PACKET ON THE INTERNAL INTERFACES TO THE RIGHT SERVER #
                sendp(Packet,iface="InternalInterface")

                # RETURNING THE LIST OF THE TEMPORARY PORT OF CLIENT #
                return(buffer)

Теперь, если пакет пришел изнутри межсетевого экрана, будет вызвана функция BufferPort.


def BufferPort(Packet,buffer):

    # GETTING THE PORT DESTINATION OF THE PACKET #
    Dport = str(Packet[IP].dport)

    # CHECKING IF THE TEMPORARY SOCKET IS ON THE BUFFER LIST #
    for yo in buffer:

        print("checking buffer")
        lo = lo + 1

        # IF THE TEMPORARY SOCKET IS IN, REPLACE IP BY THE EXTERNAL FIREWALL INTERFACE IP AND RECALCULATE PACKET CHECKSUM #
        if(Dport in yo):

            ipDestBuff = yo.split(":")[1]
            ipDestBuff = ipDestBuff.replace(" ","")
            ipDestBuff = ipDestBuff.replace("\n","")

            Packet[IP].dst = ipDestBuff
            Packet[IP].src = "192.168.1.81"

            del Packet[IP].chksum
            del Packet[TCP].chksum
            Packet.show2()

            sendp(Packet,iface="ens192")
            buffer[lo] = ""
    return buffer

Спасибо.

...