2017-08-15 4 views
2

Für ein Projekt bei Scool muss ich den Netzwerkverkehr für ein neues tcp-Handshake-Paket schnuppern. Ich möchte automatisch eine neue iptables-Regel für diese TCP-Verbindung in einen Andock-Container erstellen.iptables ignore pakage senden von scapy

#!/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 pakage and send the pakage 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 pakage 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() 

Das Sniffing funktioniert und die iptables-Befehle funktionieren.

Das Problem ist, wenn ich die Verpackung mit scapy erneut sende. Es sollte zum Dockercontainer weitergeleitet werden. Aber dieses Paket kommt nie zu den iptables-Regeln. Wenn ich das Paket vom Client erneut sende, funktioniert die Regel.

Gibt es eine Methode auf Scapy, um ein Paket in iptables zu senden?

Vielen Dank für Hilfe

Antwort

1

scapy sendet auf einem niedrigen Niveau Paket und sie werden nicht von netfilter gesehen. Wenn Sie Pakete senden möchten, die von netfilter gesehen werden, können Sie sie entweder von einem anderen Computer aus senden oder Sie können die reguläre API socket verwenden, damit der IP-Stack des Hosts Pakete für Sie sendet.