Forráskód Böngészése

Actualizar 'Pythonv1.py'

yosoyhendrix 1 hete
szülő
commit
f88794ea6b
1 módosított fájl, 78 hozzáadás és 86 törlés
  1. 78 86
      Pythonv1.py

+ 78 - 86
Pythonv1.py

@@ -1,16 +1,8 @@
 # -*- coding: utf-8 -*-
 
 # ==============================================================================
-# PROXY MULTIFILAMENTADO DE ALTA DISPONIBILIDAD - VERSIÓN PYTHON 3
-#
-# CARACTERÍSTICAS PRINCIPALES:
-# 1. Rotación de Mensajes: Cada respuesta HTTP 101 varía cíclicamente.
-# 2. Soporte Dual Stack: Escucha en IPv4 (0.0.0.0) e IPv6 (::) simultáneamente.
-# 3. Thread-Safe: Uso de Locks para evitar colisiones entre hilos.
-# 4. Gestión de Logs: Rotación automática para evitar saturación de disco.
-# 5. Rate-Limiting: Protección básica contra ataques de inundación por IP.
+# PROXY MULTIFILAMENTADO PROFESIONAL - VERSIÓN ULTRA-ROBUSTA (PYTHON 3)
 # ==============================================================================
-
 #screen -dmS badvpn2 /bin/badvpn-udpgw --listen-addr 127.0.0.1:7300 --max-clients 1000 --max-connections-for-client 100
 #screen -dmS pydic-80 python3 /root/Pythonv1.py 8080
 
@@ -27,15 +19,28 @@ import itertools
 IPV4_ADDR = '0.0.0.0'
 IPV6_ADDR = '::'
 LISTENING_PORT = int(sys.argv[1]) if sys.argv[1:] else 8080
+DEFAULT_HOST = '127.0.0.1:223'
 
-# --- CONFIGURACIÓN DE SEGURIDAD ---
+# --- CONFIGURACIÓN DE SEGURIDAD AVANZADA ---
 MAX_CONNECTIONS = 1000
-CONNECTION_COOLDOWN = 5  # Segundos entre conexiones de la misma IP
-TIMEOUT = 60             # Tiempo de espera para sockets
-BUFLEN = 16384           # 16KB de buffer para mayor velocidad
+CONNECTION_COOLDOWN = 0.5
+TIMEOUT = 60
+BUFLEN = 16384
+
+# 🛡️ LISTA BLANCA DE IPs (Si está vacía, permite todas)
+# Ejemplo: ALLOWED_IPS = ['127.0.0.1', '192.168.1.50']
+ALLOWED_IPS = []
+
+# 🚫 LISTA NEGRA DE DOMINIOS (Bloquea conexiones a estos hosts)
+BLOCKED_HOSTS = ['sitio-prohibido.com', 'anuncios.malware.net']
 
