Продолжаем наше знакомство с фаерволом Netfilter & Iptables. Во второй части статьи речь пойдет об управлении правилами iptables. Мы научимся добавлять правила в межсетевой экран, сохранять их и восстанавливать. Рассмотрим утилиты для управления правилами и напишем свой скрипт управления.
Отключение Selinux и Firewalld в CentOS/RHEL системах
Если вы хотите начать использовать iptables в CentOS или других Red Hat производных системах, то перед настройкой необходимо отключить Selinux и firewalld.
Для отключения selinux отредактируем файл /etc/sysconfig/selinux.
# Открываем файл для редактирования nano /etc/sysconfig/selinux # Находим строку SELINUX=enforced, заменяем на disabled SELINUX=disabled # Сохраняем и выходим.
Firewalld - надстройка над iptables, играющая роль брандмауэра, применяется в RHEL системах по умолчанию. Так как управлять фаерволом мы будем при помощи собственных правил, то firewalld необходимо отключить.
# Останавливаем firewalld и удаляем его из автозагрузки systemctl stop firewalld systemctl disable firewalld
Добавление и сохранение правил iptables
Добавляются правила несколькими способами, можно вводить правила через консоль, а можно править файл в котором они записываются.
Для примера добавим какое-нибудь безобидное правило, чтобы не затрагивать подключение. Например запретим прохождение транзитных пакетов.
iptables -P FORWARD DROP
Проверим текущие настройки межсетевого экрана командой iptables -L -n -v.
iptables -L -n -v Chain FORWARD (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination
В цепочке FORWARD действием по умолчанию значится DROP, следовательно правило работает.
В данный момент новые настройки фаервола хранятся в оперативной памяти и находиться там они будут ровно до момента перезагрузки или выключения компьютера. Если состояние правил не сохранить, то после перезапуска будут загружены настройки по умолчанию и все опять будет открыто.
Изменения в правилах сохраняются/записываются посредством встроенной утилиты iptables-save. Необходимо создать файл в который будут записываться правила.
# Создаем файл для хранения правил touch iptables_rules
Так-как я нахожусь в системе под root, то команда создаст файл в домашней директории root-пользователя /root/iptables_rules. Для создания файла в другом каталоге, команда должна выглядеть так:
touch /path/to/your/file/iptables_rules
Воспользуемся iptables-save и сохраним изменения, записав их в созданный файл iptables_rules.
# Сохраняем текущий набор правил: iptables-save > /root/iptables_rules
Cодержимое файла iptables_rules, в который были записаны правила, будет выглядеть так:
# Generated by iptables-save v1.4.21 on Sat Sep 24 09:43:01 2016 *filter :INPUT ACCEPT [236:21072] :FORWARD DROP [0:0] :OUTPUT ACCEPT [155:23765] COMMIT # Completed on Sat Sep 24 09:43:01 2016
Утилита iptables-save считала текущие настройки правил из оперативной памяти и записала их в указанный файл, в форме понятной для пользователя, то есть в форме правил.
Можно править файл и добавлять правила непосредственно в него. Правила не относящиеся ни к одной из таблиц заносятся в таблицу filter и добавляются между строками *filter и COMMIT.
Политики по умолчанию записываются после знака двоеточия (:).
- iptables -P FORWARD DROP будет записано как :FORWARD DROP
Обычные правила записываются после политик по умолчанию, без слова iptables. Например нужно запретить любые подключения с машины под адресом 192.168.1.100, добавляем нужное правило (iptables -A INPUT -s 192.168.1.100 -j DROP) в файл iptables_rules.
# Generated by iptables-save v1.4.21 on Fri Sep 2 23:13:32 2016 *filter :INPUT ACCEPT [74:4408] :FORWARD DROP [0:0] :OUTPUT ACCEPT [50:4600] -A INPUT -s 192.168.1.100 -j DROP COMMIT # Completed on Fri Sep 2 23:13:32 2016
Если правила добавляются сразу в файл минуя консоль, то их нужно применить в фаерволе, для этого существует утилита iptables-restore.
iptables-restore < /root/iptables_rules
Правила из файла переносятся в настройки фаервола и применяются. Если следом выполнить команду для просмотра действующих правил, то можно увидеть что правило добавлено.
iptables -L -n -v Chain INPUT (policy ACCEPT 63 packets, 4526 bytes) pkts bytes target prot opt in out source destination 0 0 DROP all -- * * 192.168.1.100 0.0.0.0/0 Chain FORWARD (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 48 packets, 3876 bytes) pkts bytes target prot opt in out source destination
Применение и восстановление правил iptables
Правило добавленное через консоль, применяется в фаерволе, но не сохраняется в дальнейшем, поэтому сохранять правила нужно вручную.
iptables-save > /path to file/filename
Если правило добавлено сразу в файл, то оно не применяется в фаерволе и его надо применить.
iptables-restore < /path to file/filename
Для восстановления правил после перезагрузки или включения системы необходимо применять iptables-restore. Чтобы не проделывать процедуру восстановления правил каждый раз, правила можно добавить в автозагрузку.
CentOS
В CentOS добавить правила в автозагрузку можно посредством правки файла rc.local.
# Редактируем файл: nano /etc/rc.d/rc.local # Добавляем в конец файла: /sbin/iptables-restore < /root/iptables_rules # Сохраняем и выходим. # Делаем файл исполняемым: chmod +x /etc/rc.d/rc.local
Теперь правила будут применяться в фаерволе при запуске системы. Для того чтобы запретить загрузку через rc.local, уберите добавленную строку или закомментируйте ее.
#/sbin/iptables-restore < /root/iptables_rules
Debian & Ubuntu
В Debian & Ubuntu все работает также, только rc.local расположен в каталоге /etc, загрузку можно прописать здесь. Можно сделать иначе, в Debian & Ubuntu запуск правил удобнее прописать в конф. файле сетевых интерфейсов /etc/network/interfaces.
# Редактируем файл: nano /etc/network/interfaces # Добавляем строку в конец раздела eth0: pre-up iptables-restore < /root/iptables_rules
Теперь правила будут стартовать совместно с сетевым интерфейсом. Можно делать перезапуск правил путем перезагрузки сетевого интерфейса, для применения внесенных правок.
ifdown eth0 && ifup eth0
Можно пойти дальше и прописать команду для сохранения текущего состояния правил при выключении/перезапуске компьютера или при перезапуске интерфейса.
# Редактируем файл: nano /etc/network/interfaces # Добавляем строку в конец раздела eth0: post-down iptables-save > /root/iptables_rules
Теперь, даже если вы забудете сохранить внесенные изменения в правила, система сделает это автоматически. Файл интерфейсов должен выглядеть примерно так:
# This file describes the network interfaces available on your system # and how to activate them. For more information, see interfaces(5). source /etc/network/interfaces.d/* # The loopback network interface auto lo iface lo inet loopback # The primary network interface auto eth0 iface eth0 inet static address 192.168.1.7 netmask 255.255.255.0 gateway 192.168.1.1 network 192.168.1.0 broadcast 192.168.1.255 # Сохранение правил iptables post-down iptables-save > /root/iptables_rules # Старт правил iptables pre-up iptables-restore < /root/iptables_rules
Данные схемы рабочие, но неудобные, делать сохранение и восстановление правил можно по другому, при помощи специальных утилит. Теперь когда мы знаем механизм работы, можно переходить к изучению утилит помогающих управлять правилами iptables.
iptables-services в CentOS/RHEL системах
В CentOS существует утилита управления правилами iptables, делающая все вышеописанное, она создает файл для записи, сохраняет изменения, загружает правила при запуске системы. Эта утилита называется iptables-services.
# Устанавливаем yum -y install iptables-services # Добавляем в автозагрузку и запускаем systemctl start iptables.service systemctl enable iptables.service
После установки в директории /etc/sysconfig появляются файлы iptables и ip6tables, в эти файлы производится запись правил. В файл iptables производится запись правил для протокола IPv4, в файл ip6tables для протокола IPv6.
Конфигурационный файл находится в /etc/sysconfig/iptables-config. Здесь нас интересуют два параметра:
- IPTABLES_SAVE_ON_STOP="no" - сохранение текущих правил при остановке демона iptables, по умолчанию отключено.
- IPTABLES_SAVE_ON_RESTART="no" - сохранение текущих правил при перезапуске/перезагрузке системы, по умолчанию отключено.
Включим сохранение текущих правил, нужно заменить значения с "no" на "yes". Правила будут сохраняться автоматически в файл /etc/sysconfig/iptables, при перезагрузке системы/службы iptables. Также правила можно сохранять командой restart.
service iptables restart
Остальные параметры оставляем по умолчанию, без веской причины трогать их не следует.
- IPTABLES_MODULES="" - здесь указываются дополнительные модули iptables, которые будут загружаться при старте.
- IPTABLES_MODULES_UNLOAD="yes" - выгрузка модулей iptables, при перезагрузке или остановке межсетевого экрана.
- IPTABLES_SAVE_COUNTER="no" - сохранение счетчиков правил и цепочек, при остановке или перезагрузке.
- IPTABLES_STATUS_NUMERIC="yes" - вывод значений ip-адресов и портов в числовом виде.
- IPTABLES_STATUS_VERBOSE="no" - расширенный вывод информации.
- IPTABLES_STATUS_LINENUMBERS="yes" - вывод информации в пронумерованных строках.
- #IPTABLES_SYSCTL_LOAD_LIST=".nf_conntrack .bridge-nf" - перезагрузка параметров ядра при старте или перезапуске.
iptables-persistent в Debian & Ubuntu
Почти то же, что и iptables-services, только немного неудобнее.
# Устанавливаем apt-get -y install iptables-persistent
Во время установки будет задано два вопроса, на которые следует ответить положительно.
После установки в каталоге /etc/iptables появятся файлы rules.v4 и rules.v6. В эти файлы будут записываться правила межсетевого экрана.
Управление правилами при помощи iptables-persistent немного отличается от iptables-services в более неудобную сторону. После добавления новых правил через консоль, следует выполнять команду для их сохранения.
dpkg-reconfigure iptables-persistent
Команда записывает изменения правил в файл /etc/iptables/rules.v4, в процессе выполнения запрашивается подтверждение. Если после добавления нового правила вы не выполните эту команду, то оно будет работать только до первой перезагрузки или отключения системы.
Автоматически сохранять текущие правила при перезагрузке iptables-persistent не может.
Для подстраховки можно воспользоваться рассмотренным выше способом и добавить в файл /etc/network/interfaces, команду для автоматического сохранения правил.
post-down iptables-save > /etc/iptables/rules.v4
Также после установки пакета появляется демон netfilter-persistent при помощи которого можно управлять правилами iptables.
При выполнении команды --help можно посмотреть список доступных команд для управления.
netfilter-persistent --help Usage: /usr/sbin/netfilter-persistent (start|stop|restart|reload|flush|save)
Выполняться они могут через команду - service
- service netfilter-persistent start - запустить сервис
- service netfilter-persistent stop - остановить сервис
- service netfilter-persistent restart - перезапустить сервис
- service netfilter-persistent reload - восстановить правила из файлов rules.v4/rules.v6
- service netfilter-persistent save - сохранить правила в файлы rules.v4/rules.v6
- service netfilter-persistent flush - полностью очищает текущие правила, все становится открыто, но не очищает файл с записанными правилами. Поэтому после перезагрузки, правила из файла считаются и загрузятся снова, если его предварительно не очистить.
Таким образом для сохранения правил можно пользоваться как dpkg-reconfigure так и service netfilter-persistent save, например.
Скрипт для правил iptables
Самый удобный, надежный, самый легкий способ управления правилами, я как всегда приберег для конца статьи. Помимо всех вышеописанных способов правила можно добавлять скриптом.
Перед написанием скрипта, установите iptables-services в CentOS, iptables-persistent в Debian. На самом деле можно обойтись и без них, но с ними немного удобнее.
Создаем скрипт, по привычке я называю его ipt.sh, скрипт можно назвать как угодно, например myname.sh, где myname это имя скрипта.
nano /etc/ipt.sh
В начале скрипта всегда указывается интерпретатор, в нашем случае /bin/bash, он указывается после так называемого sha-bang "#!". Не стоит путать с "#", строки начинающиеся с символа "#" являются комментариями, такие строки не выполняются.
# Указываем интерпретатор для выполнения скрипта: #!/bin/bash
Теперь можно добавлять необходимые правила, правила записываются обычным образом, без каких-либо дополнительных требований. В качестве примера приведу свой минимальный набор правил, которым пользуюсь повсеместно, добавляя в него необходимые правила в зависимости от обстоятельств.
Данный набор правил закрывает любые подключения извне, кроме подключений к работающим на сервере службам через разрешенные порты.
# Очистка текущих правил iptables -F iptables -X # Назначение политик по умолчанию iptables -P INPUT DROP iptables -P OUTPUT DROP iptables -P FORWARD DROP # Локальный трафик iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT # Исходящие соединения iptables -A OUTPUT -o ens3 -j ACCEPT # Related & Established соединения iptables -A INPUT -p all -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A OUTPUT -p all -m state --state ESTABLISHED,RELATED -j ACCEPT # открыть порты для веб-сервера iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT iptables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT # открыть порт для ssh iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT # открыть порт для postfix iptables -A INPUT -p tcp -m tcp --dport 25 -j ACCEPT
Примечание: обязательно смените имя сетевого интерфейса ens3 на свое (eth0 или enp0s3) в правиле разрешающем выходной трафик.
Теперь надо прописать команду для сохранения правил в файл из которого будут считываться при загрузке. Делается это при помощи утилиты iptables-save, как видите ничего нового, все это мы уже проходили выше.
Если вы пишете скрипт в CentOS, то указываем /etc/sysconfig/iptables, если в Debian или Ubuntu, то /etc/iptables/rules.v4. Именно поэтому в начале я говорил, что должны стоять iptables-services и iptables-persistent, соответственно.
Сохранение правил.
# Сохраняем правила: /sbin/iptables-save > /etc/iptables/rules.v4
Основная часть скрипта готова. В конец скрипта я еще дописываю какую-нибудь фразу, чтобы знать что скрипт выполнился, например - "Правила обновлены!".
echo "Правила обновлены!"
В конечном виде скрипт выглядит так.
#!/bin/bash # Очистка текущих правил iptables -F iptables -X # Назначение политик по умолчанию iptables -P INPUT DROP iptables -P OUTPUT DROP iptables -P FORWARD DROP # Локальный трафик iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT # Исходящие соединения iptables -A OUTPUT -o ens3 -j ACCEPT # Related & Established соединения iptables -A INPUT -p all -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A OUTPUT -p all -m state --state ESTABLISHED,RELATED -j ACCEPT # открыть порты для веб-сервера iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT iptables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT # открыть порт для ssh iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT # открыть порт для postfix iptables -A INPUT -p tcp -m tcp --dport 25 -j ACCEPT # Сохраняем правила: /sbin/iptables-save > /etc/iptables/rules.v4 echo "Правила обновлены!"
Скрипт написан. Теперь его надо сделать исполняемым.
chmod 0740 /etc/ipt.sh
После чего его необходимо выполнить.
/etc/ipt.sh
Если после выполнения скрипта проверить состояние фаервола, можно увидеть следующее.
iptables -L -n -v Chain INPUT (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0 61 4164 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:443 1 40 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:25 Chain FORWARD (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy DROP 2 packets, 300 bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT all -- * lo 0.0.0.0/0 0.0.0.0/0 0 0 ACCEPT all -- * ens3 0.0.0.0/0 0.0.0.0/0 46 4444 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
Межсетевой экран в порядке, правила применены и работают. А что с файлом для сохранения?
cat /etc/iptables/rules.v4 # Generated by iptables-save v1.4.21 on Sun Oct 9 19:36:31 2016 *filter :INPUT DROP [0:0] :FORWARD DROP [0:0] :OUTPUT DROP [0:0] -A INPUT -i lo -j ACCEPT -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT -A INPUT -p tcp -m tcp --dport 25 -j ACCEPT -A OUTPUT -o lo -j ACCEPT -A OUTPUT -o ens3 -j ACCEPT -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT COMMIT # Completed on Sun Oct 9 19:36:31 2016
Здесь тоже порядок, все правила на месте. Как можно видеть, скриптом убиваются два зайца, правила одновременно заносятся и в межсетевой экран, и в файл из которого будут загружаться при старте системы. Именно поэтому я считаю данный способ самым надежным, здесь нельзя забыть сохранить правила.
Сама работа скрипта очень проста. Скрипт имитирует ввод правил в консоль, с последующим сохранением в файл. Если нужно добавить или убрать правила, то редактируйте скрипт и заново выполняйте его.
/etc/ipt.sh
На этом пока все.