from flask import Flask, render_template_string import subprocess import threading import queue import requests import time import re from datetime import datetime import psycopg2 from psycopg2 import pool # --- Config --- TARGET_PORT = 11434 # Ollama port NUM_CHECKERS = 50 # Workers DB_URL = "postgresql://neondb_owner:npg_r7oFwW5XsmtG@ep-patient-lake-agwy3kca-pooler.c-2.eu-central-1.aws.neon.tech/ollama?sslmode=require" # --- Global State --- processed_ips = set() ip_queue = queue.Queue() active_checks = 0 stats = { "found": 0, "verified_models": 0, "verification_failed": 0, "api_success": 0, "api_failed": 0, "start_time": time.time() } # --- DB Pool --- db_pool = psycopg2.pool.SimpleConnectionPool( minconn=1, maxconn=10, dsn=DB_URL ) # --- Flask App --- app = Flask(__name__) # --- Homepage (Real-Time Stats) --- @app.route('/') def home(): uptime = int(time.time() - stats["start_time"]) return render_template_string(''' Niansuh ZMap Scanner

NIANSUH ZMAP SCANNER

🔍 Scanned IPs: {{ stats.found }}

✅ Verified Ollama: {{ stats.verified_models }}

🚀 Queue Size: {{ queue_size }}

🔄 Active Checks: {{ active_checks }}

⏱️ Uptime: {{ uptime }}s

''', stats=stats, queue_size=ip_queue.qsize(), active_checks=active_checks, uptime=uptime) # --- Verify Ollama --- def verify_ollama(ip): global active_checks, stats active_checks += 1 try: url = f"http://{ip}:{TARGET_PORT}/api/tags" response = requests.get(url, timeout=3) if response.status_code == 200 and "models" in response.json(): stats["verified_models"] += 1 conn = db_pool.getconn() try: with conn.cursor() as cur: cur.execute(""" INSERT INTO providers (ip, port, first_seen) VALUES (%s, %s, %s) ON CONFLICT (ip) DO NOTHING """, (ip, TARGET_PORT, datetime.utcnow())) conn.commit() stats["api_success"] += 1 except Exception as e: print(f"DB Error: {e}") stats["api_failed"] += 1 finally: db_pool.putconn(conn) except: stats["verification_failed"] += 1 finally: active_checks -= 1 # --- Worker --- def worker(): while True: if not ip_queue.empty(): ip = ip_queue.get() verify_ollama(ip) time.sleep(0.01) # --- ZMap Scanner --- def run_zmap(): print("=== Starting ZMap Scan ===") process = subprocess.Popen( ["sudo", "zmap", "-p", str(TARGET_PORT), "-o", "-"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True ) for line in process.stdout: ip = line.strip() if re.match(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$", ip): if ip not in processed_ips: processed_ips.add(ip) stats["found"] += 1 ip_queue.put(ip) print("ZMap finished. Restarting in 5 sec...") time.sleep(5) run_zmap() # --- Start --- if __name__ == '__main__': # Start workers for _ in range(NUM_CHECKERS): threading.Thread(target=worker, daemon=True).start() # Start ZMap threading.Thread(target=run_zmap, daemon=True).start() app.run(host='0.0.0.0', port=5000, threaded=True)