Преглед на файлове

Actualizar 'C/proxy_v3_nativo.c'

yosoyhendrix преди 2 дни
родител
ревизия
239137d2f1
променени са 1 файла, в които са добавени 120 реда и са изтрити 96 реда
  1. 120 96
      C/proxy_v3_nativo.c

+ 120 - 96
C/proxy_v3_nativo.c

@@ -1,7 +1,8 @@
 /*
  * =====================================================================================
  * PROXY MULTIFILAMENTADO PROFESIONAL - VERSIÓN 3 (NATIVO EN C)
- * Compilación en Ubuntu: gcc -O3 -o proxy_v3 proxy_v3_nativo.c -lpthread
+ * Mejoras: Registro de Logs detallados y Monitoreo de tráfico.
+ * Compilación: gcc -O3 -o proxy_v3 proxy_v3_nativo.c -lpthread
  * =====================================================================================
  */
 
@@ -15,15 +16,17 @@
 #include <pthread.h>
 #include <signal.h>
 #include <time.h>
+#include <sys/stat.h>
 
 // --- CONFIGURACIÓN BASE ---
-#define DEFAULT_PORT 80 // Puedes cambiarlo al ejecutar
+#define DEFAULT_PORT 8080
 #define SSH_HOST "127.0.0.1"
 #define SSH_PORT 22
 #define BUFLEN 16384
 #define MAX_CONNECTIONS 300
+#define LOG_FILE "/root/proxy-v3.log"
 
-// --- FAKE WEB ROBUSTA (Réplica exacta de Nginx 1.24) ---
+// --- FAKE WEB ROBUSTA (Nginx 1.24) ---
 const char *FAKE_WEB_RESPONSE = 
     "HTTP/1.1 400 Bad Request\r\n"
     "Server: nginx/1.24.0\r\n"
@@ -34,7 +37,6 @@ const char *FAKE_WEB_RESPONSE =
     "<body>\r\n<center><h1>400 Bad Request</h1></center>\r\n"
     "<hr><center>nginx/1.24.0</center>\r\n</body>\r\n</html>\r\n";
 
-// --- RESPUESTA DE CONEXIÓN ACEPTADA (Con tu Agent) ---
 const char *HTTP_101_RESPONSE = 
     "HTTP/1.1 101 Switching Protocols\r\n"
     "Server: nginx/1.24.0\r\n"
@@ -42,35 +44,46 @@ const char *HTTP_101_RESPONSE =
     "Connection: Upgrade\r\n"
     "X-Proxy-Agent: Gemini-Ultra-Robust-v3\r\n\r\n";
 
-// Variables globales de estado
-int active_connections = 0;
+// Mutexes para sincronización
+pthread_mutex_t log_mutex = PTHREAD_MUTEX_INITIALIZER;
 pthread_mutex_t conn_mutex = PTHREAD_MUTEX_INITIALIZER;
+int active_connections = 0;
 
-// Estructura para pasar datos al hilo
 typedef struct {
     int client_fd;
     struct sockaddr_in addr;
 } client_data_t;
 
