1
0

Proxy-ssl.py 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. # -*- coding: utf-8 -*-
  2. # ==============================================================================
  3. # PROXY VPN v6 TLS - EDICIÓN PERSONALIZADA
  4. # Optimizado con Evasión de Escaneo Activo (400 OK) y Soporte Stunnel/SSH
  5. # ==============================================================================
  6. import socket
  7. import threading
  8. import select
  9. import sys
  10. import time
  11. import itertools
  12. import os
  13. import ssl
  14. # --- CONFIGURACIÓN BASE ---
  15. LISTENING_PORT = int(sys.argv[1]) if len(sys.argv) > 1 else 443
  16. SSH_HOST = '127.0.0.1'
  17. SSH_PORT = 22 # Puerto de SSH local (Dropbear u OpenSSH)
  18. LOG_FILE = "/root/proxy-ssl.log"
  19. MAX_LOG_SIZE = 10 * 1024 * 1024
  20. # --- CONFIGURACIÓN SSL/TLS ---
  21. USE_SSL = True
  22. CERT_FILE = "/root/cert.pem"
  23. KEY_FILE = "/root/key.pem"
  24. # --- CONFIGURACIÓN DE SEGURIDAD AVANZADA ---
  25. MAX_CONNECTIONS = 200
  26. CONNECTION_COOLDOWN = 0.5
  27. BUFLEN = 16384
  28. AUTO_BAN_STRIKES = 3
  29. BAN_TIME = 3600
  30. banned_ips_memory = {}
  31. ip_strikes = {}
  32. ip_strikes_lock = threading.Lock()
  33. # --- RESPUESTA FAKE WEB (ANTI ACTIVE PROBING) ---
  34. # Se utiliza "400 OK" para confundir a los escáneres de seguridad
  35. FAKE_WEB_RESPONSE = (
  36. b"HTTP/1.1 400 OK\r\n"
  37. b"Server: nginx/1.21.0\r\n"
  38. b"Content-Type: text/html; charset=UTF-8\r\n"
  39. b"Connection: close\r\n\r\n"
  40. b"<!DOCTYPE html>\n<html>\n<head><title>Error</title></head>\n"
  41. b"<body style='text-align:center; padding:50px; font-family:sans-serif;'>\n"
  42. b"<h1>Hola</h1>\n<p>400 Bad Request</p>\n"
  43. b"</body>\n</html>\n"
  44. )
  45. # --- CUSTOM HEADERS PARA VPN ---
  46. CUSTOM_HEADERS = {
  47. "Server": "nginx/1.21.0",
  48. "X-Forwarded-For": "127.0.0.1",
  49. "Content-Type": "text/html; charset=UTF-8",
  50. "Proxy-Connection": "keep-alive",
  51. "Cache-Control": "no-cache",
  52. "X-Proxy-Agent": "Gemini-Ultra-Robust-v6-TLS",
  53. "X-Forwarded-For-Proxy": "True"
  54. }
  55. MENSAJES = [
  56. "🚀 CONEXION TLS ESTABLECIDA",
  57. "🛡️ CIFRADO MILITAR ACTIVO",
  58. "🔋 MODO SIGILO SSL OK",
  59. "Pfsense",
  60. "OPNsense",
  61. "VyOS",
  62. "Claro",
  63. "Windows Server",
  64. "BSD Free",
  65. "Altice",
  66. "Viva",
  67. "Google",
  68. "TNSR",
  69. "🌐 BYPASS DE FIREWALL OK"
  70. ]
  71. mensaje_cycle = itertools.cycle(MENSAJES)
  72. cycle_lock = threading.Lock()
  73. def log(msg, addr=None):
  74. try:
  75. if os.path.exists(LOG_FILE) and os.path.getsize(LOG_FILE) > MAX_LOG_SIZE:
  76. with open(LOG_FILE, 'w') as f: f.write(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] LOG REINICIADO\n")
  77. timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
  78. client_info = f" [{addr[0]}]" if addr else ""
  79. log_entry = f"[{timestamp}]{client_info} {msg}\n"
  80. with open(LOG_FILE, 'a') as f: f.write(log_entry)
  81. print(log_entry.strip())
  82. except: pass
  83. active_connections = 0
  84. conn_lock = threading.Lock()
  85. class ConnectionHandler(threading.Thread):
  86. def __init__(self, client_socket, addr):
  87. super().__init__(daemon=True)
  88. self.client = client_socket
  89. self.addr = addr
  90. self.target = None
  91. self.tx_bytes = 0
  92. self.rx_bytes = 0
  93. def build_http_response(self, status_msg):
  94. headers_str = "".join([f"{k}: {v}\r\n" for k, v in CUSTOM_HEADERS.items()])
  95. return (f"HTTP/1.1 101 {status_msg}\r\n{headers_str}Connection: Upgrade\r\nUpgrade: websocket\r\n\r\n").encode('utf-8')
  96. def run(self):
  97. global active_connections
  98. client_ip = self.addr[0]
  99. try:
  100. # 1. Verificar Baneo Temporal
  101. if client_ip in banned_ips_memory:
  102. if time.time() < banned_ips_memory[client_ip]:
  103. return
  104. else:
  105. del banned_ips_memory[client_ip]
  106. # 2. Control de Inundación (Rate Limiting)
  107. now = time.time()
  108. with ip_strikes_lock:
  109. last_time = ip_strikes.get(f"{client_ip}_last", 0)
  110. if (now - last_time) < CONNECTION_COOLDOWN:
  111. strikes = ip_strikes.get(client_ip, 0) + 1
  112. ip_strikes[client_ip] = strikes
  113. if strikes >= AUTO_BAN_STRIKES:
  114. banned_ips_memory[client_ip] = now + BAN_TIME
  115. log(f"⛔ IP Baneada (Flood/Spam)", self.addr)
  116. return
  117. ip_strikes[f"{client_ip}_last"] = now
  118. ip_strikes[client_ip] = 0
  119. # 3. Lectura de Payload inicial
  120. self.client.settimeout(2.0)
  121. payload = b""
  122. try:
  123. payload = self.client.recv(BUFLEN)
  124. except socket.timeout:
  125. pass # Modo Stunnel Silencioso
  126. except:
  127. return
  128. # 4. Conexión al destino SSH
  129. try:
  130. self.target = socket.create_connection((SSH_HOST, SSH_PORT), timeout=5)
  131. except Exception as e:
  132. log(f"❌ Error destino: {e}", self.addr)
  133. return
  134. # 5. Lógica de respuesta según el tráfico
  135. if payload:
  136. if payload.startswith(b"SSH-"):
  137. log(f"✅ Túnel (Modo SSH Directo)", self.addr)
  138. self.target.sendall(payload)
  139. elif b"HTTP/" in payload and b"Upgrade: websocket" not in payload:
  140. log(f"🕵️ Escáner detectado. Respondiendo 400 OK Fake Web.", self.addr)
  141. self.client.sendall(FAKE_WEB_RESPONSE)
  142. return
  143. else:
  144. with cycle_lock: current_status = next(mensaje_cycle)
  145. self.client.sendall(self.build_http_response(current_status))
  146. log(f"✅ Túnel (Modo WebSocket HTTP): {current_status}", self.addr)
  147. else:
  148. log(f"✅ Túnel (Modo Stunnel Silencioso)", self.addr)
  149. self.tunnel()
  150. except Exception as e:
  151. pass
  152. finally:
  153. with conn_lock: active_connections -= 1
  154. self.cleanup()
  155. def tunnel(self):
  156. self.client.settimeout(None)
  157. self.target.settimeout(None)
  158. sockets = [self.client, self.target]
  159. while True:
  160. try:
  161. readable, _, error = select.select(sockets, [], sockets, 300)
  162. if error or not readable: break
  163. for s in readable:
  164. data = s.recv(BUFLEN)
  165. if not data: return
  166. if s is self.client:
  167. self.target.sendall(data)
  168. self.tx_bytes += len(data)
  169. else:
  170. self.client.sendall(data)
  171. self.rx_bytes += len(data)
  172. except: break
  173. def cleanup(self):
  174. total_mb = (self.tx_bytes + self.rx_bytes) / (1024 * 1024)
  175. if total_mb > 0.05:
  176. log(f"[*] Cierre de sesión. Tráfico: {total_mb:.2f} MB", self.addr)
  177. for s in [self.client, self.target]:
  178. if s:
  179. try: s.close()
  180. except: pass
  181. def main():
  182. global active_connections
  183. # Preparar Contexto SSL Permisivo
  184. context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
  185. try:
  186. context.load_cert_chain(certfile=CERT_FILE, keyfile=KEY_FILE)
  187. except Exception as e:
  188. print(f"Error certificados: {e}")
  189. sys.exit(1)
  190. # Iniciar Servidor Dual Stack
  191. try:
  192. addr_info = socket.getaddrinfo(None, LISTENING_PORT, socket.AF_UNSPEC, socket.SOCK_STREAM, 0, socket.AI_PASSIVE)
  193. addr_info.sort(key=lambda x: x[0] == socket.AF_INET6, reverse=True)
  194. af, socktype, proto, canonname, sa = addr_info[0]
  195. server = socket.socket(af, socktype, proto)
  196. server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  197. if af == socket.AF_INET6:
  198. try: server.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0)
  199. except: pass
  200. server.bind(sa)
  201. server.listen(600)
  202. log(f"=====================================================")
  203. log(f"🚀 Servidor v6 TLS Personalizado - Puerto {LISTENING_PORT}")
  204. log(f"🛡️ Backlog: 600 | Anti-Probing: 400 OK")
  205. log(f"=====================================================")
  206. while True:
  207. try:
  208. raw_c, addr = server.accept()
  209. try:
  210. client = context.wrap_socket(raw_c, server_side=True)
  211. with conn_lock:
  212. if active_connections >= MAX_CONNECTIONS:
  213. client.close()
  214. continue
  215. active_connections += 1
  216. ConnectionHandler(client, addr).start()
  217. except:
  218. raw_c.close()
  219. except:
  220. time.sleep(0.05)
  221. except Exception as e:
  222. log(f"Error crítico: {e}")
  223. finally:
  224. server.close()
  225. if __name__ == "__main__":
  226. main()