ENTERPRISE EDGE BRIDGE // ZERO-CA INSTALLATION

Локальный SNI-мост и DNS-сплиттер на базе Cloudflare Edge

Прозрачный туннель для разработки без установки локальных корневых SSL-сертификатов. Направляет только заблокированные AI-сервисы (ChatGPT, Google Antigravity, Gemini, Grok) через бинарный WebSocket-мост к глобальной сети Cloudflare. Весь остальной сетевой трафик идёт напрямую на полной скорости провайдера.

// Безопасность
0 Root-CA
Сквозной TLS: браузер и IDE общаются с целевым сервером напрямую без расшифровки на диске.
// DNS Over-the-Wire
< 1 мс
Локальный dnsmasq перехватывает ровно заданные хосты, остальной интернет резолвится через 1.1.1.1.
// Ресурсоёмкость
~50 МБ RAM
Ультралегкий стек Node.js 22 Alpine + Alpine dnsmasq в изолированных контейнерах.
// Совместимость
100% IDE / CLI
Идеально работает с Google Antigravity, Cursor, VS Code, git, pip, npm и системным curl.

Как работает сквозной конвейер CF-PROXY

Никакого глобального VPN, занижающего скорость домашнего интернета. Разделение потоков происходит на сетевом уровне ядра.

01 / CLIENT USER OS
Запрос приложения
ChatGPT, Antigravity IDE или Browser обращаются к chatgpt.com на 443 порт.
→
02 / DNSMASQ 127.0.0.1:53
Селективный DNS
dnsmasq возвращает 127.0.0.1 только для целевых AI-доменов. Все остальные домены идут в 1.1.1.1.
→
03 / SNI BRIDGE 127.0.0.1:443
Байт-парсер SNI
bridge.mjs считывает ClientHello SNI по RFC 6066 без расшифровки и открывает WebSocket к Cloudflare.
→
04 / EDGE CLOUDFLARE
Worker Gateway
Cloudflare Worker принимает TCP-пакеты через WebSocket и транслирует их напрямую к апстриму OpenAI / Google.
Изучить детали архитектуры и RFC 6066 →

Инженерные преимущества CF-PROXY

Почему разработчики выбирают CF-PROXY вместо стандартных VPN и навязчивых MITM-прокси.

01 / SECURITY

Нулевая возня с SSL Root-CA

Вам не нужно генерировать самоподписанные сертификаты, добавлять их в системный Keychain или ломать валидацию TLS в Node.js / Python через NODE_TLS_REJECT_UNAUTHORIZED=0.

STATUS: END-TO-END ENCRYPTED
02 / ROUTING

Прецизионный Split-Tunneling

Туннелируется строго то, что вы внесли в dnsmasq.conf. Госуслуги, интернет-банкинг, локальная сеть (LAN) и тяжёлые загрузки продолжают работать через прямого провайдера без задержек.

RULE ENGINE: DNS-LEVEL
03 / COMPATIBILITY

Совместимость с Google Antigravity & IDE

Современные AI-редакторы (Google Antigravity, Cursor, Copilot) часто сбрасывают TLS-соединение при обнаружении неизвестных промежуточных сертификатов. CF-PROXY передает сырые байты, исключая сбои.

SUPPORTED: CURSOR, ANTIGRAVITY, VSCODE
04 / PROTOCOL

WebSocket Multiplexing

Пакеты упаковываются в стандартный защищенный WebSocket-поток (WSS). Это полностью обходит DPI-фильтры провайдеров и инспектирование сетевых пакетов на границе сети.

TRANSPORT: WSS PROTOCOL
05 / INFRASTRUCTURE

Глобальная сеть Cloudflare

Использует инфраструктуру Cloudflare Workers в 300+ точках присутствия по всему миру. Запросы выходят в интернет через высокоскоростной Anycast с минимальным пингом.

NETWORK: 300+ GLOBAL POPS
06 / CONTAINERIZATION

Развертывание в 1 команду

Всё упаковано в docker-compose.yml. Никаких зависимостей на хост-машине. Чистый запуск, изолированное окружение, автоперезапуск при падении.

ORCHESTRATION: DOCKER COMPOSE

Исходные конфигурационные файлы проекта

Полный и прозрачный стек: изучайте, адаптируйте под свои домены и запускайте локально.

