fw4: Фільтрація трафіку за IP-наборами через DNS

Цей посібник демонструє, як створити набір IP-адрес для фільтрації трафіку. Це еквівалент dns_ipset для nftables/fw4, які є типовими починаючи з OpenWrt 22.03.

Уникнути обходу DNS-фільтрації (наприклад, фільтрація DNS за допомогою блокувальників реклами або через DoH) шляхом прямого підключення до IP-адреси. Основний сценарій — обмеження доступу до Інтернету для пристроїв типу SmartTV, IoT та ін., яким потрібно дозволити лише певний набір сайтів.

Для цього створюється набір IP-адрес з дозволених або заборонених доменів. Потім додається правило фаєрволу для дозволу або блокування трафіку до цих IP. Приклад нижче — для дозволеного доступу через інтерфейс з назвою wildlan.

  1. Необхідна зона фаєрволу без переспрямування (forwarding) у wan, щоб за замовчуванням не було доступу до Інтернету. У прикладі така зона позначена як wildlan.
  2. Встановлені утиліти dig та grep (потрібні лише для Випадку 2).
  3. Стандартна конфігурація fw4 з таблицею inet fw4.

Цей посібник охоплює два варіанти реалізації залежно від версії dnsmasq. Випадок 1 стосується лише dnsmasq 2.87 або новішої версії.

Встановіть dnsmasq-full наступним чином:

opkg update; cd /tmp/ && opkg download dnsmasq-full; opkg install ipset libnettle8 libnetfilter-conntrack3;
opkg remove dnsmasq; opkg install dnsmasq-full --cache /tmp/; rm -f /tmp/dnsmasq-full*.ipk;

Перевірте, чи встановлено dnsmasq:

opkg list-installed dns*

Коректний результат: `dnsmasq-full - 2.88-1`

У файлі /etc/hotplug.d/iface/20-firewall додайте такий код для створення nft-набору IP-адрес. Приклад нижче охоплює лише IPv4, але його можна розширити для IPv6.

# Фільтрація wildlan за IP-адресами
## Створити набір у таблиці "inet fw4" з назвою "allowlist", що зберігає тип "ipv4_addr"
nft add set inet fw4 allowlist { type ipv4_addr \;}
nft insert rule inet fw4 forward_wildlan ip daddr @allowlist accept

Зона wildlan не має доступу до Інтернету, якщо IP-адреса не входить до набору allowlist. Починаючи з dnsmasq 2.87, розв’язані (resolved) DNS-імена можуть автоматично додаватися до набору.

Відредагуйте /etc/dnsmasq.conf, додавши:

# IP-адреси, що відповідають дозволеним доменам, будуть збережені у nftset ("/4#" — IPv4)
nftset=/first.allowed.urls/4#inet#fw4#allowlist
nftset=/second.allowed.urls/4#inet#fw4#allowlist
...

Якщо потрібно дозволити лише ті IP, що були отримані через ваш DNS-сервер, а не напряму, використовуйте символ `#` як шаблон:

nftset=/#/4#inet#fw4#allowlist

Щоб переглянути IP-адреси, що потрапили до дозволеного списку, виконайте:

nft list set inet fw4 allowlist
Зауваження: набір буде порожній, доки не буде здійснено DNS-запит до відповідних доменів через dnsmasq.

Цей варіант застосовується лише для OpenWrt 22.03, OpenWrt 22.03.1 та OpenWrt 22.03.2, які мають застарілу версію dnsmasq. У цьому випадку ми не можемо використовувати dnsmasq для автоматичного наповнення IP-адрес у наборі, тому це потрібно зробити через скрипт.

У файл /etc/hotplug.d/iface/20-firewall додайте наступний код для створення nft-набору, до якого ми додаватимемо IP-адреси. Наведений код охоплює лише IPv4, але його можна розширити для IPv6:

# Фільтрація wildlan за IP-адресами
## Створення набору "allowlist" у таблиці "inet fw4" для типу "ipv4_addr"
nft add set inet fw4 allowlist { type ipv4_addr \;}
 
## Додавання елементів до "allowlist" з файлу wildlan-urls.list
for address in $(dig a -f /etc/sets-ipdns/wildlan-urls.list +short | grep -v '\.$'); do
  nft add element inet fw4 allowlist {$address timeout 24h}
done
 
nft insert rule inet fw4 forward_wildlan ip daddr @allowlist accept

Список доменів, до яких дозволено трафік, зберігається в спеціальному файлі /etc/sets-ipdns/wildlan-urls.list. Для створення цього файлу виконайте:

cd /etc
mkdir sets-ipdns
cd sets-ipdns
vim wildlan-urls.list

Усередині vim додайте список доменів, до яких слід дозволити доступ.

На основі цього правила в ланцюжку forward, буде дозволено лише трафік до IP-адрес із набору @allowlist.

Файл /etc/hotplug.d/iface/20-firewall виконується при кожній зміні стану інтерфейсів (зазвичай при завантаженні системи), тому список IP буде оновлений лише під час запуску. Цей набір потрібно періодично оновлювати з двох причин: 1. IP-адреси можуть змінюватись. 2. У разі використання DNS Load Balancing, запит у різний час може повертати різні (але всі валідні) IP.

Для цього налаштуйте планувальник (через LuCI або файл /etc/crontabs/root), щоб запускати скрипт оновлення кожні 15 хвилин:

15 * * * * /etc/sets-ipdns/update-sets.sh

У файлі /etc/sets-ipdns/update-sets.sh:

## Додати IP-адреси до allowlist з доменів у wildlan-urls.list
for address in $(dig a -f /etc/sets-ipdns/wildlan-urls.list +short | grep -v '\.$'); do
  nft add element inet fw4 allowlist {$address timeout 24h}
done

Зробіть скрипт виконуваним і перезавантажте систему:

chmod +x /etc/sets-ipdns/update-sets.sh
reboot

Після перезавантаження перевірте вміст @allowlist, список має містити IP-адреси (IPv4):

nft list set inet fw4 allowlist

Фінальна перевірка — переконайтесь, що доступні лише домени, які є в /etc/sets-ipdns/wildlan-urls.list. Жодні інші не повинні відкриватися, якщо тільки ті самі IP не використовуються кількома доменами (це трапляється з CDN).

У ВИПАДКУ 1 дозволяються всі домени та піддомени, які зазначені у конфігурації. У ВИПАДКУ 2лише ті домени, які вказані явно. Тому цей варіант працює лише з сервісами, які не використовують багато піддоменів.

Крім того, у ВИПАДКУ 2 скрипт періодично виконує DNS-запити для всіх доменів із файлу /etc/sets-ipdns/wildlan-urls.list, тому список бажано тримати невеликим.

Команди в /etc/hotplug.d/iface/20-firewall виконуються лише при зміні стану інтерфейсів. Це не відбувається при внесенні змін у фаєрвол через UCI або LuCI, тому після таких змін правила з цього файлу не застосовуються. У результаті пристрої, які залежать від цих правил, втрачають підключення.

Правила буде повторно застосовано при наступній зміні стану інтерфейсу (наприклад, при перепідключенні). Це можна також зробити вручну, щоб “перезібрати” правила.

У майбутніх версіях OpenWrt може бути реалізовано підтримку спеціального файлу з NFT-командами, який викликатиметься при кожному оновленні конфігурації фаєрволу — це повністю вирішить проблему.

This website uses cookies. By using the website, you agree with storing cookies on your computer. Also you acknowledge that you have read and understand our Privacy Policy. If you do not agree leave the website.More information about cookies
  • Last modified: 2025/06/01 09:35
  • by vazaz