Firewall в Linux

Netfilter архітектура

Netfilter — підсистема ядра Linux для фільтрації пакетів.

┌─────────────────────────────────────────────────────────────────┐
│                        Netfilter Hooks                          │
│                                                                 │
│  Incoming packet                                                │
│                                                                │
│                                                                │
│  ┌─────────────┐                                                │
│   PREROUTING    DNAT, перенаправлення                       │
│  └──────┬──────┘                                                │
│                                                                │
│    Routing decision                                             │
│                                                               │
│     (for this host) (forwarding)                              │
│                                                               │
│ ┌───────┐      ┌─────────┐                                      │
│  INPUT        FORWARD   Трафік через роутер               │
│ └───┬───┘      └────┬────┘                                      │
│                                                               │
│                                                               │
│ Local process                                                  │
│                                                               │
│                                                               │
│ ┌────────┐                                                     │
│  OUTPUT                                                      │
│ └────┬───┘                                                     │
│                                                               │
│                                                               │
│  ┌──────────────────────┐                                       │
│       POSTROUTING        SNAT, masquerade                   │
│  └──────────────────────┘                                       │
│                                                                │
│                                                                │
│     Outgoing packet                                             │
└─────────────────────────────────────────────────────────────────┘

iptables

Таблиці (Tables)

Таблиця Призначення Chains
filter Фільтрація (за замовчуванням) INPUT, FORWARD, OUTPUT
nat Network Address Translation PREROUTING, POSTROUTING, OUTPUT
mangle Модифікація пакетів Всі
raw Обхід connection tracking PREROUTING, OUTPUT

Базовий синтаксис

iptables [-t table] -A chain -p protocol --dport port -j action

# Приклади:
# -t filter (за замовчуванням)
# -A CHAIN: додати правило (append)
# -I CHAIN: вставити на початок (insert)
# -D CHAIN: видалити правило
# -L: переглянути правила
# -F: очистити всі правила
# -p: протокол (tcp, udp, icmp)
# --dport: destination port
# --sport: source port
# -s: source IP
# -d: destination IP
# -i: input interface
# -o: output interface
# -j: action (ACCEPT, DROP, REJECT, LOG)

Переглянути правила

# Всі правила (verbose, numeric)
iptables -L -v -n

# З номерами рядків
iptables -L --line-numbers

# Конкретна таблиця
iptables -t nat -L -v -n

# Як команди (для збереження)
iptables-save

Базові правила для сервера

# Очистити всі правила
iptables -F
iptables -X
iptables -t nat -F

# Політика за замовчуванням
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# Дозволити loopback
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

# Дозволити established/related з'єднання
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Дозволити SSH
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# Дозволити HTTP/HTTPS
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# Дозволити ping (ICMP)
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT

# Логувати та відкидати все інше
iptables -A INPUT -j LOG --log-prefix "iptables-dropped: "
iptables -A INPUT -j DROP

Stateful firewall

# Connection states:
# NEW       — перший пакет з'єднання
# ESTABLISHED — пакети існуючого з'єднання
# RELATED   — пов'язані з'єднання (FTP data, ICMP errors)
# INVALID   — некоректні пакети

# Приклад stateful правил
iptables -A INPUT -m state --state INVALID -j DROP
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -m state --state NEW -p tcp --dport 22 -j ACCEPT

Rate limiting

# Обмеження SSH підключень (захист від brute-force)
iptables -A INPUT -p tcp --dport 22 -m state --state NEW \
    -m recent --set --name SSH
iptables -A INPUT -p tcp --dport 22 -m state --state NEW \
    -m recent --update --seconds 60 --hitcount 4 --name SSH -j DROP

# Або через limit module
iptables -A INPUT -p tcp --dport 22 -m limit --limit 3/min --limit-burst 3 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j DROP

NAT / Masquerade

# Увімкнути IP forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
# або в /etc/sysctl.conf: net.ipv4.ip_forward=1

# SNAT / Masquerade (для роутера)
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

# DNAT / Port forwarding
# Зовнішній порт 8080 → внутрішній сервер 192.168.1.10:80
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8080 \
    -j DNAT --to-destination 192.168.1.10:80
iptables -A FORWARD -p tcp -d 192.168.1.10 --dport 80 -j ACCEPT

Збереження правил

# Debian/Ubuntu
iptables-save > /etc/iptables/rules.v4
# Відновлення при старті через iptables-persistent

# RHEL/CentOS
service iptables save
# або
iptables-save > /etc/sysconfig/iptables

nftables

nftables — сучасна заміна iptables (з Linux 3.13+).

Переваги над iptables