683 Bytes
services:
  sni-bridge:
    image: node:22-alpine
    container_name: cf-proxy-bridge
    restart: unless-stopped
    environment:
      - WORKER_HOST=switcher.richcorp.online
    #extra_hosts:
      #- "geo-nicdns.catvoodoo0.workers.dev:162.159.135.42"
    ports:
      - "127.0.0.1:443:443"
    volumes:
      - ./bridge.mjs:/app/bridge.mjs:ro
    command: node /app/bridge.mjs

  dnsmasq:
    image: alpine:3.20
    container_name: cf-proxy-dns
    restart: unless-stopped
    command: sh -c "apk add --no-cache dnsmasq && dnsmasq -k --log-facility=-"
    ports:
      - "127.0.0.1:53:53/udp"
      - "127.0.0.1:53:53/tcp"
    volumes:
      - ./dnsmasq.conf:/etc/dnsmasq.conf:ro
import net from "node:net";

// Впиши сюда свой привязанный поддомен на .online (без https:// и слэшей)
const WORKER_HOST = "switcher.richcorp.online";

function extractSNI(buf) {
  try {
    if (buf.length < 43 || buf[0] !== 0x16 || buf[5] !== 0x01) return null;
    let pos = 43;
    if (pos >= buf.length) return null;
    pos += 1 + buf[pos];
    if (pos + 2 > buf.length) return null;
    pos += 2 + buf.readUInt16BE(pos);
    if (pos + 1 > buf.length) return null;
    pos += 1 + buf[pos];
    if (pos + 2 > buf.length) return null;
    const extTotalLen = buf.readUInt16BE(pos);
    pos += 2;

    const end = Math.min(buf.length, pos + extTotalLen);
    while (pos + 4 <= end) {
      const extType = buf.readUInt16BE(pos);
      const extLen = buf.readUInt16BE(pos + 2);
      pos += 4;
      if (extType === 0x0000 && pos + 5 <= end) {
        const nameLen = buf.readUInt16BE(pos + 3);
        if (pos + 5 + nameLen <= end) {
          return buf.toString("utf8", pos + 5, pos + 5 + nameLen);
        }
      }
      pos += extLen;
    }
  } catch (_) {}
  return null;
}

net.createServer((client) => {
  client.setNoDelay(true);
  const chunks = [];

  const onFirstData = (chunk) => {
    chunks.push(chunk);
    const fullBuf = Buffer.concat(chunks);

    if (fullBuf.length < 5) return;
    const recordLen = fullBuf.readUInt16BE(3);
    if (fullBuf.length < 5 + recordLen && fullBuf.length < 2048) return;

    client.removeListener("data", onFirstData);

    const sni = extractSNI(fullBuf);
    if (!sni || sni === WORKER_HOST) {
      client.destroy();
      return;
    }

    console.log(`[CONNECT] ${sni} -> wss://${WORKER_HOST}`);

    const ws = new WebSocket(`wss://${WORKER_HOST}/?host=${encodeURIComponent(sni)}&port=443`);
    ws.binaryType = "arraybuffer";

    const queue = [fullBuf];
    const onQueueData = (c) => queue.push(c);
    client.on("data", onQueueData);

    ws.onopen = () => {
      client.removeListener("data", onQueueData);
      for (const c of queue) ws.send(c);
      queue.length = 0;

      client.on("data", (c) => {
        if (ws.readyState === WebSocket.OPEN) ws.send(c);
      });
    };

    ws.onmessage = (e) => {
      if (!client.destroyed) client.write(new Uint8Array(e.data));
    };

    ws.onclose = (e) => {
      if (e.code !== 1000 && e.code !== 1005) {
        console.log(`[WS CLOSED] ${sni} | Code: ${e.code} | Reason: ${e.reason}`);
      }
      client.destroy();
    };

    ws.onerror = (err) => {
      console.error(`[WS ERROR] ${sni}:`, err.message || "Connection error");
      client.destroy();
    };

    client.on("close", () => { try { ws.close(); } catch (_) {} });
    client.on("error", () => { try { ws.close(); } catch (_) {} });
  };

  client.on("data", onFirstData);
  client.on("error", () => client.destroy());
}).listen(443, () => {
  console.log(`SNI Tunnel Bridge active -> wss://${WORKER_HOST}`);
});
no-resolv
server=1.1.1.1
server=8.8.8.8

# ChatGPT / OpenAI
address=/chatgpt.com/127.0.0.1
address=/openai.com/127.0.0.1
address=/oaistatic.com/127.0.0.1
address=/oaiusercontent.com/127.0.0.1

# Google Antigravity
address=/antigravity.google/127.0.0.1
address=/daily-cloudcode-pa.googleapis.com/127.0.0.1
address=/cloudcode-pa.googleapis.com/127.0.0.1
address=/cloudaicompanion.googleapis.com/127.0.0.1
address=/generativelanguage.googleapis.com/127.0.0.1
address=/aiplatform.googleapis.com/127.0.0.1
address=/businessaicode.googleapis.com/127.0.0.1
address=/gemini.google.com/127.0.0.1

