Перейти к основному содержимому

On-Premise сервер

CloudPub On-Premise — это корпоративное решение для развертывания платформы туннелирования на собственной инфраструктуре. Данная версия позволяет организациям получить полный контроль над процессом публикации локальных сервисов, обеспечивая максимальную безопасность, соответствие требованиям информационной безопасности и независимость от внешних облачных провайдеров.

Серверная часть поставляется в виде универсального Docker-образа. Образ не содержит привязки к домену, секретов или брендинга - вся конфигурация задается переменными окружения при запуске контейнера. Один и тот же образ обслуживает любое развертывание, а установка занимает несколько минут.

примечание

Здесь описан серверный образ. Образ Docker для агента описан на отдельной странице.

Системные требования

Раздел содержит минимальные и рекомендуемые системные требования для развертывания и стабильной работы системы. Требования разделены на базовые (необходимые для функционирования основных компонентов) и дополнительные (зависящие от планируемой нагрузки и количества подключаемых агентов).

примечание

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

Базовые требования

  • Операционная система: Debian 12 или Ubuntu 22.04 (рекомендуется использовать минимальную установку без графического интерфейса)
  • RAM: 4 GB
  • CPU: 4 ядра (для базовой работы системы и сервиса туннелей)
  • Дисковое пространство: 50 GB для системы и базовых нужд

Дополнительные требования

  • RAM: Дополнительно 25 МБ на каждого подключенного агента
  • CPU: 1 дополнительное ядро на каждых 250 агентов
  • Если требуется запись трафика: примерно 1 GB на агента в день

Пример: Сервер на 1000 агентов

  • RAM: 4 GB + (1000 * 25 MB) = 29 GB
  • CPU: 4 ядра + (1000 / 250) = 8 ядер
  • Дисковое пространство: 50 GB + (1000 * 1 GB) = 1050 GB (около 1 TB, глубина записи 1 день)

Подготовка инфраструктуры

Для корректной работы системы требуется подготовка инфраструктуры. Процесс развертывания включает настройку сервера, конфигурацию доменных имен, SSL-сертификатов и интеграцию с внешними сервисами.

Все компоненты должны быть подготовлены заранее, так как некоторые из них могут потребовать времени на получение или настройку (например, SSL-сертификаты или настройка DNS).

warning

Настоятельно рекомендуется настроить бекапы виртуальной машины средствами гипервизора или использовать специализированные инструменты резервного копирования для Linux. Настройка резервного копирования является ответственностью пользователя.

Необходимые компоненты и информация

  • Зарегистрированый домен 1 или 2 уровня (example.com или tunnel.example.com)
  • WildCard TLS сертификат в формате PEM (сертификат и приватный ключ), покрывающий и сам домен, и маску поддоменов: example.com + *.example.com (или tunnel.example.com + *.tunnel.example.com)
  • Возможность добавить в DNS A-записи домена и wildcard-маски
  • Сервер (виртуальный или физический), соответсвующий системным требованиям
  • Логин/пароль root или пользователь с правами sudo
  • SSH доступ к серверу (публичный ключ будет предоставлен)
  • SMTP сервер для отправки транзакционной почты (host, логин, пароль, port, TLS/SSL)
  • E-Mail адрес для системных уведомлений и поддержки пользователей
  • Название сайта (например, "MyCompany Tunnel")
  • Опционально: API token и Chat ID для бота telegram c системными уведомлениями
  • Опционально: логин/пароль акканута на DockerHub (если нужен репозиторий Docker образов)

Домен, DNS и TLS-сертификат

Каждая публикация получает собственный поддомен внутри домена сервера, например resolutely-tough-petrel.example.com. Поэтому для полноценной работы нужны две вещи: wildcard-запись A в DNS и wildcard TLS-сертификат. Без них панель управления откроется, но опубликованные ресурсы будут недоступны или отдадут ошибку сертификата.

Записи DNS. На IP-адрес сервера должны указывать A-записи и самого домена, и wildcard-маски. Домен может быть как второго уровня, так и поддоменом:

; вариант 1: домен второго уровня, IP сервера 203.0.113.10
example.com. IN A 203.0.113.10
*.example.com. IN A 203.0.113.10

; вариант 2: выделенный поддомен
tunnel.example.com. IN A 203.0.113.10
*.tunnel.example.com. IN A 203.0.113.10

Первая запись обслуживает панель управления, вторая - поддомены публикаций. Проверить можно так (обе команды должны вернуть IP сервера, вторая - для любого случайного имени):

dig +short example.com
dig +short random-name.example.com

Тот же публичный IP укажите в CLOUDPUB_IP и CLOUDPUB_EDGES.

Сертификат. Он должен покрывать оба имени: сам домен и маску поддоменов. Wildcard сам по себе апекс не покрывает, поэтому в SAN должны быть обе записи:

X509v3 Subject Alternative Name:
DNS:example.com, DNS:*.example.com

Проверить готовый сертификат:

openssl x509 -in certificate.crt -noout -checkhost example.com
openssl x509 -in certificate.crt -noout -checkhost demo.example.com
warning

Маска покрывает ровно один уровень. Сертификат на *.example.com подходит для demo.example.com, но не подходит ни для example.com, ни для a.b.example.com. При развертывании на поддомене (tunnel.example.com) нужны SAN tunnel.example.com и *.tunnel.example.com.

Wildcard-сертификат от Let's Encrypt выпускается только через проверку DNS-01, HTTP-01 для масок не работает:

certbot certonly --manual --preferred-challenges dns \
-d example.com -d '*.example.com'

Полученные файлы кладутся в том данных, см. TLS-сертификаты. Если сертификат не предоставлен, контейнер выпускает самоподписанный сразу с обоими именами - этого достаточно для первого запуска и тестов, но браузер будет предупреждать о недоверенном сертификате.

Быстрый старт

Для работы нужны три сервиса: PostgreSQL, Redis и сам сервер. Минимальный docker-compose.yml:

services:
db:
image: postgres:latest
environment:
POSTGRES_USER: cloudpub
POSTGRES_PASSWORD: <пароль-БД>
POSTGRES_DB: cloudpub
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
- pgdata:/var/lib/postgresql/data/pgdata
restart: unless-stopped

redis:
image: redis:7-alpine
restart: unless-stopped

node:
image: docker.ermak.dev/cloudpub/server:latest
ports:
- "443:443"
- "80:80"
environment:
CLOUDPUB_DOMAIN: cloud.example.com # единственная обязательная переменная
POSTGRES_HOST: db
POSTGRES_PASSWORD: <пароль-БД>
REDIS_HOST: redis
volumes:
- cloudpub-data:/var/lib/cloudpub
restart: unless-stopped
depends_on:
- db
- redis

volumes:
pgdata:
cloudpub-data:
docker compose up -d

При первом запуске контейнер автоматически: формирует конфигурацию сервера под указанный домен, дожидается базы данных, применяет миграции, создает расширение pg_trgm, генерирует самоподписанный TLS-сертификат (если не предоставлен настоящий) и запускает все сервисы.

Первый администратор создается интерактивно:

docker compose exec node clo createsuperuser

После этого панель управления доступна по адресу https://cloud.example.com.

Дистрибутивы агента образ раздает сам, по адресу https://cloud.example.com/download/stable/. Ссылки на панели управления и автообновление подключенных агентов ведут туда же, поэтому установка и обновление агентов не требуют доступа в интернет.

Требования к сети

Порты 443 и 80 должны быть доступны снаружи (порт 80 обслуживает перенаправление на HTTPS и ACME-проверки). A-записи домена и wildcard-маски, а также требования к сертификату описаны в разделе Домен, DNS и TLS-сертификат.

Переменные окружения

Обязательная переменная одна - CLOUDPUB_DOMAIN. Остальные опциональны и сгруппированы по назначению.

Идентификация сервера