┌─────────────────────────────────────────────────────────────────┐
│  iptables                        nftables                       │
├─────────────────────────────────────────────────────────────────┤
│  Окремі утиліти (iptables,       Одна утиліта (nft)            │
│  ip6tables, ebtables, arptables)                               │
│                                                                 │
│  Лінійна обробка правил         Sets, maps для швидшого        │
│                                  matching                       │
│                                                                 │
│  Правила оновлюються            Атомарне оновлення             │
│  по одному                                                      │
│                                                                 │
│  Менш читабельний синтаксис     Чистіший синтаксис             │
└─────────────────────────────────────────────────────────────────┘

Базовий синтаксис

# Переглянути правила
nft list ruleset

# Структура: table → chain → rule
nft add table inet filter
nft add chain inet filter input { type filter hook input priority 0 \; policy drop \; }
nft add rule inet filter input tcp dport 22 accept

Конфігураційний файл

# /etc/nftables.conf
#!/usr/sbin/nft -f

flush ruleset

table inet filter {
    chain input {
        type filter hook input priority 0; policy drop;

        # Loopback
        iif lo accept

        # Established/related
        ct state established,related accept

        # Invalid
        ct state invalid drop

        # ICMP
        ip protocol icmp accept
        ip6 nexthdr icmpv6 accept

        # SSH
        tcp dport 22 accept

        # HTTP/HTTPS
        tcp dport { 80, 443 } accept

        # Log dropped
        log prefix "nft-dropped: " drop
    }

    chain forward {
        type filter hook forward priority 0; policy drop;
    }

    chain output {
        type filter hook output priority 0; policy accept;
    }
}

# NAT таблиця
table inet nat {
    chain prerouting {
        type nat hook prerouting priority -100;
    }

    chain postrouting {
        type nat hook postrouting priority 100;
        oifname "eth0" masquerade
    }
}

Sets та Maps

# Sets — набір значень для швидкого matching
nft add set inet filter ssh_allowed { type ipv4_addr \; }
nft add element inet filter ssh_allowed { 192.168.1.0/24, 10.0.0.5 }
nft add rule inet filter input ip saddr @ssh_allowed tcp dport 22 accept

# В конфіг файлі:
table inet filter {
    set ssh_allowed {
        type ipv4_addr
        elements = { 192.168.1.0/24, 10.0.0.5 }
    }

    chain input {
        ip saddr @ssh_allowed tcp dport 22 accept
    }
}

# Named ports set
set web_ports {
    type inet_service
    elements = { 80, 443, 8080 }
}

Міграція з iptables

# Конвертувати iptables правила в nftables
iptables-save > rules.txt
iptables-restore-translate -f rules.txt > rules.nft

# Або використовувати iptables-nft (compatibility layer)
# Команди iptables працюють, але використовують nftables backend

UFW (Uncomplicated Firewall)

UFW — простий frontend для iptables/nftables.

Базові команди

# Увімкнути/вимкнути
ufw enable
ufw disable

# Статус
ufw status
ufw status verbose
ufw status numbered

# Політика за замовчуванням
ufw default deny incoming
ufw default allow outgoing

Правила

# Дозволити порт
ufw allow 22
ufw allow 80/tcp
ufw allow 443/tcp

# Дозволити сервіс (з /etc/services)
ufw allow ssh
ufw allow http
ufw allow https

# Дозволити з конкретної IP
ufw allow from 192.168.1.0/24
ufw allow from 192.168.1.100 to any port 22

# Заборонити
ufw deny 23

# Видалити правило
ufw delete allow 80
# або за номером
ufw status numbered
ufw delete 3

# Rate limiting для SSH
ufw limit ssh

Application profiles

# Переглянути доступні профілі
ufw app list

# Дозволити профіль
ufw allow 'Nginx Full'
ufw allow 'OpenSSH'

# Інформація про профіль
ufw app info 'Nginx Full'

UFW конфігураційні файли

# /etc/ufw/before.rules — правила перед user rules
# /etc/ufw/after.rules — правила після user rules
# /etc/ufw/user.rules — user rules (автогенеровані)

# Приклад NAT в before.rules:
*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
COMMIT

firewalld

firewalld — dynamic firewall manager (RHEL, CentOS, Fedora).

Концепція зон

# Зони визначають рівень довіри до мережі
# drop — відкидати все вхідне
# block — відхиляти все вхідне (з ICMP повідомленням)
# public — публічна мережа (default)
# external — зовнішня мережа (NAT masquerade)
# dmz — DMZ
# work — робоча мережа
# home — домашня мережа
# internal — внутрішня мережа
# trusted — довіряти всьому

Базові команди

# Статус
firewall-cmd --state
firewall-cmd --list-all

# Переглянути зони
firewall-cmd --get-zones
firewall-cmd --get-active-zones
firewall-cmd --get-default-zone

# Змінити зону інтерфейсу
firewall-cmd --zone=public --change-interface=eth0

Правила

# Додати сервіс (тимчасово)
firewall-cmd --zone=public --add-service=http

