Skip to main content
Это тот же отдельный сервер авторизации, что и в self-hosted quickstart, только без Docker: архив с самодостаточным исполняемым файлом плюс установщик, который регистрирует его юнитом systemd или службой Windows. На целевой машине .NET не нужен. Эта страница — про установку: где лежат файлы, как регистрируется служба, как её обновить и удалить. Что писать в конфигурацию (хранилища, сертификаты, клиенты, каналы) от способа поставки не зависит и остаётся в self-hosted quickstart.
После установщика у вас работающая служба, а не продакшен. Он пишет стартовую конфигурацию — хранилище в памяти и два самоподписанных сертификата токенов, — чтобы служба сразу отвечала на /health/live, а не отказывалась стартовать. Всё, что делает её продакшен-инстансом, — шаг 6.

1. Скачайте архив и проверьте его

В релизе три архива и один файл сумм: Это ассеты релиза, и база их адреса постоянна — permalink/latest всегда указывает на последний релиз:
Имя файла несёт версию, поэтому адрес целиком постоянной ссылкой не является: как только выйдет следующий релиз, пути с предыдущей версией среди ассетов permalink/latest не будет и скачивание ответит 404. Поэтому адрес репозитория и текущую версию каждый раз берите на veriqa.app/source, а не сохраняйте готовый URL:
--ignore-missing здесь обязателен, если скачан один архив: в файле сумм перечислены все три, и без флага sha256sum падает на двух недостающих. На Windows:
True — архив целый.

2. Установка на Linux

Архив распаковывается в один каталог veriqa-authserver/ и несёт свой установщик install.sh. Запустите его от root из этого каталога:
Установщик заводит системного пользователя veriqa (без оболочки входа, домашний каталог не создаётся), копирует программу, создаёт каталоги конфигурации и данных, генерирует сертификаты токенов, пишет стартовую конфигурацию, кладёт unit-файл и включает службу. Запускать её он не запускает: стартовую конфигурацию нужно прочитать до первого старта, а не после.
Каталог программы принадлежит только этой установке. Оба установщика пишут в него, ничего предварительно не расчищая: файл из архива перезаписывает свой аналог, всё остальное остаётся на месте — и удаление зеркально: --uninstall / -Uninstall забирает ровно те файлы, которые установщик скопировал, и больше ничего, а сам каталог оставляет, если в нём осталось что-то ещё. Укажите в --install-directory / -InstallDirectory отдельный каталог — тогда установка снимается одним шагом.
Умолчание --urls — только loopback: инстанс доступен с этой же машины и с reverse-proxy на ней, и больше ниоткуда.
TLS нужен самому API, а не только чтобы открыть инстанс наружу. По обычному HTTP эндпоинт токена отвечает 400 invalid_request — «This server only accepts HTTPS requests» (ID2083), — поэтому бэкенд, вызывающий API подтверждений, не получит токена даже с этой же машины. Сделайте шаг 7 до первого вызова: поставьте перед хостом reverse-proxy или дайте Kestrel сертификат.
Запускайте службу, прочитав то, что напечатал установщик:
Установщик отказывается работать поверх уже зарегистрированной службы с тем же именем (use --uninstall first), а не пересоздаёт её молча. Обновление существующей установки — Обновление.

3. Установка на Windows

Распакуйте .zip и запустите install.ps1 из распакованного каталога в PowerShell от администратора (работает и Windows PowerShell 5.1, и PowerShell 7):
Служба регистрируется с автозапуском под виртуальной учётной записью NT SERVICE\<ServiceName> — своя учётная запись и пароль не нужны. Каталог конфигурации — %ProgramData%\Veriqa; его список доступа строится заново, без наследования, поэтому группа Users к лежащим там секретам доступа не получает. Как и на Linux, служба зарегистрирована, но не запущена:

4. Что даёт первый запуск

Установка сознательно доведена ровно до состояния «стартует», и не дальше:
  • хранилище OpenIddict — InMemory: зарегистрированные клиенты, выданные токены и журнал теряются при каждом рестарте;
  • сертификаты токенов самоподписанные, RSA-2048, сроком на два года, сгенерированы на этой машине;
  • ни один канал и ни один OIDC-клиент не настроены, поэтому настоящий вход пока не завершится.
Оба эндпоинта здоровья в этом состоянии отвечают 200:
/health/ready отвечает 200 потому, что стартовая конфигурация не объявляет ни одной внешней зависимости для проверки, — а не потому, что инстанс готов к продакшену.

5. Где что лежит

Конфигурация, ключи Data Protection и сертификаты токенов живут вне каталога программы, чтобы её замена их не трогала. На Linux /etc/veriqa — root:veriqa 0750, а /var/lib/veriqa — 0700 с владельцем veriqa: там секреты, и читает их только учётная запись службы. Почему каталог ключей не опционален. Ключи Data Protection защищают cookie входа и всё, что хост шифрует. Без каталога ключей и без Redis хост держит их в памяти, и каждый рестарт делает недействительным выданное предыдущим процессом — пользователей выбрасывает из начатых входов. Поэтому установщик задаёт Veriqa:DataProtection:KeysDirectory в окружении самой службы, а каталог переживает и обновление, и обычное удаление. Служба регистрируется с четырьмя переменными окружения — им место именно в окружении, потому что они говорят, откуда читается конфигурация:

