Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iptables ignore package send by scapy

For a Projekt at Scool i need to sniff the network traffic for a new tcp handshake package. I want to create automatically a new iptables rule for this tcp connection into a docker container.

#!/usr/bin/env python2

import subprocess
from scapy.all import *

def find_tcp_handshake(port, docker_ip):
    global SYN
    global ACK
    # sniff for new syn package and send the package to function process_handshake()
    sniff(lfilter=lambda x: x.haslayer(TCP) and str(x[TCP].dport) == port and x[TCP].flags & SYN and not x[TCP].flags & ACK, prn = lambda x:     process_handshake(paket = x, port = port, docker_ip = docker_ip))

def process_handshake(paket, port, docker_ip):
    # get the four tcp parameter (destination an source - port and ip)
    destination_port = port
    source_ip = str(paket[IP].src)
    source_port = str(paket[TCP].sport)
    # add the iptables rule
    add_ipt_rule(destination_ip = docker_ip, destination_port = destination_port, source_ip = source_ip, source_port = source_port)
    # remove the ethernet layer (make sometimes problems)
    paket = paket[IP]
    # remove checksums (make sometimes problems)
    del paket[TCP].chksum
    del paket[IP].chksum
    # this package will not arrive the docker container
    send(paket)

# funktion to send commands to bash
def command (c):
    return subprocess.Popen(c.split(" "), stdout=subprocess.PIPE).stdout.read().rstrip()

# this rules are created from docker by default with the argument -p 80:80. I've added the source_ip and source_port part
def add_ipt_rule(destination_ip, destination_port, source_ip, source_port):
    command("iptables -I DOCKER -d " + destination_ip + "/32 -s " + source_ip + " ! -i docker0 -o docker0 -p tcp -m tcp --dport " + destination_port + " -j     ACCEPT")
    command("iptables -t nat -I POSTROUTING -s " + destination_ip + "/32 -d " + destination_ip + "/32 -p tcp -m tcp --dport " + destination_port + " -j     MASQUERADE")
    command("iptables -t nat -I DOCKER ! -i docker0 -p tcp -m tcp -s " + source_ip + " --sport " + source_port + " --dport " + destination_port + " -j     DNAT --to-destination " + destination_ip + ":" + destination_port)

# my original script creates docker container itself and manage these in a sqlite database
def main():
    docker_ip = "127.17.0.2"
    port = "80"
    find_tcp_handshake(port = port, docker_ip = docker_ip)


# TCP-Flags for sniff rule (not all in use)
FIN = 0x01
SYN = 0x02
RST = 0x04
PSH = 0x08
ACK = 0x10
URG = 0x20
ECE = 0x40
CWR = 0x80

if __name__ == "__main__":
    main()

The sniffing is working and the iptables commands are working.

The problem is when i resend the package with scapy. It should be forwardet to the docker container. But this package never arrives the iptables rules. When i resend the package from client, the rule is working.

Is there a method on scapy to send a package into iptables?

like image 242
C. Schmid Avatar asked Dec 31 '25 17:12

C. Schmid


1 Answers

Scapy sends packet at a low level and they are not seen by netfilter. If you want to send packets seen by netfilter, either you can send them from another computer, or you can use the regular socket API to have the host's IP stack send packets for you.

like image 189
Pierre Avatar answered Jan 03 '26 07:01

Pierre



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!