2016-04-12 14 views
0

Full (ohne Funktion) Code unterPython3 Threading, versuchen mehrere IPs/Testport simultaineously

Voll (Arbeits, w/o Gewinde) ping Code hier: http://pastebin.com/KUYzNtT2

ich ein kleines geschrieben habe Skript, das macht folgende:

  1. Pull Netzwerk-Informationen aus einer Datenbank
  2. Ping jede IP in einem cidr (dh - 192.168.0.0/24); wenn es oben ist, um zu sehen, testen, ob ein bestimmt Port offen ist
  3. Anzeige der Ergebnisse

Dies funktioniert gut, aber ich mag Einfädeln implementieren, um das Skript läuft schneller zu machen; genau wie ich Tausende von IPs scannen muss und es dauert ewig.

Ich habe mit Threading-Tutorials herumgespielt, aber ich kann nicht begreifen, wie man es in meinem Skript implementiert.

Alle Gedanken oder Vorschläge sind willkommen.

EDIT: Ich ging in eine andere Richtung, basierend auf diesem Handbuch: http://chriskiehl.com/article/parallelism-in-one-line/

Nun betreibe ich das Programm und erhalten: File "port_test.py", line 39, in display_results for (client, location, cidr) in results: ValueError: too many values to unpack (expected 3) und ich verstehe nicht, warum. Gedanken?

** EDIT: Ich denke, ich habe herausgefunden, warum es fehlgeschlagen, sieht aus wie pool.map erwartet nur einen Datenpunkt. Wenn ich nur die Datenbank nach CIDRs anstelle der anderen zwei Spalten abfrage, beginnt das Programm Daten auszuspucken (VIEL schneller als vorher). So, jetzt muss ich herausfinden, wie die beiden anderen Spalten zu den Ergebnissen hinzufügen, dann die Ergebnisse sortieren, um sie sinnvoll sind (es gibt keine, um die Ergebnisse, die ich sinnvoll annehmen macht)

#! /usr/bin/python 
# Import modules 
import socket 
import subprocess 
import ipaddress 
import mysql.connector 
import configparser 
import logging 
import coloredlogs 
from multiprocessing.dummy import Pool as ThreadPool 

#logging.basicConfig(format='%(levelname)s:%(message)s',level=logging.INFO) 


coloredlogs.install(level='DEBUG') 
coloredlogs.DEFAULT_LOG_FORMAT = '%(asctime)s -- %(message)s' 
# read from the config file 
config = configparser.ConfigParser() 
config.read('config.ini') 
db=config['mysql'] 
net=config['network'] 
port = int(net['port']) 

# create the connection, connect, and setup the query 
cnx = mysql.connector.connect(user=db['user'], database=db['database'], password=db['password']) 
cursor = cnx.cursor() 

query = ("select fw.net_cidr as cidr " 
     "from firewalls fw " 
      "left join clients c on c.id = fw.client_id " 
      "left join locations l on l.id = fw.location_id " 
       "where fw.net_cidr <> '' and c.active = '1' and fw.active = '1'") 

cursor.execute(query) 
results = cursor.fetchall() 

def display_results(results): 
# execute and display the results 
    for (cidr) in results: 
      logging.info("{} --> ".format(cidr)) 
      try: 
       # Prompt the user to input a network address 
       net_addr = str(cidr) 

       # Create the network 
       ip_net = ipaddress.ip_network(net_addr) 

       # Get all hosts on that network 
       all_hosts = list(ip_net.hosts()) 
      except ValueError as e: 
       logging.warning(e) 
       continue 

      # For each IP address in the subnet, test to see if port 3389 is open 
      for i in range(len(all_hosts)): 
       sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
       sock.settimeout(.25) 
       result = sock.connect_ex((str(all_hosts[i]),port)) 
       if result == 0: 
         logging.info(str(all_hosts[i]) + ": " + net['port'] + " is open") 
      else: 
        logging.debug(str(all_hosts[i]) + ": " + net['port'] + " is not open") 

# make a pool of workers 
pool = ThreadPool(4) 

# ping the cidrs in their own thread 
pool.map(display_results, results) 
pool.close() 
pool.join() 

# close the database connection 
cursor.close() 
cnx.close() 
+0

Was ist Ihre Frage? RT funktioniert nicht? Du solltest [mcve] lesen. –

+1

Siehe [diese Antwort] (http://stackoverflow.com/a/35925129/1172714). Sie müssen Ihre Threads verwenden, um andere Daten zu verwenden (sie können einen Cursor nicht für eine einzelne Datenbankabfrage verwenden). Sie haben vier Threads, die eine Funktion aufrufen, die ein Argument ohne Argument erfordert. Dann konsumieren Sie die Ergebnisse des Cursors, nachdem Sie versucht haben, die Threads zu starten, und schließen dann die Verbindung, ohne zu warten, ob die Threads beendet sind. (aber sie sind an diesem Punkt, weil sie die Funktion mit der falschen Anzahl von Argumenten nicht aufrufen konnten) – dsh

+2

auch, schauen Sie sich das Modul concurrent.futures an, das sowohl ProcessPoolExecutor als auch ThreadPoolExecutor hat. Sie haben schöne Beispiele in den Dokumenten. Python 3: https://docs.python.org/3/library/concurrent.futures.html Python 2.7: http: // pythonhosted.org/futures/ –

Antwort

-1

greifen alle Daten zunächst und speichern Sie es in einem Queue.

Erstellen einer Funktion, die kontinuierlich verläuft, bis die Queue leer ist (dh while my_queue.empty() is False.

Schnappen das erste Objekt in dem Queue mit Queue ‚s get() Methode.

Dann es verarbeiten.

Initialize so viele Threads wie Sie wollen, werden sie ausgeführt, bis die Queue leer ist.