Перейти до змісту

Посібник iptables для firewalld - Вступ

Коли було представлено firewalld як брандмауер за замовчуванням (його було представлено у 2011 році, але я вважаю, що він з’явився вперше в CentOS 7.), автор продовжував використовувати iptables. На це було дві причини. По-перше, доступна на той час документація для firewalld використовувала спрощені правила й не показувала, як firewalld захищав сервер аж до рівня IP. По-друге, автор мав понад десятиліття досвіду роботи з iptables, і було легше продовжувати використовувати його замість вивчення firewalld.

Цей документ має на меті розглянути обмеження більшості посилань на firewalld і змусити автора використовувати firewalld для імітації цих детальніших правил брандмауера.

Зі сторінки посібника: «firewalld надає динамічно керований брандмауер із підтримкою мережевих зон/зон брандмауера для визначення рівня довіри мережевих з’єднань або інтерфейсів. Він підтримує параметри брандмауера IPv4, IPv6, мости Ethernet і розділення параметрів часу виконання та постійної конфігурації. Він також підтримує інтерфейс для служб або програм для безпосереднього додавання правил брандмауера».

firewalld — це зовнішня частина підсистем ядра netfilter і nftables у Rocky Linux.

Цей посібник присвячено застосуванню правил із брандмауера iptables до брандмауера firewalld. Якщо ви справді лише на початку свого шляху до брандмауера, цей документ може допомогти вам більше. Прочитайте обидва документи, щоб максимально використати firewalld.

Передумови та припущення

  • У цьому документі припускається, що ви є користувачем root або маєте підвищені привілеї за допомогою sudo.
  • Побіжне знання правил брандмауера, зокрема iptables, або, як мінімум, ви хочете дізнатися щось про firewalld.
  • Вам зручно вводити команди в командному рядку.
  • Усі наведені тут приклади стосуються IP-адрес IPv4.

Зони

Щоб зрозуміти firewalld, вам потрібно зрозуміти використання зон. Зони забезпечують деталізацію наборів правил брандмауера.

firewalld має кілька вбудованих зон:

зона приклад використання
drop скидає вхідні з'єднання без відповіді - дозволяє лише вихідні пакети.
block відхиляє вхідні з’єднання з повідомленням icmp-host-prohibited для IPv4 та icmp6-adm-prohibited для IPv6 – можливі лише мережеві з’єднання, ініційовані в цій системі.
public для використання в громадських місцях - приймає лише вибрані вхідні з'єднання.
external приймає лише вибрані вхідні підключення для використання у зовнішніх мережах із увімкненим маскуванням.
dmz лише вибрані вхідні з’єднання приймаються для загальнодоступних комп’ютерів у вашій демілітаризованій зоні з обмеженим доступом до вашої внутрішньої мережі.
work для комп'ютерів у робочих зонах - приймає лише вибрані вхідні з'єднання.
home для використання в домашніх умовах - приймає лише вибрані вхідні з'єднання
internal для доступу до внутрішнього мережевого пристрою – приймає лише вибрані вхідні з’єднання.
trusted приймає всі мережеві підключення.

Примітка

firewall-cmd — програма командного рядка для керування демоном firewalld.

Щоб отримати список існуючих зон у вашій системі, введіть:

firewall-cmd --get-zones

Важливо

Не забудьте перевірити стан свого брандмауера, якщо firewalld-cmd повертає помилку, за допомогою:

команда firewall-cmd:

$ firewall-cmd --state
running

команда systemctl:

$ systemctl status firewalld

Автору більшість цих назв зон не подобається. drop, block, public і trusted є зрозумілими, але деякі недостатньо добрі для ідеальної гранульованої безпеки. Візьмемо цей розділ правил iptables як приклад:

iptables -A INPUT -p tcp -m tcp -s 192.168.1.122 --dport 22 -j ACCEPT

Тут ви дозволяєте єдину IP-адресу для SSH (порт 22) на сервері. Якщо ви вирішите використовувати вбудовані зони, ви можете використовувати для цього «довірені». По-перше, ви додаєте IP до зони, а по-друге, ви застосовуєте правило до зони:

