feat: migrate to Gitea, productize Helm chart, unify version

- CI: replace GitLab pipeline with Gitea Actions (.gitea/workflows/release.yaml);
  publish .deb/image/hosted/chart to Gitea registries; gate image+hosted on .deb
  (needs + registry pre-check)
- drop connectone/Nexus; apt now from the Gitea Debian registry
- single version source (/VERSION=3.2.8); CI enforces .env/Chart consistency
- restructure: build/->packaging/deb, root Dockerfile->packaging/image,
  hosted/->packaging/hosted, .kube/->charts/freeradius
- Helm chart: documented values, DB password via Secret/$ENV, configurable
  scheduling/persistence; remove plaintext creds and hostPath PV
- gitignore *.env_cnf; docs for hosted (RU)/helm/root + agent KB sync

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Georg K
2026-06-12 05:45:10 +03:00
parent da25848bf8
commit 99e1245ed3
52 changed files with 1079 additions and 287 deletions

120
packaging/hosted/README.md Normal file
View File

@@ -0,0 +1,120 @@
# Hosted установка (bare-metal / VM)
## Для чего этот репозиторий
Это сборка и поставка кастомного **FreeRADIUS 3.2.x** для hotspot / captive-portal
сценариев. Прикладного кода здесь нет: репозиторий собирает апстримный FreeRADIUS с
дополнительным модулем `rlm_raw`, накладывает конфиги и доставляет результат в двух
видах - bare-metal (этот каталог) и Kubernetes (Helm-чарт в `charts/freeradius`).
## Как это работает
1. Точки доступа / hotspot-шлюзы (NAS) шлют RADIUS-запросы. Статически клиенты **не**
прописаны - они резолвятся динамически. `clients.conf` объявляет сеть `0.0.0.0/0`
как динамическую (`client dynamic`).
2. Когда приходит пакет от неизвестного NAS, FreeRADIUS вызывает виртуальный сервер
`dynamic_clients` (`sites-enabled/dynamic-clients`). Тот ищет NAS по `NAS-Identifier`
в таблице `nas` PostgreSQL: если запись есть - берёт из БД `secret`/`shortname` и
определяет клиента на лету; если нет - идёт в REST к сервису `hotspotter`.
3. Авторизация абонента идёт в site `default` через SQL (схема RADIUS: `radcheck`,
`radreply`, `radacct`, ...) и/или REST. Hotspotter получает `hotspot-group`
(= `Called-Station-Id`) и `hotspot-id` (= `NAS-Identifier`) и решает, пускать ли.
4. Профиль урезан под задачу: отключены `eap`, `inner-tunnel`, `proxy_rate_limit`,
включён `delay_reject`.
## Зачем нужен rlm_raw
`NAS-Identifier` и `Called-Station-Id` - строковые RADIUS-атрибуты, в которые
hotspot-шлюзы кладут идентификатор точки/группы. Это значение должно совпадать
**байт-в-байт** с `nas.shortname` в БД и с записями в hotspotter.
Штатный xlat `%{NAS-Identifier}` отдаёт значение уже после разбора и нормализации
FreeRADIUS (атрибут декодируется по словарю, к строке применяется обработка). Для
произвольных байтов и нестандартных форматов это меняет значение и ломает поиск.
Модуль `rlm_raw` добавляет xlat `%{raw:...}`, который возвращает атрибут ровно так,
как его прислал NAS, без перекодирования. Все ключевые конфиги (`dynamic-clients`,
`mods-enabled/rest`) построены на `%{raw:Called-Station-Id}` и `%{raw:NAS-Identifier}`,
поэтому модуль обязателен - без него конфиг просто не загрузится. Именно поэтому
FreeRADIUS пересобирается из исходников с `rlm_raw`, а не ставится из стандартного apt.
## Что в этом каталоге
| Файл | Назначение |
|------|------------|
| `.env` | Версия пакета: `FREERADIUS_TAG` (ставится как `<tag>+git`). |
| `.env_cnf_example` | Шаблон для `.env_cnf`. Скопировать и заполнить. |
| `.env_cnf` | Локальные секреты/хосты. **В git не попадает** (gitignore). |
| `config/` | radiusd.conf, dictionary, clients.conf, mods/sites. |
| `install.sh` | Первичная установка (root). |
| `update.sh` | Смена версии пакета (root). |
| `cron/radius-renew.sh` | Ежемесячный перевыпуск сертификатов. |
Этот бандл публикуется CI как generic-пакет:
`https://git.ahax86.ru/api/packages/pub/generic/hosted/<version>/hosted.tar.gz`
## Требования
- Ubuntu 24.04 (noble), root.
- Доступ к `git.ahax86.ru`, к PostgreSQL и к REST-сервису `hotspotter`.
- Нужная версия `.deb` уже опубликована в Debian-реестре Gitea (CI собирает её первой).
## Установка
```bash
cp .env_cnf_example .env_cnf
$EDITOR .env_cnf # заполнить хосты/порты/креды
sudo ./install.sh
```
`install.sh` подключает Debian-реестр Gitea, ставит запиненные пакеты (`apt-mark hold`),
рендерит `sites-enabled/default`, `mods-enabled/rest` и `mods-enabled/sql` из `.env_cnf`,
копирует статические конфиги, включает `delay_reject`, ставит systemd-юнит и cron.
Переменные `.env_cnf`:
| Переменная | Смысл |
|------------|-------|
| `FR_MAIN_PORT` / `FR_ACC_PORT` | UDP-порты auth / accounting. |
| `FR_API_HOST` / `FR_API_PORT` | Endpoint REST hotspotter. |
| `FR_PG_HOST` / `FR_PG_PORT` | Хост / порт PostgreSQL. |
| `FR_PG_USER` / `FR_PG_PASS` / `FR_PG_DB` | Креды / база PostgreSQL. |
### Приватный реестр
Если реестр `pub` не публичный, перед запуском задайте токен:
```bash
export DEB_AUTH="<gitea-user>:<token-с-read:package>"
sudo -E ./install.sh
```
Прочие переопределения (значения по умолчанию):
`DEB_REGISTRY=https://git.ahax86.ru/api/packages/pub/debian`,
`DEB_DISTRIBUTION=noble`, `DEB_COMPONENT=main`.
## Смена версии
```bash
# поменять FREERADIUS_TAG в .env, затем:
sudo ./update.sh
```
`update.sh`: `apt-mark unhold` → установка нужной версии → `apt-mark hold` → перезапуск.
## Удаление
```bash
sudo apt-mark unhold libfreeradius3 freeradius-common freeradius-postgresql \
freeradius-rest freeradius-utils freeradius
sudo apt-get purge -y freeradius freeradius-common freeradius-config \
freeradius-python3 libfreeradius3 freeradius-postgresql freeradius-rest freeradius-utils
sudo rm -rf /etc/freeradius /usr/lib/freeradius
```
## Проверка в Docker
```bash
docker build . -t hosted:test -f Dockerfile
docker run -ti -p 1812:1812/udp -p 1813:1813/udp hosted:test /bin/bash
```