# ARCHITECTURE — стек мирткани.рф (источник: CentOS 7.8, цель: CentOS Stream 9)

Снято с боевого сервера 2026-05-21. Это описание того, **что воспроизводим** на новой ОС.

## Поток запроса
```
                          :80 / :443 (TLS, Let's Encrypt SAN ~22 домена)
   Internet ───────────►  nginx 1.18  (фронт, отдаёт статику, кэш html_pages, anti-flood)
                              │  proxy_pass http://127.0.0.1:8888
                              ▼
                          Apache httpd 2.4  (бэкенд, :8888)  ── mod_remoteip (реальный IP из X-Real-IP)
                              │  SetHandler proxy:fcgi://127.0.0.1:9082
                              ▼
                          php-fpm 8.2  (:9082, пул www, user apache)
                              │
                              ▼
                          MariaDB  (база db_mt_new, localhost:3306)
```
- На источнике был cookie-роутер PHP (php82/php80/php74 → :9082/:9080/:9000). **На новой ОС оставляем только 8.2** (:9082) — откатные версии убраны по решению владельца.

## Ключевые параметры
| Что | Значение |
|---|---|
| Webroot (DocumentRoot) | `/var/www/mirtkani.rf` |
| Домен | мирткани.рф → punycode `xn--80apbgijsq.xn--p1ai` |
| Apache backend | `Listen 127.0.0.1:8888` (+ доп. `8887`), `User/Group apache` |
| php-fpm | сервис `php82-php-fpm`, `listen 127.0.0.1:9082`, `user/group apache` |
| БД | MariaDB, база `db_mt_new` @ localhost, datadir `/var/lib/mysql` (~19G) |
| PHP ini (ключевое) | memory_limit 512M, upload/post 64M, TZ Europe/Moscow, short_open_tag On, opcache on, session.save_path `/var/lib/php/session` |
| SSL | Let's Encrypt **wildcard** `*.xn--80apbgijsq.xn--p1ai` (+ apex) через **Cloudflare DNS-01**, lineage `/etc/letsencrypt/live/xn--80apbgijsq.xn--p1ai/` |
| Bitrix ядро | 26.250.100 (PHP 8.x-only), PHP-фиксы наложены (см. сайт `patch/`) |

## Мультисайт (поддомены 3-го уровня)
- **Нет файловых симлинков.** Все региональные поддомены идут на ОДИН docroot через wildcard:
  - nginx: `server_name *.xn--80apbgijsq.xn--p1ai` (в `bx/site_enabled/*.conf`)
  - Apache: `ServerAlias *.xn--80apbgijsq.xn--p1ai` (в `bx/vhosts/01-s-mirtkani.rf.conf`)
- Регион определяется в PHP модулем **intec.regionality** (одно ядро, одна БД). Все поддомены покрыты одним **wildcard-сертификатом** `*.xn--80apbgijsq.xn--p1ai` (новые регионы не требуют перевыпуска). Историч. список поддоменов — в `manifests/ssl-domains.txt`.

## Где что лежит (конфиги в пакете → куда на новой ОС)
| Пакет `configs/` | Целевой путь | Примечание |
|---|---|---|
| `nginx/nginx.conf`, `nginx/bx/`, `nginx/ssl/` | `/etc/nginx/...` | anti-flood zone `flood` 20r/s burst40, `connlimit` 50; deny php в /upload |
| `httpd/conf/httpd.conf`, `httpd/bx/` | `/etc/httpd/...` | vhost мультисайта + php-роутер + mod_remoteip + `SetEnv BITRIX_ENV_TYPE general` |
| `httpd/conf.d/php.conf` | `/etc/httpd/conf.d/php.conf` | mod_php-блок инертен (php через fpm) |
| `php82/php.d/99-bitrix.ini`, `php82/php-fpm.d/www.conf` | `/etc/opt/remi/php82/...` | основной тюнинг PHP |
| `mariadb/my.cnf.d/z9_bitrix.cnf` | `/etc/my.cnf.d/z9_bitrix.cnf` | sql_mode="", READ-COMMITTED, innodb_buffer_pool 4G |
| `letsencrypt/` | `/etc/letsencrypt/` | старый SAN-cert + аккаунт (fallback/история; приватные ключи!) |
| `cloudflare/cloudflare.ini` | `/root/.secrets/cloudflare.ini` (chmod 600) | **API-токен Cloudflare** для certbot DNS-01 (секрет!) |
| `firewalld/public.xml` | `/etc/firewalld/zones/public.xml` | порты 80/443/21/ssh + drop 45.227.253.15 |
| `cron/*` | `/etc/cron.d/...` | см. ниже |

