build-deb now checks the Debian registry first and skips the slow source compile+upload when the pinned version already exists. Add a force_deb workflow_dispatch input to rebuild anyway, and make upload.sh idempotent (HTTP 409 -> already published, skip). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
108 lines
7.2 KiB
Markdown
108 lines
7.2 KiB
Markdown
# FreeRADIUS - обзор инфраструктуры
|
||
|
||
Профиль: infra-lite. Бизнес-логику самого FreeRADIUS здесь не описываем.
|
||
|
||
## Назначение
|
||
|
||
Сборка и поставка кастомного FreeRADIUS 3.2.x для hotspot/captive-portal сценариев.
|
||
Репозиторий не содержит сервиса - он упаковывает апстримный FreeRADIUS с
|
||
доп. модулем `rlm_raw` и накладывает конфиги под две среды выполнения.
|
||
|
||
## Версия - единый источник
|
||
|
||
`VERSION` (корень) = `3.2.8`. Из него CI выводит:
|
||
- `RADIUS_TAG=release_3_2_8` (тег исходников FreeRADIUS для сборки .deb),
|
||
- пин пакетов `3.2.8+git` (образ и hosted),
|
||
- `appVersion` чарта.
|
||
|
||
CI (`prepare`) падает, если `packaging/hosted/.env` (`FREERADIUS_TAG`) или
|
||
`charts/freeradius/Chart.yaml` (`appVersion`) разошлись с `VERSION`. Ветка
|
||
`rlm_raw` - отдельный параметр (`workflow_dispatch` input, дефолт `v3.2.4`).
|
||
|
||
## Артефакты (Gitea, owner `pub`)
|
||
|
||
| Артефакт | Реестр |
|
||
|----------|--------|
|
||
| `.deb` | `https://git.ahax86.ru/api/packages/pub/debian` (distribution `noble`, component `main`) |
|
||
| Образ | `git.ahax86.ru/pub/freeradius:<version>` (+ `latest`) |
|
||
| Hosted-бандл | `.../api/packages/pub/generic/freeradius-hosted/<version>/freeradius-hosted.tar.gz` |
|
||
| Helm-чарт | `https://git.ahax86.ru/api/packages/pub/helm` |
|
||
|
||
Соглашение: локальный alias helm-репо - `ahax86` (`helm repo add ahax86 ...`).
|
||
|
||
## Релизный поток (`.gitea/workflows/release.yaml`, `workflow_dispatch`)
|
||
|
||
```
|
||
prepare ──► build-deb ──► build-image ──► package-helm
|
||
└──► package-hosted
|
||
```
|
||
|
||
- `.deb` - источник истины: `build-image` и `package-hosted` имеют `needs: build-deb`
|
||
И дополнительно проверяют, что версия `3.2.8+git` уже опубликована в Debian-реестре
|
||
(GET `dists/noble/main/binary-amd64/Packages`), иначе fail.
|
||
- `build-deb` пропускает долгую пересборку, если версия уже в реестре. Принудительно -
|
||
input `force_deb=true`. Заливка идемпотентна: `upload.sh` пропускает HTTP 409 (уже есть).
|
||
- Авторизация: репо-секреты `PACKAGES_USER` / `PACKAGES_TOKEN` (Gitea token, scope
|
||
`write:package`).
|
||
- Раннер: `ubuntu-latest` с доступным Docker.
|
||
|
||
## Режимы развёртывания
|
||
|
||
- Kubernetes (`charts/freeradius/`): продуктовый Helm-чарт. Образ из `build-image`.
|
||
Конфиги `default`/`rest` - в ConfigMap; `sql` - тоже в ConfigMap, но пароль БД не
|
||
хранится там, а подставляется в рантайме через `$ENV{DB_PASSWORD}` из Secret
|
||
(`db.password` или `db.existingSecret`). `entrypoint.sh` копирует `/configs/*` в
|
||
`/etc/freeradius`. Сертификаты на PVC (`persistence`). nodeSelector/tolerations -
|
||
конфигурируемые (по умолчанию пусто). Установка - из Helm-реестра Gitea.
|
||
- Hosted / bare-metal (`packaging/hosted/install.sh`, root): ставит запиненные .deb из
|
||
Debian-реестра Gitea (`apt-mark hold`), подставляет хосты/порты/креды в конфиги через
|
||
`sed` из `.env_cnf`, ставит systemd-юнит и cron на ежемесячный перевыпуск сертификатов
|
||
(`cron/radius-renew.sh`). `update.sh` бампит версию пакета (`unhold` -> install -> hold).
|
||
Для приватного реестра - `DEB_AUTH="user:token"`.
|
||
|
||
## Внешние зависимости и хосты
|
||
|
||
- Gitea: `git.ahax86.ru`, owner `pub`. Образы - container registry, .deb - Debian-реестр,
|
||
чарт - Helm-реестр, hosted - generic-пакет. GPG-ключ apt-репо:
|
||
`https://git.ahax86.ru/api/packages/pub/debian/repository.key`.
|
||
- PostgreSQL `radius_db` (схема RADIUS: `radacct`, `radcheck`, `nas`, ...). В k8s -
|
||
`postgresql-pgbouncer:6432`, юзер `admin`; в hosted - из `.env_cnf`.
|
||
- REST API `hotspotter` (k8s: `hotspotter:8080`, эндпоинт `radius/auth`). Используется
|
||
как fallback-авторизация NAS, когда клиента нет в таблице `nas`.
|
||
|
||
## Сетевые порты
|
||
|
||
- Auth/acct: 31812 / 31813 (см. site `default`, `values.yaml` `service.*`, `.env_cnf`).
|
||
- В k8s публикуются Service'ом (по умолчанию NodePort 31812/31813).
|
||
|
||
## Инварианты
|
||
|
||
- Клиенты (NAS) резолвятся динамически: site `dynamic-clients` ищет NAS по `shortname`
|
||
(= `NAS-Identifier`) в таблице `nas`; если нет - идёт `rest` к `hotspotter`. Статический
|
||
`clients.conf` минимален.
|
||
- Включён модуль `delay` (delay_reject); удалены `eap`, `inner-tunnel`, `proxy_rate_limit`
|
||
(синхронно в образе и hosted).
|
||
- Модуль `rlm_raw` обязателен: конфиги используют `%{raw:...}` (Called-Station-Id,
|
||
NAS-Identifier). Без него сборка/конфиг не работают.
|
||
- Сертификаты в k8s переживают рестарты через PVC; `entrypoint.sh` копирует дефолтные
|
||
только если каталог `certs` пуст.
|
||
|
||
## Риски и known warts
|
||
|
||
- Образ при сборке тянет .deb из Debian-реестра Gitea - предполагается публичный read для
|
||
owner `pub`. Если реестр приватный, сборку образа надо чинить (read-токен/buildkit secret),
|
||
а на нодах нужен `DEB_AUTH` для apt.
|
||
- Повторная заливка той же версии .deb обрабатывается: `build-deb` её пропускает, а
|
||
`upload.sh` не падает на HTTP 409. Переиздать изменённое содержимое той же версии нельзя -
|
||
нужно либо bump `VERSION`, либо удалить пакет в Gitea. `force_deb` только пересобирает.
|
||
- Пароль БД: в hosted - в `.env_cnf` (gitignored, `*.env_cnf`); в k8s - в Secret. В git не
|
||
попадает.
|
||
|
||
## Рабочие правила
|
||
|
||
- Менять конфиги/версии осознанно: одно изменение часто нужно отразить и в чарте
|
||
(`charts/freeradius/`), и в hosted (`packaging/hosted/`), и в образе (`packaging/image/`).
|
||
- Версию менять только в `VERSION` (плюс синхронно `.env`/`Chart.yaml`, иначе CI упадёт).
|
||
- Прод-выкладка только вручную через Gitea Actions и только по команде пользователя.
|
||
- Долгоживущие решения дописывать сюда. Держать обзор кратким и актуальным.
|