Proxy-ssl.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. # -*- coding: utf-8 -*-
  2. import socket
  3. import threading
  4. import select
  5. import sys
  6. import time
  7. import itertools
  8. import os
  9. import ssl
  10. # ==============================================================================
  11. # CONFIGURACIÓN DEL SISTEMA
  12. # ==============================================================================
  13. LISTENING_PORT = int(sys.argv[1]) if len(sys.argv) > 1 else 443
  14. SSH_HOST = '127.0.0.1'
  15. SSH_PORT = 22 # Cambiar a 223 si usas Dropbear modificado
  16. LOG_FILE = "/root/proxy.log"
  17. MAX_LOG_SIZE = 10 * 1024 * 1024 # 10MB antes de rotar
  18. # RUTAS DE CERTIFICADOS SSL (Deben existir en el servidor)
  19. CERT_FILE = "/root/cert.pem"
  20. KEY_FILE = "/root/key.pem"
  21. # ==============================================================================
  22. # PARÁMETROS DE RESILIENCIA Y SEGURIDAD
  23. # ==============================================================================
  24. MAX_CONNECTIONS = 200
  25. CONNECTION_COOLDOWN = 0.7
  26. BUFLEN = 16384
  27. TIMEOUT_HTTP = 3.0
  28. # SISTEMA DE AUTO-BANEO TEMPORAL
  29. AUTO_BAN_STRIKES = 3
  30. BAN_TIME = 3600 # 1 hora de baneo
  31. banned_ips = {}
  32. ip_strikes = {}
  33. # RESPUESTA WEB FALSA (Para engañar a escáneres como Shodan)
  34. FAKE_WEB = (
  35. b"HTTP/1.1 200 OK\r\n"
  36. b"Server: nginx/1.24.0\r\n"
  37. b"Content-Type: text/html; charset=UTF-8\r\n"
  38. b"Connection: close\r\n\r\n"
  39. b"<!DOCTYPE html><html><head><title>Welcome</title></head>"
  40. b"<body style='font-family:sans-serif;text-align:center;padding:50px;'>"
  41. b"<h1>404 Not Found</h1><p>The requested resource was not found.</p>"
  42. b"</body></html>"
  43. )
  44. # MENSAJES PARA LA INYECCIÓN HTTP (NetMod)
  45. MENSAJES = [
  46. "🚀 CONEXION TLS ESTABLECIDA",
  47. "🛡️ CIFRADO MILITAR ACTIVO",
  48. "🔋 MODO SIGILO SSL OK",
  49. "Pfsense",
  50. "OPNsense",
  51. "VyOS",
  52. "Claro",
  53. "Windows Server",
  54. "BSD Free",
  55. "VyOS",
  56. "Altice",
  57. "Viva",
  58. "Google",
  59. "VyOS",
  60. "TNSR",
  61. "🌐 BYPASS DE FIREWALL OK"
  62. ]
  63. mensaje_cycle = itertools.cycle(MENSAJES)
  64. cycle_lock = threading.Lock()
  65. # ==============================================================================
  66. # FUNCIONES DE SOPORTE
  67. # ==============================================================================
  68. def write_log(msg, addr=None):
  69. try:
  70. if os.path.exists(LOG_FILE) and os.path.getsize(LOG_FILE) > MAX_LOG_SIZE:
  71. with open(LOG_FILE, 'w') as f: f.write("--- LOG REINICIADO ---\n")
  72. ts = time.strftime("%Y-%m-%d %H:%M:%S")
  73. ip_info = f" [{addr[0]}]" if addr else ""
  74. log_line = f"[{ts}]{ip_info} {msg}\n"
  75. with open(LOG_FILE, 'a') as f: f.write(log_line)
  76. print(log_line.strip())
  77. except: pass
  78. active_conn_count = 0
  79. conn_count_lock = threading.Lock()
  80. class ProxyHandler(threading.Thread):
  81. def __init__(self, client_socket, addr):
  82. super().__init__(daemon=True)
  83. self.client = client_socket
  84. self.addr = addr
  85. self.target = None
  86. def run(self):
  87. global active_conn_count
  88. client_ip = self.addr[0]
  89. try:
  90. # 1. Verificar Baneo
  91. if client_ip in banned_ips:
  92. if time.time() < banned_ips[client_ip]: return
  93. else: del banned_ips[client_ip]
  94. # 2. Leer Petición inicial
  95. self.client.settimeout(TIMEOUT_HTTP)
  96. try:
  97. data = self.client.recv(BUFLEN)
  98. except: data = b""
  99. # 3. Lógica de Detección de Protocolo
  100. if data:
  101. # Si es un navegador/escáner buscando web
  102. if b"HTTP/" in data and b"Upgrade: websocket" not in data:
  103. write_log("🕵️ Escáner detectado. Enviando Fake Web.", self.addr)
  104. self.client.sendall(FAKE_WEB)
  105. return
  106. # Si es tráfico SSH directo (sin inyector)
  107. if data.startswith(b"SSH-"):
  108. self.target = socket.create_connection((SSH_HOST, SSH_PORT), timeout=5)
  109. self.target.sendall(data)
  110. else:
  111. # Es un Inyector (NetMod/NekoBox)
  112. with cycle_lock: current_msg = next(mensaje_cycle)
  113. resp = f"HTTP/1.1 101 {current_msg}\r\nConnection: Upgrade\r\nUpgrade: websocket\r\n\r\n"
  114. self.client.sendall(resp.encode('utf-8'))
  115. self.target = socket.create_connection((SSH_HOST, SSH_PORT), timeout=5)
  116. else:
  117. # Conexión vacía (posible probe silencioso)
  118. self.target = socket.create_connection((SSH_HOST, SSH_PORT), timeout=5)
  119. # 4. Iniciar Túnel
  120. self.bridge()
  121. except Exception as e:
  122. pass
  123. finally:
  124. with conn_count_lock: active_conn_count -= 1
  125. self.cleanup()
  126. def bridge(self):
  127. self.client.settimeout(None)
  128. self.target.settimeout(None)
  129. sockets = [self.client, self.target]
  130. while True:
  131. r, _, e = select.select(sockets, [], sockets, 300)
  132. if e or not r: break
  133. for s in r:
  134. try:
  135. data = s.recv(BUFLEN)
  136. if not data: return
  137. (self.target if s is self.client else self.client).sendall(data)
  138. except: return
  139. def cleanup(self):
  140. for s in [self.client, self.target]:
  141. if s:
  142. try: s.close()
  143. except: pass
  144. def main():
  145. global active_conn_count
  146. # Configuración de Contexto SSL Flexible (Compatible con NetMod)
  147. context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
  148. try:
  149. context.load_cert_chain(certfile=CERT_FILE, keyfile=KEY_FILE)
  150. except Exception as e:
  151. print(f"Error cargando certificados: {e}")
  152. sys.exit(1)
  153. # Creación del Socket Servidor (Dual Stack IPv4/IPv6)
  154. try:
  155. server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  156. server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  157. server.bind(('', LISTENING_PORT))
  158. server.listen(500)
  159. print(f"=====================================================")
  160. print(f"🚀 PROXY V7 RESILIENTE INICIADO - PUERTO {LISTENING_PORT}")
  161. print(f"🛡️ MOTOR ANTI-CRASH Y FAKE WEB ACTIVADOS")
  162. print(f"=====================================================")
  163. while True:
  164. try:
  165. raw_client, addr = server.accept()
  166. # 5. Envolver conexión en SSL
  167. try:
  168. client = context.wrap_socket(raw_client, server_side=True)
  169. except:
  170. raw_client.close()
  171. continue
  172. with conn_count_lock:
  173. if active_conn_count >= MAX_CONNECTIONS:
  174. client.close()
  175. continue
  176. active_conn_count += 1
  177. ProxyHandler(client, addr).start()
  178. except socket.error:
  179. time.sleep(0.05) # Pausa ante saturación de sockets
  180. continue
  181. except Exception:
  182. time.sleep(0.5)
  183. continue
  184. except Exception as e:
  185. print(f"Error crítico: {e}")
  186. finally:
  187. server.close()
  188. if __name__ == "__main__":
  189. main()