-# --- LISTA DE MENSAJES ROTATIVOS ---
-# Se enviarán en la línea de estado de la respuesta HTTP 101
+# 📑 ENCABEZADOS A INYECTAR (Se añaden a la comunicación con el destino)
+CUSTOM_HEADERS = {
+    "X-Proxy-Agent": "Gemini-Ultra-Robust-v3",
+    "X-Forwarded-For-Proxy": "True"
+}
+
+# --- MENSAJES ROTATIVOS ---
 MENSAJES = [
     "Pfsense",
     "OPNsense",
@@ -51,25 +56,19 @@ MENSAJES = [
     "TNSR"
 ]
 
-# Inicialización del iterador cíclico y lock de seguridad
 mensaje_cycle = itertools.cycle(MENSAJES)
 cycle_lock = threading.Lock()
 
-# --- CONFIGURACIÓN DE LOGS ---
-LOG_FILE = 'proxy_server.log'
+# --- SISTEMA DE LOGS ---
+LOG_FILE = 'proxy_avanzado.log'
 def setup_logger():
-    logger = logging.getLogger("ProxyLogger")
+    logger = logging.getLogger("ProxyAvanzado")
     logger.setLevel(logging.INFO)
     formatter = logging.Formatter('%(asctime)s [%(levelname)s] %(message)s')
-    
-    # Rotación de logs: 5MB por archivo, máximo 3 backups
-    handler = logging.handlers.RotatingFileHandler(LOG_FILE, maxBytes=5*1024*1024, backupCount=3)
+    handler = logging.handlers.RotatingFileHandler(LOG_FILE, maxBytes=10*1024*1024, backupCount=5)
     handler.setFormatter(formatter)
-    
-    # Salida a consola
     console = logging.StreamHandler()
     console.setFormatter(formatter)
-    
     logger.addHandler(handler)
     logger.addHandler(console)
     return logger
@@ -85,50 +84,59 @@ class ConnectionHandler(threading.Thread):
         self.client = client_socket
         self.addr = addr
         self.target = None
-        self.log_id = f"{addr[0]}:{addr[1]}"
+        self.log_id = "{}:{}".format(addr[0], addr[1])
 
     def finish(self):
-        """Cierra todos los recursos de la conexión de forma segura."""
         for s in [self.client, self.target]:
             if s:
-                try:
-                    s.close()
-                except:
-                    pass
+                try: s.close()
+                except: pass
         conn_limit.release()
 
+    def is_ip_allowed(self, ip):
+        if not ALLOWED_IPS: return True
+        return ip in ALLOWED_IPS
+
+    def is_host_blocked(self, target_str):
+        host = target_str.split(':')[0].lower()
+        return host in BLOCKED_HOSTS
+
     def run(self):
         try:
-            # 1. Leer petición inicial
+            # Validar IP en lista blanca
+            if not self.is_ip_allowed(self.addr[0]):
+                log.warning("[{}] IP no autorizada. Cerrando.".format(self.log_id))
+                return
+
             data = self.client.recv(BUFLEN)
-            if not data:
+            if not data: return
+
+            headers_text = data.decode('latin-1', errors='ignore')
+            target_info = self.extract_header(headers_text, 'X-Real-Host') or DEFAULT_HOST
+
+            # Validar dominio bloqueado
+            if self.is_host_blocked(target_info):
+                log.warning("[{}] Intento de acceso a host bloqueado: {}".format(self.log_id, target_info))
+                self.client.sendall(b"HTTP/1.1 403 Forbidden\r\n\r\n")
                 return
 
-            # 2. Determinar destino (Header X-Real-Host o Default)
-            headers = data.decode('latin-1', errors='ignore')
-            target_info = self.extract_header(headers, 'X-Real-Host') or "127.0.0.1:22"
-            
-            # 3. Obtener mensaje rotativo de forma segura
             with cycle_lock:
                 msg = next(mensaje_cycle)
 
-            # 4. Intentar conectar al destino
             if not self.connect_to_target(target_info):
+                log.error("[{}] Error conectando a {}".format(self.log_id, target_info))
                 return
 
-            # 5. Enviar respuesta con el mensaje rotado
-            resp = (f"HTTP/1.1 101 {msg}\r\n"
-                    f"Connection: Upgrade\r\n"
-                    f"Upgrade: websocket\r\n\r\n").encode('utf-8')
+            # Respuesta al cliente
+            resp = "HTTP/1.1 101 {}\r\nConnection: Upgrade\r\nUpgrade: websocket\r\n\r\n".format(msg).encode('utf-8')
             self.client.sendall(resp)
             
-            log.info(f"[{self.log_id}] Conectado a {target_info} | Mensaje: {msg}")
+            log.info("[{}] OK -> {} | Msg: {}".format(self.log_id, target_info, msg))
 
-            # 6. Iniciar túnel bidireccional
             self.bridge()
 
         except Exception as e:
-            log.error(f"[{self.log_id}] Error: {e}")
+            log.error("[{}] Error: {}".format(self.log_id, e))
         finally:
             self.finish()
 
@@ -140,94 +148,78 @@ class ConnectionHandler(threading.Thread):
 
     def connect_to_target(self, target_str):
         try:
-            parts = target_str.split(':')
-            host = parts[0]
-            port = int(parts[1]) if len(parts) > 1 else 22
+            host, port = (target_str.split(':') + [22])[:2]
+            port = int(port)
             
-            # Soporte IPv4 e IPv6 automático
             infos = socket.getaddrinfo(host, port, socket.AF_UNSPEC, socket.SOCK_STREAM)
             for res in infos:
-                af, socktype, proto, canonname, sa = res
+                af, socktype, proto, _, sa = res
                 try:
                     self.target = socket.socket(af, socktype, proto)
                     self.target.settimeout(10)
                     self.target.connect(sa)
                     return True
                 except:
+                    if self.target: self.target.close()
                     continue
             return False
-        except:
-            return False
+        except: return False
 
     def bridge(self):
-        """Mueve datos entre cliente y destino usando select."""
         sockets = [self.client, self.target]
         while True:
-            readable, _, error = select.select(sockets, [], sockets, TIMEOUT)
-            if error or not readable:
-                break
-            
-            for s in readable:
-                other = self.target if s is self.client else self.client
-                try:
+            try:
+                readable, _, error = select.select(sockets, [], sockets, TIMEOUT)
+                if error or not readable: break
+                for s in readable:
+                    other = self.target if s is self.client else self.client
                     chunk = s.recv(BUFLEN)
-                    if not chunk:
-                        return
+                    if not chunk: return
                     other.sendall(chunk)
-                except:
-                    return
+            except: break
 
 def main():
-    # Crear sockets de escucha
     listeners = []
-    for addr_info in [(socket.AF_INET, IPV4_ADDR), (socket.AF_INET6, IPV6_ADDR)]:
+    for af, addr in [(socket.AF_INET, IPV4_ADDR), (socket.AF_INET6, IPV6_ADDR)]:
         try:
-            s = socket.socket(addr_info[0], socket.SOCK_STREAM)
+            s = socket.socket(af, socket.SOCK_STREAM)
             s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
-            if addr_info[0] == socket.AF_INET6:
-                s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 1)
-            s.bind((addr_info[1], LISTENING_PORT))
+            if af == socket.AF_INET6:
+                try: s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 1)
+                except: pass
+            s.bind((addr, LISTENING_PORT))
             s.listen(128)
             listeners.append(s)
