@chumarov

Какая утилита есть для модификации заголовков сетевых пакетов, проходящих через сетевой мост?

Есть комп с линуксом. У него две сетевухи - одна смотрит в mirror порт на коммутаторе, другая смотрит в комп системой записи.

КОММУТАТОР
|
|
|
|
eth0
ЛИНУКСОВЫЙ КОМП
eth1
|
|
|
|
КОМП ДЛЯ ЗАПИСИ ПРИХОДЯЩИХ ПАКЕТОВ

Пакетики идут только с коммутатора в комп - от компа в коммутатор идти не должны.
На линуксовом компе нужно сделать что-то вроде моста, но так чтобы он менял у пролетающих UDP пакетов src port на 5060, если он равен 38906.

Зачем это - это отдельная история

Что я пытался сделать:
1) Настроил бридж на eth0 и eth1. Сделал sysctl -w net.bridge.bridge-nf-call-iptables=1 чтобы пакеты с бриджа попадали в iptables. Добавлял ВСЕВОЗМОЖНЫЕ варианты SNAT для цепочки POSTROUTING.
Например
iptables -t nat -A POSTROUTING -o br1 —protocol udp —sport 38906 -j SNAT —to-source :5060
И таких я перепробовал наверное все варианты. Пробовал и DNAT для PREROUTING и проч...
Некоторые работали, но не совсем.
2)Убрал настройку моста. Сделал скрипт на питоне на сырых сокетах - все работает, но я не люблю хенд-мейд, так как это ненадежно и плохо поддерживаемо.

Вобщем еще раз ситуация: на коммутаторе я подменять порт не могу - так ак это миррор порт на микротике - а он модифицировать заголовки не умеет на таких портах. На iptables не получилось. Какие еще есть идеи? На ettercap наверное можно. Но долго пробовать а времени мало. Если ничего не найду - придется оставить скрипт на питоне. Вобщем вопрос - есть еще какие-то утилиты для модификации проходящих пакетов - ну что-то вроде iptebles?
  • Вопрос задан
  • 826 просмотров
Решения вопроса 1
@chumarov Автор вопроса
Решил оставить скрипт - за неделю ни разу не отвалился. (если все же будут косяки - порекомендовали попробовать freeBSD с netgraph'ом)
Вот скрипт
#!/usr/bin/env python
import socket, sys, struct, datetime
from struct import *
#ethtool -K eth1 tx off

BUF_SIZE = 1600         # > 1500
ETH_P_ALL = 3           # To receive all Ethernet protocols
InterfaceIN = "eth1"
InterfaceOUT = "eth0"


# Open socket for input packets
sockINPUT = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(ETH_P_ALL))
sockINPUT.bind((InterfaceIN, 0))
sockINPUT.setblocking(1)

# Open socket for output packets
sockOUTPUT = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(ETH_P_ALL))
sockOUTPUT.bind((InterfaceOUT, 0))
sockOUTPUT.setblocking(1)

print 'Raw socket opened'

while True:
    packet = sockINPUT.recvfrom(65565)

    packet = packet[0]
    #parse ethernet header
    eth_length = 14
    eth_header = packet[:eth_length]
    eth = unpack('!6s6sH' , eth_header)
    eth_protocol = socket.ntohs(eth[2])
    if eth_protocol == 8 :
        ip_header = packet[eth_length:20+eth_length]

        #now unpack them :)
        iph = unpack('!BBHHHBBH4s4s' , ip_header)

        version_ihl = iph[0]
        version = version_ihl >> 4
        ihl = version_ihl & 0xF

        iph_length = ihl * 4

        #ttl = iph[5]
        protocol = iph[6]
        s_addr = socket.inet_ntoa(iph[8]);
        d_addr = socket.inet_ntoa(iph[9]);
		
        #print dir(cap_out)
        print str(datetime.datetime.now())+'  Source Address : ' + str(s_addr) + ' Destination Address : ' + str(d_addr)
        #UDP packets
        #UDP packets
        if protocol == 17 :
            #print 'Version : ' + str(version) + ' IP Header Length : ' + str(ihl) + ' TTL : ' + str(ttl) + ' Protocol : ' + str(protocol) + ' Source Address : ' + str(s_addr) + ' Destination Address : ' + $
            u = iph_length + eth_length
            udph_length = 8
            udp_header = packet[u:u+4]

            #now unpack them :)
            udph = unpack('!HH' , udp_header)
            #print type(udp_header)
            source_port = udph[0]
            dest_port = udph[1]
            #length = udph[2]
            #checksum = udph[3]
            #38906
            if source_port == 38906:
                #print 'Source Port : ' + str(source_port) + ' Dest Port : ' + str(dest_port)
                #print packet
                udp_header = pack('!HH' , 5060, dest_port)
                packet = packet[:u]+ udp_header + packet[u+4:]

            #print UDP headers
            print 'UDP  sport : ' + str(source_port) + ' dport : ' + str(dest_port)

    sockOUTPUT.send(packet)
	
	
sockINPUT.close()
sockOUTPUT.close()
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
gbg
@gbg Куратор тега Компьютерные сети
Любые ответы на любые вопросы
suseFirewall решает этот вопрос именно через iptables. Так что поставьте suseFirewall, задайте в нем нужное правило - и посмотрите, чего он натолкает в iptables.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы