Привет, Хабр. Расскажу, как написал self-hosted аналог ngrok на Go. 10 часов чистого времени, один человек + Claude Code.ПроблемаНужно протестировать вебхук от Привет, Хабр. Расскажу, как написал self-hosted аналог ngrok на Go. 10 часов чистого времени, один человек + Claude Code.ПроблемаНужно протестировать вебхук от

Написал свой ngrok за 10 часов (Antigravity + Claude Code)

Привет, Хабр. Расскажу, как написал self-hosted аналог ngrok на Go. 10 часов чистого времени, один человек + Claude Code.

shdv5zpukx5fwyqpid2iriewbsw.png

Проблема

Нужно протестировать вебхук от Т-Банк/Telegram/любого внешнего сервиса. Запускаешь ngrok — не работает. Россия заблокирована. Каждый раз VPN, а с ним становится недоступна часть внутренних ресурсов. В какой-то момент решил написать своё.

Что получилось

GoPublic — полноценный self-hosted аналог ngrok:

  • Клиент + сервер с туннелированием через yamux

  • TUI на Bubble Tea

  • Web-инспектор на localhost:4040 с replay запросов

  • Авторизация через Telegram OAuth

  • Let's Encrypt сертификаты (с нюансами — ниже)

  • Конфиг нескольких туннелей через gopublic.yaml

  • Auto-update клиента с Ed25519 подписями

  • CI/CD с деплоем на VPS

Код: github.com/region23/gopublic.su
Сервис: gopublic.su — не думаю, что желающих будет много, поэтому бесплатно.

Архитектура

Client (localhost:3000) ↓ TLS/TCP :4443 ↓ yamux multiplexing Server Control Plane (:4443) ↓ HTTP Ingress (:80/:443) ↓ Public Internet ← роутинг по Host header

Два бинаря. Сервер слушает :4443 для управления туннелями (yamux over TLS) и :80/:443 для входящих HTTP-запросов. Клиент подключается, устанавливает yamux-сессию, принимает запросы и проксирует на локальный порт.

Почему yamux

yamux от HashiCorp — мультиплексирование TCP-соединений. Как HTTP/2, но для TCP: одно соединение, много потоков. Первый stream — handshake (авторизация + привязка доменов). Все последующие — HTTP-запросы от пользователей.

Альтернативы рассматривал, но yamux проверен временем — используется в Consul, Nomad, Vault.

Auto-update клиента

Клиент умеет обновляться сам. При запуске проверяет GitHub Releases, если есть новая версия — предлагает обновиться по нажатию u.

Проблема: как убедиться, что скачанный бинарник не подменён? HTTPS недостаточно — GitHub можно скомпрометировать, MITM возможен на уровне CDN.

Решение — Ed25519 подписи:

  1. При релизе CI генерирует checksums.txt (SHA256-хеши всех бинарей)

  2. Подписывает его приватным ключом Ed25519 → checksums.sig

  3. Публичный ключ зашит в клиенте на этапе компиляции

При обновлении клиент:

  1. Скачивает checksums.txt и checksums.sig

  2. Проверяет подпись публичным ключом

  3. Скачивает бинарник

  4. Проверяет SHA256

Если хоть один шаг не сходится — обновление отклоняется.

На Unix установка атомарная через os.Rename. На Windows сложнее — нельзя заменить запущенный exe, поэтому создаётся batch-скрипт, который заменяет файл при следующем запуске. На MacOS все работает как часы :)

Let's Encrypt: лимиты и wildcard

Сейчас использую стандартный ACME HTTP-01 challenge через golang.org/x/crypto/acme/autocert. Работает, но есть ограничение: 50 сертификатов на домен в неделю.

Каждый новый туннель — это random-name.gopublic.su, и на каждый нужен отдельный сертификат. 50 новых доменов в неделю — и лимит исчерпан. Сейчас я создаю 2 домена на пользователя при регистрации, то есть моя система выдержит 25 новых пользователей в неделю.

Решение: wildcard-сертификат

Wildcard-сертификат *.gopublic.su покрывает все поддомены. Но для него нужен DNS-01 challenge — Let's Encrypt проверяет владение доменом через TXT-запись в DNS.

Пока работаю на HTTP-01, но переход на DNS-01 в планах. Если сервис начнёт расти — это первое, что придётся сделать.