ПеременнаяНазначениеПо умолчанию
CLOUDPUB_DOMAINПубличный домен сервера- (обязательна)
CLOUDPUB_PORTПубличный HTTPS-порт443
CLOUDPUB_IPПубличный IP-адрес, показываемый пользователям для A-записей при подключении своего доменапусто
CLOUDPUB_EDGESСписок публичных IP-адресов сервера через запятую (используется бэкендом)127.0.0.1
примечание

Для развертывания на одном сервере задайте CLOUDPUB_IP и CLOUDPUB_EDGES в один и тот же публичный IP-адрес.

Брендинг и интерфейс

ПеременнаяНазначениеПо умолчанию
CLOUDPUB_SITE_NAMEНазвание сайта в интерфейсеCloudPub
CLOUDPUB_ENTITY, CLOUDPUB_INNЮридическое лицо и ИНН в подвалепусто
CLOUDPUB_EMAIL, CLOUDPUB_PHONE, CLOUDPUB_TELEGRAMКонтакты поддержки в интерфейсепусто
CLOUDPUB_TRAFFIC_LIMITЛимит трафика бесплатного тарифа, байт (0 - без лимита)0
CLOUDPUB_LOG_LEVELУровень логирования сервераinfo
CLOUDPUB_DEBUGРежим отладки Django (true/false) - только для диагностикиfalse

TLS

ПеременнаяНазначениеПо умолчанию
CLOUDPUB_CERT_FILE, CLOUDPUB_KEY_FILEПути к сертификату и ключу основного доменаcerts/certificate.{crt,key} в томе
CLOUDPUB_CA_FILEПуть к CA-бандлу для проверки клиентских сертификатовне задан
CLOUDPUB_ACME_EMAILE-Mail для регистрации ACME-аккаунта (сертификаты клиентских доменов)не задан

Почта (SMTP)

ПеременнаяНазначениеПо умолчанию
CLOUDPUB_EMAIL_HOSTSMTP-сервер (без него почта пишется в файлы)не задан
CLOUDPUB_EMAIL_PORTПорт SMTP465
CLOUDPUB_EMAIL_USER, CLOUDPUB_EMAIL_PASSWORDУчетные данные SMTPпусто
CLOUDPUB_EMAIL_USE_SSLИспользовать SSLtrue
CLOUDPUB_EMAIL_USE_TLSИспользовать STARTTLSfalse
CLOUDPUB_SUPPORT_EMAILАдрес отправителя и адрес поддержкиsupport@<домен>

Интеграции и уведомления

ПеременнаяНазначениеПо умолчанию
CLOUDPUB_TELEGRAM_BOT_TOKEN, CLOUDPUB_TELEGRAM_CHAT_IDTelegram-бот для системных уведомленийне задан
CLOUDPUB_SENTRY_DSNDSN для отправки ошибок в Sentryне задан
CLOUDPUB_SMS_RU_API_KEYКлюч API sms.ru для отправки SMSне задан

Учетные записи

ПеременнаяНазначениеПо умолчанию
CLOUDPUB_ADMIN_EMAIL, CLOUDPUB_ADMIN_PASSWORDАвтосоздание администратора при старте (для развертывания из секрет-менеджера; иначе используйте clo createsuperuser)не задан

База данных и кеш

ПеременнаяНазначениеПо умолчанию
POSTGRES_HOST, POSTGRES_PORT, POSTGRES_DB, POSTGRES_USER, POSTGRES_PASSWORDПодключение к PostgreSQLdb:5432, cloudpub
CLOUDPUB_DB_CONNECTПолный URL подключения к PostgreSQL (заменяет POSTGRES_*)строится из POSTGRES_*
REDIS_HOST, REDIS_PORTПодключение к Redisredis:6379
CLOUDPUB_REDIS_URLПолный URL подключения к Redis (заменяет REDIS_HOST/PORT)строится из REDIS_HOST/PORT
warning

Без настроенного SMTP исходящая почта (ссылки регистрации, восстановление пароля) не доставляется. Для боевого развертывания задайте CLOUDPUB_EMAIL_* или создавайте пользователей через администратора.

Различие Telegram-переменных

