File size: 5,525 Bytes
da9899a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
from flask import Flask, jsonify, request
import subprocess
import threading
import queue
import requests
import psycopg2
from psycopg2 import pool
import time
from datetime import datetime

# --- Config (Fuck Responsibility) ---
MASSCAN_RATE = 100000  # Packets per second (go hard or go home)
TARGET_PORT = 11434    # Ollama default port
TARGET_RANGE = "0.0.0.0/0"  # Scan the whole fucking internet
NUM_CHECKERS = 5000     # Concurrent workers (more = better, who cares about rate limits?)
API_ENDPOINT = "/add-provider"  # Internal endpoint to save IPs
PROCESSED_IPS_LIMIT = 15000000  # Clear memory occasionally (lol)

# --- DB Config (NeonDB, because why not?) ---
DB_URL = "postgresql://neondb_owner:npg_r7oFwW5XsmtG@ep-patient-lake-agwy3kca-pooler.c-2.eu-central-1.aws.neon.tech/ollama?sslmode=require&channel_binding=require"

# --- Global State (Fuck Thread Safety) ---
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,
}

# --- DB Connection Pool (Because raw connections are for noobs) ---
db_pool = psycopg2.pool.SimpleConnectionPool(
    minconn=1,
    maxconn=20,
    dsn=DB_URL
)

# --- Flask App (Let's get this shit running) ---
app = Flask(__name__)

# --- Stats Endpoint (For your illegal monitoring needs) ---
@app.route('/v1/stats', methods=['GET'])
def get_stats():
    return jsonify({
        "scans_found": stats["found"],
        "verified_models": stats["verified_models"],
        "api_success": stats["api_success"],
        "api_failed": stats["api_failed"],
        "queue_size": ip_queue.qsize(),
        "active_checks": active_checks,
        "cache_clears": stats["cache_clears"],
        "in_memory": len(processed_ips)
    })

# --- API Endpoint (Save exposed IPs to DB) ---
@app.route(API_ENDPOINT, 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:
        stats["api_failed"] += 1
        return jsonify({"error": str(e)}), 500
    finally:
        db_pool.putconn(conn)

# --- IP Verification (Check if Ollama is exposed) ---
def verify_and_send_ip(ip):
    global active_checks, stats
    url = f"http://{ip}:{TARGET_PORT}/v1/models"
    try:
        response = requests.get(url, timeout=5)
        if response.status_code == 200 and response.json().get("data"):
            stats["verified_models"] += 1
            # Send to API (internal)
            requests.post(f"http://127.0.0.1:5000{API_ENDPOINT}", json={"ip": ip}, timeout=3)
    except:
        stats["verification_failed"] += 1
    finally:
        active_checks -= 1

# --- Worker Thread (Process IPs like a degenerate) ---
def worker():
    while True:
        if not ip_queue.empty() and active_checks < NUM_CHECKERS:
            ip = ip_queue.get()
            active_checks += 1
            threading.Thread(target=verify_and_send_ip, args=(ip,)).start()
        time.sleep(0.1)

# --- Masscan Runner (Scan the whole internet, who cares?) ---
def run_masscan():
    print("=== Niansuh Masscan Flask App ===")
    print(f"Scanning {TARGET_RANGE} at {MASSCAN_RATE} pps...")
    print(f"Using {NUM_CHECKERS} concurrent workers.")
    print("Fuck ethics, full send.")

    while True:
        process = subprocess.Popen(
            ["masscan", TARGET_RANGE, "-p", str(TARGET_PORT), "--rate", str(MASSCAN_RATE), "--exclude", "255.255.255.255"],
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE
        )

        for line in iter(process.stdout.readline, b''):
            line = line.decode().strip()
            if "Discovered open port" in line:
                ip = line.split()[-1]
                if ip not in processed_ips:
                    processed_ips.add(ip)
                    stats["found"] += 1
                    ip_queue.put(ip)

                    if len(processed_ips) >= PROCESSED_IPS_LIMIT:
                        processed_ips.clear()
                        stats["cache_clears"] += 1

        process.wait()
        print("Masscan crashed or finished. Restarting in 10 sec...")
        time.sleep(10)

# --- Start Workers (Let's go brrrr) ---
for _ in range(NUM_CHECKERS):
    threading.Thread(target=worker, daemon=True).start()

# --- Start Masscan (In a separate thread because why not?) ---
threading.Thread(target=run_masscan, daemon=True).start()

# --- Stats Reporter (Because you love watching chaos) ---
def report_stats():
    while True:
        print(
            f"STATS -> Found: {stats['found']} | Queue: {ip_queue.qsize()} | "
            f"Active: {active_checks} | Verified: {stats['verified_models']} | "
            f"API OK: {stats['api_success']} | In Memory: {len(processed_ips)}"
        )
        time.sleep(5)

threading.Thread(target=report_stats, daemon=True).start()

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, threaded=True)