Ir al contenido
OmniRoute source

Stealth Guide (Español)

open-sse/utils/tlsClient.ts — wreq-js (Chrome 124)

Sección titulada «open-sse/utils/tlsClient.ts — wreq-js (Chrome 124)»

Las sesiones persistentes de wreq-js se crean de forma diferida por ámbito de cuenta y proxy resuelto. El TlsClient de ámbito global del proceso agrupa un máximo de 128 sesiones que se hacen pasar por Chrome 124 en macOS para proveedores de origen protegidos por Cloudflare. TlsClient.fetch() aplica un cierre seguro cuando el entorno de ejecución nativo no está disponible; el código que realiza la llamada puede seleccionar explícitamente una alternativa fuera de este contenedor.

  • Perfil de sesión: browser: "chrome_124", os: "macos"
  • Resolución del proxy (prioridad): HTTPS_PROXY → HTTP_PROXY → ALL_PROXY (también en minúsculas)
  • Tiempo de espera: TLS_CLIENT_TIMEOUT_MS (heredado de FETCH_TIMEOUT_MS, valor predeterminado 600000)
  • La respuesta de wreq-js es compatible con fetch (headers, text(), json(), clone(), body).
  • Supervisor del primer byte (open-sse/utils/tlsFirstByteWatchdog.ts, #12656): TlsClient.fetch() se resuelve en cuanto llegan los encabezados del proveedor de origen, por lo que TLS_CLIENT_TIMEOUT_MS por sí solo no puede limitar un cuerpo que nunca entrega un primer byte. guardTlsFirstByte() enfrenta la primera llamada read() del cuerpo a TLS_FIRST_BYTE_WATCHDOG_MS (valor predeterminado 10000; 0 lo desactiva); un cuerpo correcto no se ve afectado, mientras que un cuerpo bloqueado cancela el lector de wreq y permite que la lógica existente de alternativa TLS de proxyFetch pase al despachador directo/proxy (una solicitud que no puede reproducirse de forma segura, por ejemplo, una solicitud POST con cuerpo, sigue generando un error en lugar de volver a intentarse silenciosamente).

Transporte de proveedores mediante cookies web — wreq-js 3.2.0

Sección titulada «Transporte de proveedores mediante cookies web — wreq-js 3.2.0»

open-sse/services/tlsClientBase.ts es el adaptador compartido por los cinco transportes especializados mediante cookies web que aparecen a continuación. Cada contenedor ligero específico del proveedor selecciona un perfil de navegador/SO. El adaptador utiliza el cargador único del entorno de ejecución de wreq y el grupo de transportes de open-sse/utils/tlsClient.ts, indexados por perfil + SO + proxy resuelto, mientras que cada solicitud utiliza cookieMode: "ephemeral". Por tanto, las cuentas y las solicitudes comparten conexiones en el nivel de transporte, pero nunca una sesión de wreq ni un almacén de cookies.

Proveedor Perfil SO emulado Política de EOF del flujo
Claude chrome_146 Linux incluir [DONE]
Perplexity firefox_148 macOS incluir event: end_of_stream
Grok chrome_146 Linux excluir [DONE]
Notion chrome_146 Windows incluir [DONE]
LMArena chrome_146 Windows sin centinela; cerrar en el EOF nativo
  • La transmisión consume directamente el ReadableStream de la respuesta nativa; no se crea ningún archivo temporal ni proceso auxiliar.
  • Se inspeccionan hasta 256 bytes iniciales antes de exponer un flujo. Los proveedores SSE almacenan en búfer los errores que no son SSE; Grok/LMArena asignan los desafíos de Cloudflare a 403 y las páginas HTML intermedias a 502.
  • El tiempo de espera de la solicitud nativa permanece envuelto por un plazo límite absoluto de JS. Un bloqueo invalida y cierra únicamente el transporte afectado de perfil/SO/proxy antes de que la siguiente solicitud vuelva a crearlo.
  • La prioridad de resolución del proxy es proxyUrl por llamada → contexto de cuenta/panel limitado a la solicitud → HTTPS_PROXY/HTTP_PROXY/ALL_PROXY (incluidas las variantes en minúsculas). Los errores de resolución aplican un cierre seguro en lugar de filtrar una conexión directa. LMArena resuelve deliberadamente contra arena.ai.
  • byteResponse devuelve una URL data: con el tipo de contenido correcto y sin corrupción de UTF-8.
  • Los errores son TlsClientUnavailableError (paquete/complemento no disponible), TlsClientHangError (plazo límite superado) y WreqTransportCapacityError (el código de error compartido de capacidad de sesión) cuando las 128 ranuras limitadas de perfil/SO/proxy están activas o cerrándose.

La sesión genérica de TlsClient anterior sigue estando especializada en el estado persistente de cookies respaldado por el navegador. Ambas rutas reutilizan un único cargador de módulos de wreq almacenado en caché y un enlace al ciclo de vida del proceso; sus grupos permanecen separados porque la duración de sus cookies es intencionadamente diferente.

Los perfiles son compatibles con el paquete fijado, pero la aceptación real del WAF puede cambiar independientemente de las pruebas de contrato locales. Valide los cambios de huellas digitales con una cuenta activa expresamente autorizada antes de afirmar que existe paridad con un navegador del proveedor de origen.


Cuando cliCompatMode está activado, OmniRoute transforma las solicitudes salientes de Claude para que sean indistinguibles del tráfico de claude-cli. Tres módulos colaboran:

Calcula la huella de 3 caracteres cc_version integrada en la cabecera de facturación:

SHA256(SALT + msg[4] + msg[7] + msg[20] + version)[:3]
  • FINGERPRINT_SALT = "59cf53e54c78" (codificado de forma fija; coincide con el cliente oficial)
  • Entradas: caracteres en los índices 4, 7 y 20 del texto del primer mensaje del usuario + cadena de versión
  • Salida: prefijo hexadecimal de 3 caracteres

claudeCodeCCH.ts (hash del contenido del cliente)

Sección titulada «claudeCodeCCH.ts (hash del contenido del cliente)»

Comprobación de integridad del lado del servidor que la CLI oficial de Claude Code calcula mediante Bun/Zig. OmniRoute la vuelve a implementar con xxhash-wasm:

  1. Serializar el cuerpo con el marcador de posición cch=00000;
  2. xxhash64(bytes, seed) & 0xFFFFF
  3. Hexadecimal en minúsculas de 5 caracteres, rellenado con ceros
  4. Sustituir cch=00000; por el token calculado

Constantes:

  • Semilla: 0x6e52736ac806831e
  • Patrón: /\bcch=([0-9a-f]{5});/

Inserta un conector de ancho cero Unicode (U+200D) después del primer carácter de los nombres de clientes «sensibles», para que los filtros ascendentes no puedan encontrarlos mediante grep. Lista de palabras predeterminada:

opencode, open-code, cline, roo-cline, roo_cline, cursor, windsurf,
aider, continue.dev, copilot, avante, codecompanion

Se aplica a: bloques system, todo messages[].content y tools[].description / tools[].function.description. El operador puede sobrescribirla mediante setSensitiveWords().

claudeCodeCompatible.ts — proveedores anthropic-compatible-cc-*

Sección titulada «claudeCodeCompatible.ts — proveedores anthropic-compatible-cc-*»

Para retransmisores Anthropic de terceros que solo aceptan tráfico de «Claude Code real»:

  • CLAUDE_CODE_COMPATIBLE_USER_AGENT = "claude-cli/2.1.258 (external, sdk-cli)"
  • CLAUDE_CODE_COMPATIBLE_STAINLESS_PACKAGE_VERSION = "0.112.1"
  • CLAUDE_CODE_COMPATIBLE_STAINLESS_RUNTIME_VERSION = "v26.3.0"
  • anthropic-beta = "claude-code-20250219,interleaved-thinking-2025-05-14,effort-2025-11-24" de forma predeterminada
  • La opción por conexión «Habilitar la beta de ocultación del razonamiento» añade redact-thinking-2026-02-12 cuando un servicio ascendente compatible con CC requiere específicamente flujos de razonamiento oculto
  • La opción por conexión «Habilitar la visualización del razonamiento resumido» almacena providerSpecificData.requestDefaults.summarizeThinking y añade display: "summarized" a las solicitudes de razonamiento compatibles con CC que aún no hayan establecido un modo de visualización
  • CONTEXT_1M_BETA_HEADER = "context-1m-2025-08-07" (familia Opus/Sonnet 4.x)
  • Ruta predeterminada: /v1/messages?beta=true

Módulos relacionados del mismo paquete:

  • claudeCodeConstraints.ts — reglas de temperatura y control de caché
  • claudeCodeToolRemapper.ts — reasignación de nombres de herramientas
  • claudeCodeExtraRemap.ts — normalización adicional de la carga útil

Las solicitudes de Antigravity conservan el texto del solicitante byte por byte. OmniRoute no inserta caracteres de ancho cero en los prompts ni cambia el nombre de las herramientas o las inyecta para imitar a un cliente IDE.

Elimina los marcadores del SDK de Stainless (x-stainless-lang, x-stainless-package-version, x-stainless-os, x-stainless-arch, x-stainless-runtime, x-stainless-runtime-version, x-stainless-timeout, x-stainless-retry-count, x-stainless-helper-method) antes del reenvío.

⚠️ Riesgo: ANTIGRAVITY_CREDITS=always (punto crítico de bloqueo de cuentas)

Sección titulada «⚠️ Riesgo: ANTIGRAVITY_CREDITS=always (punto crítico de bloqueo de cuentas)»

ANTIGRAVITY_CREDITS=always (utilizado por open-sse/executors/antigravity.ts) dirige todas las solicitudes a través de los excesos de créditos de Antigravity AI (créditos de pago de Google), en lugar de permitir que la cuota del nivel gratuito de Google limite el uso. Esto está documentado como una funcionalidad, pero es el motivo más común de infracción de las condiciones del servicio que observamos: varias cuentas de Google Ultra han sido bloqueadas con 403 / "service disabled for ToS violation" / insufficient_quota después de ejecutarse durante unas horas con =always.

La aplicación de estas restricciones se realiza del lado de Google y OmniRoute no puede impedirla. El nombre de la variable de entorno y la documentación existente hacen que parezca una opción segura de activar; no lo es.

Por qué esto activa la detección de abuso de forma más agresiva que el uso exclusivo del nivel gratuito:

  • El gasto automatizado y sostenido en una sola cuenta de Google genera señales diferentes a las del nivel gratuito, que alcanza la cuota y se detiene.
  • Los excesos de créditos no tienen un límite de velocidad, por lo que un cliente mal configurado puede consumir varios cientos de USD en minutos y parecer una operación de reventa de claves de API o tráfico de bots.
  • Que varios usuarios de OmniRoute consuman créditos excedentes en paralelo desde la misma IP externa agrava la señal.

Configuración recomendada:

  1. Mantener el valor predeterminado ANTIGRAVITY_CREDITS=off, a menos que el operador acepte explícitamente el riesgo asociado a los créditos de pago y a las medidas aplicadas sobre la cuenta. retry envía primero la solicitud normal e inyecta créditos como máximo una vez después de un error 429 de cuota apto; always inyecta créditos en la primera solicitud.
  2. Distribuir la carga entre proveedores mediante Auto-Combo (model: "auto" o el combo kr/glm/etc) en lugar de saturar una sola cuenta de Antigravity.
  3. Establecer límites de RPM por conexión en la página de edición del proveedor Antigravity (Panel de control → Proveedores → Antigravity → conexión → límite de velocidad). Entre 30 y 60 RPM es un límite máximo justificable para un uso sostenido.
  4. Utilizar una red ascendente estable y controlada por el operador y evitar compartir una misma cuenta entre usuarios o cargas de trabajo no relacionados.
  5. En caso de bloqueo: presentar una apelación mediante support.google.com → «Restaurar el acceso a Workspace/cuenta», incluyendo el cuerpo exacto de la respuesta quota_exceeded / service disabled enviado por Google. La restauración no está garantizada.

La referencia de variables de entorno documenta las implicaciones para la cuenta y el gasto de cada modo de créditos.

Puntos de contacto:

  • open-sse/executors/antigravity.ts — lee process.env.ANTIGRAVITY_CREDITS
  • src/lib/oauth/providers/antigravity.ts — gestión de credenciales
  • Informe original del incidente: Discusión #1183

Registro de huellas digitales de CLI — open-sse/config/cliFingerprints.ts

Sección titulada «Registro de huellas digitales de CLI — open-sse/config/cliFingerprints.ts»

Tabla por proveedor que fija el orden exacto de las cabeceras y de los campos del cuerpo JSON capturado a partir de trazas de mitmproxy de las CLI oficiales. Actualmente registrados: codex, claude, además de perfiles derivados en tiempo de ejecución en providerHeaderProfiles.ts para antigravity y github.

interface CliFingerprint {
headerOrder: string[]; // distingue entre mayúsculas y minúsculas
bodyFieldOrder: string[]; // claves JSON de nivel superior
userAgent?: string | (() => string);
extraHeaders?: Record<string, string>;
}

Se activa o desactiva por proveedor mediante variables de entorno (véase más abajo). Cuando está desactivado, las cabeceras/claves del cuerpo aparecen en el orden que Node/JSON les haya dado, lo que facilita la identificación de la huella digital.


Proxy MITM (Antigravity, Linux/macOS/Windows)

Sección titulada «Proxy MITM (Antigravity, Linux/macOS/Windows)»

Para las CLI cuyos binarios no pueden redirigirse mediante OPENAI_BASE_URL, OmniRoute ejecuta un proxy local con terminación TLS. Los endpoints se encuentran en src/app/api/cli-tools/antigravity-mitm/.

Método Endpoint Propósito
GET /api/cli-tools/antigravity-mitm Estado: en ejecución, pid, dnsConfigured, certExists
POST /api/cli-tools/antigravity-mitm Iniciar MITM (requiere apiKey + sudoPassword)
DELETE /api/cli-tools/antigravity-mitm Detener MITM
GET /api/cli-tools/antigravity-mitm/alias Listar alias de modelos
PUT /api/cli-tools/antigravity-mitm/alias Guardar alias de modelos para una herramienta

Host objetivo interceptado: daily-cloudcode-pa.googleapis.com (servidor upstream de Antigravity).

Secuencia de inicio (src/mitm/manager.ts::startMitm)

Sección titulada «Secuencia de inicio (src/mitm/manager.ts::startMitm)»
  1. Generar un certificado autofirmado mediante selfsigned (RSA-2048, SHA-256, 1 año) — cert/generate.ts
  2. Instalar el certificado en el almacén de confianza del sistema — cert/install.ts
  3. Añadir la entrada de hosts 127.0.0.1 daily-cloudcode-pa.googleapis.com — dns/dnsConfig.ts
  4. Iniciar src/mitm/server.cjs con ROUTER_API_KEY + MITM_LOCAL_PORT (valor predeterminado: 443)
  5. Guardar el PID en <DATA_DIR>/mitm/.mitm.pid

Detección dinámica del almacén de confianza en Linux — cert/install.ts

Sección titulada «Detección dinámica del almacén de confianza en Linux — cert/install.ts»

getLinuxCertConfig() recorre una lista de prioridades y selecciona el primer directorio existente:

Familia de distribuciones Directorio Comando de actualización
Debian / Ubuntu /usr/local/share/ca-certificates update-ca-certificates
Arch / CachyOS / Manjaro /etc/ca-certificates/trust-source/anchors update-ca-trust
Fedora / RHEL / CentOS /etc/pki/ca-trust/source/anchors update-ca-trust
openSUSE /etc/pki/trust/anchors update-ca-certificates

Nombre de archivo del certificado: omniroute-mitm.crt. Coincidencia de huellas digitales mediante getCertFingerprint() (SHA-1 del DER).

Además, updateNssDatabases() instala el certificado en las bases de datos NSS de cada usuario cuando certutil está disponible: ~/.pki/nssdb, ~/snap/chromium/.../nssdb y todos los perfiles de Firefox (incluidos los de snap), con el nombre descriptivo OmniRoute MITM Root CA.

  • macOS: security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain
  • Windows: PowerShell con privilegios elevados → certutil -addstore Root

Todos los endpoints MITM requieren autenticación de administración (requireCliToolsAuth). La contraseña de sudo se almacena en caché dentro del ámbito del módulo (nunca en globalThis) y se elimina al ejecutar stopMitm().


Sobrescrituras de User-Agent — variables de entorno (sección 12 de .env.example)

Sección titulada «Sobrescrituras de User-Agent — variables de entorno (sección 12 de .env.example)»
Variable Valor predeterminado
CLAUDE_USER_AGENT claude-cli/2.1.258 (external, cli)
CODEX_USER_AGENT codex-cli/0.155.0 (Windows 10.0.26200; x64)
GITHUB_USER_AGENT GitHubCopilotChat/0.54.0
ANTIGRAVITY_USER_AGENT antigravity/2.0.1 linux/arm64 google-api-nodejs-client/10.3.0
KIRO_USER_AGENT AWS-SDK-JS/3.0.0 kiro-ide/1.0.0
QODER_USER_AGENT Qoder-Cli
CURSOR_USER_AGENT Cursor/3.4

Utilizadas por open-sse/executors/base.ts::buildHeaders() mediante una búsqueda dinámica. Actualice estos valores cuando los proveedores publiquen nuevas versiones de la CLI — las cadenas de UA obsoletas comienzan a rechazarse por corresponder a clientes desactualizados.

Interruptores del modo de compatibilidad con CLI (.env.example, sección 13)

Sección titulada «Interruptores del modo de compatibilidad con CLI (.env.example, sección 13)»
Variable Efecto
CLI_COMPAT_CODEX=1 Huella digital de Codex
CLI_COMPAT_CLAUDE=1 Huella digital de claude-cli
CLI_COMPAT_GITHUB=1 Huella digital de GitHub Copilot Chat
CLI_COMPAT_ANTIGRAVITY=1 Huella digital de Antigravity
CLI_COMPAT_KIRO=1 Kiro
CLI_COMPAT_CURSOR=1 Cursor
CLI_COMPAT_KIMI_CODING=1 Kimi Coding
CLI_COMPAT_KILOCODE=1 KiloCode
CLI_COMPAT_CLINE=1 Cline
CLI_COMPAT_ALL=1 Habilita todo lo anterior

La IP del proveedor se conserva siempre: el interruptor solo modifica la representación de la solicitud en la red; no cambia la IP de salida.


OmniRoute depura los encabezados entrantes del cliente antes de reenviarlos, de modo que una solicitud procedente de Cursor no revele User-Agent: Cursor/X.Y.Z a un servidor ascendente de Claude. Consulte src/shared/constants/upstreamHeaders.ts para ver la lista de bloqueo, que se mantiene sincronizada con los esquemas de Zod y las pruebas unitarias.


Actualización de huellas digitales cuando un proveedor las cambia

Sección titulada «Actualización de huellas digitales cuando un proveedor las cambia»
  1. Capture el tráfico de la CLI oficial con mitmproxy (interceptación TLS + volcado)
  2. Extraiga JA3/JA4 y el orden literal de los encabezados
  3. Actualice la entrada correspondiente de CLI_FINGERPRINTS[...]
  4. Actualice el valor predeterminado de *_USER_AGENT correspondiente en .env.example
  5. Si también cambió el protocolo de enlace TLS, actualice el envoltorio del proveedor correspondiente o la opción browser: de wreq-js
  6. Ejecute las pruebas TLS específicas del proveedor y una prueba canario manual contra el proveedor activo
  7. Publíquelo en una versión de parche y documéntelo en CHANGELOG.md

  • open-sse/services/__tests__/claudeTlsClient.test.ts — comportamiento del envoltorio TLS compartido
  • tests/unit/anthropic-cache-fingerprint.test.ts — determinismo de la huella digital
  • tests/unit/chatgpt-web-source-retirement.test.ts — la fuente sigilosa común de ChatGPT Web permanece ausente, mientras que Codex Web sigue presente


Código fuente de OmniRoute (a58000c7685f)

HagiCode

HagiCode es un espacio de trabajo de programación con agentes, flujos estructurados, ejecución multiagente y vistas de Hero Dungeon.

Convierte ideas en software útil con un flujo de trabajo con agentes más inteligente, rápido y ameno.

Interfaz principal de HagiCode con tema claro
  • SmartLos flujos estructurados convierten la intención en un itinerario ejecutable desde la idea hasta la entrega.
  • EfficientLos flujos multiagente permiten avanzar en paralelo con la investigación, implementación y revisión.
  • FunHero Dungeon hace que las largas sesiones de programación sean visuales y colaborativas.
Visitar HagiCode