Ollama / app.py
rkihacker's picture
Update app.py
d123f27 verified
raw
history blame
5.62 kB
from flask import Flask, jsonify, render_template_string
import subprocess
import threading
import queue
import requests
import psycopg2
from psycopg2 import pool
import time
from datetime import datetime
import re
# --- Config ---
MASSCAN_RATE = 10000 # Reduced to avoid ISP blocks
TARGET_PORT = 11434 # Ollama default port
TARGET_RANGE = "0.0.0.0/0" # Scan everything
NUM_CHECKERS = 50 # Workers
PROCESSED_IPS_LIMIT = 1000000
# --- DB Config ---
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,
"cache_clears": 0,
"last_scan_time": time.time(),
}
# --- DB Connection 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():
return render_template_string('''
<!DOCTYPE html>
<html>
<head>
<title>Niansuh Masscan - Live Stats</title>
<meta http-equiv="refresh" content="2">
<style>
body { font-family: monospace; background: #000; color: #0f0; }
.stats { font-size: 1.2em; }
.scanned { color: #ff0; }
.verified { color: #0ff; }
.queue { color: #f0f; }
</style>
</head>
<body>
<h1>NIANSUH MASSCAN - LIVE STATS</h1>
<div class="stats">
<p>πŸ” <span class="scanned">Scanned IPs: {{ stats.found }}</span></p>
<p>βœ… <span class="verified">Verified Ollama: {{ stats.verified_models }}</span></p>
<p>πŸš€ <span class="queue">Queue: {{ queue_size }}</span></p>
<p>πŸ”„ Active Checks: {{ active_checks }}</p>
<p>πŸ—ƒοΈ In Memory: {{ in_memory }}</p>
<p>⏱️ Uptime: {{ uptime }} seconds</p>
</div>
</body>
</html>
''', stats=stats, queue_size=ip_queue.qsize(), active_checks=active_checks, in_memory=len(processed_ips), uptime=int(time.time() - stats["last_scan_time"]))
# --- Stats API ---
@app.route('/v1/stats')
def get_stats():
return jsonify({
**stats,
"queue_size": ip_queue.qsize(),
"active_checks": active_checks,
"in_memory": len(processed_ips),
"uptime": int(time.time() - stats["last_scan_time"])
})
# --- API Endpoint (Save IPs) ---
@app.route('/add-provider', methods=['POST'])
def add_provider():
ip = request.json.get('ip')
if not ip:
stats["api_failed"] += 1
return jsonify({"error": "No IP provided"}), 400
conn = db_pool.getconn()
try:
with conn.cursor() as cur:
cur.execute("""
INSERT INTO providers (ip, port, first_seen, last_seen)
VALUES (%s, %s, %s, %s)
ON CONFLICT (ip) DO UPDATE SET last_seen = %s
""", (ip, TARGET_PORT, datetime.utcnow(), datetime.utcnow(), datetime.utcnow()))
conn.commit()
stats["api_success"] += 1
return jsonify({"status": "success"}), 200
except Exception as e:
print(f"DB Error: {e}")
stats["api_failed"] += 1
return jsonify({"error": str(e)}), 500
finally:
db_pool.putconn(conn)
# --- Verify Ollama Instance ---
def verify_and_send_ip(ip):
global active_checks
active_checks += 1
url = f"http://{ip}:{TARGET_PORT}/api/tags"
try:
response = requests.get(url, timeout=3)
if response.status_code == 200 and "models" in response.json():
stats["verified_models"] += 1
requests.post("http://127.0.0.1:5000/add-provider", json={"ip": ip}, timeout=2)
except:
stats["verification_failed"] += 1
finally:
active_checks -= 1
# --- Worker (Process IPs) ---
def worker():
while True:
if not ip_queue.empty():
ip = ip_queue.get()
verify_and_send_ip(ip)
time.sleep(0.01)
# --- Masscan Runner (Now Works) ---
def run_masscan():
print("=== NIANSUH MASSCAN STARTED ===")
print(f"Scanning {TARGET_RANGE} at {MASSCAN_RATE} pps...")
# Run masscan with sudo (required for raw sockets)
process = subprocess.Popen(
["sudo", "masscan", TARGET_RANGE, "-p", str(TARGET_PORT), "--rate", str(MASSCAN_RATE), "--output-format", "list"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True
)
for line in process.stdout:
line = line.strip()
if re.match(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$", line): # Match IPs
if line not in processed_ips:
processed_ips.add(line)
stats["found"] += 1
ip_queue.put(line)
if len(processed_ips) >= PROCESSED_IPS_LIMIT:
processed_ips.clear()
stats["cache_clears"] += 1
print("Masscan stopped. Restarting in 5 sec...")
time.sleep(5)
run_masscan()
# --- Start Everything ---
if __name__ == '__main__':
# Start workers
for _ in range(NUM_CHECKERS):
threading.Thread(target=worker, daemon=True).start()
# Start masscan in a separate thread
threading.Thread(target=run_masscan, daemon=True).start()
# Start Flask
app.run(host='0.0.0.0', port=5000, threaded=True)