yosoyhendrix 1 день назад
Родитель
Сommit
3b6cbb71d3
1 измененных файлов с 84 добавлено и 46 удалено
  1. 84 46
      C/proxy_dual.c

+ 84 - 46
C/proxy_dual.c

@@ -1,9 +1,8 @@
 /*
  * =====================================================================================
- * PROXY VPN DUAL (TCP + TLS) - ULTIMATE BARE-METAL EDITION V10
- * Correcciones Finales: 
- * 1. Anti-Flood reprogramado: Reseteo por segundo para permitir Navegadores/VPNs.
- * 2. SSL_pending afinado para conexiones SSH directas.
+ * PROXY VPN DUAL (TCP + TLS) - CLASSIC IPv4 EDITION + ULTIMATE SECURITY
+ * Rollback: Sockets restaurados a AF_INET (0.0.0.0) para máxima estabilidad SSL.
+ * Features mantenidas: Anti-Flood Tolerante, Auto-Ban en RAM, Headers Completos.
  * Compilación: gcc -O3 -o proxy_dual proxy_dual.c -lssl -lcrypto -lpthread
  * =====================================================================================
  */
@@ -32,13 +31,13 @@
 #define CERT_FILE "/root/cert.pem"
 #define KEY_FILE "/root/key.pem"
 
-// --- SEGURIDAD ANTI-FLOOD (Afiliado a la perfección) ---
+// --- SEGURIDAD ANTI-FLOOD Y BANEO ---
 #define MAX_TRACKED_IPS 200
