Iptables - пошаговая настройка надежного Firewall для Linux сервера
06 августа 2026
Каждому администратору Linux рано или поздно приходится сталкиваться с обеспечением безопасности сервера. Одним из самых проверенных, надежных и распространенных инструментов для фильтрации сетевого трафика является iptables.
Когда дома работает полноценный сервер на базе Linux (особенно с публичным веб-сервером на 80 и 443 портах), вопрос безопасности перестает быть теоретическим. Стандартная политика «всё открыто по умолчанию» — прямой путь к незваным гостям в логах.
В этой статье я разберу, как установить iptables на сервер, а также как устроена эта утилита, из каких компонентов она состоит и как с её помощью выстроить жесткую оборону: закрыть лишние порты внешнему миру, оставить SSH только для локальной сети, отсечь сканеры портов и защититься от базовых сетевых атак.
1. Что такое iptables и как оно работает?
iptables — это инструмент командной строки, который используется для настройки ядра Linux по фильтрации пакетов (netfilter).
В основе работы iptables лежат четыре ключевых понятия:
Таблицы (Tables)— определяют общую категорию правил (например, фильтрация или нат).Цепочки (Chains)— точки прохождения пакета, в которых применяются правила.Правила (Rules)— конкретные инструкции: если пакет соответствует условию, то сделать с ним определенное действие.Действия (Targets/Policy)— что именно сделать с пакетом (принять, сбросить, перенаправить).
2. Архитектура: Таблицы и Цепочки
Основные таблицы:
filter(основная по умолчанию) — используется для принятия или отклонения пакетов.nat(Network Address Translation) — используется для перенаправления портов и подмены IP-адресов (например, для шлюзов или Docker).mangle— для специального изменения заголовков пакетов.raw— для работы с пакетами до того, как ядро начнет отслеживать соединения (connection tracking).
Стандартные цепочки в таблице filter:
- INPUT — обрабатывает входящий трафик, направленный на сам сервер.
- OUTPUT — обрабатывает исходящий трафик, генерируемый самим сервером.
- FORWARD — обрабатывает транзитный трафик (когда сервер работает как маршрутизатор).
3. Установка iptables
В большинстве дистрибутивов Linux iptables уже установлен по умолчанию. Проверить это можно командой:
iptables --versionЕсли утилита отсутствует или требуется установить пакет для сохранения правил после перезагрузки, необходимо выполнить следующие действия:
sudo apt update
sudo apt install iptables iptables-persistent -yПакет iptables-persistent автоматически сохраняет текущие правила и восстанавливает их при каждой загрузке системы.
4. Базовые команды для управления
Прежде чем писать правила, надо вспомнить основные команды для проверки текущего состояния.
Посмотреть правила в виде списка с номерами и счетчиками пакетов:
sudo iptables -L -v -n --line-numbersПосмотреть правила конкретной таблицы (например, filter):
sudo iptables -t filter -L -v -nОсновные ключи команд:
-A (Append) — добавить правило в конец цепочки.
-I (Insert) — вставить правило в начало цепочки (под определенным номером).
-D (Delete) — удалить правило.
-F (Flush)— очистить все правила в цепочке/таблице.
-P (Policy) — установить политику по умолчанию для цепочки.
5. Сохранение правил
По умолчанию любые изменения в iptables действуют до первой перезагрузки системы. Чтобы сохранить конфигурацию:
sudo netfilter-persistent save
sudo netfilter-persistent reload
6. Базовая политика: запретить всё, что не разрешено
Первое и главное правило безопасного сервера — изменить политики по умолчанию для цепочек INPUT и FORWARD на DROP. Это значит, что любой входящий пакет по умолчанию будет отброшен, если для него нет явного разрешающего правила.
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [28:2551]
7. Зеленый свет для локального интерфейса и установленных соединений
Сервер должен общаться сам с собой (loopback) и уметь отвечать тем, кому он сам уже разрешил подключение (state tracking):
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -m conntrack --ctstate INVALID -j DROPПакеты интерфейса lo принимаются без ограничений.
Установленные соединения (ESTABLISHED, RELATED) продолжают работать штатно.
Битые и поврежденные пакеты (INVALID) сразу отбрасываются.
8. Защита от сканеров и мусорных TCP-флагов
Злоумышленники часто сканируют порты с помощью нестандартных комбинаций флагов (NULL, XMAS-сканирование и т.д.). Для этого создаю отдельную цепочку bad_tcp_flags, которая мгновенно рубит подобные трафики:
-A INPUT -p tcp -j bad_tcp_flags
-A bad_tcp_flags -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
-A bad_tcp_flags -p tcp -m tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
-A bad_tcp_flags -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -j DROP
-A bad_tcp_flags -p tcp -m tcp --tcp-flags FIN,RST FIN,RST -j DROP
-A bad_tcp_flags -p tcp -m tcp --tcp-flags FIN,ACK FIN -j DROP
-A bad_tcp_flags -p tcp -m tcp --tcp-flags PSH,ACK PSH -j DROP
-A bad_tcp_flags -p tcp -m tcp --tcp-flags ACK,URG URG -j DROP
-A bad_tcp_flags -p tcp -j RETURN
9. Отражение SYN-flood атак
Чтобы сервер не захлебнулся от лавины полуоткрытых соединений при DDoS-атаке или сканировании, настраиваю лимиты для SYN-пакетов:
-A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j syn_flood
-A syn_flood -m limit --limit 222/sec --limit-burst 2000 -j RETURN
-A syn_flood -j DROPА также ограничиваю ICMP (ping), чтобы сеть не забивали мусорным эхо-запросами, оставляя скромный лимит в 2 пакета в секунду:
-A INPUT -p icmp -m icmp --icmp-type 8 -m limit --limit 2/sec -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 8 -j DROP
10. Публичные службы (доступы извне)
Мой веб-сервер должен быть доступен всему миру, поэтому порты 80 (HTTP) и 443 (HTTPS) открыты для новых входящих соединений (--ctstate NEW):
-A INPUT -p tcp -m tcp --dport 80 -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -m conntrack --ctstate NEW -j ACCEPT
11. Закрытый контур: администрирование только из локальной сети
Всё, что связано с управлением сервера, не должно торчать в публичный интернет. Доступ по SSH, принтеры (CUPS), панель Webmin, SNMP-мониторинг и локальные порты жестко привязаны к домашней подсети 192.168.0.0/24:
-A INPUT -s 192.168.0.0/24 -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -s 192.168.0.0/24 -p tcp -m tcp --dport 631 -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -s 192.168.0.0/24 -p tcp -m tcp --dport 10000 -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -s 192.168.0.0/24 -p udp -m udp --dport 161 -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -s 192.168.0.0/24 -p tcp -m tcp --dport 5000 -m conntrack --ctstate NEW -j ACCEPT
12. Защита от IP-спуфинга в таблице raw
На уровне таблицы raw в самом начале прохождения пакетов активирую фильтрацию обратного пути (rpfilter), что защищает от подделки IP-адресов отправителя (IP spoofing):
*raw
:PREROUTING ACCEPT [27:3015]
:OUTPUT ACCEPT [0:0]
-A PREROUTING -m rpfilter --invert -m comment --comment "spoofing attacks" -j DROP
COMMIT
13. Пример создания и настройки скрипта /etc/iptables/firewall.sh
Итак как пример, создам свои правила с учетом всего описанного выше и помещу в скрипт /etc/iptables/firewall.sh, который будет автоматически применяется при запуске системы. Такая конфигурация гарантирует, что снаружи видны исключительно веб-страницы сайта, а все административные инструменты остаются за надежной стеной локальной сети.
Цель: Перенести набор команд iptables в исполняемый Bash-скрипт, настроить правильные права доступа и автоматизировать его применение при загрузке системы или изменении конфигурации.
13.1 Создание файла скрипта
Создаю файл firewall.sh конфигурации брандмауэра в директории /etc/iptables/ с помощью текстового редактора (например, nano):
sudo nano /etc/iptables/firewall.sh
13.2 Внутрь вставлю готовый набор правил:
#!/bin/sh
# 1. Полная очистка всех таблиц
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -t raw -F
iptables -t raw -X
# 2. Дефолтные политики
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# 3. Защита от IP Spoofing (таблица raw)
iptables -t raw -A PREROUTING -m rpfilter --invert -m comment --comment "spoofing attacks" -j DROP
# 4. Базовые правила (Loopback и установленные соединения)
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# 5. Блокировка невалидных пакетов (Invalid)
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
# 6. Блокировка аномальных TCP-флагов (Сканеры портов)
iptables -N bad_tcp_flags
iptables -A INPUT -p tcp -j bad_tcp_flags
iptables -A bad_tcp_flags -p tcp --tcp-flags ALL NONE -j DROP
iptables -A bad_tcp_flags -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
iptables -A bad_tcp_flags -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
iptables -A bad_tcp_flags -p tcp --tcp-flags FIN,RST FIN,RST -j DROP
iptables -A bad_tcp_flags -p tcp --tcp-flags ACK,FIN FIN -j DROP
iptables -A bad_tcp_flags -p tcp --tcp-flags ACK,PSH PSH -j DROP
iptables -A bad_tcp_flags -p tcp --tcp-flags ACK,URG URG -j DROP
iptables -A bad_tcp_flags -p tcp -j RETURN
# 7. Защита от SYN-Flood (Лимит burst 2000, 222 req/s)
iptables -N syn_flood
iptables -A INPUT -p tcp --syn -j syn_flood
iptables -A syn_flood -m limit --limit 222/s --limit-burst 2000 -j RETURN
iptables -A syn_flood -j DROP
# 8. Защита от Ping-of-Death / ICMP Flood (оставляем мягкий лимит на пинги)
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 2/s --limit-burst 5 -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-request -j DROP
# 9. Разрешающие правила для сервисов:
# HTTP (80)
iptables -A INPUT -p tcp --dport 80 -m conntrack --ctstate NEW -j ACCEPT
# HTTPS (443)
iptables -A INPUT -p tcp --dport 443 -m conntrack --ctstate NEW -j ACCEPT
# Стандартный SSH (порт 22) только для устройств из локальной сети 192.168.0.0/24
iptables -A INPUT -s 192.168.0.0/24 -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
# Разрешаем доступ к CUPS (порт 631) только из локальной сети 192.168.0.0/24
iptables -A INPUT -s 192.168.0.0/24 -p tcp --dport 631 -m conntrack --ctstate NEW -j ACCEPT
# Webmin (порт 10000) только из локальной сети 192.168.0.0/24
iptables -A INPUT -s 192.168.0.0/24 -p tcp --dport 10000 -m conntrack --ctstate NEW -j ACCEPT
# SNMP (порт 161 UDP) для всех устройств из локальной сети 192.168.0.0/24
iptables -A INPUT -s 192.168.0.0/24 -p udp --dport 161 -m conntrack --ctstate NEW -j ACCEPT
# SSH на нестандартном порту 14922 если доступ к серверу осуществляется из WAN
iptables -A INPUT -p tcp --dport 14922 -m conntrack --ctstate NEW -j ACCEPT
# 10. Сохранение
netfilter-persistent save
13.3 Назначение прав и запуск
Чтобы файл можно было запускать как исполняемый скрипт от имени суперпользователя, делаю файл исполняемым и запускаю для применения правил прямо сейчас:
sudo chmod +x /etc/iptables/firewall.sh
sudo /etc/iptables/firewall.shСовет: перед запуском нужно обязательно убедиться, что фильтр в части доступа по SSH настроен точно верно, иначе можно легко потерять доступ к удаленному серверу при их применении.
13.4 Автоматизация при загрузке системы (Systemd Service)
Чтобы скрипт автоматически применялся при каждом включении сервера, создам системный сервис systemd:
sudo nano /etc/systemd/system/firewall.serviceДобавляю в него следующий конфигурационный блок:
[Unit]
Description=Apply custom iptables firewall rules
After=network.target
[Service]
Type=oneshot
ExecStart=/etc/iptables/firewall.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.targetВключить и активировать созданный сервис:
sudo systemctl daemon-reload
sudo systemctl enable firewall.service
sudo systemctl start firewall.service
Заключение
Зачем вообще это нужно: Настройка iptables превращает уязвимый домашний сервер в защищенную крепость, которая отражает сетевые атаки, блокирует сканеры портов и предотвращает несанкционированный доступ к административным панелям из интернета.
Зачем столько читать: Чтобы не просто скопировать чужой набор команд, а досконально понять архитектуру сетевого экрана (таблицы, цепочки, логику обработки пакетов) и научиться самостоятельно управлять правилами фильтрации.
Главный результат: Теперь сервер надежно защищен, веб-сайты доступны всему миру, а управление скрыто в безопасном контуре локальной сети и автоматически восстанавливается после любых перезагрузок.