1
0

VPN.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. =============================================================================
  5. PROXY VPN DUAL (TCP + TLS) - ULTIMATE PYTHON EDITION
  6. Características: IPv4 & IPv6 (Dual-Stack), Multiplexación 80/443,
  7. Fake Web Nginx, Anti-Flood en RAM, Mensajes Rotativos y Custom Headers.
  8. =============================================================================
  9. """
  10. import socket
  11. import ssl
  12. import threading
  13. import select
  14. import time
  15. import datetime
  16. import os
  17. import sys
  18. import signal # <--- ¡AQUÍ ESTÁ LA LIBRERÍA QUE FALTABA!
  19. # --- CONFIGURACIÓN BASE ---
  20. PORT_TCP = 80
  21. PORT_TLS = 443
  22. SSH_HOST = "127.0.0.1"
  23. SSH_PORT = 22
  24. CERT_FILE = "/root/cert.pem"
  25. KEY_FILE = "/root/key.pem"
  26. LOG_FILE = "/root/proxy-dual-python.log"
  27. # --- SEGURIDAD ANTI-FLOOD Y BANEO ---
  28. AUTO_BAN_STRIKES = 20 # Límite de conexiones por segundo exacto (tolera navegadores)
  29. BAN_TIME = 3600 # Castigo de 1 hora en segundos
  30. ip_database = {} # Base de datos en memoria RAM
  31. db_lock = threading.Lock()
  32. # --- FAKE WEB RESPONSES ---
  33. FAKE_WEB_TCP = (
  34. b"HTTP/1.1 400 Bad Request\r\n"
  35. b"Server: nginx/1.24.0\r\n"
  36. b"Content-Type: text/html\r\n"
  37. b"Connection: close\r\n\r\n"
  38. b"<html><body><center><h1>400 Bad Request</h1></center><hr><center>nginx/1.24.0</center></body></html>\r\n"
  39. )
  40. FAKE_WEB_TLS = (
  41. b"HTTP/1.1 400 OK\r\n"
  42. b"Server: nginx/1.21.0\r\n"
  43. b"Content-Type: text/html\r\n"
  44. b"Connection: close\r\n\r\n"
  45. b"<html><body><center><h1>400 Bad Request</h1></center></body></html>\r\n"
  46. )
  47. # --- MENSAJES ROTATIVOS ---
  48. MENSAJES = [
  49. "🚀 CONEXION ESTABLECIDA",
  50. "🛡️ CIFRADO MILITAR ACTIVO",
  51. "🔋 MODO SIGILO SSL OK",
  52. "Pfsense",
  53. "OPNsense",
  54. "VyOS",
  55. "Claro",
  56. "Google",
  57. "TNSR",
  58. "🌐 BYPASS DE FIREWALL OK"
  59. ]
  60. msg_idx = 0
  61. msg_lock = threading.Lock()
  62. # --- FUNCIONES DE REGISTRO (LOGS) ---
  63. def write_log(ip, proto, msg):
  64. try:
  65. # Limpiar la etiqueta de IPv4-mapped-IPv6 para que el log se vea limpio
  66. if ip and ip.startswith("::ffff:"):
  67. ip = ip.replace("::ffff:", "")
  68. timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
  69. log_line = f"[{timestamp}] [{proto}] [{ip if ip else 'SISTEMA'}] {msg}"
  70. print(log_line)
  71. with open(LOG_FILE, "a") as f:
  72. f.write(log_line + "\n")
  73. except Exception:
  74. pass
  75. # --- MOTOR ANTI-FLOOD (AUTO-BAN) ---
  76. def check_and_update_ip(ip):
  77. global ip_database
  78. now = time.time()
  79. with db_lock:
  80. # Limpieza periódica de IPs viejas para no saturar la RAM
  81. if len(ip_database) > 1000:
  82. ip_database = {k: v for k, v in ip_database.items() if v["ban_until"] > now or (now - v["last_connect"] < 60)}
  83. if ip not in ip_database:
  84. ip_database[ip] = {"last_connect": now, "strikes": 1, "ban_until": 0}
  85. return 1
  86. record = ip_database[ip]
  87. # ¿Está baneado?
  88. if record["ban_until"] > now:
  89. return 0
  90. # Tolerancia por segundo exacto
  91. if int(now) == int(record["last_connect"]):
  92. record["strikes"] += 1
  93. if record["strikes"] > AUTO_BAN_STRIKES:
  94. record["ban_until"] = now + BAN_TIME
  95. return -1 # Acaba de ser baneado
  96. else:
  97. # Nuevo segundo, resetear contador
  98. record["strikes"] = 1
  99. record["last_connect"] = now
  100. return 1
  101. # --- MANEJADOR PRINCIPAL DE CONEXIONES ---
  102. def connection_handler(client_sock, client_addr, is_tls):
  103. proto_name = "TLS" if is_tls else "TCP"
  104. client_ip = client_addr[0]
  105. # Extraer IP limpia para los logs
  106. clean_ip = client_ip.replace("::ffff:", "") if client_ip.startswith("::ffff:") else client_ip
  107. # 1. Filtro de Seguridad
  108. sec_status = check_and_update_ip(client_ip)
  109. if sec_status == 0:
  110. client_sock.close()
  111. return
  112. elif sec_status == -1:
  113. write_log(clean_ip, proto_name, "⛔ IP Baneada (Intento de Flood bloqueado)")
  114. client_sock.close()
  115. return
  116. # 2. Envoltura SSL (Solo para el puerto 443)
  117. if is_tls:
  118. try:
  119. context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
  120. context.load_cert_chain(certfile=CERT_FILE, keyfile=KEY_FILE)
  121. client_sock.settimeout(5.0) # Tiempo máximo para el handshake
  122. client_sock = context.wrap_socket(client_sock, server_side=True)
  123. except ssl.SSLError:
  124. # Probablemente un escáner escaneando puertos SSL con texto plano
  125. client_sock.close()
  126. return
  127. except Exception as e:
  128. client_sock.close()
  129. return
  130. # 3. Lectura del Payload (Con Timeout para soportar NetMod)
  131. client_sock.settimeout(3.0)
  132. try:
  133. buffer = client_sock.recv(16384)
  134. except socket.timeout:
  135. buffer = b"" # Túnel Silencioso (NetMod)
  136. except Exception:
  137. client_sock.close()
  138. return
  139. # 4. Conectar al destino SSH Local
  140. try:
  141. target_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  142. target_sock.settimeout(5.0)
  143. target_sock.connect((SSH_HOST, SSH_PORT))
  144. except Exception:
  145. write_log(clean_ip, proto_name, "❌ Error conectando a servidor SSH interno")
  146. client_sock.close()
  147. return
  148. # 5. Lógica de Enrutamiento y Camuflaje
  149. if buffer:
  150. if buffer.startswith(b"SSH-"):
  151. write_log(clean_ip, proto_name, "✅ Túnel Directo SSH")
  152. target_sock.sendall(buffer)
  153. elif b"HTTP/" in buffer and b"Upgrade: websocket" not in buffer:
  154. # Es un navegador web o un bot escáner
  155. write_log(clean_ip, proto_name, "🕵️ Escáner detectado. Respondiendo Fake Web (400 OK).")
  156. fake_resp = FAKE_WEB_TLS if is_tls else FAKE_WEB_TCP
  157. client_sock.sendall(fake_resp)
  158. client_sock.close()
  159. target_sock.close()
  160. return
  161. else:
  162. # Es una petición de inyección (NetMod / HTTP Custom)
  163. global msg_idx
  164. with msg_lock:
  165. status_msg = MENSAJES[msg_idx]
  166. msg_idx = (msg_idx + 1) % len(MENSAJES)
  167. srv_header = "nginx/1.21.0" if is_tls else "nginx/1.24.0"
  168. agent_header = "Gemini-Ultimate-Python-TLS" if is_tls else "Gemini-Ultimate-Python-TCP"
  169. response = (
  170. f"HTTP/1.1 101 {status_msg}\r\n"
  171. f"Server: {srv_header}\r\n"
  172. f"X-Forwarded-For: 127.0.0.1\r\n"
  173. f"Content-Type: text/html; charset=UTF-8\r\n"
  174. f"Proxy-Connection: keep-alive\r\n"
  175. f"Cache-Control: no-cache\r\n"
  176. f"X-Proxy-Agent: {agent_header}\r\n"
  177. f"Connection: Upgrade\r\n"
  178. f"Upgrade: websocket\r\n\r\n"
  179. )
  180. client_sock.sendall(response.encode('utf-8'))
  181. write_log(clean_ip, proto_name, f"✅ Túnel Inyectado Establecido: {status_msg}")
  182. # Reenviar si el cliente mandó carga SSH extra junto con el Header HTTP
  183. partes = buffer.split(b"\r\n\r\n", 1)
  184. if len(partes) > 1 and partes[1]:
  185. target_sock.sendall(partes[1])
  186. else:
  187. # Buffer vacío (Timeout)
  188. write_log(clean_ip, proto_name, "✅ Túnel Modo Silencioso (Stunnel)")
  189. # 6. Bucle Multiplexor (El Puente de Red)
  190. client_sock.settimeout(None)
  191. target_sock.settimeout(None)
  192. sockets = [client_sock, target_sock]
  193. tx_bytes = 0
  194. rx_bytes = 0
  195. try:
  196. while True:
  197. r, _, _ = select.select(sockets, [], [], 300) # 5 minutos de inactividad max
  198. if not r:
  199. break
  200. if client_sock in r:
  201. data = client_sock.recv(16384)
  202. if not data:
  203. break
  204. target_sock.sendall(data)
  205. rx_bytes += len(data)
  206. if target_sock in r:
  207. data = target_sock.recv(16384)
  208. if not data:
  209. break
  210. client_sock.sendall(data)
  211. tx_bytes += len(data)
  212. except Exception:
  213. pass
  214. finally:
  215. total_mb = (tx_bytes + rx_bytes) / (1024 * 1024)
  216. if total_mb > 0.05:
  217. write_log(clean_ip, proto_name, f"[*] Conexión finalizada. Tráfico: {total_mb:.2f} MB")
  218. client_sock.close()
  219. target_sock.close()
  220. # --- SERVIDORES DE ESCUCHA (DUAL-STACK IPv4 e IPv6) ---
  221. def server_listener(port, is_tls):
  222. proto_name = "TLS" if is_tls else "TCP"
  223. try:
  224. # MAGIA DUAL-STACK: AF_INET6 con IPV6_V6ONLY en 0 escucha IPv4 e IPv6 simultáneamente
  225. server = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
  226. server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  227. # Desactivar exclusividad IPv6 (Permite mapear IPv4 a IPv6)
  228. try:
  229. server.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0)
  230. except AttributeError:
  231. pass # Si el sistema no lo soporta, sigue adelante
  232. server.bind(("", port))
  233. server.listen(500)
  234. write_log(None, proto_name, f"Escuchando en puerto {port} (IPv4 e IPv6)...")
  235. while True:
  236. client_sock, client_addr = server.accept()
  237. # Desplegar un hilo por cada cliente conectado
  238. t = threading.Thread(target=connection_handler, args=(client_sock, client_addr, is_tls))
  239. t.daemon = True
  240. t.start()
  241. except Exception as e:
  242. write_log(None, "SISTEMA", f"❌ Error fatal en puerto {port}: {e}")
  243. sys.exit(1)
  244. # --- HILO MAESTRO ORQUESTADOR ---
  245. if __name__ == "__main__":
  246. # Ignorar errores de "Broken Pipe" que crashean los servidores
  247. if hasattr(signal, 'SIGPIPE'):
  248. signal.signal(signal.SIGPIPE, signal.SIG_IGN)
  249. if not os.path.exists(CERT_FILE) or not os.path.exists(KEY_FILE):
  250. write_log(None, "SISTEMA", f"⚠️ ADVERTENCIA: No se encontraron los certificados en {CERT_FILE}. TLS fallará.")
  251. write_log(None, "SISTEMA", "=========================================================")
  252. write_log(None, "SISTEMA", "🚀 PROXY DUAL PYTHON INICIADO (Ultimate Edition)")
  253. write_log(None, "SISTEMA", "🛡️ IPv4/IPv6 Dual-Stack | Anti-Flood RAM | Fake Web Nginx")
  254. write_log(None, "SISTEMA", "=========================================================")
  255. # Lanzar servidor TCP (Puerto 80)
  256. t_tcp = threading.Thread(target=server_listener, args=(PORT_TCP, False))
  257. t_tcp.daemon = True
  258. t_tcp.start()
  259. # Lanzar servidor TLS (Puerto 443)
  260. t_tls = threading.Thread(target=server_listener, args=(PORT_TLS, True))
  261. t_tls.daemon = True
  262. t_tls.start()
  263. # Mantener el script vivo infinitamente
  264. try:
  265. while True:
  266. time.sleep(86400)
  267. except KeyboardInterrupt:
  268. write_log(None, "SISTEMA", "Apagando el servidor Proxy Dual...")
  269. sys.exit(0)