firewall-cmd --zone=trusted --add-source=192.168.1.122 --permanent
firewall-cmd --zone trusted --add-service=ssh --permanent

Але що, якщо на цьому сервері у вас також є інтранет, доступний лише для IP-блоків, призначених вашій організації? Ви б тепер застосували «внутрішню» зону до цього правила? Автор надає перевагу створенню зони, яка має справу з IP-адресами адміністраторів (тих, кому дозволено захищену оболонку на сервері).

Додавання зон

Щоб додати зону, потрібно використати firewall-cmd із параметром --new-zone. Ви збираєтеся додати "admin" (для адміністратора) як зону:

firewall-cmd --new-zone=admin --permanent

Примітка

Автор часто використовує прапорець --permanent. Для тестування рекомендується додати правило без прапорця --permanent, перевірити його та, якщо воно працює належним чином, використати firewall-cmd --runtime-to-permanent, щоб перемістити правило до активного використання. запустивши firewall-cmd --reload. Якщо ризик низький (іншими словами, ви не заблокуєте себе), ви можете додати позначку --permanent, як це зроблено тут.

Перед використанням цієї зони необхідно перезавантажити брандмауер:

firewall-cmd --reload

Підказка

Примітка щодо настроюваних зон: якщо вам потрібно додати зону, яка буде довіреною, але міститиме лише певну IP-адресу джерела чи інтерфейс, а не протоколи чи служби, і «довірена» зона не працює для вас, можливо, через те, що у вас є вже використовував її для чогось іншого тощо. Для цього ви можете додати спеціальну зону, але ви повинні змінити ціль зони з «за замовчуванням» на «ПРИЙНЯТИ» (можна також використовувати REJECT або DROP, залежно від ваших цілей). Ось приклад використання інтерфейсу мосту (lxdbr0 у цьому випадку) на машині LXD.

Спочатку ви додаєте зону та перезавантажуєте її, щоб можна було її використовувати:

firewall-cmd --new-zone=bridge --permanent
firewall-cmd --reload

Далі ви змінюєте ціль зони з «за замовчуванням» на «ACCEPT» (зауважте, що для зміни цілі потрібен параметр «--permanent»), потім призначаєте інтерфейс і перезавантажуєте:

firewall-cmd --zone=bridge --set-target=ACCEPT --permanent
firewall-cmd --zone=bridge --add-interface=lxdbr0 --permanent
firewall-cmd --reload

Це повідомляє брандмауеру, що ви:

  1. змінюєте ціль зони на ACCEPT
  2. додаєте до зони інтерфейс мосту "lxdbr0".
  3. перезавантажуєте брандмауер

Все це означає, що ви приймаєте весь трафік з інтерфейсу мосту.

Перелік зон

Перш ніж продовжувати, вам потрібно вивчити процес переліку зон. Ви отримуєте один робочий стовпець, а не табличний вивід, наданий iptables -L. Виведіть зону в список за допомогою команди firewall-cmd --zone=[zone_name] --list-all. Ось як це виглядає, коли ви перераховуєте щойно створену зону «admin»:

firewall-cmd --zone=admin --list-all

admin
  target: default
  icmp-block-inversion: no
  interfaces:
  sources:
  services:
  ports:
  protocols:
  forward: no
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
Ви можете вивести список активних зон у вашій системі за допомогою цієї команди:

firewall-cmd --get-active-zones

Важливо: активні зони

Зона може тільки бути в активному стані, якщо вона має одну з цих двох умов:

  1. Зона призначається мережевому інтерфейсу.
  2. Зоні призначаються вихідні IP-адреси або діапазони мережі.

Видалення IP і служби із зони

Якщо ви дотримувалися попередніх інструкцій щодо додавання IP-адреси до «довіреної» зони, вам потрібно видалити її зараз. Пам’ятаєте нашу примітку про використання позначки --permanent? Це гарне місце, щоб уникати його використання під час належного тестування перед тим, як застосувати це правило:

firewall-cmd --zone=trusted --remove-source=192.168.1.122

Ви також хочете видалити службу SSH із зони:

firewall-cmd --zone=trusted --remove-service ssh

