Трафик на anycast-адрес (172.31.255.10) теперь сначала DNAT'ится на реальный backend (DNAT_TARGET_IP=95.163.53.117 для site-cloud) в prerouting, и только потом проходит уже существующий sNAT/masquerade в postrouting — обе цепочки в одной table inet nat, порядок хуков гарантирует правильную последовательность. DNAT включается автоматически по факту заданного dnat_target_ip (без отдельного булева флага), выключен по умолчанию — площадка A не затронута. Pre-flight assert не даёт задать dnat_target_ip без enable_snat (иначе nftables.conf вообще не разворачивается). render-check-cloud.sh дополнен проверкой DNAT-правила и валидацией синтаксиса каждого nftables.conf через `nft -c -f`. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bc3HkMiDwooSyLBLoMKNyF
27 lines
2.5 KiB
Markdown
27 lines
2.5 KiB
Markdown
# Summary: DNAT anycast → 95.163.53.117 в роли frr_anycast
|
||
|
||
**Дата:** 2026-09-10
|
||
**План:** [2026-09-10-nftables-dnat-plan.md](2026-09-10-nftables-dnat-plan.md)
|
||
|
||
## Что сделано
|
||
|
||
- `templates/nftables.conf.j2`: добавлена цепочка `prerouting` (`hook prerouting priority dstnat`) с `ip daddr <anycast-host> dnat to {{ dnat_target_ip }}`, рендерится только при заданном `dnat_target_ip`. Отрабатывает до уже существующей `postrouting`/masquerade (порядок гарантирован хуками nftables, явных зависимостей не требуется).
|
||
- `defaults/main.yml`: новая переменная `dnat_target_ip: ""` (по умолчанию выключено, площадка A не затронута).
|
||
- `tasks/main.yml`: pre-flight `assert` — если `dnat_target_ip` задан, а `enable_snat: false`, playbook останавливается с понятной ошибкой (иначе `nftables.conf` вообще не разворачивается и DNAT молча не применится).
|
||
- `site-cloud.env` / `group_vars/site_cloud.yml`: `DNAT_TARGET_IP=95.163.53.117` — DNAT включается автоматически по факту наличия значения, отдельный булев флаг не нужен.
|
||
- `render-check-cloud.sh`: добавлена проверка `dnat to 95.163.53.117` на всех 4 узлах + валидация синтаксиса каждого `nftables.conf` через `nft -c -f` (если `nft` доступен на control node).
|
||
|
||
## Результаты проверки
|
||
|
||
- `render-check.sh` (площадка A) — 6/6 OK, без изменений (роль не переиспользует `dnat_target_ip`, когда он пуст).
|
||
- `render-check-cloud.sh` — все проверки пройдены, включая новую DNAT-проверку и `nft -c` для всех 4 узлов (`vr01`–`vr04`).
|
||
- `--syntax-check` — OK для обоих playbook'ов.
|
||
|
||
## Изменённые файлы
|
||
|
||
- `ansible/roles/frr_anycast/{defaults/main.yml,tasks/main.yml,templates/nftables.conf.j2}`.
|
||
- `ansible/site-cloud.env`, `ansible/group_vars/site_cloud.yml`.
|
||
- `ansible/tests/render-check-cloud.sh`.
|
||
- `README.md` — раздел «Второе окружение» дополнен описанием DNAT.
|
||
- `docs/2026-09-10-nftables-dnat-plan.md`, `docs/2026-09-10-nftables-dnat-summary.md`.
|