Утилита iptables служит для управления правилами фаервола. Она не так проста в обращении как FirewallD, но имеет больше возможностей для гибкой настройки.
Публикую набор базовых команд, который выполняю на всех новых веб серверах (CentOS) для начальной конфигурации iptables:
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
iptables -t nat -F
iptables -t mangle -F
iptables -F
iptables -X
iptables -Z
iptables -t mangle -F
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A OUTPUT -o внешний_интерфейс -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -s ваш_ip_адрес/32 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j DROP
iptables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
>> по аналогии с предыдущей строкой открыть нужные tcp/udp порты
iptables -t mangle -A PREROUTING -p icmp -j DROP
iptables -t mangle -A PREROUTING -m state --state INVALID -j DROP
iptables -t mangle -A PREROUTING -p tcp ! --syn -m state --state NEW -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,RST FIN,RST -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,ACK FIN -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,URG URG -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,PSH PSH -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL NONE -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL ALL -j DROP
iptables -A FORWARD -m state --state INVALID -j DROP
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
Не забудьте изменить "ваш_ip_адрес" на свой ip! Эта строка разрешает доступ к SSH именно с этого ip. Если введёте неверный ip, то заблокируете себе доступ.
Если не указать "внешний_интерфейс" для доступа к интернету (OUTPUT), то перестанут работать cURL запросы с сайтов и обновления самого сервера. Название внешнего интерфейса можно посмотреть через ifconfig (блок со публичным ip адресом) или route (строка с "default").
Команды в этом списке нельзя менять местами, иначе можете заблокировать сервер (особенно первые две). В списке приведены только команды для базовой настройки. Они не открывают порты, к примеру, для MySQL или почтового клиента. Это только минимальный набор для веб сервера (открыты порты для http и https), от которого можно отталкиваться в дальнейшей настройке.
После чего сохраняем настройки iptables, чтобы после перезагрузки правила не были сброшены:
service iptables save
Перед выполнением этих команд стоит убедиться, что никаких сохранённых настроек нет. А то вдруг там есть ценные настройки. Проверяем что именно сохранилось с помощью вывода содержимого текстового файла настроек:
cat /etc/sysconfig/iptables
Рестартуем сервис и проверяем статус:
systemctl restart iptables
systemctl status iptables
Запрашиваем все правила и статистику по пакетам:
iptables -L -v
Полезные статьи
Рекомендую посмотреть полезные статьи по настройке iptables:
- https://wiki.centos.org/HowTos/Network/IPTables
- https://serveradmin.ru/nastroyka-iptables...
- https://sonikelf.ru/pervichnaya-nastrojka-iptables-.....
Домашним ПК на Linux
Для домашнего ПК можно использовать следующие настройки:
iptables -t nat -F
iptables -t mangle -F
iptables -F
iptables -X
iptables -Z
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT
iptables -A INPUT -p udp --dport 67:68 -j ACCEPT
iptables -A INPUT -p tcp --dport 67:68 -j ACCEPT
iptables -A INPUT -p icmp -m state --state NEW -j ACCEPT
iptables -t mangle -A PREROUTING -m state --state INVALID -j DROP
iptables -t mangle -A PREROUTING -p tcp ! --syn -m state --state NEW -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,RST FIN,RST -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,ACK FIN -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,URG URG -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,PSH PSH -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL NONE -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL ALL -j DROP
iptables -A FORWARD -m state --state INVALID -j DROP
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
P.S.
Чтобы сохранять правила на современных дистрибутивах нужно установить iptables-persistent:
apt install iptables-persistent
После чего сохранить все текущие правила, выполнив:
dpkg-reconfigure iptables-persistent
P.P.S.
Не забываем про ipv6. Либо отклчаем его, либо ставим правила на блокировку:
ip6tables -P INPUT ACCEPT
ip6tables -F
ip6tables -t mangle -F
ip6tables -A INPUT -i lo -j ACCEPT
ip6tables -A OUTPUT -o lo -j ACCEPT
ip6tables -P INPUT DROP
ip6tables -P FORWARD DROP
ip6tables -P OUTPUT DROP
Если указывать REJECT вместо DROP, то при DDOS атаке будет забит исходящий канал, потому что серверу придётся отвечать на каждый запрос. А если поставить DROP, то отвечать не надо.
В Ubuntu по умолчанию установлен фаервол ufw. Для его быстрой настройки на ПК можно использовать графическую утилиту gufw:
sudo apt install gufw
Она используется в LinuxMint из коробки.
Модуль state (используется в "-m state") является устаревшим. Лучше использовать "-m conntrack".
Обратите внимание, что правила "-m state" и "-m conntrack" не влияют друг на друга. Если разрешить что-то в "-m conntrack" и запретить в "-m state", то оно все равно будет доступно... Или мне так кажется? В любом случае, стоит использовать только один модуль, а не оба одновременно для одних и тех же портов.
Скоро соберусь с мыслями и перепишу полностью эту статью для "-m conntrack".
Следите за политиками. По ним можно догадаться существует ли ПО на сервере или нет. К примеру, если все порты сервера ничего не возвращают (используется DROP), а порт 3306 отвечает, что он unreachable (то есть установлено правило REJECT), то можно догадаться о существовании базы данных на сервере. Поэтому используйте везде DROP (предпочтительнее) либо REJECT. Но лучше не смешивать.
На чистой Centos8 для сохранения правил после перезагрузки выполнять:
iptables-save > /etc/sysconfig/iptables
Рекомендовано к прочтению: http://vasilisc.com/21-examples-iptables
И стоит разобраться почему такое правило является слишком инфантильным:
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
- в него надо добавлять --dport, чтобы пользователь не могут перейти на другой порт. К примеру, используя механизм модуля ядра nf_conntrack_ftp. Об этой беде прочитать можно тут: https://github.com/rtsisyk/linux-iptables-contrack-exploit .
Тогда почему бы не записывать сразу длинное:
iptables -A INPUT -m state --state ESTABLISHED,RELATED,NEW --dport ## -j ACCEPT
Тогда если уж и есть упоротый модуль, который открывает произвольные порты в обход iptables, то хоть нельзя будет перескочить на него с того, где было установлено соединение.
Для 99% трафика к серверу достаточно использовать правило без RELATED:
iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT
Только некоторым программам (и модулям ядра) он может пригодиться (для работы FTP, SIP, RTSP, ICMP и т.п.).
Рекомендую ознакомиться со всеми документами: https://www.netfilter.org/documentation/
Плохо ставить правила без указания состояния:
iptables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
Потому что в таком случае можно отправить на порт первый пакет не установки нового соединения SYN, а какой-нибудь ACK или FIN. И по этим данным ответа, по поведению сервера, получить информацию о системном ПО.
Состояния RELATED используются не только в ужасном nf_conntrack_ftp. Но ещё и для оповещение сервера через icmp ответов от клиента об ошибках передачи. И если в ipv4 это не столь критично и важно (можно дождаться обрыва соединения на транспортом уровне), то в ipv6 такие ответы несут более сложные и полезные функции. Поэтому не стоит полностью запрещать пинг по ipv6. (хотя, об этом тоже надо подумать получше).
Исходящие соединения тоже должны быть под контролем. То есть плохо ставить:
iptables -P OUTPUT ACCEPT
Надо для каждой службы прописывать правило приёма и пересылки. К примеру, вот для нескольких портов:
iptables -A INPUT -p tcp -m multiport --dports 80,443 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp -m multiport --dports 80,443 -m conntrack --ctstate ESTABLISHED -j ACCEPT
Для Debian/Ubuntu надо установить пакет iptables-persistent, чтобы правила не обнулялись после перезагрузки.
apt install iptables-persistent
Включить пакет и правила в автозагрузку:
systemctl enable netfilter-persistent.service
Проверить статус:
systemctl status netfilter-persistent.service
Во время установки будет предложено сохранить текущие правила в файл, чтобы загружать их при старте системы. Чтобы вручную запустить этот диалог, необходимо выполнить:
dpkg-reconfigure iptables-persistent
Далее после любых изменений правил надо выполнять:
iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6