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