## Cron
- **Активные (переносим):**
  - `43 6 * * * certbot renew && systemctl reload nginx` — продление SSL.
  - `0 * * * * /usr/bin/php /var/www/mirtkani.rf/local/crontab/update_product_data.php` — почасовое обновление товаров (на новой ОС путь к php → `/usr/bin/php82`).
- **`/etc/cron.d/bitrixagent` — БИТЫЙ на источнике:** указывал на `/var/www/html/bitrix/...`, которого нет (там только заглушка). Т.е. агенты Битрикса фактически шли «на хитах», а не на кроне. В пакете cron пересоздан с корректным путём, но **закомментирован** — включать только если в админке включена «Агенты на кроне» (иначе дубли).

## SELinux — главное отличие el9
На CentOS 7 здесь SELinux фактически не мешал. **CentOS Stream 9 — enforcing по умолчанию.** Без настройки Apache не достучится до php-fpm, а nginx — до Apache. Решается `70-selinux.sh`: булевы `httpd_can_network_connect(_db)`, метки портов 8888/8887/9082 как `http_port_t`, контекст `httpd_sys_rw_content_t` на docroot.

## Что НЕ переносим / меняем осознанно (best practices на el9)
- **Откатные PHP 7.4 / 8.0** — убраны (ядро 26.x требует 8.x; в remi el9 7.4 нет).
- **mod_geoip / mod_rpaf** (legacy) — на el9 нет. `mod_geoip.conf` обёрнут в `<IfModule>` → просто не сработает. Реальный real-IP делает **mod_remoteip** (`RemoteIPHeader X-Real-IP`), он в базовом httpd el9.
- **Apache mod_ssl / conf.d/ssl.conf** — не ставим (TLS только на nginx), иначе конфликт Listen 443.
- **Версии** новее источника (nginx stable el9, httpd 2.4.62, MariaDB 10.11 LTS, php 8.2.x) — это норма при смене мажора ОС.
- **SSL переведён с webroot HTTP-01 (SAN со списком поддоменов) на Cloudflare DNS-01 (wildcard).** Так задумано: один `*.<домен>` покрывает все региональные поддомены, выпуск не зависит от веб-сервера/IP, новые регионы — без перевыпуска. Токен Cloudflare (Zone:Read + Zone:DNS:Edit) проверен боевыми curl-запросами 2026-05-21 и лежит в `configs/cloudflare/`. `python3-certbot-dns-cloudflare` ставится в `20-packages.sh`.
- **swap** — на источнике 0. На новой ОС рекомендуется добавить 2–4G (best practice; см. RUNBOOK, опционально).

## Стороннее / стабы (можно игнорировать)
- `/var/www/{mir-tkani39.ru, mt.rusdev.ru, html, cgi-bin}` — заглушки/служебное, к боевому сайту отношения не имеют.
- `/var/www/.settings.php` — stray-файл вне docroot, не используется текущим сайтом.

## Безопасность (контекст, не часть стека)
Сервер пережил взлом (май 2026), дыра закрыта в коде (`universelite_s1/.../ComponentsActions.php`), он в файловом бэкапе. После миграции — сменить пароли (Bitrix-админы, БД, SSH/FTP). Подробности — в отчёте `/home/bitrix/migration-report-2026-05-20.md` (на старом сервере).
