Сейчас я кодирую брандмауэр на 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
Спасибо.