Тоді тестуйте. Ви хочете переконатися, що у вас є вихід через ssh з іншої зони перед виконанням останніх двох кроків. (Див. Попередження нижче!). Якщо ви не внесли жодних інших змін, у «загальнодоступній» зоні все одно буде дозволено SSH, оскільки він є там за замовчуванням.

Коли ви задоволені, перенесіть правила виконання на постійні:

firewall-cmd --runtime-to-permanent

і перезавантажте:

firewall-cmd --reload

Важливо

Затримайтеся з останньою інструкцією, якщо ви працюєте на віддаленому сервері або VPS! НІКОЛИ не видаляйте службу ssh з віддаленого сервера, якщо у вас немає іншого способу доступу до оболонки (див. нижче).

Припустімо, ви заблокували собі доступ до ssh через брандмауер. У такому випадку вам потрібно буде (у найгіршому випадку) відремонтувати сервер особисто, звернутися до служби підтримки або, можливо, перевстановити ОС із панелі керування (залежно від того, фізичний чи віртуальний сервер).

Використання нової зони - Додавання адміністративних IP

Тепер просто повторіть наші початкові кроки, використовуючи зону «admin»:

firewall-cmd --zone=admin --add-source=192.168.1.122
firewall-cmd --zone admin --add-service=ssh

Укажіть зону, щоб переконатися, що вона виглядає правильно та правильно додано службу:

firewall-cmd --zone=admin --list-all

Перевірте своє правило, щоб переконатися, що воно працює. Для тестування:

  1. SSH як користувач root або ваш користувач із підтримкою sudo з вашої вихідної IP-адреси (вище це 192.168.1.122) (використовуйте користувача root, оскільки ви збираєтеся запускати команди на хості, якому це потрібно. Якщо ви використовуєте користувача sudo, не забудьте sudo -s після підключення.)
  2. Після підключення запустіть tail /var/log/secure, і ви отримаєте результат, який виглядає приблизно так:

Feb 14 22:02:34 serverhostname sshd[9805]: Accepted password for root from 192.168.1.122 port 42854 ssh2
Feb 14 22:02:34 serverhostname sshd[9805]: pam_unix(sshd:session): session opened for user root by (uid=0)
Це показує, що вихідна IP-адреса для нашого з’єднання SSH є тією самою IP-адресою, яку ви щойно додали до зони «admin». Ви можете перенести це правило на постійне значення:

firewall-cmd --runtime-to-permanent

Коли ви закінчите додавати правила, перезавантажте:

firewall-cmd --reload

Можливо, вам знадобляться інші служби, додані в зону «admin», але SSH наразі є найлогічнішим.

Важливо

За замовчуванням у «загальнодоступній» зоні ввімкнено службу ssh; це може бути зобов'язанням безпеки. Після створення адміністративної зони, призначення ssh і перевірки ви можете видалити службу з публічної зони.

Якщо у вас є кілька адміністративних IP-адрес, які вам потрібно додати (цілком імовірно), додайте їх до джерел для зони. У цьому випадку ви додаєте IP-адресу до зони «admin»:

firewall-cmd --zone=admin --add-source=192.168.1.151 --permanent

Примітка

Пам’ятайте, що якщо ви працюєте на віддаленому сервері або VPS і маєте підключення до Інтернету, яке не завжди використовує ту саму IP-адресу, ви можете відкрити свою службу ssh для діапазону IP-адрес, які використовує ваш постачальник послуг Інтернету або географічний область. Знову ж таки, це робиться для того, щоб вас не заблокував ваш брандмауер.

Багато провайдерів стягують додаткову плату за виділені IP-адреси, якщо вони пропонуються, тому це викликає справжнє занепокоєння.

У наведених тут прикладах передбачається, що ви використовуєте IP-адреси у власній приватній мережі для доступу до сервера, який також є локальним.

Правила ICMP

Перегляньте інший рядок у нашому брандмауері iptables, який ви хочете емулювати в firewalld – правило ICMP:

iptables -A INPUT -p icmp -m icmp --icmp-type 8 -s 192.168.1.136 -j ACCEPT

Для новачків ICMP — це протокол передачі даних для звітування про помилки. Він повідомляє, коли виникають проблеми з підключенням до машини.