Каталог конфигурации

VERIQA_CONFIG_DIRECTORY называет каталог, а не файл. Из него хост читает appsettings.json и appsettings.Production.json — оба необязательные — и накладывает их поверх файлов, поставляемых с программой. Порядок источников, от слабого к сильному:
  1. appsettings.json каталога программы;
  2. appsettings.Production.json каталога программы;
  3. appsettings.json каталога конфигурации;
  4. appsettings.Production.json каталога конфигурации;
  5. переменные окружения (Veriqa__OpenIddict__…);
  6. аргументы командной строки.
Поэтому единственная строка, которую пишет установщик, — Provider = InMemory — побеждает Provider = PostgreSQL из каталога программы, а всё, что передано через окружение, по-прежнему побеждает оба файла. Если переменная называет несуществующий каталог, хост не стартует и говорит об этом: VERIQA_CONFIG_DIRECTORY points to '/etc/veriqa', which does not exist. Существующий каталог без файлов ошибкой не является.
В self-hosted quickstart собственные настройки интегратора лежат в config/veriqa.json, который ищется относительно корня контента. У службы корень контента — каталог программы, а его заменяет обновление, поэтому в этом способе поставки кладите свои настройки в каталог конфигурации.

6. Переход в продакшен

Рядом с программой установка кладёт шаблон appsettings.Production.sample.json. В нём те же ключи, что в self-hosted quickstart, со значениями-плейсхолдерами REPLACE_ME. Используйте его как образец и правьте файл, написанный установщиком, а не затирайте этот файл шаблоном: в шаблоне нет путей к сертификатам, сгенерированным на этой машине, а каждый REPLACE_ME в нём — значение, которое вам ещё предстоит задать.
Копию кладите вне /etc/veriqa: начиная с правки ниже в ней лежат секреты — токен бота, строки подключения, пароли сертификатов, — а полное удаление её на Linux не заберёт, на Windows же, наоборот, не пощадит: %ProgramData%\Veriqa уходит целиком. Что именно туда писать, описано один раз, для обоих способов поставки:
Замена сертификатов токенов делает недействительными все токены, подписанные старой парой, а переключение хранилища с InMemory на базу начинает с пустой: клиенты, зарегистрированные в памяти, придётся объявить в конфигурации. Сделайте и то и другое до того, как через инстанс пойдут реальные входы.

SQL Server на Windows

В архиве для Windows нет Microsoft.Data.SqlClient.SNI.dll — нативной сетевой библиотеки, через которую драйвер SQL Server работает на Windows: она принадлежит Microsoft, распространяется по Microsoft Software License Terms, и Veriqa её не распространяет. PostgreSQL она не нужна, Linux — тоже. Если для какого-либо хранилища выбран SqlServer, а библиотеки нет, служба не стартует, а сообщение называет версию Microsoft.Data.SqlClient и даёт ссылку на её страницу на nuget.org. Возьмите библиотеку из NuGet-пакета Microsoft.Data.SqlClient.SNI.runtime — в версии, указанной на этой странице в разделе Dependencies, — и положите рядом с программой. Скачивая её, вы принимаете условия Microsoft:
Установщик удаляет из каталога программы только те файлы, которые положил сам, поэтому библиотека переживает обновление; после него сверьте, что драйвер нового релиза указывает ту же версию, которую вы скопировали. При полном удалении удалите её вручную.

7. HTTPS

Хост говорит по HTTP на адресах из --urls / -Urls, а OpenIddict отдаёт /connect/token и остальной протокол только по https, поэтому шаг не факультативный, открыт инстанс наружу или нет. Поставить перед ним TLS можно двумя путями. (а) Reverse-proxy на той же машине. Оставьте --urls равным http://127.0.0.1:8080, терминируйте TLS в NGINX / Caddy / IIS и проксируйте на loopback. Чтобы OpenIddict строил https-URL, proxy должен передавать X-Forwarded-Proto и X-Forwarded-For, а самому proxy нужно доверять — та же секция ForwardedHeaders, что в self-hosted, шаг 6, в файле конфигурации установки:
appsettings.Production.json
По умолчанию доверие есть только к loopback, так что proxy на той же машине покрыт и без этой секции — явная запись делает границу доверия видимой прямо в конфигурации. Proxy на другом хосте не покрыт: впишите сюда его адрес или его сеть в KnownIPNetworks. На proxy же лежит и ограничение частоты по IP — см. Продакшн-харденинг. (б) Сертификат прямо в Kestrel, без proxy вообще. Это обычная конфигурация ASP.NET Core в том же файле (Kestrel endpoints):
appsettings.Production.json
Секция Kestrel:Endpoints заменяет адреса из ASPNETCORE_URLS, а не добавляется к ним, поэтому переустановка не нужна — но HTTP-эндпоинт, заданный установщиком через --urls, вместе с этим пропадает. Если он всё ещё нужен (например, для локальных проб здоровья), объявите рядом эндпоинт Http. Серверный сертификат держите читаемым только учётной записью службы, рядом с сертификатами токенов.

