23 сентября я сделал первый коммит в проект для портфолио: Телеграм-бот, который сам ставит и настраивает панель 3x-ui, чтобы у человека был свой VPN без ручной возни. Прошло три недели и около 40 коммитов, и VPN оказался не самой интересной частью.
Как это выглядит#
Вы арендуете сервер с Debian 12 или 13 у любого хостера, получаете IP и пароль root и присылаете боту одну строку ip:пароль. Бот переводит ssh на случайный порт со входом только по ключу, включает фаервол, обновляет систему и дальше управляет сервером сам.
Сервер можно забрать в любой момент кнопкой «Вернуть». Бот уберет свои доступы, откатит ssh и фаервол и пришлет новый пароль root. Данные на сервере останутся.
VPN#
Ради этого все и затевалось. Бот ставит 3x-ui и настраивает:
- подключение VLESS + XHTTP + Reality на 443 порту, цель для Reality бот подбирает сам
- по желанию сервер маскировки: клиенты подключаются к нему, он пересылает трафик на панель, и адрес панели нигде не светится
- домен с сертификатом Let’s Encrypt для панели и подписки, а без домена короткий сертификат на IP, который продлевается автоматически
- прокси на выходе: свой или Cloudflare WARP
- шифрованный DNS на сервере: DNS-over-TLS, а если его режут, запасной DNS-over-HTTPS
Ключи клиентов бот выпускает и отзывает сам и выдает ссылки на подписку для v2rayN, Hiddify, Happ и v2rayNG. Ограничений на ключи нет: ни по трафику, ни по сроку, ни по устройствам. По каждому ключу видно трафик и когда клиент был онлайн.
Раз в сутки бот проверяет панель, Xray и сертификат подписки и пишет, если что-то сломалось или починилось.
Почему без Cloudflare#
Сначала бот умел работать через Cloudflare, и от этого пришлось отказаться. Cloudflare сам завершает TLS у себя и открывает до сервера новое соединение. А Reality живет как раз внутри TLS-рукопожатия клиента, и сервер должен увидеть его как есть. За Cloudflare Reality работать не может, так что поддержку я убрал.
Где на самом деле работа#
Когда я посмотрел на код, оказалось, что почти вся работа бота сводится к одному: взять голый Debian, закрыть его и дальше управлять им по ключу. Примерно то, что я описывал в первичной настройке сервера, только без человека. 3x-ui лишь одна из задач поверх этого.
Поэтому код настройки серверов я выделил в отдельный пакет serverus. Это библиотека на ansible без Django и без Telegram с понятным программным API. Телеграм-часть тоже стала отдельным пакетом. Django-приложение осталось связующим звеном с бизнес-логикой.
Второй сценарий: docker-сервер#
Когда такая основа есть, следующий сценарий собирается быстро. Я сделал docker-сервер:
- бот ставит Docker, Caddy и автообновления системы, сертификаты для доменов выпускает Caddy
- приложение это папка с
docker-compose.yaml,.envиcaddy.conf, ее можно прислать боту архивом или по файлам - перед применением бот показывает разницу и предупреждения по файлам, а если домен не указывает на сервер, тоже предупредит
- при применении бот проверяет compose, занятость портов и конфиг Caddy, и если что-то не так, приложение не трогает
- пересоздаются только изменившиеся сервисы
- кнопка «откатить» возвращает предыдущую версию файлов
- есть старт, стоп, рестарт и логи по сервисам, логин в приватный docker registry и гостевой доступ к volumes, чтобы залить данные
В примере к проекту лежит свой сервер RustDesk.
Один код, разные боты#
Что умеет бот, решает интерфейс, выбранный в админке: «MyPoint VPN», «Serverus» или оба сразу. Переключается на ходу, без перезапуска. Так из одного кода получаются разные боты.
Бот держит сам себя#
Моя любимая часть. Прод MyPointVPN развернут как приложение Serverus на docker-сервере, которым управляет этот же бот. Новая версия бота для него такое же приложение, как RustDesk.
Стек#
Python, Django, PostgreSQL, RabbitMQ + dramatiq (фоновые задачи с супервизором), ansible, собственный сервер Telegram Bot API, Docker, Caddy, 3x-ui v3.8.5.
Попробовать и обсудить#
У проекта есть своя страница: mypointvpn.sokolab.xyz.
- Бот
- Код, там же вики: деплой, перенос данных и как устроено приложение для Serverus
- Задачи в Redmine
- Форум для вопросов и идей, там же гостевой вход, регистрироваться не обязательно
Что дальше#
Serverus, скорее всего, станет отдельным проектом. Расскажу о нем отдельной записью, и у него будет свой лендинг. Продолжение следует.
