
Почему VPN перестал быть решением
Когда команда выросла с 15 до 50 человек, классическое VPN-решение начало создавать серьёзные головные боли. Во-первых, каждый новый сотрудник требовал ручной настройки сертификатов. Во-вторых, мы не могли автоматизировать ротацию доступов. В-третьих, VPN скрывал реальные IP-адреса разработчиков, что усложняло логирование инцидентов. Решили написать свой инструмент — forward-proxy на Go.
Архитектура нашего решения
Forward-proxy отличается от обратного тем, что клиент явно указывает адрес прокси, через который маршрутизировать запросы. Это идеально для контролируемого доступа к админкам и внутренним сервисам.
Основные компоненты
- CONNECT-handler — обрабатывает туннелирование по протоколу HTTP CONNECT для HTTPS-трафика
- Authentication layer — проверка OAuth2-токенов перед пропуском запроса
- Audit logging — логирование всех запросов с сохранением пользователя и целевого адреса
- IP whitelist manager — управление списками разрешённых целевых сервисов через API
- Rate limiting — защита от DDoS и случайных сбоев в коде
Код прокси занимает примерно 700 строк на Go, включая все тесты. Вот упрощённый пример основного обработчика:
func handleConnect(w http.ResponseWriter, r *http.Request) {
host := r.RequestURI
if !isAllowedHost(host) {
http.Error(w, “Forbidden”, http.StatusForbidden)
return
}
// Проверка токена
token := r.Header.Get(“Authorization”)
if !validateToken(token) {
http.Error(w, “Unauthorized”, http.StatusUnauthorized)
return
}
// Туннелирование
conn, _, err := w.(http.Hijacker).Hijack()
// … остальная логика
}
Как мы внедрили в боевую среду
Миграция прошла в три этапа, каждый занял две недели.
Этап 1: Параллельное включение
Запустили прокси рядом с VPN. Разработчики сначала тестировали доступ через новое решение, но VPN оставался подстраховкой. Это позволило выявить проблемы без риска потери доступа.
Этап 2: Миграция по группам
Перевели frontend-команду целиком. Они первыми жаловались на баги и сразу помогали их фиксить. Остальные команды переходили еженедельно. За две недели до полного отключения VPN мы имели 95% трафика через прокси.
Этап 3: Отключение VPN
После успешного месяца без критических инцидентов полностью отключили VPN-инфраструктуру. Сэкономили на лицензиях и убрали техдолг по их обслуживанию.
Выигрыши от нового подхода
- Автоматизация доступа — добавление нового сотрудника занимает 5 минут вместо часа ручной работы
- Полная аудитируемость — каждый запрос логируется с именем пользователя, IP-адресом клиента и целевым хостом
- Гибкие правила доступа — легко добавлять исключения по группам, времени суток или типам сервисов
- Снижение затрат — убрали лицензии VPN и связанный с ними overhead на поддержку
- Скорость — Go-приложение потребляет ~30 МБ памяти и обрабатывает 10k запросов/сек на скромном сервере
Подводные камни и решения
Проблема 1: Асинхронные запросы с браузера — некоторые инструменты (вроде kubectl) требовали явного указания прокси в конфигах. Решили выпустить простой конфиг-генератор, который подставлял адрес прокси в .kubeconfig и .gitconfig автоматически.
Проблема 2: Slow clients — медленные соединения зависали при передаче больших файлов через прокси. Добавили буферизацию и timeout на 5 минут для долгоживущих соединений.
Проблема 3: Мониторинг токенов — OAuth2-токены протухали, блокируя доступ. Внедрили кеширование валидированных токенов с TTL 15 минут и graceful refresh для истекающих.
Чеклист для внедрения в вашей компании
Если вы тоже планируете отказаться от VPN:
- Убедитесь, что у вас есть централизованная система аутентификации (OAuth2, OpenID Connect или SAML)
- Напишите или адаптируйте логирование под вашу систему сбора логов (ELK, Splunk)
- Подготовьте инструкции по настройке прокси для curl, kubectl, git, PostgreSQL-клиентов
- Установите мониторинг на саму программу прокси — её падение упадёт весь доступ
- Проведите drill — отключение VPN в выходной день, чтобы проверить fallback
- Документируйте процесс на каждом шаге
Полный исходный код нашего решения опубликован в открытом доступе на GitHub под лицензией MIT. Сообщество уже адаптировало решение для своих потребностей, и мы постоянно получаем полезные pull-request’ы.
Заключение
Написание собственного forward-proxy на Go заняло две недели разработки плюс месяц на стабилизацию. Результат стоил затрат: мы получили инструмент, который полностью отвечает нашим потребностям, сэкономили на лицензиях и приобрели полный контроль над логированием и управлением доступом. Если ваша компания использует VPN для защиты админских интерфейсов, рекомендуем серьёзно рассмотреть этот подход. Go идеален для таких задач благодаря простоте, скорости и встроенной поддержке конкурентности.
morfix.ru