| title | HTTPS и сертификаты |
|---|---|
| description | HTTPS для панели GameAP: самоподписанный сертификат командой gameapctl panel https, сертификат из файлов, автоматический выпуск через Let’s Encrypt по http-01 и dns-01, продление и работа за обратным прокси. |
| layout | default |
| lang | ru |
| category | Администрирование |
| order | 333 |
Панель умеет обслуживать HTTPS самостоятельно, без обратного прокси. Сертификат можно взять из файлов, задать прямо в конфигурации или получать автоматически через Let's Encrypt. Быстрее всего начать с самоподписанного сертификата, который выпускается одной командой gameapctl, — см. Настройка через gameapctl.
Настройки задаются в config.env — /etc/gameap/config.env в Linux
(~/.config/gameap/config.env при установке без root),
C:\gameap\web\config.env в Windows. После изменения нужен перезапуск: gameapctl panel restart.
Панель выбирает источник сама, в таком порядке:
- ACME — если заданы
ACME_ENABLED=true,ACME_EMAILиACME_DOMAINS. - Файлы — если заданы
TLS_CERT_FILEиTLS_KEY_FILE. - Значения в конфигурации — если заданы
TLS_CERTиTLS_KEY. - Нет сертификата — панель работает только по HTTP.
Проверяются именно пары: один TLS_CERT_FILE без TLS_KEY_FILE не считается заданным
источником и молча игнорируется.
gameapctl соблюдает тот же порядок: gameapctl panel https enable отказывается работать при
настроенном ACME, потому что панель всё равно проигнорирует сертификат на диске, а
gameapctl panel https disable выключает и то и другое.
HTTPS слушается на порту из HTTPS_PORT (по умолчанию 443) и только при наличии сертификата.
HTTP на HTTP_PORT работает всегда. Собственное значение панели для HTTP_PORT — 8025, но
gameapctl panel install записывает HTTP_PORT=80 при системной установке и HTTP_PORT=8025 при
пользовательской — какой порт использует именно ваша установка, смотрите в config.env.
Сертификат панели никак не связан с сертификатами gRPC, по которым панель общается с демонами. Те выпускаются внутренним центром сертификации автоматически, ACME на них не распространяется. Подробнее — GRPC API.
Панель завершает TLS сама, поэтому настраивать веб-сервер не нужно. Одна команда выпускает
самоподписанный сертификат, прописывает его в config.env и перезапускает панель:
gameapctl panel https enable
gameapctl panel https status
gameapctl panel https disableСертификат покрывает настроенный HTTP_HOST, имя хоста машины, все адреса её сетевых интерфейсов
и loopback (localhost, 127.0.0.1, ::1); срок действия — 825 дней. Повторный запуск
оставляет сертификат, который всё ещё покрывает все запрошенные имена и не истекает в ближайшее
время, — исключение, уже принятое в браузере, сохраняется. Поскольку сертификат самоподписанный,
браузеры не доверяют ему, пока он не добавлен в хранилище доверенных сертификатов на каждой машине,
с которой открывают панель; скопируйте его по пути, который печатает status.
Собственный сертификат подставляется флагами --cert и --key. Файлы остаются на месте —
укажите флагами рабочие файлы внешнего ACME-клиента, и панель подхватит каждое продление при
перезапуске.
| Флаг | Назначение |
|---|---|
--cert |
Путь к PEM-сертификату вместо самоподписанного; требует --key |
--key |
Путь к закрытому ключу для --cert |
--domain |
Домен, который должен покрывать сертификат. Повторяемый; заменяет обнаруженные имена |
--ip |
IP-адрес, который должен покрывать сертификат. Повторяемый; заменяет обнаруженные адреса |
--port |
Порт HTTPS: 443, с --scope=user — 8443 |
--days |
Срок действия самоподписанного сертификата в днях, по умолчанию 825 |
--force-https |
Перенаправлять HTTP-запросы на HTTPS (TLS_FORCE_HTTPS). Без флага остаётся как настроено |
--force |
Перевыпустить самоподписанный сертификат, даже если текущий ещё подходит |
--scope |
Область установки, system или user; по умолчанию определяется по состоянию установки |
HTTP продолжает отвечать на своём порту. Включайте --force-https только когда уверены, что порт
HTTPS доступен, — иначе вы потеряете доступ к панели отовсюду, где цель перенаправления заблокирована.
Оба слушателя обслуживает один процесс, и панель завершается, если не может загрузить
сертификат, на который настроена. Поэтому enable проверяет, что панель поднялась и отдаёт
именно тот сертификат, который только что записан, а если нет — возвращает предыдущий
config.env и перезапускает панель с ним.
disable удаляет переменные TLS из config.env (а если действует ACME — и переменные ACME_*)
и перезапускает панель на обычном HTTP. disable --purge дополнительно удаляет сертификат и ключ,
выпущенные gameapctl; сертификат, переданный через --cert, не трогается.
status печатает область установки, путь к конфигурации, адреса HTTP и HTTPS, источник
сертификата, фактически отдаваемый сертификат и срок его действия.
Где gameapctl хранит выпущенный сертификат:
| Область | Сертификат | Закрытый ключ | Порт по умолчанию |
|---|---|---|---|
| system | /etc/gameap/certs/panel.crt |
/etc/gameap/certs/panel.key |
443 |
| user | ~/.config/gameap/certs/panel.crt |
~/.config/gameap/certs/panel.key |
8443 |
| Windows | C:\gameap\web\certs\panel.crt |
C:\gameap\web\certs\panel.key |
443 |
TLS_CERT_FILE=/etc/gameap/certs/panel.crt
TLS_KEY_FILE=/etc/gameap/certs/panel.key
HTTPS_PORT=443Это пути, которые gameapctl использует сам при системной установке; при пользовательской —
~/.config/gameap/certs/, в Windows — C:\gameap\web\certs. Вместо ручной правки config.env
подключайте собственный сертификат командой gameapctl panel https enable --cert=<путь> --key=<путь>
— она записывает переменные и затем проверяет, что панель поднялась и отдаёт этот сертификат, а
при неудаче откатывает конфигурацию. Без такой проверки неверная пара останавливает панель: она
завершается, если не может загрузить настроенный сертификат.
В файле сертификата должна быть полная цепочка: сам сертификат, затем промежуточные. Без промежуточных часть клиентов не сможет проверить подпись.
Файлы читаются при запуске. После замены сертификата панель нужно перезапустить — сама она изменения в файлах не отслеживает.
Удобно, когда конфигурация раскладывается системой управления секретами и лишние файлы на диске нежелательны.
TLS_CERT=LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t...
TLS_KEY=LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0t...Принимается как обычный PEM, так и PEM в кодировке base64 — панель определяет формат сама.
Поскольку формат config.env не поддерживает многострочные значения, на практике используется
base64:
base64 -w0 panel.crt
base64 -w0 panel.keyПанель содержит встроенный клиент ACME: сертификат выпускается и продлевается без внешних утилит вроде certbot.
| Переменная | По умолчанию | Назначение |
|---|---|---|
ACME_ENABLED |
false |
Включение автоматического выпуска |
ACME_EMAIL |
"" |
Адрес для уведомлений об истечении. Обязателен |
ACME_DOMAINS |
"" |
Домены через запятую. Обязательны |
ACME_CHALLENGE_TYPE |
http-01 |
Способ подтверждения: http-01 или dns-01 |
ACME_DNS_PROVIDER |
"" |
Провайдер DNS, только для dns-01 |
ACME_DIRECTORY_URL |
боевой ACME | Адрес каталога ACME |
ACME_RENEWAL_THRESHOLD |
720h |
За сколько до истечения продлевать. По умолчанию 30 суток |
ACME_RENEWAL_CHECK_INTERVAL |
12h |
Как часто проверять срок |
ACME_PROPAGATION_TIMEOUT |
180s |
Сколько ждать распространения DNS-записи при dns-01 |
ACME_STORAGE_PATH |
acme |
Каталог для сертификатов и ключа учётной записи ACME |
ACME включается только при одновременно заданных
ACME_ENABLED=true,ACME_EMAILиACME_DOMAINS, а дляdns-01— ещё иACME_DNS_PROVIDER. Если чего-то не хватает, панель запустится без ACME и без ошибки. Проверить, что получилось, можно по состоянию в админке.
Способ по умолчанию. Ничего, кроме доступности панели из интернета, не требует.
ACME_ENABLED=true
ACME_EMAIL=[email protected]
ACME_DOMAINS=panel.example.com
ACME_CHALLENGE_TYPE=http-01
TLS_FORCE_HTTPS=trueЧто нужно:
- домены из
ACME_DOMAINSдолжны резолвиться в адрес этого сервера; - запрос на порт 80 должен доходить до панели — центр сертификации обращается именно на него;
- панель обслуживает путь
/.well-known/acme-challenge/самостоятельно, на своём HTTP-порту.
Центр сертификации всегда обращается на порт 80. Установка, выполненная
gameapctl panel installв системной области, уже слушает его (HTTP_PORT=80). Если панель на другом порту — собственное значение панели8025, а установщик при занятом 80-м берёт первый свободный из8025,8026, … — проверьтеHTTP_PORTвconfig.envи либо задайтеHTTP_PORT=80, либо пробросьте 80-й порт на порт панели средствами системы:iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8025Вместо
8025в--to-portподставьте значениеHTTP_PORTизconfig.env.Такое правило живёт только до перезагрузки. Сохраните его штатными средствами файрвола дистрибутива — теми, что восстанавливают правила при загрузке, — либо вместо проброса поставьте перед панелью обратный прокси, слушающий 80-й порт.
Порт 80 нужен не только при первом выпуске: подтверждение повторяется при каждом продлении, поэтому закрывать его потом нельзя.
При установке без root панель не может
занять порт 80 сама — непривилегированному процессу это не разрешено. Подтверждение всё равно
проходит, если 80-й порт проброшен на HTTP-порт панели или перед панелью стоит обратный прокси:
путь /.well-known/acme-challenge/ панель обслуживает на своём HTTP-порту. Если проброса нет,
используйте там dns-01.
Способ http-01 не выпускает сертификаты на поддомены с подстановкой (*.example.com) — для
них нужен dns-01.
Нужен, если панель не доступна из интернета по порту 80 или требуется сертификат с подстановкой.
Из встроенных провайдеров поддерживается только Cloudflare. Остальные подключаются плагинами:
в этом случае в ACME_DNS_PROVIDER указывается <идентификатор-плагина>:<имя-провайдера>.
ACME_ENABLED=true
ACME_EMAIL=[email protected]
ACME_DOMAINS=panel.example.com,*.example.com
ACME_CHALLENGE_TYPE=dns-01
ACME_DNS_PROVIDER=cloudflare
CLOUDFLARE_DNS_API_TOKEN=токен_из_панели_cloudflareТокен создаётся в Cloudflare с правом Zone → DNS → Edit для нужной зоны. Кроме
CLOUDFLARE_DNS_API_TOKEN принимаются CF_DNS_API_TOKEN, CLOUDFLARE_API_TOKEN и CF_API_TOKEN,
а также устаревшая пара «глобальный ключ + почта»: CLOUDFLARE_API_KEY вместе с CLOUDFLARE_EMAIL.
Предпочтительнее токен с ограниченными правами.
Если DNS-записи распространяются медленно, увеличьте ACME_PROPAGATION_TIMEOUT.
Вместо ручной правки config.env можно воспользоваться мастером:
gameapctl panel https letsencrypt setupОн спросит домены, адрес почты и способ подтверждения, запишет настройки в config.env
и перезапустит панель.
Раньше команда называлась
gameapctl panel letsencrypt. Эта форма пока работает как устаревший псевдоним, но в--helpне показывается; используйтеgameapctl panel https letsencrypt.
Тот же вызов без вопросов:
gameapctl panel https letsencrypt setup --non-interactive \
--domains=panel.example.com \
[email protected] \
--challenge=http-01Полезные флаги:
| Флаг | Назначение |
|---|---|
--challenge |
http-01 или dns-01 |
--domains |
Домены через запятую |
--email |
Адрес учётной записи ACME |
--dns-provider |
Провайдер DNS для dns-01 |
--env |
Дополнительные строки КЛЮЧ=ЗНАЧЕНИЕ в config.env — для доступов к DNS |
--staging |
Тестовый каталог Let's Encrypt |
--non-interactive |
Не задавать вопросов, а завершиться с ошибкой при нехватке параметров |
--scope |
Область установки, system или user; по умолчанию определяется по состоянию установки |
Отключение:
gameapctl panel https letsencrypt disableКоманда удаляет из config.env переменные ACME_* и перезапускает панель. Флаг --purge-certs
объявлен, но пока не реализован — выпущенные сертификаты остаются на диске.
У боевого каталога Let's Encrypt жёсткие ограничения на число попыток для одного домена, и исчерпать их при настройке легко. Пока настройка не заработала, используйте тестовый каталог:
ACME_DIRECTORY_URL=https://acme-staging-v02.api.letsencrypt.org/directoryЕго сертификаты браузер считает недоверенными, зато ограничения несравнимо мягче. Когда выпуск
пройдёт, уберите эту переменную, удалите содержимое каталога из ACME_STORAGE_PATH и перезапустите
панель, чтобы получить боевой сертификат.
Панель проверяет срок каждые ACME_RENEWAL_CHECK_INTERVAL (по умолчанию раз в 12 часов) и продлевает
сертификат, когда до истечения остаётся меньше ACME_RENEWAL_THRESHOLD (по умолчанию 30 суток).
Отдельная задача в планировщике или cron не нужна.
Сертификаты, ключ учётной записи ACME и служебные данные хранятся в каталоге ACME_STORAGE_PATH
внутри файлового хранилища панели. Если FILES_DRIVER=s3, они попадают в S3 — это то, что позволяет
нескольким экземплярам панели использовать один сертификат.
Текущее состояние доступно администратору по адресу GET /api/admin/letsencrypt/status:
{
"enabled": true,
"state": "active",
"challenge_type": "http-01",
"domains": ["panel.example.com"],
"not_after": "2026-10-30T12:00:00Z",
"last_renewal_at": "2026-08-01T12:00:00Z",
"next_renewal_check_at": "2026-08-02T00:00:00Z"
}Возможные значения state:
| Значение | Что означает |
|---|---|
disabled |
ACME выключен |
pending |
Сертификат ещё не выпущен |
active |
Сертификат выпущен и действителен |
renewing |
Идёт продление |
failed |
Последняя попытка не удалась, причина в last_error |
TLS_FORCE_HTTPS=trueВсе запросы по HTTP получают перенаправление 301, кроме /.well-known/acme-challenge/ — иначе
подтверждение по http-01 перестало бы работать.
Эта же переменная влияет на два других механизма: заголовок HSTS начинает отдаваться, даже если
TLS завершается на обратном прокси, и адрес источника для CORS вычисляется со схемой https.
Если TLS завершается на nginx, Traefik или другом прокси, сертификаты в панели настраивать не нужно
— оставьте ACME_ENABLED=false и не задавайте TLS_*. Панель будет работать по HTTP на
HTTP_PORT, а прокси — обслуживать HTTPS.
Что при этом важно:
- Прокси должен передавать заголовок
X-Forwarded-Proto: https, иначе панель не поймёт, что соединение защищено, и не отдаст HSTS. - Заголовки
X-Forwarded-Protoи заголовок изAUDIT_CLIENT_IP_HEADERпрокси должен перезаписывать, а не дополнять: панель доверяет им без проверки отправителя. - Порт 31718 через прокси обычно не проходит — демоны должны подключаться к панели напрямую.
Задайте
GRPC_EXTERNAL_HOSTс адресом, по которому панель доступна демонам. - Если публичный адрес отличается от
HTTP_HOST, перечислите его вHTTP_ALLOWED_ORIGINS.
| Признак | Причина |
|---|---|
| Панель запустилась, но HTTPS не слушается | Не задана пара переменных целиком либо не хватает одной из обязательных ACME_* |
state: failed при http-01 |
Порт 80 недоступен извне, домен не резолвится в этот сервер или его перехватывает другой сервис |
state: failed при dns-01 |
Нет прав у токена DNS или запись не успела распространиться — увеличьте ACME_PROPAGATION_TIMEOUT |
| Выпуск перестал работать после нескольких попыток | Исчерпан лимит боевого каталога Let's Encrypt. Перейдите на тестовый каталог и настройте на нём |
| Браузер ругается на цепочку | В TLS_CERT_FILE только сертификат без промежуточных |
| Сертификат заменили, но отдаётся старый | Файлы читаются при запуске — нужен gameapctl panel restart |
gameapctl panel https enable завершается с «ACME is enabled» |
ACME имеет приоритет над сертификатом на диске. Сначала выполните gameapctl panel https letsencrypt disable |
Панель не запускается после ручной правки TLS_* |
Она не может загрузить настроенный сертификат или ключ. Исправьте пару или уберите переменные; gameapctl panel https enable --cert=<путь> --key=<путь> избегает этого, проверяя результат и откатывая изменения |