Кейс // Своя VPN-инфраструктура

Fortochka
Private VPN

Python 3.12FastAPIaiogram 3SQLAlchemy 2AmneziaWGWireGuardsystemdNext.js 16
Открыть архивный сайт
01 // Резюме
Задача

Сервис,
который водили за руку

Личный VPN для друзей и семьи работает ровно до тех пор, пока людей не станет больше горстки. Каждое новое устройство — это сессия по SSH, shell-скрипт и конфиг, отправленный руками. Никто не знал, сколько кто потратил трафика; про истёкшую подписку можно было вспомнить, а можно было и нет; а когда кто-то писал «перестало работать», единственным способом понять причину было зайти на сервер и прочитать состояние интерфейса самому.

Решение

Босс
и рабочие

Вместо одного скрипта, который делает всё, сервис разделён надвое. На каждом VPN-узле работает агент: маленький HTTP-сервис ровно с шестью операциями, слушающий только внутри служебного WireGuard-туннеля — снаружи его порта не существует. Отдельно работает босс: база, планировщик и телеграм-бот, с которым люди на самом деле разговаривают. Босс инициирует всё общение, агенты только отвечают. И главное: босс не стоит в пути трафика — если он упадёт, VPN продолжит гонять пакеты, остановится только учёт.

02 // Ключевые результаты
260

тестов

183 босс · 77 агент

6

операций агента

весь контракт целиком

0

трафика через босса

только управление

2

узла под управлением

боевой и лабораторный

03 // Технические особенности

У агента нет публичной поверхности

Он слушает только адрес туннеля, поэтому скан сервера не находит на его порту ничего — проверено снаружи. Шесть операций — это весь API: список пиров, создание, включение, выключение, статистика, диагностика. Токен сравнивается функцией с постоянным временем выполнения, а не обычным равенством: сравнение строк выдаёт ответ через время работы.

Падение управляющего слоя — не падение сервиса

Босс держит базу и всем управляет, но через него не проходит ни один пакет. Выключи его — существующие туннели продолжат работать, встанут только учёт и уведомления. Тот же принцип решает, что делать с замолчавшим агентом: нет свежих данных — значит, никого не отключаем по квоте, админу приходит предупреждение. Действовать по отсутствующим данным хуже, чем действовать позже.

Учёт, переживающий перезапуск

Счётчики WireGuard обнуляются при каждом перезапуске интерфейса, и это читалось бы как внезапно потраченный отрицательный трафик. Поэтому расход накапливается относительно сохранённого базового значения, а не читается напрямую, и счётчик, уехавший назад, распознаётся как перезапуск, а не как аномалия.

04 // Разбор проекта
DEMO_RENDER // PENDING
PRJ-002

Архив // 2026

Сервис работал для небольшой группы живых людей на двух узлах и был выключен в сентябре 2026 года: платить за два сервера и следить за ними ради нескольких друзей перестало иметь смысл. Сайт оставлен как демо лендинга; купить на нём ничего нельзя.

Об этом проекте

Вопросы
об архитектуре?

Расскажу, почему агент живёт за туннелем, что происходит, когда он замолкает, и почему счётчикам трафика понадобилось базовое значение вместо простого чтения.