# Додати сервіс (permanently)
firewall-cmd --zone=public --add-service=http --permanent

# Додати порт
firewall-cmd --zone=public --add-port=8080/tcp --permanent

# Видалити
firewall-cmd --zone=public --remove-service=http --permanent

# Застосувати зміни
firewall-cmd --reload

Rich rules

# Складніші правила
firewall-cmd --zone=public --add-rich-rule='
    rule family="ipv4"
    source address="192.168.1.0/24"
    port protocol="tcp" port="22"
    accept' --permanent

# Rate limiting
firewall-cmd --zone=public --add-rich-rule='
    rule service name="ssh"
    limit value="3/m"
    accept' --permanent

Практичні сценарії

1. Захист VPS

# Мінімальний захист для VPS
# iptables варіант

# Очистити
iptables -F

# Політики
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# Loopback
iptables -A INPUT -i lo -j ACCEPT

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

# SSH (з rate limit)
iptables -A INPUT -p tcp --dport 22 -m state --state NEW \
    -m recent --set --name SSH
iptables -A INPUT -p tcp --dport 22 -m state --state NEW \
    -m recent --update --seconds 60 --hitcount 5 --name SSH -j DROP
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# Web
iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT

# ICMP (ping)
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT

# Save
iptables-save > /etc/iptables/rules.v4

2. NAT Router

# Налаштування роутера з NAT

# Увімкнути forwarding
sysctl -w net.ipv4.ip_forward=1
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf

# nftables конфігурація
table inet filter {
    chain input {
        type filter hook input priority 0; policy drop;
        iif lo accept
        ct state established,related accept
        tcp dport 22 accept  # SSH на роутер
        drop
    }

    chain forward {
        type filter hook forward priority 0; policy drop;
        ct state established,related accept
        # Дозволити трафік з LAN в WAN
        iifname "eth1" oifname "eth0" accept
    }

    chain output {
        type filter hook output priority 0; policy accept;
    }
}

table inet nat {
    chain postrouting {
        type nat hook postrouting priority 100;
        oifname "eth0" masquerade
    }
}

3. Port Forwarding

# Прокидання порту на внутрішній сервер
# WAN:8080 → 192.168.1.10:80

# iptables
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8080 \
    -j DNAT --to-destination 192.168.1.10:80
iptables -A FORWARD -p tcp -d 192.168.1.10 --dport 80 \
    -m state --state NEW -j ACCEPT

# nftables
table inet nat {
    chain prerouting {
        type nat hook prerouting priority -100;
        iifname "eth0" tcp dport 8080 dnat to 192.168.1.10:80
    }
}
table inet filter {
    chain forward {
        ip daddr 192.168.1.10 tcp dport 80 ct state new accept
    }
}

Діагностика

Перегляд правил

# iptables
iptables -L -v -n
iptables -L -v -n --line-numbers
iptables -t nat -L -v -n

# nftables
nft list ruleset
nft list table inet filter

# UFW
ufw status verbose

# firewalld
firewall-cmd --list-all

Логування

# iptables — додати LOG перед DROP
iptables -A INPUT -j LOG --log-prefix "iptables-input: " --log-level 4
iptables -A INPUT -j DROP

# Переглянути логи
journalctl -k | grep iptables
dmesg | grep iptables
tail -f /var/log/kern.log | grep iptables

# nftables
nft add rule inet filter input log prefix \"nft-input: \" drop

Тестування

# Перевірити чи порт відкритий
nc -zv server 22
nmap -p 22,80,443 server

# Тест з конкретного IP
# (на іншому сервері)
curl -v http://server:80
ssh user@server

Типові проблеми

Проблема Причина Рішення
Locked out of SSH DROP policy без SSH rule Rescue mode, console
Connection timeout Firewall blocking Перевірити правила, логи
NAT не працює ip_forward вимкнено sysctl net.ipv4.ip_forward=1
Rules lost after reboot Не збережено iptables-save, persistent
Slow connections Reverse DNS lookup Дозволити DNS (53/udp)

Підсумок

Інструмент Коли використовувати
iptables Legacy системи, прості налаштування
nftables Нові системи, складні правила, performance
UFW Ubuntu/Debian, простий десктоп/сервер
firewalld RHEL/CentOS/Fedora, динамічне управління

Базові принципи:
1. Default DENY для INPUT
2. Дозволяти тільки необхідне
3. Rate limiting для SSH
4. Логувати dropped пакети
5. Зберігати правила persistent


Див. також

  • Hardening — загальний захист сервера
  • TLS/SSL — шифрування з'єднань
  • OSI L4 — транспортний рівень
  • MikroTik Firewall — firewall на MikroTik

Шлях: security/firewall-linux.md

UMTC Wiki © 2026 | Ukrainian Military Tactical Communications