Насправді ви, ймовірно, залишите ICMP відкритим для всіх наших локальних IP (у цьому випадку 192.168.1.0/24). У наших «загальнодоступних» і «адміністративних» зонах ICMP буде ввімкнено за замовчуванням, тому перше, що потрібно зробити, щоб обмежити ICMP цією однією мережевою адресою, це заблокувати ці запити на «загальнодоступних» і «адміністраторських».

Знову ж таки, це для демонстраційних цілей. Ви обов’язково захочете, щоб ваші користувачі-адміністратори мали ICMP для ваших серверів, і, ймовірно, вони й надалі будуть, оскільки вони є членами IP-адреси локальної мережі.

Щоб вимкнути ICMP у «публічній» зоні:

firewall-cmd --zone=public --add-icmp-block={echo-request,echo-reply} --permanent

Виконайте те ж саме в нашій «довіреній» зоні:

firewall-cmd --zone=trusted --add-icmp-block={echo-request,echo-reply} --permanent

Ось вступ до чогось нового: фігурні дужки "{}" дозволяють нам вказати більше ніж один параметр. Як завжди, після внесення таких змін вам потрібно перезавантажити:

firewall-cmd --reload

Тестування за допомогою ping із забороненої IP-адреси дасть вам:

ping 192.168.1.104
PING 192.168.1.104 (192.168.1.104) 56(84) bytes of data.
From 192.168.1.104 icmp_seq=1 Packet filtered
From 192.168.1.104 icmp_seq=2 Packet filtered
From 192.168.1.104 icmp_seq=3 Packet filtered

Порти веб-сервера

Ось сценарій iptables для публічного дозволу http і https, протоколів, які вам знадобляться для обслуговування веб-сторінок:

iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT

А ось еквівалент firewalld, який ви, напевно, бачили багато разів раніше:

firewall-cmd --zone=public --add-service=http --add-service=https --permanent

Це добре, але що, якщо ви використовуєте, наприклад, службу Nextcloud на http/https, і ви хочете, щоб ваша довірена мережа мала доступ до неї? Це не дивно! Подібне трапляється постійно, і просто відкритий дозвіл трафіку без урахування того, хто насправді потребує доступу, становить величезний ризик для безпеки.

Ви не можете використовувати інформацію про «довірену» зону, яку ви використали вище. Це було для тестування. Ви повинні припустити, що у вас є, як мінімум, IP-блок нашої локальної мережі, доданий до «довіреного». Це буде виглядати так:

firewall-cmd --zone=trusted --add-source=192.168.1.0/24 --permanent

Додайте служби в зону:

firewall-cmd --zone=trusted --add-service=http --add-service=https --permanent

Якщо ви додали ці служби в «загальнодоступну» зону, їх потрібно видалити:

firewall-cmd --zone=public --remove-service=http --remove-service=https --permanent

Перезавантажте:

firewall-cmd --reload

Порти FTP

Поверніться до нашого сценарію iptables. У вас є такі правила роботи з FTP:

iptables -A INPUT -p tcp -m tcp --dport 20-21 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 7000-7500 -j ACCEPT

Ця частина сценарію стосується стандартних портів FTP (20 і 21) і деяких додаткових пасивних портів. FTP-сервери, такі як VSFTPD, часто потребують таких правил. Як правило, таке правило буде на загальнодоступному веб-сервері, і воно призначене для дозволу ftp-з’єднань від ваших клієнтів.

У firewalld не існує служби даних ftp (порт 20). Перелічені тут порти з 7000 по 7500 призначені для пасивних з’єднань FTP, і знову ж таки, вони не існують як служби в firewalld. Ви можете перейти на SFTP, який спрощує правила дозволу портів і, ймовірно, є рекомендованим способом.

Це демонструє перетворення набору правил iptables на firewalld. Щоб уникнути всіх цих проблем, ви можете зробити наступне.

Спочатку додайте службу FTP до зони розміщення веб-служб. Ймовірно, у цьому прикладі це буде "публічним":

firewall-cmd --zone=public --add-service=ftp --permanent

Додайте порт даних FTP:

firewall-cmd --zone=public --add-port=20/tcp --permanent

Додайте порти пасивного підключення:

firewall-cmd --zone=public --add-port=7000-7500/tcp --permanent

Перезавантажте:

firewall-cmd --reload

Порти бази даних

Якщо ви маєте справу з веб-сервером, ви майже напевно маєте справу з базою даних. Ви обробляєте доступ до цієї бази даних так само ретельно, як і до інших служб. Якщо доступ не потрібен зі світу, застосуйте своє правило до чогось іншого, ніж "публічне". Інше міркування: чи потрібно взагалі пропонувати доступ? Знову ж таки, це, ймовірно, залежить від вашого середовища. Там, де раніше працював автор, наші клієнти використовували розміщений веб-сервер. У багатьох були сайти WordPress; ніхто не потребує доступу до будь-якого інтерфейсу для MariaDB. Якщо клієнту потрібен був додатковий доступ, нашим рішенням було створення контейнера LXD для його веб-сервера, побудова брандмауера за бажанням клієнта та покладання на нього відповідальності за те, що відбувається на цьому сервері. Проте, якщо ваш сервер загальнодоступний, вам може знадобитися надати доступ до phpmyadmin або іншого інтерфейсу MariaDB. У цьому випадку вам потрібно подбати про вимоги до пароля для бази даних і встановити для користувача бази даних щось інше, ніж значення за замовчуванням. Для автора довжина пароля є основним фактором під час створення паролів.

Безпека пароля — це обговорення в іншому документі, присвяченому цьому. Припускається, що у вас є хороша політика паролів для доступу до вашої бази даних, а рядок iptables у вашому брандмауері, який працює з базою даних, виглядає так:

iptables -A INPUT -p tcp -m tcp --dport=3600 -j ACCEPT

У цьому випадку додайте службу до «публічної» зони для перетворення firewalld:

firewall-cmd --zone=public --add-service=mysql --permanent

Розгляд Postgresql

Postgresql використовує свій службовий порт. Ось приклад правила таблиці IP-адрес:

iptables -A INPUT -p tcp -m tcp --dport 5432 -s 192.168.1.0/24 -j ACCEPT

Хоча він менш поширений на загальнодоступних веб-серверах, він може бути більш поширеним як внутрішній ресурс. Застосовуються ті самі міркування безпеки. Якщо у вас є сервер у вашій довіреній мережі (192.168.1.0/24 у нашому прикладі), ви можете не захотіти або не потрібно надавати доступ усім у цій мережі. Postgresql має доступний список доступу для більш детальних прав доступу. Наше правило firewalld виглядатиме приблизно так:

firewall-cmd --zone=trusted --add-service=postgresql

Порти DNS

Наявність приватного чи загальнодоступного DNS-сервера також означає вживання запобіжних заходів у правилах, які ви пишете, щоб захистити ці служби. Якщо у вас є приватний DNS-сервер із правилами iptables, які виглядають так (зверніть увагу, що більшість служб DNS є UDP, а не TCP, але не завжди):

iptables -A INPUT -p udp -m udp -s 192.168.1.0/24 --dport 53 -j ACCEPT

тоді дозволити лише вашій «довіреній» зоні буде правильно. Ви вже налаштували джерела нашої «надійної» зони. Все, що вам потрібно зробити, це додати послугу в зону:

firewall-cmd --zone=trusted --add-service=dns

З загальнодоступним DNS-сервером вам просто потрібно буде додати ту саму службу до «публічної» зони:

firewall-cmd --zone=public --add-service=dns

Докладніше про правила лістингу

Примітка

Ви можете перерахувати всі правила, якщо хочете, перерахувавши правила nftables. Це негарно, і я не рекомендую цього, але якщо вам справді потрібно, ви можете створити набір правил списку nft.

Єдине, чого ви ще не зробили, це перелік правил. Це те, що ви можете зробити за зоною. Ось приклади зон, які ви використовували. Зауважте, що ви можете вказати зону перед тим, як перемістити правило на постійне місце, і це гарна ідея.

firewall-cmd --list-all --zone=trusted

Тут ви можете побачити, що ви застосували вище:

trusted (active)
  target: ACCEPT
  icmp-block-inversion: no
  interfaces:
  sources: 192.168.1.0/24
  services: dns
  ports:
  protocols:
  forward: no
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks: echo-reply echo-request
  rich rules:

Це можна застосувати до будь-якої зони. Ось, наприклад, поки що «публічна» зона:

firewall-cmd --list-all --zone=public

public
  target: default
  icmp-block-inversion: no
  interfaces:
  sources:
  services: cockpit dhcpv6-client ftp http https
  ports: 20/tcp 7000-7500/tcp
  protocols:
  forward: no
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks: echo-reply echo-request
  rich rules:
Зверніть увагу, що ви видалили доступ SSH для служб і заблокували ICMP «ехо-відповідь» і «ехо-запит».

У вашій «адміністративній» зоні поки що це виглядає так:

firewall-cmd --list-all --zone=admin

  admin (active)
  target: default
  icmp-block-inversion: no
  interfaces:
  sources: 192.168.1.122 192.168.1.151
  services: ssh
  ports:
  protocols:
  forward: no
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

Встановлення відповідних правил

Схоже, що firewalld внутрішньо обробляє таке правило iptables за умовчанням:

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

Інтерфейси

firewalld за замовчуванням слухатиме всі доступні інтерфейси. На базовому сервері з багатьма інтерфейсами, що стикаються з багатьма мережевими шлюзами, вам потрібно буде призначити інтерфейс зоні на основі мережі, до якої він стикається.

У наших прикладах інтерфейси не додано, оскільки лабораторія використовує для тестування LXD. У цьому випадку у вас є лише один інтерфейс для роботи. Скажімо, ваша «загальнодоступна» зона потребує конфігурації для використання порту Ethernet enp3s0, оскільки на цьому порту є загальнодоступна IP-адреса, і скажіть, що ваші «довірена» та «адміністративна» зони знаходяться на інтерфейсі LAN, який може бути enp3s1.

Щоб призначити ці зони відповідному інтерфейсу, використовуйте такі команди:

firewall-cmd --zone=public --change-interface=enp3s0 --permanent
firewall-cmd --zone=trusted --change-interface=enp3s1 --permanent
firewall-cmd --zone=admin --change-interface=enp3s1 --permanent
firewall-cmd --reload

Загальні команди firewall-cmd

Ви вже використали деякі команди. Ось ще кілька поширених команд і те, що вони роблять:

Команда Результат
firewall-cmd --list-all-zones подібно до firewall-cmd --list-all --zone=[zone], за винятком того, що тут перераховано усі зони та їхній вміст.
firewall-cmd --get-default-zone показує зону за замовчуванням, "публічну", якщо ви її не зміните.
firewall-cmd --list-services --zone=[zone] показує всі служби, активовані для зони.
firewall-cmd --list-ports --zone=[zone] показує всі відкриті порти в зоні.
firewall-cmd --get-active-zones показує активні зони в системі, їхні активні інтерфейси, служби та порти.
firewall-cmd --get-services показує всі доступні послуги, які можна використовувати.
firewall-cmd --runtime-to-permanent якщо ви ввели багато правил без параметра --permanent, зробіть це перед перезавантаженням.

Багато параметрів firewall-cmd тут не розглядаються, але тут ви знайдете команди, які найчастіше використовуються.

Висновок

Оскільки firewalld рекомендований і включає брандмауер із Rocky Linux, гарною ідеєю буде ознайомитися з тим, як він працює. Спрощені правила, включені в документацію для застосування служб за допомогою firewalld, часто не враховують використання сервера та не пропонують жодних варіантів, крім публічного дозволу служби. Це недолік із отворами безпеки, які не обов’язково присутні.

Коли ви побачите ці інструкції, подумайте, для чого використовується ваш сервер і чи має служба бути відкритою для світу. Якщо ні, спробуйте застосувати більшу деталізацію своїх правил, як описано вище.

Це не вичерпний посібник із firewalld, а початкова точка.

Author: Steven Spencer

Contributors: wsoyinka, Antoine Le Morvan, Ezequiel Bruni, qyecst, Ganna Zhyrnova