-// Imprimir logs en pantalla
-void log_msg(const char *ip, const char *msg) {
-    time_t now = time(NULL);
-    struct tm *t = localtime(&now);
-    char time_str[64];
-    strftime(time_str, sizeof(time_str), "%H:%M:%S", t);
-    printf("[%s] [%s] %s\n", time_str, ip ? ip : "SISTEMA", msg);
+// --- FUNCIÓN DE LOGS (ESTILO V6 TLS) ---
+void write_log(const char *ip, const char *msg) {
+    pthread_mutex_lock(&log_mutex);
+    FILE *f = fopen(LOG_FILE, "a");
+    if (f) {
+        time_t now = time(NULL);
+        struct tm *t = localtime(&now);
+        char ts[64];
+        strftime(ts, sizeof(ts), "%Y-%m-%d %H:%M:%S", t);
+        
+        if (ip) {
+            fprintf(f, "[%s] [%s] %s\n", ts, ip, msg);
+            printf("[%s] [%s] %s\n", ts, ip, msg);
+        } else {
+            fprintf(f, "[%s] %s\n", ts, msg);
+            printf("[%s] %s\n", ts, msg);
+        }
+        fclose(f);
+    }
+    pthread_mutex_unlock(&log_mutex);
 }
 
-// Hilo de manejo de conexión
+// --- MANEJADOR DE CONEXIÓN ---
 void *connection_handler(void *arg) {
     client_data_t *data = (client_data_t *)arg;
     int client_sock = data->client_fd;
-    
     char client_ip[INET_ADDRSTRLEN];
     inet_ntop(AF_INET, &(data->addr.sin_addr), client_ip, INET_ADDRSTRLEN);
-    free(data); // Liberar memoria del argumento
+    free(data);
 
-    // Timeout inicial para leer la petición
     struct timeval tv;
     tv.tv_sec = 3; tv.tv_usec = 0;
     setsockopt(client_sock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof tv);
@@ -78,88 +91,102 @@ void *connection_handler(void *arg) {
     char buffer[BUFLEN];
     int 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';
 
-        // Conectar al destino (SSH Local)
-        struct sockaddr_in target_addr;
+        // Conectar a SSH local
+        struct sockaddr_in t_addr;
         target_sock = socket(AF_INET, SOCK_STREAM, 0);
-        target_addr.sin_family = AF_INET;
-        target_addr.sin_port = htons(SSH_PORT);
-        inet_pton(AF_INET, SSH_HOST, &target_addr.sin_addr);
+        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 *)&target_addr, sizeof(target_addr)) < 0) {
-            log_msg(client_ip, "❌ Error destino SSH");
+        if (connect(target_sock, (struct sockaddr *)&t_addr, sizeof(t_addr)) < 0) {
+            write_log(client_ip, "❌ Error: No se pudo conectar al SSH local");
             goto cleanup;
         }
 
-        // Lógica de ruteo y Fake Web
         if (strncmp(buffer, "SSH-", 4) == 0) {
-            log_msg(client_ip, "✅ Túnel Directo SSH");
+            write_log(client_ip, "✅ Túnel cifrado (Modo SSH Directo)");
             send(target_sock, buffer, bytes_read, 0);
+            rx_bytes += bytes_read;
         } else if (strstr(buffer, "HTTP/") != NULL && strstr(buffer, "Upgrade: websocket") == NULL) {
-            log_msg(client_ip, "🕵️ Escáner detectado. Enviando Nginx Fake Web (400).");
+            write_log(client_ip, "🕵️ Escáner detectado. Respondiendo 400 Bad Request Fake Web.");
             send(client_sock, FAKE_WEB_RESPONSE, strlen(FAKE_WEB_RESPONSE), 0);
             goto cleanup;
         } else {
-            // Es NetMod / Inyector HTTP
-            log_msg(client_ip, "✅ Túnel WebSocket Inyectado (V3)");
+            write_log(client_ip, "✅ Túnel cifrado (Modo WebSocket HTTP): Gemini-V3");
             send(client_sock, HTTP_101_RESPONSE, strlen(HTTP_101_RESPONSE), 0);
-            // Si hay datos extra (payload SSH adelantado), reenviarlo
-            char *headers_end = strstr(buffer, "\r\n\r\n");
-            if (headers_end) {
-                int header_len = (headers_end - buffer) + 4;
-                if (bytes_read > header_len) {
-                    send(target_sock, buffer + header_len, bytes_read - header_len, 0);
+            tx_bytes += strlen(HTTP_101_RESPONSE);
+            
+            char *h_end = strstr(buffer, "\r\n\r\n");
+            if (h_end) {
+                int h_len = (h_end - buffer) + 4;
+                if (bytes_read > h_len) {
+                    send(target_sock, buffer + h_len, bytes_read - h_len, 0);
+                    rx_bytes += (bytes_read - h_len);
                 }
             }
         }
     } else {
-        goto cleanup; // Conexión vacía o timeout
+        // Posible Stunnel o NetMod Silencioso
+        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) {
+            write_log(client_ip, "✅ Túnel cifrado (Modo Stunnel Silencioso)");
+        } else {
+            goto cleanup;
+        }
     }
 
-    // --- BUCLE SELECT (EL PUENTE DE DATOS) ---
-    tv.tv_sec = 0; // Quitar timeout
+    // --- PUENTE DE DATOS ---
+    tv.tv_sec = 0;
     setsockopt(client_sock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof tv);
-    
     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);
-
-        // Timeout de inactividad de 5 minutos
-        struct timeval select_tv = {300, 0}; 
-
-        int activity = select(max_fd + 1, &readfds, NULL, NULL, &select_tv);
-        if (activity <= 0) break; // Cierre por timeout o error
-
-        // Del Cliente al SSH
-        if (FD_ISSET(client_sock, &readfds)) {
-            int bytes = recv(client_sock, buffer, sizeof(buffer), 0);
-            if (bytes <= 0) break;
-            if (send(target_sock, buffer, bytes, 0) <= 0) break;
+        fd_set fds;
+        FD_ZERO(&fds);
+        FD_SET(client_sock, &fds);
+        FD_SET(target_sock, &fds);
+        struct timeval sel_tv = {300, 0};
+
+        if (select(max_fd + 1, &fds, NULL, NULL, &sel_tv) <= 0) break;
+
+        if (FD_ISSET(client_sock, &fds)) {
+            int b = recv(client_sock, buffer, BUFLEN, 0);
+            if (b <= 0) break;
+            send(target_sock, buffer, b, 0);
+            rx_bytes += b;
         }
-
-        // Del SSH al Cliente
-        if (FD_ISSET(target_sock, &readfds)) {
-            int bytes = recv(target_sock, buffer, sizeof(buffer), 0);
-            if (bytes <= 0) break;
-            if (send(client_sock, buffer, bytes, 0) <= 0) break;
+        if (FD_ISSET(target_sock, &fds)) {
+            int b = recv(target_sock, buffer, BUFLEN, 0);
+            if (b <= 0) break;
+            send(client_sock, buffer, b, 0);
+            tx_bytes += b;
         }
     }
 
 cleanup:
+    // Log de tráfico final
+    double total_mb = (double)(tx_bytes + rx_bytes) / (1024.0 * 1024.0);
+    if (total_mb > 0.01) {
+        char stat_msg[128];
+        snprintf(stat_msg, sizeof(stat_msg), "[*] Conexión finalizada. Tráfico consumido: %.2f MB", total_mb);
+        write_log(client_ip, stat_msg);
+    }
+
     if (target_sock != -1) close(target_sock);
     close(client_sock);
 
     pthread_mutex_lock(&conn_mutex);
     active_connections--;
     pthread_mutex_unlock(&conn_mutex);
-
     pthread_exit(NULL);
 }
 
