Ubuntu 22.04 по умолчанию использует nftables — но большинство туториалов всё ещё показывают iptables. Пакет iptables на современных системах — это просто обёртка поверх nftables через iptables-nft. Правила которые вы пишете в iptables транслируются в nftables синтаксис автоматически. Лучше работать с nftables напрямую: синтаксис чище, производительность выше, а одна таблица заменяет iptables, ip6tables, arptables и ebtables.
Проверить что использует система
Убедиться что активен именно nftables, а не legacy iptables:
sudo iptables --version
Если в выводе (nf_tables) — система уже на nftables. Если (legacy) — нужна явная миграция.
Посмотреть текущие правила nftables:
sudo nft list ruleset
На свежей Ubuntu 22.04 вывод будет пустым или содержать только базовую таблицу от UFW если он установлен.
Архитектура: таблицы, цепочки, правила
В iptables было несколько жёстко заданных таблиц: filter, nat, mangle. В nftables вы создаёте свои таблицы с любыми именами и выбираете для них семейство адресов.
Семейства:
ip— только IPv4ip6— только IPv6inet— IPv4 и IPv6 одновременно (самый удобный для большинства задач)arp,bridge,netdev— специализированные
Типы цепочек:
type filter hook input— входящий трафикtype filter hook forward— транзитныйtype filter hook output— исходящийtype nat hook prerouting— DNAT до маршрутизацииtype nat hook postrouting— SNAT после маршрутизации
Установка и первый запуск
nftables уже установлен на Ubuntu 22.04. Проверить и включить:
sudo apt install nftables
sudo systemctl enable --now nftables
Конфигурационный файл:
sudo nano /etc/nftables.conf
После изменений применить:
sudo nft -f /etc/nftables.conf
Проверить синтаксис без применения:
sudo nft -c -f /etc/nftables.conf
Базовый stateful firewall для VPS
Минимальная рабочая конфигурация которая разрешает SSH, HTTP, HTTPS и блокирует остальное:
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
iif lo accept
ct state established,related accept
ct state invalid drop
ip protocol icmp accept
ip6 nexthdr icmpv6 accept
tcp dport 22 accept
tcp dport { 80, 443 } accept
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
Разбор ключевых решений:
iif lo accept — разрешить loopback. Без этого сломается DNS-резолвинг и межпроцессное взаимодействие.
ct state established,related accept — разрешить ответы на уже установленные соединения. Это stateful: не нужно прописывать правила в обе стороны.
ct state invalid drop — явно отбросить пакеты с неверным состоянием соединения. Защита от некоторых атак.
policy drop в chain input — запрещать всё что явно не разрешено. Безопаснее чем policy accept.
Sets: работа с группами адресов и портов
Sets — одна из главных фишек nftables над iptables. Вместо десятков отдельных правил — одно правило и список.
Разрешить несколько портов:
tcp dport { 22, 80, 443, 8080 } accept
Создать именованный set для заблокированных IP:
table inet filter {
set blocklist {
type ipv4_addr
flags interval
elements = { 192.168.1.0/24, 10.0.0.1, 203.0.113.0/28 }
}
chain input {
type filter hook input priority 0; policy drop;
ip saddr @blocklist drop
ct state established,related accept
tcp dport { 22, 80, 443 } accept
}
}
Добавить IP в set на лету без перезагрузки правил:
sudo nft add element inet filter blocklist { 198.51.100.1 }
Удалить:
sudo nft delete element inet filter blocklist { 198.51.100.1 }
Set с timeout — автоматически удалять IP через заданное время (аналог временного бана):
set blocklist {
type ipv4_addr
flags dynamic, timeout
timeout 1h
}
NAT: проброс портов и маскарадинг
Проброс входящего порта 8080 на внутренний сервис 3000:
table ip nat {
chain prerouting {
type nat hook prerouting priority -100;
tcp dport 8080 dnat to :3000
}
chain postrouting {
type nat hook postrouting priority 100;
oif "eth0" masquerade
}
}
masquerade — автоматически использует IP исходящего интерфейса как source NAT. Удобнее чем snat to когда IP интерфейса может меняться.
Включить IP forwarding (нужно для NAT):
sudo sysctl -w net.ipv4.ip_forward=1
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.d/99-forward.conf
Rate limiting: защита от перебора
Ограничить количество новых SSH-соединений — защита от брутфорса без fail2ban:
chain input {
type filter hook input priority 0; policy drop;
ct state established,related accept
tcp dport 22 ct state new limit rate 5/minute burst 10 packets accept
tcp dport 22 ct state new drop
tcp dport { 80, 443 } accept
}
limit rate 5/minute burst 10 packets — максимум 5 новых соединений в минуту с возможностью краткосрочного всплеска до 10. Все что сверх — отбрасывается следующим правилом.
Логирование отброшенных пакетов
Логировать что именно отбрасывается (полезно при отладке):
chain input {
type filter hook input priority 0; policy drop;
ct state established,related accept
tcp dport { 22, 80, 443 } accept
limit rate 5/minute log prefix "nft drop: " flags all
drop
}
Смотреть логи:
sudo journalctl -k | grep "nft drop"
Миграция с iptables
Экспортировать текущие правила iptables в формат nftables:
sudo iptables-save | sudo iptables-restore-translate -f /dev/stdin
Вывод покажет эквивалентные nftables правила. Можно скопировать в /etc/nftables.conf.
Проверить что правила от UFW не конфликтуют:
sudo nft list ruleset | grep -A5 "ufw"
Если используете UFW — либо оставьте его, либо отключите и переходите на чистый nftables:
sudo ufw disable
sudo systemctl stop ufw
Сохранение правил между перезагрузками
Сохранить текущий ruleset в файл:
sudo nft list ruleset > /etc/nftables.conf
systemd сервис nftables применяет /etc/nftables.conf при старте автоматически. Убедиться что сервис включён:
sudo systemctl enable nftables
Шпаргалка
| Задача | Команда |
|---|---|
| Посмотреть все правила | sudo nft list ruleset |
| Применить конфиг | sudo nft -f /etc/nftables.conf |
| Проверить синтаксис | sudo nft -c -f /etc/nftables.conf |
| Сбросить все правила | sudo nft flush ruleset |
| Добавить IP в блоклист | sudo nft add element inet filter blocklist { IP } |
| Удалить IP из блоклиста | sudo nft delete element inet filter blocklist { IP } |
| Список таблиц | sudo nft list tables |
| Список цепочек | sudo nft list chains |
| Перевести правила iptables | sudo iptables-save | iptables-restore-translate -f /dev/stdin |
| Сохранить ruleset | sudo nft list ruleset > /etc/nftables.conf |