8. Проверка

Discovery должен вернуться с https-URL; если вернулся с http — proxy не в доверенных, шаг 7. Полный чек-лист развёрнутого инстанса, включая первый вход, — self-hosted, шаг 8. На Linux лог службы — в журнале:
На Windows неудачный старт фиксирует Service Control Manager в «Просмотре событий» → «Журналы Windows». Чтобы увидеть сообщение самого хоста, запустите исполняемый файл в консоли из каталога программы, с тем же окружением:

Обновление

Обновление заменяет программу и сохраняет конфигурацию, ключи Data Protection и сертификаты токенов: они специально живут вне каталога программы.
На Windows те же два шага: .\install.ps1 -Uninstall из распакованного архива установленной версии, затем .\install.ps1 из нового архива и Start-Service Veriqa. Повторный запуск не перезаписывает существующий appsettings.Production.json и не перегенерирует существующие сертификаты — он сообщает, что оставил их. Если вы ставили с нестандартными --service-name, --install-directory или --config-directory, передайте те же значения обоим запускам. --urls / -Urls устанавливающему запуску нужно повторить тоже, и по другой причине: это значение нигде не хранится, прочитать его установщику неоткуда. Юнит-файл — на Windows окружение службы — пишется заново при каждой установке, поэтому установка без него возвращает службе адрес по умолчанию http://127.0.0.1:8080, и экземпляр перестаёт отвечать где-либо, кроме loopback.

Удаление

Обычное удаление убирает службу и программу и сохраняет конфигурацию, ключи Data Protection и сертификаты, чтобы установка поверх них сохранила текущие входы и секреты:
Запускать нужно из распакованного архива установленной версии: по этому архиву установщик и определяет, какие файлы в каталоге программы его собственные, — их он и забирает. Каталог программы уходит вместе с ними, если после этого он пуст; если в нём осталось что-то ещё, каталог сохраняется, и установщик об этом сообщает, а не расчищает его. Без архива рядом установщик снимает службу и предупреждает, что файлы программы отличить не смог, — угадывать он не станет. Полное удаление дополнительно сносит написанную установщиком конфигурацию, каталог данных и (на Linux) пользователя veriqa:
Полное удаление делает недействительными все выданные cookie — ключи Data Protection уходят вместе с каталогом, — а токены, подписанные удалёнными сертификатами, перестают приниматься. Сохраните копию /etc/veriqa/appsettings.Production.json (или %ProgramData%\Veriqa\appsettings.Production.json), если эта установка ещё вернётся, — и храните её вне этих каталогов: копия рядом с конфигурацией бэкапом не является. На Windows она уйдёт вместе с %ProgramData%\Veriqa, а на Linux останется лежать вместе с секретами: каталог сохраняется, а установщик не называет, что в нём осталось.
На Linux /var/lib/veriqa уходит целиком, а /etc/veriqa теряет написанный установщиком appsettings.Production.json и удаляется только тогда, когда в нём ничего не осталось. На Windows все три вещи лежат в %ProgramData%\Veriqa, и он уходит целиком. --remove-data / -RemoveData без ключа удаления отклоняется, и ничего не меняется. Удалять дважды безопасно: службы уже нет, установщик сообщает об этом и забирает то, что осталось от установки.

Типичные отказы

Отказы, которые роняют хост на старте — нет сертификата, неполный клиент, канал без токена, неизвестное значение провайдера, — одинаковы в обоих способах поставки и перечислены в self-hosted, шаг 9. На Linux сообщение лежит в journalctl -u veriqa.

Сборка архивов из исходников

Для релизных архивов в репозитории есть пара скриптов с одинаковым поведением — build/publish-host.sh и build/publish-host.ps1:
Они публикуют хост self-contained и однофайловым для linux-x64, linux-arm64 и win-x64, упаковывают каждый результат вместе с файлами установки его ОС и кладут архивы и veriqa-authserver-<версия>-SHA256SUMS.txt в artifacts/host/. Версия берётся из build/Versions.props. На выходе — ровно то, что ставится по этой странице: та же раскладка, тот же appsettings.Production.sample.json и никакого appsettings.Development.json.

Дальше

Self-hosted quickstart

Хранилища, сертификаты, клиенты и каналы — сама конфигурация.

Настройка каналов

MAX, Telegram, WhatsApp, другие мессенджеры и Email — от начала до конца.

Справочник конфигурации

Каждая секция, ключ и дефолт в одном месте.

Продакшн-харденинг

Что проверить перед выкаткой.