# xAI Grok
address=/grok.com/127.0.0.1
events {
    worker_connections 1024;
}

http {
    resolver 1.1.1.1 8.8.8.8 ipv6=off;

    # Увеличиваем лимиты на размер заголовков и Cookie от браузера
    client_header_buffer_size 64k;
    large_client_header_buffers 8 64k;
    underscores_in_headers on;

    # Увеличиваем буферы для ответов от воркера
    proxy_buffer_size 128k;
    proxy_buffers 8 256k;
    proxy_busy_buffers_size 256k;

    server {
        listen 443 ssl;
        server_name _;

        ssl_certificate     /etc/nginx/certs/cert.pem;
        ssl_certificate_key /etc/nginx/certs/key.pem;
        ssl_protocols TLSv1.2 TLSv1.3;

        location / {
            set $worker_host "frisky-squid-8674.catvoodoo.deno.net"; # домен на deno.dev / workers.dev

            # Защита от случайной петли
            if ($host = $worker_host) {
                return 508 "Loop detected";
            }

            proxy_pass https://$worker_host;

            proxy_ssl_server_name on;
            proxy_ssl_name $worker_host;
            proxy_ssl_protocols TLSv1.2 TLSv1.3;

            proxy_set_header Host $worker_host;
            proxy_set_header X-Target-Host $host;
            proxy_set_header Accept-Encoding ""; # чтобы воркер не путался со сжатием

            proxy_buffering off;
            proxy_http_version 1.1;
            proxy_set_header Connection "";
            client_max_body_size 100M;
        }
    }
}

Сравнение архитектурных подходов

Почему классические методы уступают связке селективного DNS и прямого SNI-моста.

Критерий оценки CF-PROXY (Edge Bridge) Классический VPN MITM Прокси (Charles/Mitmproxy) SOCKS5 Прокси
Установка корневых Root CA НЕ ТРЕБУЕТСЯ (0 сертов) Не требуется ОБЯЗАТЕЛЬНА (риск компрометации) Не требуется
Совместимость с Google Antigravity & IDE 100% Нативная (без сбоев) Часто сбоит при смене IP Ломает валидацию сертификатов Требует явной настройки прокси
Локальная скорость провайдера (Банки/Видео) 100% Прямое соединение Весь трафик замедляется Ограничено локальным демоном Только настроенные программы
Шифрование данных (E2E TLS) Непрерывное (End-to-End) Защищено туннелем Расшифровывается в plaintext Сквозное
Обход DPI блокировок Высокий (WSS на 443 порт) Часто блокируется по протоколу Средний Низкий (легко детектируется)
Потребление системных ресурсов < 50 МБ RAM 200–500 МБ RAM 300+ МБ (Java / Python) 20–50 МБ

Готовые пресеты для разработчиков и AI

Пакетные правила для бесперебойной работы ключевых сервисов генеративного интеллекта.

PRESET 01

OpenAI

ChatGPT Web, Whisper, DALL-E, API эндпоинты и CDN статических ресурсов oaistatic.com.

5 ДОМЕНОВ В БАЗЕ
PRESET 02

Google Antigravity

Платформа Antigravity, Gemini API, Vertex AI, Cloud Code тетрады и фоновые телеметрические шлюзы.

8 ДОМЕНОВ В БАЗЕ
PRESET 03

xAI Grok

Веб-клиент grok.com, портал x.ai и сопутствующие сервисы потоковой генерации ответов.

3 ДОМЕНА В БАЗЕ
PRESET 04

Anthropic Claude

Claude 3.5 Sonnet / Opus веб-интерфейс, организация сессий и фоновые WebSocket каналы.

3 ДОМЕНА В БАЗЕ
Открыть интерактивный генератор правил →

Часто задаваемые вопросы

Нужен ли собственный домен для Cloudflare Worker?

Да, для корректной маршрутизации WebSocket в Cloudflare рекомендуется привязать любой дешевый домен (например, в зоне .online, .xyz или свой рабочий домен). Ворк-хост указывается в переменной WORKER_HOST в файлах bridge.mjs и docker-compose.yml.

Видит ли локальный мост мои пароли или токены API?

Нет. bridge.mjs считывает только заголовок ClientHello, в котором серверное имя (SNI) передается открыто по спецификации TLS. Никакой расшифровки полезной нагрузки (payload) не происходит. Сессия TLS шифруется непосредственно между вашим браузером/IDE и сервером OpenAI/Google.

Что делать, если порт 53 или 443 уже занят в системе?

На Linux порт 53 часто резервируется службой systemd-resolved. В нашей документации подробно описано, как освободить порт или назначить слушающий интерфейс 127.0.0.1 без конфликтов с локальными резолверами.