Inspector: отладка вебхуков

На localhost:4040 поднимается web-интерфейс. Каждый проксированный запрос логируется: метод, путь, заголовки, тело, время ответа.

8lr7yz7vn5oyyavghsq_3cwdiia.png

Главная фича — replay. Пришёл вебхук от Telegram, посмотрел payload, поправил код, нажал replay — запрос повторился к локальному серверу. Не нужно заново тригерить событие в Telegram.

bxncdtphnbcdq1xcgb-fwxhczrc.png

Настройка сервера через Claude Code

Это был самый неожиданный опыт. Дал Claude Code SSH-доступ (по ключу) к VPS и попросил настроить продакшн. За 15 минут он:

  1. Обновил систему, поставил Docker и docker-compose

  2. Настроил firewall (ufw) — открыл только 22, 80, 443, 4443

  3. Создал systemd-сервис для автозапуска

  4. Настроил логирование с ротацией

  5. Сгенерировал docker-compose.yml под проект

  6. Настроил GitHub Actions для автодеплоя

CI/CD работает так: push в main → GitHub Actions собирает образ → пушит в GitHub Container Registry → подключается по SSH к VPS → делает docker-compose pull && up.

Я ожидал, что придётся править руками. Не пришлось. Он даже добавил health-check и правильный restart policy.

Timeline

Вечер 1 (~5 часов):

  • Базовая архитектура клиент-сервер

  • Yamux-туннелирование

  • Handshake-протокол

  • Локальный запуск работает

Вечер 2 (~5 часов):

  • Регистрация домена gopublic.su

  • Настройка VPS через Claude Code

  • Let's Encrypt интеграция

  • CI/CD пайплайн

  • TUI на Bubble Tea

  • Auto-update с подписями

Итого: 10 часов — от идеи до работающего продакшна.

Про вайбкодинг

Я слышал много восторженных отзывов про Antigravity. Купил подписку и как раз решил на этом проекте попробовать в деле. В Antigravity разработал спецификацию на проект и первую бету. Но экспириенс работы с этой IDE и Gimini 3 Pro показал себя слабо: долго думает, код пишет невнимательно, упуская детали из ТЗ, сама IDE глючит, ну и кредиты закончились за пару часов :)))

Открыл проект в Claude Code и продолжил в нем — совсем другой уровень. Рефакторинг, ревизия безопасности (нашёл пару потенциальных проблем с race conditions), помог настроить инфраструктуру. Особенно впечатлила работа с SSH — я не ожидал, что он сможет реально настроить сервер.

Это не "ИИ написал код за меня". Это "ИИ ускорил меня в 10-20 раз". Архитектурные решения, дизайн протокола, выбор библиотек — всё равно мои. Но рутину — код, настройка сервера, написание тестов — он забрал на себя.

Стек

  • Go 1.24

  • yamux — мультиплексирование

  • Gin — HTTP-роутер

  • Bubble Tea — TUI

  • Cobra — CLI

  • GORM — ORM для SQLite

  • securecookie — шифрование сессий

  • golang.org/x/crypto — Ed25519, autocert

Итого

За 10 часов один человек с ИИ-ассистентом собрал production-ready сервис уровня ngrok:

Код: github.com/region23/gopublic.su
Сервис: gopublic.su

Буду рад фидбэку!
P.S. Меня всегда триггерит, когда в конце статьи просят подписаться на телеграм-канал. Я просить подписаться не буду, но если что, он у меня тоже есть. Там пишу регулярно, в основном на тему "ИИ в разработке".

Источник

Отказ от ответственности: Статьи, размещенные на этом веб-сайте, взяты из общедоступных источников и предоставляются исключительно в информационных целях. Они не обязательно отражают точку зрения MEXC. Все права принадлежат первоисточникам. Если вы считаете, что какой-либо контент нарушает права третьих лиц, пожалуйста, обратитесь по адресу service@support.mexc.com для его удаления. MEXC не дает никаких гарантий в отношении точности, полноты или своевременности контента и не несет ответственности за любые действия, предпринятые на основе предоставленной информации. Контент не является финансовой, юридической или иной профессиональной консультацией и не должен рассматриваться как рекомендация или одобрение со стороны MEXC.