83 lines
7.9 KiB
Markdown
83 lines
7.9 KiB
Markdown
---
|
||
date: 2026-06-05
|
||
type: decision
|
||
tags: [benelux, openwrt, firewall, fw4, nftables, blackout, recovery, alex-bot]
|
||
status: closed
|
||
severity: critical
|
||
---
|
||
|
||
# Бенелюкс — после blackout вся LAN без интернета: `fw4` не строит `forward` chain
|
||
|
||
## Симптомы (поверхностные)
|
||
|
||
- Александр пожаловался: «после отключения электричества интернет не работает»
|
||
- В `unifi.ui.com` UniFi-консоль (UCK G2 Plus `Benelyuks`, `192.168.1.199`) показана **Offline** с прошлого дня — у неё часы отстали почти на 19 часов (NTP не достучался)
|
||
- Mac, телефоны, IoT — Wi-Fi видят, IP получают, но «без интернета»
|
||
- При этом **сам Cudy роутер** (`100.70.207.97` через NetBird) полноценно работает, ping `8.8.8.8` от него = 0% loss
|
||
|
||
## Корневая причина
|
||
|
||
После blackout-перезагрузки Cudy пакет `firewall4` (v2024.12.18, OpenWrt 24.10.3) не смог собрать ruleset, потому что **новый `nftables v1.1.1` отказался парсить старый синтаксис в `/etc/nftables.d/*.nft`**:
|
||
|
||
```nft
|
||
chain dstnat { # ← UNEXPECTED '{', expecting string or last
|
||
iifname "wt0" tcp dport ... dnat ip to ...
|
||
}
|
||
chain printer_dnat_pre { # ← Chain of type "nat" is not supported
|
||
type nat hook prerouting priority dstnat; policy accept;
|
||
...
|
||
}
|
||
```
|
||
|
||
Файлы, написанные раньше, использовали **chain-with-type-hook** или **add-rules-to-existing-chain-via-block** — оба синтаксиса в v1.1.1 либо не поддерживаются вообще, либо требуют точное соответствие имени уже существующего chain в `table inet fw4`.
|
||
|
||
Поскольку парсер падал на каждом из этих файлов, **fw4 откатывался** и **не создавал `forward` и `dstnat` chains вообще** → весь LAN-форвардинг через NAT отсутствовал → ни одно устройство в `192.168.1.0/24` не могло выйти наружу. UCK не достукался до облака Ubiquiti → UI cloud = Offline. Параллельно с этим её время отстало (NTP UDP/123 режется провайдером «Умные сети») — это две **независимые** проблемы.
|
||
|
||
## Что сделал в восстановлении
|
||
|
||
1. **Поставил время UCK вручную** через SSH (`date -u -s "..."; hwclock -w`)
|
||
2. **Диагностика nft**: ядро (`nft_chain_nat`, `nf_nat`, `nft_ct`) и userspace (`v1.1.1`) на месте, ручные команды через arg работают, но `nft -f file` со стандартным fw4-output падает на пользовательских includes
|
||
3. **Случайно усугубил**: `opkg install --force-reinstall firewall4` без `opkg update` — opkg сначала удалил пакет, потом не смог скачать (репозиторий блокировался). `fw4` исчез. Скачал `.ipk` с Mac → `scp -O` (legacy режим, потому что Cudy без sftp-server) → `opkg install /tmp/firewall4.ipk` ✓
|
||
4. **Отключил все user-`.nft`-файлы** (`mv → .disabled-20260605-syntax`), оставил только `10-custom-filter-chains.nft` (дефолтный шаблон от пакета) → `fw4 reload` поднял базовый ruleset с `forward`/`dstnat`/`srcnat` chains → LAN-форвардинг заработал
|
||
5. **Подкоп**: создал зону `awg` через UCI (`uci add firewall zone` + `device='awg0'` + `masq=1` + forwarding `lan → awg`) → подкоп заработал (`api.telegram.org` HTTP 302 за 0.27s)
|
||
6. **Удалил принтер-файлы окончательно** (Олег сказал не нужны)
|
||
|
||
## Что временно отключено (`.disabled-20260605-syntax`)
|
||
|
||
| Файл | Назначение | Что внутри |
|
||
|---|---|---|
|
||
| `00-emergency-block.nft` | input drop SSH с WAN | Дубликат wan-zone drop, **не критично** |
|
||
| `51-awg0-masq.nft` | masquerade `awg0` для LAN | **Заменено UCI-зоной `awg`** (см. выше) |
|
||
| `99-incident-20260520.nft` | output drop SMTP/SSH + forward drop SSH | Бот Алекс `alex-secwatch.sh` через `nft insert rule` восстановит SSH-блок каждые 15 мин; SMTP-output на роутере и так не нужен |
|
||
|
||
## Что узнал про бота Алекса
|
||
|
||
Подозревал что бот деплоит битые `.nft` файлы → проверил. **Бот невиновен**, его архитектура **правильная**:
|
||
|
||
- `/opt/assistant/alex-secwatch.sh` (крон `*/15`) использует **`nft insert rule inet fw4 input iifname "eth0" tcp dport 22 counter drop comment "..."`** — это **runtime-вставка через arg-синтаксис**, который **поддерживается в nft v1.1.1**
|
||
- Никаких записей в `/etc/nftables.d/` бот не делает
|
||
- Битые .nft файлы создал я (Claude) в предыдущих сессиях, не бот
|
||
|
||
## Правило на будущее: как добавлять firewall-правила на Бенелюксе (и любом OpenWrt 24.10+)
|
||
|
||
| Цель | Как делать | Что НЕ делать |
|
||
|---|---|---|
|
||
| Persistent через ребут | **UCI**: `uci add firewall rule/redirect/zone/forwarding`, потом `uci commit firewall; fw4 reload` | НЕ писать `/etc/nftables.d/*.nft` с `chain xxx { type ... hook ... }` или с `chain xxx { ... }` блоком |
|
||
| Runtime, временно | `nft insert rule inet fw4 <chain> <expression>` через SSH (как делает бот Алекс) | — |
|
||
| DNAT (port forward) | `uci add firewall redirect; uci set firewall.@redirect[-1].target='DNAT'; uci set ...src_dport ...dest_ip ...dest_port; uci commit; fw4 reload` | НЕ писать вручную `chain printer_dnat_pre { type nat hook prerouting ... }` |
|
||
| Masquerade-зона для нового интерфейса (`awg0`, `wt0` и др.) | `uci add firewall zone; uci set ...device='awg0' masq='1'; uci add firewall forwarding; uci set ...src=lan dest=awg; uci commit; fw4 reload` | — |
|
||
|
||
## Открытое для бота Алекса
|
||
|
||
Если в будущем бот должен деплоить какие-то правила (например автоматический проброс принтера или DNAT для нового сервиса):
|
||
- использовать `uci add firewall redirect ...` через SSH к Cudy (persistent),
|
||
- или `nft insert rule` (временно, как уже делается для SSH-блока).
|
||
|
||
**Никогда** не писать в `/etc/nftables.d/*.nft` с `chain xxx { ... }` синтаксисом — оно работало на старом nft (v1.0.x), но в v1.1.1 OpenWrt 24.10.3 ломает весь fw4.
|
||
|
||
## TODO
|
||
|
||
- [ ] При следующем доступе на Cudy — перепроверить что `alex-secwatch.sh` через `nft insert` восстановил SSH-WAN-блок (должно произойти через 15 мин от 09:30 UTC)
|
||
- [ ] Долгосрочный фикс времени UCK: включить ntpd-сервер на Cudy (`uci set system.ntp.enable_server=1`) и в UI UCK Network → System → NTP прописать `192.168.1.1` (см. [[../projects/benilux/credentials#известная-проблема-ntp-не-работает]])
|
||
- [ ] Удалить файлы `*.disabled-20260605-syntax` с роутера через 1-2 недели когда подтвердим что ничего не сломалось
|