CLOUDPUB_TELEGRAM - это контакт поддержки, отображаемый в интерфейсе. Токен и chat ID бота для системных уведомлений задаются отдельными переменными CLOUDPUB_TELEGRAM_BOT_TOKEN и CLOUDPUB_TELEGRAM_CHAT_ID.

TLS-сертификаты

Сертификат основного домена. Положите wildcard-сертификат в том данных: certs/certificate.crt и certs/certificate.key (пути настраиваются через CLOUDPUB_CERT_FILE/CLOUDPUB_KEY_FILE). Если сертификат не предоставлен, контейнер генерирует самоподписанный - удобно для первого запуска и тестов. При смене домена самоподписанный сертификат перевыпускается автоматически, предоставленный вручную - никогда не затрагивается.

Сертификаты клиентских доменов. Когда пользователь подключает собственный домен, сертификат выпускается автоматически через Let's Encrypt (задайте CLOUDPUB_ACME_EMAIL) и продлевается встроенными заданиями. Сертификат, полученный вне CloudPub, достаточно положить в том данных как letsencrypt/live/<домен>/fullchain.pem и privkey.pem - сервер подхватывает содержимое каталога на лету, без перезапуска.

Хранение данных

Все постоянное состояние сервера живет в одном томе, смонтированном в /var/lib/cloudpub:

/var/lib/cloudpub/
├── certs/ сертификат основного домена
├── instance_id уникальный идентификатор установки (создается при первом старте)
├── license файл лицензии (устанавливается при развертывании)
├── letsencrypt/ ACME-аккаунт и сертификаты клиентских доменов
├── media/ записи трафика и медиа-данные
└── sockets/ служебные сокеты публикаций

Резервная копия развертывания - это дамп PostgreSQL плюс архив этого тома:

docker compose exec db pg_dump -U cloudpub cloudpub > backup.sql
docker run --rm -v cloudpub_cloudpub-data:/data -v $PWD:/backup alpine \
tar czf /backup/cloudpub-data.tar.gz -C /data .

Redis используется только как кеш и шина сообщений - его данные не требуют сохранения.

Лицензирование

Сервер лицензируется по количеству агентов и одновременно активных публикаций. Без файла лицензии он работает в пробном режиме со встроенными ограничениями: до 5 агентов и до 10 одновременно активных публикаций. Лицензия снимает или расширяет эти лимиты.

Лицензия привязывается к идентификатору установки - случайному UUID, который генерируется при первом старте сервера и хранится в томе данных. Получить его можно командой:

docker compose exec node cat /var/lib/cloudpub/instance_id

Идентификатор также выводится в лог сервера при старте (строка Instance ID).

Порядок активации:

  1. Получите идентификатор установки и передайте его поставщику лицензии.
  2. Полученный файл лицензии поместите в том данных:
docker compose cp license node:/var/lib/cloudpub/license
  1. Лицензия применяется автоматически в течение нескольких секунд, перезапуск сервера не требуется. Сводка по лимитам выводится в лог при старте.
warning

Идентификатор установки хранится в томе данных (instance_id). При удалении тома он будет сгенерирован заново, и файл лицензии перестанет подходить - сохраняйте резервную копию тома или как минимум файлов instance_id и license.

Пути файлов настраиваются переменными окружения:

ПеременнаяНазначениеПо умолчанию
CLOUDPUB_LICENSE_PATHПуть к файлу лицензии/var/lib/cloudpub/license
CLOUDPUB_INSTANCE_ID_PATHПуть к идентификатору установки/var/lib/cloudpub/instance_id

Администрирование

Любые команды управления выполняются внутри контейнера через clo:

docker compose exec node clo createsuperuser # создать администратора
docker compose exec node clo changepassword # сменить пароль пользователя
docker compose exec node clo shell # консоль Django

Изменение конфигурации. Поменяйте переменные окружения в compose-файле и пересоздайте контейнер: docker compose up -d --force-recreate node. Данные при этом сохраняются - они живут в томе и базе данных.

Обновление. Получите новый образ и перезапустите: docker compose pull node && docker compose up -d node. Миграции базы данных применяются автоматически при старте.