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)