Browse Source

Añadir 'C/VPN.py'

yosoyhendrix 1 day ago
parent
commit
caebd7f160
1 changed files with 320 additions and 0 deletions
  1. 320 0
      C/VPN.py

+ 320 - 0
C/VPN.py

@@ -0,0 +1,320 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+"""
+=============================================================================
+PROXY VPN DUAL (TCP + TLS) - ULTIMATE PYTHON EDITION
+Características: IPv4 & IPv6 (Dual-Stack), Multiplexación 80/443, 
+Fake Web Nginx, Anti-Flood en RAM, Mensajes Rotativos y Custom Headers.
+=============================================================================
+"""
+
+import socket
+import ssl
+import threading
+import select
+import time
+import datetime
+import os
+import sys
+
+# --- CONFIGURACIÓN BASE ---
+PORT_TCP = 80
+PORT_TLS = 443
+SSH_HOST = "127.0.0.1"
+SSH_PORT = 22
+CERT_FILE = "/root/cert.pem"
+KEY_FILE = "/root/key.pem"
+LOG_FILE = "/root/proxy-dual-python.log"
+
+# --- SEGURIDAD ANTI-FLOOD Y BANEO ---
+AUTO_BAN_STRIKES = 20    # Límite de conexiones por segundo exacto (tolera navegadores)
+BAN_TIME = 3600          # Castigo de 1 hora en segundos
+ip_database = {}         # Base de datos en memoria RAM
+db_lock = threading.Lock()
+
+# --- FAKE WEB RESPONSES ---
+FAKE_WEB_TCP = (
+    b"HTTP/1.1 400 Bad Request\r\n"
+    b"Server: nginx/1.24.0\r\n"
+    b"Content-Type: text/html\r\n"
+    b"Connection: close\r\n\r\n"
+    b"<html><body><center><h1>400 Bad Request</h1></center><hr><center>nginx/1.24.0</center></body></html>\r\n"
+)
+
+FAKE_WEB_TLS = (
+    b"HTTP/1.1 400 OK\r\n"
+    b"Server: nginx/1.21.0\r\n"
+    b"Content-Type: text/html\r\n"
+    b"Connection: close\r\n\r\n"
+    b"<html><body><center><h1>400 Bad Request</h1></center></body></html>\r\n"
+)
+
+# --- MENSAJES ROTATIVOS ---
+MENSAJES = [
+    "🚀 CONEXION ESTABLECIDA", 
+    "🛡️ CIFRADO MILITAR ACTIVO", 
+    "🔋 MODO SIGILO SSL OK", 
+    "Pfsense", 
+    "OPNsense", 
+    "VyOS", 
+    "Claro", 
+    "Google", 
+    "TNSR", 
+    "🌐 BYPASS DE FIREWALL OK"
+]
+msg_idx = 0
+msg_lock = threading.Lock()
+
+
+# --- FUNCIONES DE REGISTRO (LOGS) ---
+def write_log(ip, proto, msg):
+    try:
+        # Limpiar la etiqueta de IPv4-mapped-IPv6 para que el log se vea limpio
+        if ip and ip.startswith("::ffff:"):
+            ip = ip.replace("::ffff:", "")
+            
+        timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
+        log_line = f"[{timestamp}] [{proto}] [{ip if ip else 'SISTEMA'}] {msg}"
+        
+        print(log_line)
+        with open(LOG_FILE, "a") as f:
+            f.write(log_line + "\n")
+    except Exception:
+        pass
+
+
+# --- MOTOR ANTI-FLOOD (AUTO-BAN) ---
+def check_and_update_ip(ip):
+    global ip_database
+    now = time.time()
+    
+    with db_lock:
+        # Limpieza periódica de IPs viejas para no saturar la RAM
+        if len(ip_database) > 1000:
+            ip_database = {k: v for k, v in ip_database.items() if v["ban_until"] > now or (now - v["last_connect"] < 60)}
+
+        if ip not in ip_database:
+            ip_database[ip] = {"last_connect": now, "strikes": 1, "ban_until": 0}
+            return 1
+
+        record = ip_database[ip]
+
+        # ¿Está baneado?
+        if record["ban_until"] > now:
+            return 0 
+
+        # Tolerancia por segundo exacto
+        if int(now) == int(record["last_connect"]):
+            record["strikes"] += 1
+            if record["strikes"] > AUTO_BAN_STRIKES:
+                record["ban_until"] = now + BAN_TIME
+                return -1 # Acaba de ser baneado
+        else:
+            # Nuevo segundo, resetear contador
+            record["strikes"] = 1
+            record["last_connect"] = now
+
+        return 1
+
+
+# --- MANEJADOR PRINCIPAL DE CONEXIONES ---
+def connection_handler(client_sock, client_addr, is_tls):
+    proto_name = "TLS" if is_tls else "TCP"
+    client_ip = client_addr[0]
+    
+    # Extraer IP limpia para los logs
+    clean_ip = client_ip.replace("::ffff:", "") if client_ip.startswith("::ffff:") else client_ip
+
+    # 1. Filtro de Seguridad
+    sec_status = check_and_update_ip(client_ip)
+    if sec_status == 0:
+        client_sock.close()
+        return
+    elif sec_status == -1:
+        write_log(clean_ip, proto_name, "⛔ IP Baneada (Intento de Flood bloqueado)")
+        client_sock.close()
+        return
+
+    # 2. Envoltura SSL (Solo para el puerto 443)
+    if is_tls:
+        try:
+            context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
+            context.load_cert_chain(certfile=CERT_FILE, keyfile=KEY_FILE)
+            client_sock.settimeout(5.0) # Tiempo máximo para el handshake
+            client_sock = context.wrap_socket(client_sock, server_side=True)
+        except ssl.SSLError:
+            # Probablemente un escáner escaneando puertos SSL con texto plano
+            client_sock.close()
+            return
+        except Exception as e:
+            client_sock.close()
+            return
+
+    # 3. Lectura del Payload (Con Timeout para soportar NetMod)
+    client_sock.settimeout(3.0)
+    try:
+        buffer = client_sock.recv(16384)
+    except socket.timeout:
+        buffer = b"" # Túnel Silencioso (NetMod)
+    except Exception:
+        client_sock.close()
+        return
+
+    # 4. Conectar al destino SSH Local
+    try:
+        target_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        target_sock.settimeout(5.0)
+        target_sock.connect((SSH_HOST, SSH_PORT))
+    except Exception:
+        write_log(clean_ip, proto_name, "❌ Error conectando a servidor SSH interno")
+        client_sock.close()
+        return
+
+    # 5. Lógica de Enrutamiento y Camuflaje
+    if buffer:
+        if buffer.startswith(b"SSH-"):
+            write_log(clean_ip, proto_name, "✅ Túnel Directo SSH")
+            target_sock.sendall(buffer)
+            
+        elif b"HTTP/" in buffer and b"Upgrade: websocket" not in buffer:
+            # Es un navegador web o un bot escáner
+            write_log(clean_ip, proto_name, "🕵️ Escáner detectado. Respondiendo Fake Web (400 OK).")
+            fake_resp = FAKE_WEB_TLS if is_tls else FAKE_WEB_TCP
+            client_sock.sendall(fake_resp)
+            client_sock.close()
+            target_sock.close()
+            return
+            
+        else:
+            # Es una petición de inyección (NetMod / HTTP Custom)
+            global msg_idx
+            with msg_lock:
+                status_msg = MENSAJES[msg_idx]
+                msg_idx = (msg_idx + 1) % len(MENSAJES)
+
+            srv_header = "nginx/1.21.0" if is_tls else "nginx/1.24.0"
+            agent_header = "Gemini-Ultimate-Python-TLS" if is_tls else "Gemini-Ultimate-Python-TCP"
+            
+            response = (
+                f"HTTP/1.1 101 {status_msg}\r\n"
+                f"Server: {srv_header}\r\n"
+                f"X-Forwarded-For: 127.0.0.1\r\n"
+                f"Content-Type: text/html; charset=UTF-8\r\n"
+                f"Proxy-Connection: keep-alive\r\n"
+                f"Cache-Control: no-cache\r\n"
+                f"X-Proxy-Agent: {agent_header}\r\n"
+                f"Connection: Upgrade\r\n"
+                f"Upgrade: websocket\r\n\r\n"
+            )
+            
+            client_sock.sendall(response.encode('utf-8'))
+            write_log(clean_ip, proto_name, f"✅ Túnel Inyectado Establecido: {status_msg}")
+
+            # Reenviar si el cliente mandó carga SSH extra junto con el Header HTTP
+            partes = buffer.split(b"\r\n\r\n", 1)
+            if len(partes) > 1 and partes[1]:
+                target_sock.sendall(partes[1])
+    else:
+        # Buffer vacío (Timeout)
+        write_log(clean_ip, proto_name, "✅ Túnel Modo Silencioso (Stunnel)")
+
+    # 6. Bucle Multiplexor (El Puente de Red)
+    client_sock.settimeout(None)
+    target_sock.settimeout(None)
+    sockets = [client_sock, target_sock]
+    
+    tx_bytes = 0
+    rx_bytes = 0
+
+    try:
+        while True:
+            r, _, _ = select.select(sockets, [], [], 300) # 5 minutos de inactividad max
+            if not r:
+                break
+            
+            if client_sock in r:
+                data = client_sock.recv(16384)
+                if not data:
+                    break
+                target_sock.sendall(data)
+                rx_bytes += len(data)
+                
+            if target_sock in r:
+                data = target_sock.recv(16384)
+                if not data:
+                    break
+                client_sock.sendall(data)
+                tx_bytes += len(data)
+    except Exception:
+        pass
+    finally:
+        total_mb = (tx_bytes + rx_bytes) / (1024 * 1024)
+        if total_mb > 0.05:
+            write_log(clean_ip, proto_name, f"[*] Conexión finalizada. Tráfico: {total_mb:.2f} MB")
+        client_sock.close()
+        target_sock.close()
+
+
+# --- SERVIDORES DE ESCUCHA (DUAL-STACK IPv4 e IPv6) ---
+def server_listener(port, is_tls):
+    proto_name = "TLS" if is_tls else "TCP"
+    try:
+        # MAGIA DUAL-STACK: AF_INET6 con IPV6_V6ONLY en 0 escucha IPv4 e IPv6 simultáneamente
+        server = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
+        server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+        
+        # Desactivar exclusividad IPv6 (Permite mapear IPv4 a IPv6)
+        try:
+            server.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0)
+        except AttributeError:
+            pass # Si el sistema no lo soporta, sigue adelante
+            
+        server.bind(("", port))
+        server.listen(500)
+        
+        write_log(None, proto_name, f"Escuchando en puerto {port} (IPv4 e IPv6)...")
+        
+        while True:
+            client_sock, client_addr = server.accept()
+            # Desplegar un hilo por cada cliente conectado
+            t = threading.Thread(target=connection_handler, args=(client_sock, client_addr, is_tls))
+            t.daemon = True
+            t.start()
+            
+    except Exception as e:
+        write_log(None, "SISTEMA", f"❌ Error fatal en puerto {port}: {e}")
+        sys.exit(1)
+
+
+# --- HILO MAESTRO ORQUESTADOR ---
+if __name__ == "__main__":
+    # Ignorar errores de "Broken Pipe" que crashean los servidores
+    if hasattr(signal, 'SIGPIPE'):
+        signal.signal(signal.SIGPIPE, signal.SIG_IGN)
+
+    if not os.path.exists(CERT_FILE) or not os.path.exists(KEY_FILE):
+        write_log(None, "SISTEMA", f"⚠️ ADVERTENCIA: No se encontraron los certificados en {CERT_FILE}. TLS fallará.")
+
+    write_log(None, "SISTEMA", "=========================================================")
+    write_log(None, "SISTEMA", "🚀 PROXY DUAL PYTHON INICIADO (Ultimate Edition)")
+    write_log(None, "SISTEMA", "🛡️  IPv4/IPv6 Dual-Stack | Anti-Flood RAM | Fake Web Nginx")
+    write_log(None, "SISTEMA", "=========================================================")
+
+    # Lanzar servidor TCP (Puerto 80)
+    t_tcp = threading.Thread(target=server_listener, args=(PORT_TCP, False))
+    t_tcp.daemon = True
+    t_tcp.start()
+
+    # Lanzar servidor TLS (Puerto 443)
+    t_tls = threading.Thread(target=server_listener, args=(PORT_TLS, True))
+    t_tls.daemon = True
+    t_tls.start()
+
+    # Mantener el script vivo infinitamente
+    try:
+        while True:
+            time.sleep(86400)
+    except KeyboardInterrupt:
+        write_log(None, "SISTEMA", "Apagando el servidor Proxy Dual...")
+        sys.exit(0)