-#define AUTO_BAN_STRIKES 20 // 20 conexiones permitidas POR SEGUNDO
-#define BAN_TIME 3600 // Castigo de 1 hora
+#define AUTO_BAN_STRIKES 20 // 20 conexiones por segundo (Tolerante con Navegadores)
+#define BAN_TIME 3600 // 1 hora de bloqueo en RAM
 
 typedef struct {
-    char ip[INET6_ADDRSTRLEN];
+    char ip[INET_ADDRSTRLEN];
     time_t last_connect;
     int strikes;
     time_t ban_until;
@@ -51,6 +50,7 @@ pthread_mutex_t ip_db_mutex = PTHREAD_MUTEX_INITIALIZER;
 const char *FAKE_WEB_TCP = "HTTP/1.1 400 Bad Request\r\nServer: nginx/1.24.0\r\nContent-Type: text/html\r\nConnection: close\r\n\r\n<html><body><center><h1>400 Bad Request</h1></center><hr><center>nginx/1.24.0</center></body></html>\r\n";
 const char *FAKE_WEB_TLS = "HTTP/1.1 400 OK\r\nServer: nginx/1.21.0\r\nContent-Type: text/html\r\nConnection: close\r\n\r\n<html><body><center><h1>400 Bad Request</h1></center></body></html>\r\n";
 
+// --- MENSAJES ROTATIVOS ---
 const char *MENSAJES[] = {"🚀 CONEXION ESTABLECIDA", "🛡️ CIFRADO MILITAR ACTIVO", "🔋 MODO SIGILO SSL OK", "Pfsense", "OPNsense", "VyOS", "Claro", "Google", "TNSR", "🌐 BYPASS OK"};
 #define NUM_MENSAJES (sizeof(MENSAJES) / sizeof(MENSAJES[0]))
 int mensaje_idx = 0;
@@ -60,14 +60,15 @@ int active_connections = 0;
 pthread_mutex_t conn_mutex = PTHREAD_MUTEX_INITIALIZER;
 pthread_mutex_t log_mutex = PTHREAD_MUTEX_INITIALIZER;
 
+// VOLVEMOS A IPv4 (sockaddr_in)
 typedef struct {
     int client_fd;
-    struct sockaddr_storage addr; 
+    struct sockaddr_in addr; 
     int is_tls; 
     SSL_CTX *ssl_ctx;
 } client_data_t;
 
-// --- REGISTRO LOG ---
+// --- FUNCIONES DE REGISTRO ---
 void write_log(const char *ip, const char *proto, const char *msg) {
     pthread_mutex_lock(&log_mutex);
     FILE *f = fopen(LOG_FILE, "a");
@@ -83,7 +84,7 @@ void write_log(const char *ip, const char *proto, const char *msg) {
     pthread_mutex_unlock(&log_mutex);
 }
 
-// --- NUEVO MOTOR ANTI-FLOOD (Tolerante a Navegadores) ---
+// --- MOTOR ANTI-FLOOD (Mantenido intacto) ---
 int check_and_update_ip(const char *ip) {
     pthread_mutex_lock(&ip_db_mutex);
     time_t now = time(NULL);
@@ -96,17 +97,17 @@ int check_and_update_ip(const char *ip) {
             found = 1;
             if (ip_database[i].ban_until > now) {
                 pthread_mutex_unlock(&ip_db_mutex);
-                return 0; // Baneado
+                return 0; // Sigue castigado
             }
             if (now == ip_database[i].last_connect) {
                 ip_database[i].strikes++;
                 if (ip_database[i].strikes > AUTO_BAN_STRIKES) {
                     ip_database[i].ban_until = now + BAN_TIME;
                     pthread_mutex_unlock(&ip_db_mutex);
-                    return -1; // Nuevo Ban
+                    return -1; // Nuevo Ban detectado
                 }
             } else {
-                ip_database[i].strikes = 1; // Un segundo nuevo, reseteamos el contador
+                ip_database[i].strikes = 1; 
                 ip_database[i].last_connect = now;
             }
             break;
@@ -122,6 +123,7 @@ int check_and_update_ip(const char *ip) {
     return 1;
 }
 
+// --- CONFIGURACIÓN SSL ---
 SSL_CTX *create_ssl_context() {
     SSL_load_error_strings();
     OpenSSL_add_ssl_algorithms();
@@ -132,46 +134,45 @@ SSL_CTX *create_ssl_context() {
     return ctx;
 }
 
+// --- VOLVEMOS AL SOCKET IPv4 CLÁSICO (AF_INET) ---
 int create_server_socket(int port) {
-    int s_sock = socket(AF_INET6, SOCK_STREAM, 0);
+    int s_sock = socket(AF_INET, SOCK_STREAM, 0);
     if (s_sock < 0) return -1;
-    int opt = 1; setsockopt(s_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
-    int no = 0; setsockopt(s_sock, IPPROTO_IPV6, IPV6_V6ONLY, &no, sizeof(no));
+    
+    int opt = 1; 
+    setsockopt(s_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
 
-    struct sockaddr_in6 addr;
+    struct sockaddr_in addr;
     memset(&addr, 0, sizeof(addr));
-    addr.sin6_family = AF_INET6;
-    addr.sin6_addr = in6addr_any;
-    addr.sin6_port = htons(port);
+    addr.sin_family = AF_INET;
+    addr.sin_addr.s_addr = INADDR_ANY; // 0.0.0.0 puro
+    addr.sin_port = htons(port);
 
     if (bind(s_sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) return -1;
     listen(s_sock, 600);
     return s_sock;
 }
 
+// --- HILO TRABAJADOR ---
 void *connection_handler(void *arg) {
     client_data_t *data = (client_data_t *)arg;
     int client_sock = data->client_fd;
     int is_tls = data->is_tls;
     SSL_CTX *ctx = data->ssl_ctx;
     
-    char client_ip[INET6_ADDRSTRLEN];
-    if (data->addr.ss_family == AF_INET) {
-        struct sockaddr_in *s = (struct sockaddr_in *)&data->addr;
-        inet_ntop(AF_INET, &s->sin_addr, client_ip, sizeof(client_ip));
-    } else { 
-        struct sockaddr_in6 *s = (struct sockaddr_in6 *)&data->addr;
-        inet_ntop(AF_INET6, &s->sin6_addr, client_ip, sizeof(client_ip));
-    }
+    // Extracción simple de IP (IPv4)
+    char client_ip[INET_ADDRSTRLEN];
+    inet_ntop(AF_INET, &(data->addr.sin_addr), client_ip, INET_ADDRSTRLEN);
     free(data);
 
     const char *proto_name = is_tls ? "TLS" : "TCP";
 
+    // Pasar por el Filtro Anti-Flood
     int sec_status = check_and_update_ip(client_ip);
     if (sec_status == 0) {
         close(client_sock); pthread_mutex_lock(&conn_mutex); active_connections--; pthread_mutex_unlock(&conn_mutex); pthread_exit(NULL);
     } else if (sec_status == -1) {
-        write_log(client_ip, proto_name, "⛔ IP Baneada (Flood de >20 req/s)");
+        write_log(client_ip, proto_name, "⛔ IP Baneada (Intento de Flood bloqueado)");
         close(client_sock); pthread_mutex_lock(&conn_mutex); active_connections--; pthread_mutex_unlock(&conn_mutex); pthread_exit(NULL);
     }
 
@@ -179,29 +180,42 @@ void *connection_handler(void *arg) {
     if (is_tls) {
         ssl = SSL_new(ctx);
         SSL_set_fd(ssl, client_sock);
-        if (SSL_accept(ssl) <= 0) {
+        if (SSL_accept(ssl) <= 0) { // Si falla el Handshake (ej. es un escáner no-TLS)
             SSL_free(ssl); close(client_sock);
             pthread_mutex_lock(&conn_mutex); active_connections--; pthread_mutex_unlock(&conn_mutex);
             pthread_exit(NULL);
         }
     }
 
-    fd_set init_fds; FD_ZERO(&init_fds); FD_SET(client_sock, &init_fds);
-    struct timeval init_tv = {3, 0}; 
+    // --- EL LECTOR INTELIGENTE ---
     char buffer[BUFLEN];
     int bytes_read = 0;
 
     int ssl_has_data = is_tls ? SSL_pending(ssl) : 0;
-    if (ssl_has_data > 0 || select(client_sock + 1, &init_fds, NULL, NULL, &init_tv) > 0) {
-        if (is_tls) bytes_read = SSL_read(ssl, buffer, sizeof(buffer)-1);
-        else bytes_read = recv(client_sock, buffer, sizeof(buffer)-1, 0);
-    } 
+    
+    // Si OpenSSL ya capturó el mensaje, lo leemos directo. 
+    // Si no, esperamos 3 segundos en el cable físico.
+    if (ssl_has_data > 0) {
+        bytes_read = SSL_read(ssl, buffer, sizeof(buffer)-1);
+    } else {
+        fd_set readfds; 
+        FD_ZERO(&readfds); 
+        FD_SET(client_sock, &readfds);
+        struct timeval tv = {3, 0}; 
+
+        if (select(client_sock + 1, &readfds, NULL, NULL, &tv) > 0) {
+            if (is_tls) bytes_read = SSL_read(ssl, buffer, sizeof(buffer)-1);
+            else bytes_read = recv(client_sock, buffer, sizeof(buffer)-1, 0);
+        }
+    }
 
     int target_sock = -1;
     long tx_bytes = 0, rx_bytes = 0;
 
     if (bytes_read > 0) {
         buffer[bytes_read] = '\0';
+        
+        // Preparar conexión SSH local
         struct sockaddr_in t_addr;
         target_sock = socket(AF_INET, SOCK_STREAM, 0);
         t_addr.sin_family = AF_INET;
@@ -210,14 +224,18 @@ void *connection_handler(void *arg) {
 
         if (connect(target_sock, (struct sockaddr *)&t_addr, sizeof(t_addr)) < 0) goto cleanup;
 
+        // Lógica de Enrutamiento
         if (strncmp(buffer, "SSH-", 4) == 0) {
+            // SSH Directo
             send(target_sock, buffer, bytes_read, 0);
         } else if (strstr(buffer, "HTTP/") != NULL && strstr(buffer, "Upgrade: websocket") == NULL) {
-            write_log(client_ip, proto_name, "🕵️ Escáner detectado. Fake Web OK.");
+            // Navegador web o bot escáner
+            write_log(client_ip, proto_name, "🕵️ Escáner detectado. Respondiendo Fake Web.");
             if (is_tls) SSL_write(ssl, FAKE_WEB_TLS, strlen(FAKE_WEB_TLS));
             else send(client_sock, FAKE_WEB_TCP, strlen(FAKE_WEB_TCP), 0);
             goto cleanup;
         } else {
+            // Petición válida de NetMod (WebSocket)
             pthread_mutex_lock(&msg_mutex);
             const char *status_msg = MENSAJES[mensaje_idx];
             mensaje_idx = (mensaje_idx + 1) % NUM_MENSAJES;
@@ -231,27 +249,36 @@ void *connection_handler(void *arg) {
                 "Content-Type: text/html; charset=UTF-8\r\n"
                 "Proxy-Connection: keep-alive\r\n"
                 "Cache-Control: no-cache\r\n"
-                "X-Proxy-Agent: Gemini-Ultra-Dual-C\r\n"
+                "X-Proxy-Agent: Gemini-Ultra-Classic-IPv4\r\n"
                 "Connection: Upgrade\r\n"
                 "Upgrade: websocket\r\n\r\n", status_msg);
 
             if (is_tls) SSL_write(ssl, response, strlen(response));
             else send(client_sock, response, strlen(response), 0);
+            
+            write_log(client_ip, proto_name, "✅ Túnel Inyectado Establecido");
         }
     } else {
+        // Timeout de 3 seg: Es NetMod en modo Silencioso (Stunnel)
         struct sockaddr_in t_addr;
         target_sock = socket(AF_INET, SOCK_STREAM, 0);
         t_addr.sin_family = AF_INET;
         t_addr.sin_port = htons(SSH_PORT);
         inet_pton(AF_INET, SSH_HOST, &t_addr.sin_addr);
         if (connect(target_sock, (struct sockaddr *)&t_addr, sizeof(t_addr)) != 0) goto cleanup;
+        write_log(client_ip, proto_name, "✅ Túnel Modo Silencioso Establecido");
     }
 
+    // --- BUCLE MULTIPLEXOR ---
     int max_fd = (client_sock > target_sock) ? client_sock : target_sock;
 
     while (1) {
-        fd_set readfds; FD_ZERO(&readfds); FD_SET(client_sock, &readfds); FD_SET(target_sock, &readfds);
-        struct timeval select_tv = {300, 0};
+        fd_set readfds; 
+        FD_ZERO(&readfds); 
+        FD_SET(client_sock, &readfds); 
+        FD_SET(target_sock, &readfds);
+        
+        struct timeval select_tv = {300, 0}; // 5 min idle max
         int pending = is_tls ? SSL_pending(ssl) : 0;
         
         if (pending == 0) {
@@ -281,10 +308,12 @@ cleanup:
     pthread_exit(NULL);
 }
 
+// --- HILO MAESTRO ---
 int main(int argc, char **argv) {
     int port_tcp = DEFAULT_PORT_TCP, port_tls = DEFAULT_PORT_TLS;
     if (argc >= 3) { port_tcp = atoi(argv[1]); port_tls = atoi(argv[2]); }
 
+    // Limpiar base de datos de castigos
     memset(ip_database, 0, sizeof(ip_database));
     signal(SIGPIPE, SIG_IGN); 
 
@@ -292,22 +321,31 @@ int main(int argc, char **argv) {
     int server_tcp = create_server_socket(port_tcp);
     int server_tls = create_server_socket(port_tls);
 
-    if (server_tcp < 0 || server_tls < 0) exit(1);
+    if (server_tcp < 0 || server_tls < 0) {
+        printf("Error fatal creando sockets.\n");
+        exit(1);
+    }
 
-    write_log(NULL, "SISTEMA", "🚀 PROXY DUAL BARE-METAL INICIADO (Ultimate V10)");
-    write_log(NULL, "SISTEMA", "🛡️  Módulos: Anti-Flood Tolerante, IPv4/IPv6, Multi-hilo, Headers OK");
+    write_log(NULL, "SISTEMA", "=====================================================");
+    write_log(NULL, "SISTEMA", "🚀 PROXY DUAL BARE-METAL (Classic IPv4 + Security)");
+    write_log(NULL, "SISTEMA", "🛡️  Módulos: Anti-Flood (20/s), Auto-Ban RAM, Full Headers");
+    write_log(NULL, "SISTEMA", "=====================================================");
 
     int max_server_fd = (server_tcp > server_tls) ? server_tcp : server_tls;
 
     while (1) {
-        fd_set master_fds; FD_ZERO(&master_fds); FD_SET(server_tcp, &master_fds); FD_SET(server_tls, &master_fds);
+        fd_set master_fds; 
+        FD_ZERO(&master_fds); 
+        FD_SET(server_tcp, &master_fds); 
+        FD_SET(server_tls, &master_fds);
+        
         if (select(max_server_fd + 1, &master_fds, NULL, NULL, NULL) < 0) continue;
 
         int active_sock = -1, is_tls = 0;
         if (FD_ISSET(server_tcp, &master_fds)) { active_sock = server_tcp; is_tls = 0; }
         else if (FD_ISSET(server_tls, &master_fds)) { active_sock = server_tls; is_tls = 1; }
 
-        struct sockaddr_storage c_addr;
+        struct sockaddr_in c_addr;
         socklen_t c_len = sizeof(c_addr);
         int client_sock = accept(active_sock, (struct sockaddr *)&c_addr, &c_len);
         if (client_sock < 0) continue;