---
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 недели когда подтвердим что ничего не сломалось