@@ -167,66 +194,63 @@ int main(int argc, char **argv) {
     int port = DEFAULT_PORT;
     if (argc > 1) port = atoi(argv[1]);
 
-    // Ignorar SIGPIPE (Vital en C: evita que el servidor crashee si un cliente corta de golpe)
     signal(SIGPIPE, SIG_IGN);
 
-    int server_sock = socket(AF_INET, SOCK_STREAM, 0);
+    int s_sock = socket(AF_INET, SOCK_STREAM, 0);
     int opt = 1;
-    setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
+    setsockopt(s_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
 
-    struct sockaddr_in server_addr;
-    server_addr.sin_family = AF_INET;
-    server_addr.sin_addr.s_addr = INADDR_ANY;
-    server_addr.sin_port = htons(port);
+    struct sockaddr_in s_addr;
+    s_addr.sin_family = AF_INET;
+    s_addr.sin_addr.s_addr = INADDR_ANY;
+    s_addr.sin_port = htons(port);
 
-    if (bind(server_sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
-        perror("Fallo en bind");
-        exit(EXIT_FAILURE);
+    if (bind(s_sock, (struct sockaddr *)&s_addr, sizeof(s_addr)) < 0) {
+        perror("Error Bind");
+        exit(1);
     }
 
-    if (listen(server_sock, 500) < 0) {
-        perror("Fallo en listen");
-        exit(EXIT_FAILURE);
-    }
+    listen(s_sock, 500);
 
-    printf("=====================================================\n");
-    printf("🚀 PROXY NATIVO V3 (TCP) INICIADO - PUERTO %d\n", port);
-    printf("🛡️  Fake Web: Nginx 1.24 | Agent: Gemini-Ultra-Robust-v3\n");
-    printf("=====================================================\n");
+    write_log(NULL, "=====================================================");
+    char start_msg[128];
+    snprintf(start_msg, sizeof(start_msg), "🚀 PROXY NATIVO V3 (TCP) INICIADO - PUERTO %d", port);
+    write_log(NULL, start_msg);
+    write_log(NULL, "🛡️  Backlog: 500 | Fake-Web: Nginx 1.24 | Logs: ACTIVADOS");
+    write_log(NULL, "=====================================================");
 
     while (1) {
-        struct sockaddr_in client_addr;
-        socklen_t addr_len = sizeof(client_addr);
-        int client_sock = accept(server_sock, (struct sockaddr *)&client_addr, &addr_len);
-
-        if (client_sock < 0) continue;
+        struct sockaddr_in c_addr;
+        socklen_t c_len = sizeof(c_addr);
+        int c_sock = accept(s_sock, (struct sockaddr *)&c_addr, &c_len);
+        if (c_sock < 0) continue;
 
         pthread_mutex_lock(&conn_mutex);
         if (active_connections >= MAX_CONNECTIONS) {
             pthread_mutex_unlock(&conn_mutex);
-            close(client_sock);
+            close(c_sock);
             continue;
         }
         active_connections++;
         pthread_mutex_unlock(&conn_mutex);
 
-        client_data_t *data = malloc(sizeof(client_data_t));
-        data->client_fd = client_sock;
-        data->addr = client_addr;
+        client_data_t *d = malloc(sizeof(client_data_t));
+        d->client_fd = c_sock;
+        d->addr = c_addr;
 
-        pthread_t thread_id;
+        pthread_t tid;
         pthread_attr_t attr;
         pthread_attr_init(&attr);
         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
         
-        if (pthread_create(&thread_id, &attr, connection_handler, (void *)data) != 0) {
-            close(client_sock);
-            free(data);
+        if (pthread_create(&tid, &attr, connection_handler, d) != 0) {
+            close(c_sock);
+            free(d);
             pthread_mutex_lock(&conn_mutex); active_connections--; pthread_mutex_unlock(&conn_mutex);
         }
         pthread_attr_destroy(&attr);
     }
 
-    close(server_sock);
+    close(s_sock);
     return 0;
-}
+}