-            log.info(f"Escuchando en {addr_info[1]}:{LISTENING_PORT}")
+            log.info("Escuchando en {}:{}".format(addr, LISTENING_PORT))
         except Exception as e:
-            log.warning(f"No se pudo abrir socket en {addr_info[1]}: {e}")
+            log.debug("Interfaz {} ocupada: {}".format(addr, e))
 
     if not listeners:
-        log.critical("No hay sockets disponibles. Saliendo.")
+        log.critical("No se pudo iniciar ningun listener.")
         return
 
-    log.info("Servidor Proxy iniciado. Presiona Ctrl+C para salir.")
-    
     try:
         while True:
             r, _, _ = select.select(listeners, [], [])
             for s in r:
                 client, addr = s.accept()
-                
-                # Control de frecuencia por IP
                 ip = addr[0]
                 with ip_lock:
                     now = time.time()
-                    last = ip_history.get(ip, 0)
-                    if now - last < CONNECTION_COOLDOWN:
+                    if now - ip_history.get(ip, 0) < CONNECTION_COOLDOWN:
                         client.close()
                         continue
                     ip_history[ip] = now
 
-                # Control de límite total
                 if not conn_limit.acquire(blocking=False):
-                    log.warning(f"Límite de conexiones alcanzado ({MAX_CONNECTIONS})")
                     client.close()
                     continue
 
-                # Iniciar manejador
                 ConnectionHandler(client, addr).start()
     except KeyboardInterrupt:
-        log.info("Cerrando servidor...")
+        log.info("Servidor detenido.")
     finally:
-        for s in listeners:
-            s.close()
+        for s in listeners: s.close()
 
 if __name__ == "__main__":
     main()