Настройка Linux-файрвола с помощью iptables в CentOS / RHEL 7 | Windows для системных администраторов

Основы iptables

Все данные передаются по сети в виде пакетов. Ядро Linux предоставляет интерфейс для фильтрации пакетов входящего и исходящего трафика при помощи специальных таблиц. Iptables — это приложение командной строки и межсетевой экран для Linux, которым можно пользоваться для создания, поддержания работоспособности и проверки этих таблиц.

Можно создать несколько таблиц. В каждой таблице может содержаться несколько цепочек. Цепочка — это набор правил. Каждое правило определяет, что делать с пакетом, если он соответствует условиям. При соответствии пакета над ним выполняется целевое действие (TARGET). Это может быть проверка следующей цепочкой или один из следующих вариантов:

  • ACCEPT: разрешить передачу пакета.
  • DROP: запретить передачу пакета.
  • RETURN: пропустить текущую цепочку и перейти к следующему правилу в цепочке, которая ее вызвала.

В данном руководстве мы будем работать с одной из таблиц по умолчанию, которая называется фильтром (filter). В таблице фильтра есть три цепочки (набора правил):

  • INPUT – используется для контроля входящих пакетов. Можно разрешать или блокировать  подключения по порту, протоколу или IP-адресу источника.
  • FORWARD – используется для фильтрации пакетов, приходящих на сервер, но перенаправляемых куда-либо еще.
  • OUTPUT – используется для фильтрации исходящих пакетов.

Что такое nat

Для начала нам нужно понять, что настраивать мы будем самый обыкновенный NAT(Network Address Translation). Для жаждущих, я в конце упомяну и о проксе сервере на примере squid. Как я уже сказал разжёвывать будем практически всё.

Что же такое NAT? На самом деле все просто, все компьютеры имеют физический (MAC) и сетевой (IP) адреса. Нас в данный момент интересуют IP адреса. IP адрес в пределах одной сети должен быть уникальным! А при нынешнем стандарте IPv4 уникальными могут быть всего-то 4 294 967 296 (2

32

), что совсем не много и они практически кончились. но не переживайте вот вот вступит в широкое распространение IPv6, а там адресов навалом!

Но тут вы можете заметить, компьютеров значительно больше того числа, что позволяет IPv4 или скажете, что у друга дома такой же адрес как и у вас! И вот тут-то и заходит речь о NAT — он позволяет соединять компьютерные сети между собой используя единственный, свой IP адрес, действия фаервола при этом называется SNAT(Source NAT или подмена адреса источника). Т.е.

Теперь, когда мы знаем что такое NAT и для чего он нужен, можно приступать непосредственно к настройке сервера.

Работа с файлом конфигурации.

Заметка, в основном, для себя, чтобы не ошибиться и ничего не забыть. Всего, естественно, не охватить сразу, так что со временем буду добавлять записи. Подробного описания ключей и опции тут не будет, только конкретные примеры iptables.

Для работы с файлом конфигурации поставим текстовый редактор:

# yum -y install mc

Итак, в стандартной установке этой программы в CentOS 7 файл правил iptables выглядит следующим образом.

# mcedit /etc/sysconfig/iptables

Хоть нас и предупреждают, что редактировать этот файл не рекомендуется, именно сюда будут записываться новые правила iptables. Синтаксис строки с правилом аналогичен синтаксису команды. Пройдемся немного по основным командам.

Просмотр текущего состояния iptables:

# iptables -nvL –line-number

Тут у нас 3 цепочки правил:

  • INPUT — для входящих пакетов, здесь и будут отображаться записываемые правила.
  • FORWARD — для входящих пакетов, перенаправленных на выход, в данном случае все запрещено, так как компьютер не является роутером.
  • OUTPUT — для исходящих пакетов, тут всё разрешено.

Можно посмотреть каждую цепочку отдельно, например:

Разрешение трафика на локальном узле

Первым делом нам нужно обязательно разрешить трафик через интерфейс loopback. Чтобы связь между приложениями и базами данных на сервере продолжалась в обычном режиме.

sudo iptables -A INPUT -i lo -j ACCEPT

Пример результата:

Настройка Linux-файрвола с помощью iptables в CentOS / RHEL 7 | Windows для системных администраторов
Опция -A используется для добавления в цепочку INPUT правила, разрешающего все соединения для интерфейса lo. Это обозначение для интерфейса loopback, он используется для всей связи на локальном узле, например, связи между базой данных и веб-приложением на одной машине.

Iptables

Задача выполнения NAT не требует специализированных вычислительных ресурсов, ее в состоянии решать процессоры общего назначения, которые установлены, например, в любом домашнем роутере. В масштабах оператора связи эту задачу можно решить используя commodity серверы под управлением FreeBSD (ipfw/pf)

Включить трансляцию адресов совсем не сложно. Для начала необходимо прописать правило в iptables в таблицу nat:

iptables -t nat -A POSTROUTING -s 100.64.0.0/10 -j SNAT --to <pool_start_addr>-<pool_end_addr> --persistent

Операционная система загрузит модуль nf_conntrack, который будет следить за всеми активными соединениями и выполнять необходимые преобразования. Тут есть несколько тонкостей. Во-первых, поскольку речь идет о NAT в масштабах оператора связи, то необходимо подкрутить timeout’ы, потому что со значениями по умолчанию размер таблицы трансляций достаточно быстро вырастет до катастрофических значений. Ниже пример настроек, которые я использовал на своих серверах:

net.ipv4.ip_forward = 1
net.ipv4.ip_local_port_range = 8192 65535

net.netfilter.nf_conntrack_generic_timeout = 300
net.netfilter.nf_conntrack_tcp_timeout_syn_sent = 60
net.netfilter.nf_conntrack_tcp_timeout_syn_recv = 60
net.netfilter.nf_conntrack_tcp_timeout_established = 600
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 60
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 45
net.netfilter.nf_conntrack_tcp_timeout_last_ack = 30
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_close = 10
net.netfilter.nf_conntrack_tcp_timeout_max_retrans = 300
net.netfilter.nf_conntrack_tcp_timeout_unacknowledged = 300
net.netfilter.nf_conntrack_udp_timeout = 30
net.netfilter.nf_conntrack_udp_timeout_stream = 60
net.netfilter.nf_conntrack_icmpv6_timeout = 30
net.netfilter.nf_conntrack_icmp_timeout = 30
net.netfilter.nf_conntrack_events_retry_timeout = 15
net.netfilter.nf_conntrack_checksum=0


И во-вторых, поскольку по умолчанию размер таблицы трансляций не рассчитан на работу в условиях оператора связи, его необходимо увеличить:

net.netfilter.nf_conntrack_max = 3145728

Также необходимо увеличить и количество buckets для хэш-таблицы, хранящей все трансляции (это опция модуля nf_conntrack):

options nf_conntrack hashsize=1572864

После этих нехитрых манипуляций получается вполне работающая конструкция, которая может транслировать большое количество клиентских адресов в пул внешних. Однако, производительность этого решения оставляет желать лучшего. В своих первых попытках использования GNU/Linux для NAT (примерно 2021 год) я смог получить производительность около 7Gbit/s при 0.

8Mpps на один сервер (Xeon E5-1650v2). С того времени в сетевом стеке ядра GNU/Linux было сделано много различных оптимизаций, производительность одного сервера на том же железе выросла практически до 18-19 Gbit/s при 1.8-1.9 Mpps (это были предельные значения), но потребность в объеме трафика, обрабатываемого одним сервером, росла намного быстрее.

Анализ сетевой активности на шлюзе в linux

В данной конфигурации шлюз может успешно функционировать. Но иногда хочется посмотреть, а что вообще на нем происходит. Например, кто-то занимает весь канал, интернет тормозит, а мы как слепые котята сидим и не видим ничего. Нужно какое-то средство для просмотра загрузки сети на шлюзе. И такое средство есть – программа iftop.

Она отсутствует в стандартном репозитории CentOS 7. Для ее установки необходимо подключить репозиторий epel:

# yum -y install epel-release

Устанавливаем iftop на CentOS 7:

# yum -y install iftop

Теперь мы можем смотреть загрузку сети на шлюзе в режиме реального времени. Чтобы увидеть сетевую активность, достаточно запустить iftop:

# iftop

По-умолчанию она слушает интерфейс eth0. Это внешний интерфейс шлюза, на нем все подключения будут отображены от имени самого шлюза и определить, кто же в сети занимает канал мы не сможем. Чтобы это увидеть, необходимо запустить просмотр сетевой активности на локальном интерфейсе. Сделать это не сложно, достаточно запустить iftop с параметром:

# iftop -i eth1 -P

Теперь уже гораздо интереснее. Я еще добавил параметр -P, который отображает порты, по которым проходят соединения. Посмотрим, кто больше всех загружает канал интернета:

В моем случае это пользователь с ip 192.168.10.98, на котором я запустил проверку скорости интернета с серверов Яндекса.

Если у вас не большая сеть и не много пользователей, то с помощью этой простой и эффективной утилиты вы сможете легко определить, кто, к примеру, качает торренты или чем-то еще загружает канал.

:/>  Создаем загрузочную флешку в UltraISO для windows

Включаем маршрутизацию, firewall и nat

Чтобы сервер мог маршрутизировать пакеты между сетевыми адаптерами, необходимо выполнить следующую настройку. Находим файл /etc/sysctl.conf и вставляем туда строку:

# mcedit /etc/sysctl.conf
net.ipv4.ip_forward = 1

Чтобы заработала настройка, выполняем команду:

# sysctl -p

Теперь приступаем к самому главному – настройке фаерволла. Опять же отсылаю вас к своему материалу, где я очень подробно рассмотрел вопрос настройки iptables в CentOS 7. Там же приведен готовый скрипт для iptables. Так что выполняем все необходимые действия без пояснений.

Отключаем firewalld:

# systemctl stop firewalld
# systemctl disable firewalld

Устанавливаем службы iptables:

# yum -y install iptables-services

Скачиваем скрипт с правилами iptables.sh. Данные правила включают NAT, закрывают доступ к серверу снаружи, разрешают пинги, разрешают всем пользователям локальной сети доступ в интернет. Дополнительный функционал отключен. В скрипте подробно описаны все правила. Вам необходимо только заменить в начале переменные на свои. В моем случае это будет выглядеть так:

# Внешний интерфейс
export WAN=eth0
export WAN_IP=192.168.1.25
# Локальная сеть
export LAN1=eth1
export LAN1_IP_RANGE=192.168.10.1/24

Помещаем отредактированный скрипт в /etc/iptables.sh и делаем его исполняемым:

# chmod 0740 /etc/iptables.sh

Запускаем iptables:

# systemctl start iptables.service

Добавляем их в автозагрузку:

# systemctl enable iptables.service

Выполняем скрипт с правилами:

# /etc/iptables.sh

Проверяем установленные правила:

# iptables -L -v -n

Если у вас то же самое, значит вы все сделали правильно.

По сути наш шлюз уже готов и может обслуживать клиентов. Но не работает одна важна служба, без которой нормальной работы с интернетом не получится. Нам нужно настроить кэширущий dns сервер для клиентов локальной сети. Можно пойти по простому и очень простому пути.

Очень простой путь это установить dnsmasq, который помимо dns сервера включает в себя еще и dhcp сервер, который нам может пригодиться.

Конфигурация

Чтобы воспользоваться этой функцией нам надо:

  • Использовать свежее ядро. Несмотря на то, что сам функционал появился еще в ядре 4.16, довольно долго он было очень «сырой» и регулярно вызывал kernel panic. Стабилизировалось всё примерно в декабре 2021 года, когда вышли LTS ядра 4.19.90 и 5.4.5.
  • Переписать правила iptables в формат nftables, используя достаточно свежую версию nftables. Точно работает в версии 0.9.0

Если с первым пунктом всё в принципе понятно, главное не забыть включить модуль в конфигурацию при сборке (CONFIG_NFT_FLOW_OFFLOAD=m), то второй пункт требует пояснений. Правила nftables описываются совсем не так, как в iptables.

раскрывает практически все моменты, также есть специальные

правил из iptables в nftables. Поэтому я приведу только пример настройки NAT и flow offload. Небольшая легенда для примера: , — это сетевые интерфейсы, через которые проходит трафик, реально их может быть больше двух. , — начальный и конечный адрес диапазона «белых» адресов.

Конфигурация NAT очень проста:

#! /usr/sbin/nft -f

table nat {
        chain postrouting {
                type nat hook postrouting priority 100;
                oif <o_if> snat to <pool_addr_start>-<pool_addr_end> persistent
        }
}

С flow offload немного сложнее, но вполне понятно:

#! /usr/sbin/nft -f

table inet filter {
        flowtable fastnat {
                hook ingress priority 0
                devices = { <i_if>, <o_if> }
        }

        chain forward {
                type filter hook forward priority 0; policy accept;
                ip protocol { tcp , udp } flow offload @fastnat;
        }
}

Вот, собственно, и вся настройка. Теперь весь TCP/UDP трафик будет попадать в таблицу fastnat и обрабатываться намного быстрее.

Настройка nat (masquerade)

Большинство организаций получает от своих интернет-провайдеров ограниченное количество публично доступных IP-адресов, поэтому администратору требуется разделять доступ к Интернету, не выдавая каждому узлу сети публичный IP-адрес. Для доступа к внутренним и внешним сетевым службам узлы локальной сети используют внутренний (частный) IP-адрес.

Граничные маршрутизаторы (межсетевые экраны) могут получать входящие соединения из Интернета и передавать их нужным узлам локальной сети и наоборот, направлять исходящие соединения узлов удаленным интернет-службам. Такое перенаправление сетевого трафика может быть опасным, особенно учитывая доступность современных средств взлома, осуществляющих подмену внутренних IP-адресов и таким образом маскирующих машину злоумышленника под узел вашей локальной сети.

Чтобы этого не случилось, в Iptables существуют политики маршрутизации и перенаправления, которые можно применять для исключения злонамеренного использования сетевых ресурсов. Политика FORWARD позволяет администратору контролировать маршрутизацию пакетов в локальной сети.

sudo iptables -A FORWARD -i eth1 -j ACCEPT
sudo iptables -A FORWARD -o eth1 -j ACCEPT

Эти правила предоставляют системам за шлюзом доступ к внутренней сети. Шлюз направляет пакеты от узла локальной сети к узлу назначения и наоборот (опции -o и -i), передавая их через устройство eth1.

Важно: по умолчанию в большинстве дистрибутивов Linux перенаправление отключено. Чтобы его включить, нужно внести изменения в файл конфигурации /etc/sysctl.conf. Найдите там такую строчку net.ipv4.ip_forward = 0 и измените 0 на 1:

net.ipv4.ip_forward = 1

Разрешение перенаправления пакетов внутренним интерфейсом брандмауэра позволяет узлам локальной сети связываться друг с другом, но у них не будет доступа в Интернет. Чтобы обеспечить узлам локальной сети с частными IP-адресами возможность связи с внешними публичными сетями, нужно настроить на брандмауэре трансляцию сетевых адресов (NAT). Создадим правило:

sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

В этом правиле используется таблица NAT, поэтому она указывается в явном виде (-t nat) и указана встроенная цепочка этой таблицы POSTROUTING для внешнего сетевого интерфейса eth0 (-o eth0). POSTROUTING позволяет изменять пакеты, когда они выходят из внешнего интерфейса шлюза.

Настройка автозагрузки правил iptables в debian –

Чем отличается настройка iptables в Debian от других операционных систем? Тем, что достаточно давно сложилось так, что способ загрузки правил iptables оставался на усмотрение администратора, который администрирует сервер. И хотя позже появились такие решения, как ufw, пришедший из Ubuntu, или iptables-persistent, все равно может потребоваться реализовать автоматическую загрузку таблиц самостоятельно. И есть несколько способов это сделать…

Прежде, чем рассматривать способы загрузки и сохранения таблиц, давайте разберемся, что мы можем использовать. Это три команды:

iptables
iptables-save
iptables-restore

Команда iptables — это основная команда для изменения текущих таблиц, по ней можно найти много информации на просторах Интернета, поэтому пока не будем подробно рассматривать все ее возможности.

Команда iptables-save выдает на стандартный вывод действующие в данный момент правила iptables, поэтому для сохранения их в файл надо использовать перенаправление потоков:

iptables-save > /etc/iptables/iptables.today

Команда iptables-restore делает, как вы уже догадались, обратное. То есть восстанавливает правила iptables. Работает она тоже со стандартными потоками, поэтому загрузка правил будет выглядеть так:

iptables-restore < /etc/iptables/iptables.today

А теперь давайте более подробно посмотрим, как же, собственно, организовать загрузку правил автоматически.

Способ 1. Простой способ.

Самый простой способ загрузки таблиц – это вызывать загрузку после поднятия основного сетевого интерфейса при помощи параметра post-up, размещенного в файле /etc/network/interfaces

Что для этого потребуется? В первую очередь нам потребуется директория, в которой будут храниться файлы с таблицами. В соответствии со стандартом FHS, это будет /etc/iptables/, в ней мы будем хранить файлы с правилами, полученными при помощи iptables-save. Перед настройкой правил сначала сбросим содержимое правил по умолчанию:

iptables -F INPUT
iptables -F OUTPUT
iptables -F FORWARD

Теперь посмотрим, что у нас получилось:

iptables-save

У вас должны быть чистые списки правил. Это состояние желательно сохранить на случай необходимости сброса правил.

iptables-save > /etc/iptables/iptables.clean

Детальную настройку правил мы рассматривать не будем, мы сейчас не об этом. После настройки необходимых правил сохраняем их снова в файл. Я предпочитаю включать в название файла дату и время сохранения правил. Во-первых, так понятнее, что когда сохранялось, во-вторых, сортировка при просмотре в файловых менеджерах о именам выстроит список файлов по времени их создания.

iptables-save > /etc/iptables/iptables-`date  %Y%m%d-%H%M%S`

Имя получается длинное, но зато при использовании такого шаблона точно можно определить, в какое время этот файл был получен.

:/>  Оптимизация SSD в Windows 7 x64

Теперь делаем еще одно действие, которое нам позволит не переписывать название файла с правилами для загрузки. Создаем символическую ссылку на файл, в который мы только что сохранили правила. Пусть это будет файл iptables-20210904-223007, тогда делаем так:

ln -s /etc/iptables/iptables-20210904-223007 /etc/iptables/iptables.default

И последнее, что надо сделать – изменить файл /etc/network/interfaces, дописав одну строчку. Должно получиться примерно следующее:

auto eth0
iface eth0 inet dhcp
post-up /sbin/iptables-restore < /etc/iptables/iptables.default

И после этого сохраняем.

В общем, вот и всё. Теперь после поднятия интерфейса правила iptables будут загружены автоматически. Какие у этого способа есть минусы? Если кто-нибудь изменит файл /etc/network/interfaces, например, какая-нибудь программа-менеджер сети, то строчка с загрузкой правил может потеряться. Не факт, конечно, но вероятность есть. Второе – если у вас несколько сетевых интерфейсов, то вам надо либо вешать на событие post-up каждого интерфейса, либо точно знать, что выбранный вами интерфейс точно поднимается. Вариация этого способа – размещение скрипта загрузки правил в директории /etc/network/{if-pre-up.d|if-up.d}. В таком случае По соответствующему событию правила будут загружаться автоматически.

Способ 2. Совсем простой способ.

Еще более простой способ, которым многие пользуются – это написать шелл-скрипт загрузки правил и вызывать его из, например, /etc/rc.local или еще из какого-нибудь места при загрузке системы. Минус тут очевиден – для сохранения текущего состояния надо будет править этот самый скрипт, что не есть хорошо и удобно. Предыдущий способ в этом смысле выигрывает.

Способ 3. Самый сложный, но и самый интересный с моей точки зрения.

Третий способ состоит в написании собственного скрипта, делающего вид, что он сервис, и этот сервис будет запускаться при старте системы. Кроме того, мы сможем очищать текущие правила и изменять файл с правилами, который будет загружаться по умолчанию. И для этого всего мы будем использовать только один скрипт. Ну и, конечно же, этот скрипт должен самостоятельно проверять, есть ли у нас необходимые файл и директории и создавать их, если их нет. Но всё по порядку.

Начнем с того, что создадим наш скрипт и поместим его в директорию /etc/init.d, где у нас хранятся скрипты для других сервисов.

# touch /etc/init.d/ip-firewall
# chmod  x /etc/init.d/ip-firewall

Далее в любом удобном вам редакторе редактируем этот файл, вписываем в него следующее:

#!/bin/bash

### BEGIN INIT INFO
# Provides:          ip-firewall
# Required-Start:    $networking
# Required-Stop:     $networking
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: iptables frontend script
# Description:       iptables-based firewall
### END INIT INFO

test -f /lib/lsb/init-functions || exit 1
. /lib/lsb/init-functions

DESC="Iptables based firewall"
NAME=ip-firewall
SCRIPTNAME=/etc/init.d/ip-firewall

do_start()
{

}

do_stop()
{

}

do_list()
{

}

do_makedefault()
{

}

do_savecurrent()
{

}

case "$1" in
    start)
        do_start
    ;;
    stop)
        do_stop
    ;;
    list)
        do_list
    ;;
    makedefault)
        do_makedefault
    ;;
    savecurrent)
        do_savecurrent
    ;;
    *)
        echo Usage: "ip-firewall start|stop|list|makedefault|savecurrent"
    ;;
esac

Это наш шаблон скрипта сервиса, который мы с вами сейчас будем доводить до ума.

У нас уже есть обработка параметров и тела всех функций, осталось только написать внутренности этих функций. Начнем со старта, напишем содержимое функции do_start:

do_start()
{
  echo Starting ip-firewall...
  if [ -e /etc/iptables/iptables.default ]
  then
    /sbin/iptables-restore < /etc/iptables/iptables.default
    echo Done.
  else
    echo Unable to load rules. Make sure file /etc/iptables/iptables.default exists or make default some rules set.
}

Единственная задача этой функции, по идее,- загрузка правил фаервола, но надо также проверить, а существует ли файл, который мы хотим загрузить, и если его не существует, то выдать соответствующее предупреждение. Следующая функция – это отключение фаервола. Смысл ее будет в загрузке пустых правил. Тут мы даже не будем загружать никакого файла, а просто сбросим содержимое цепочек правил и включим разрешительные политики.

do_stop()
{
  echo Turning off ip-firewall...
  /sbin/iptables -F INPUT
  /sbin/iptables -F OUTPUT
  /sbin/iptables -F FORWARD
  /sbin/iptables -P INPUT ACCEPT
  /sbin/iptables -P OUTPUT ACCEPT
  /sbin/iptables -P FORWARD ACCEPT
  echo Done.
}

После этих действий цепочки iptables будут, но никаких запретов не будет. Следующая функция, которую мы напишем – do_list(). Ее задача – вывести список файлов с правилами. И можно сразу указать, какой из них считается файлом по умолчанию.

do_list()
{
  echo Rules sets:
  ls /etc/iptables | grep iptables | grep -v default
  echo Default rules set is:
  ls -l /etc/iptables | grep default | awk '{print $11}'
}

Теперь мы можем просмотреть список файлов с правилами и сказать, какой из этих файлов является файлом по умолчанию. Это нам необходимо для того, чтобы в дальнейшем можно было указывать, какой файл с правилами должен быть по умолчанию. Следующая функция – do_makedefault(). Ее задача – сделать некоторый файл с правилами файлом по умолчанию, чтобы он загружался автоматически при старте нашего скрипта. Поскольку файл, который у нас загружается, всегда будет иметь одно и то же название, он всегда будет просто символической ссылкой, а указывать эта ссылка будет на разные файлы. В этой функции у нас будет использоваться еще один параметр скрипта, поэтому добавим значение $2 в вызов функции в структуре case. Должно получиться так:

makedefault)
  do_makedefault $2
;;

Итак

do_makedefault(){
  echo Setting rules set "$1" as default...
  rm -f /etc/iptables/iptables.default
  ln -s /etc/iptables/$1 /etc/iptables/iptables.default
  echo Done.
}

В самой функции этот параметр превратится в $1, потому что для скрипта он второй, а для функции – первый. Как вы видите ,мы просто удаляем символическую ссылку с названием iptables.default и делаем новую на тот файл, название которого указано. Указывать надо только имя файла, путь указывать не нужно. А флаг -f мы используем для подавления сообщения об ошибке, если такого файла не существует.

И осталась последняя функция – do_savecurrent(). Она будет тоже выполнять всего одно несложное действие – сохранять текущие правила iptables в файл с включенным в название временем сохранения этих самых правил.

do_savecurrent(){
  NEWFILENAME="/etc/iptables/iptables-`date  %Y%m%d-%H%M%S`"
  echo Saving current rules set...
  /sbin/iptables-save > $NEWFILENAME
  echo Done.
}

Вот, собственно, сам скрипт почти закончен. Осталось сделать еще одну малость – автоматическое создание директорий, в которых будут храниться правила, если их не существует, и, если файл /etc/iptables/iptables.default не существует, то сбросим правила и политики и создадим файл iptables.clean, после чего создадим символическую ссылку на него с названием iptables.default. Для этого напишем отдельную функцию do_init():

do_init(){
  echo Initiating...
  if [ ! -e /etc/iptables ]
    then
      echo Directory /etc/iptables not found. Creating...
      mkdir /etc/iptables
      echo Done.
  fi
  if [ ! -e /etc/iptables/iptables.default ]
    then
      echo Default rules set not found. Creating...
      /sbin/iptables -F INPUT
      /sbin/iptables -F OUTPUT
      /sbin/iptables -F FORWARD
      /sbin/iptables -P INPUT ACCEPT
      /sbin/iptables -P OUTPUT ACCEPT
      /sbin/iptables -P FORWARD ACCEPT
      /sbin/iptables-save > /etc/iptables/iptables.clean
      ln -s /etc/iptables/iptables.clean /etc/iptables/iptables.default
      echo Done.
  fi
}

Эту функцию будем вызывать в самом начале скрипта, еще до выбора выполняемой команды. В итоге у нас получится следующий скрипт:

#!/bin/bash

### BEGIN INIT INFO
# Provides:          ip-firewall
# Required-Start:    $networking
# Required-Stop:     $networking
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: iptables frontend script
# Description:       iptables-based firewall
### END INIT INFO

test -f /lib/lsb/init-functions || exit 1
. /lib/lsb/init-functions

DESC="Iptables based firewall"
NAME=ip-firewall
SCRIPTNAME=/etc/init.d/ip-firewall

do_start(){
  echo Starting ip-firewall...
  if [ -e /etc/iptables/iptables.default ]
  then
    /sbin/iptables-restore < /etc/iptables/iptables.default
    echo Done.
  else
    echo Unable to load rules. Make sure file /etc/iptables/iptables.default exists or make default some rules set.
  fi
}

do_stop()
{
  echo Turning off ip-firewall...
  /sbin/iptables -F INPUT
  /sbin/iptables -F OUTPUT
  /sbin/iptables -F FORWARD
  /sbin/iptables -P INPUT ACCEPT
  /sbin/iptables -P OUTPUT ACCEPT
  /sbin/iptables -P FORWARD ACCEPT
  echo Done.
}

do_list(){
  echo Rules sets:
  ls /etc/iptables | grep iptables | grep -v default
  echo
  echo Default rules set is:
  ls -l /etc/iptables | grep default | awk '{print $11}'
}

do_makedefault(){
  echo Setting rules set "$1" as default...
  rm -f /etc/iptables/iptables.default
  ln -s /etc/iptables/$1 /etc/iptables/iptables.default
  echo Done.
}

do_savecurrent()
{
  NEWFILENAME="/etc/iptables/iptables-`date  %Y%m%d-%H%M%S`"
  echo Saving current rules set...
  /sbin/iptables-save > $NEWFILENAME
  echo Done.
}

do_init(){
  echo Initiating...
  if [ ! -e /etc/iptables ]
    then
      echo Directory /etc/iptables not found. Creating...
      mkdir /etc/iptables
      echo Done.
  fi
  if [ ! -e /etc/iptables/iptables.default ]
    then
      echo Default rules set not found. Creating...
      /sbin/iptables -F INPUT
      /sbin/iptables -F OUTPUT
      /sbin/iptables -F FORWARD
      /sbin/iptables -P INPUT ACCEPT
      /sbin/iptables -P OUTPUT ACCEPT
      /sbin/iptables -P FORWARD ACCEPT
      /sbin/iptables-save > /etc/iptables/iptables.clean
      ln -s /etc/iptables/iptables.clean /etc/iptables/iptables.default
      echo Done.
  fi
}

do_init

case "$1" in
    start)
        do_start
    ;;
    stop)
        do_stop
    ;;
    list)
        do_list
    ;;
    makedefault)
        do_makedefault $2
    ;;
    savecurrent)
        do_savecurrent
    ;;
    *)
        echo Usage: "ip-firewall start|stop|list|makedefault|savecurrent"
    ;;
esac

Осталось теперь включить получившийся скрипт в автозапуск:

update-rc.d ip-firewall defaults

Всё. Теперь правила будут загружаться каждый раз после загрузки, после выполнения скрипта networking. Если сеть стартовать при использовании LSBInit не будет, то правила фаервола загружаться тоже не будут. Надеюсь, этот скрипт будет вам полезен. Любые замечания в комментариях приветствуются.

:/>  Учим Unix: Команды UNIX
[wysija_form id=”2″]

Отключение firewalld в centos 7

В CentOS 7 для управления файрволом по умолчанию используется системная служба firewalld. Она предоставляет свой интерфейс, но в итоге также работает через утилиту iptables. При этом управление файроволом должно осуществляться либо через firewalld, либо напрямую через iptables.

firewalld не замена, а обертка вокруг iptables, пользоваться из этого можно тем, что больше нравится, или больше подходит в конкретных условиях. iptables более универсален, это базовый инструмент, но он немного сложнее в освоении. firewalld предоставляет более простой интерфейс, но, например, в CentOS 6 воспользоваться им не получится, да и для других дистрибутивов необходимо наличие нужных установочных пакетов.

Проверим статус firewalld и отключим его.

systemctl status firewalld

В выводе команды обведенная красным область со словом enabled, означает включенную автозагрузку, а область, обведенная желтым, со словом active, означает, что служба запущена.

Останавливаем службу и выключаем для нее автозагрузку:

systemctl stop firewalldsystemctl disable firewalld

Повторно проверяем статус:

Теперь вывод команды показывает disabled для автозагруки (выключена), и inactive означает, что служба выключена.

Предварительная настройка сервера

Любую настройку сервера я рекомендую начинать с обновления:

# yum -y update

После этого я устанавливаю mc, так как привык к нему и постоянно пользуюсь:

# yum -y install mc

Дальше отключаем selinux. Находим файл /etc/sysconfig/selinux и редактируем его:

# mcedit /etc/sysconfig/selinux

Приводим строку с соответствующим параметром к следующему виду:

SELINUX=disabled

Чтобы применить изменения, перезагружаем сервер:

# reboot

Более подробно о базовой настройке сервера CentOS 7 читайте отдельно. Мы же двигаемся дальше.

Теперь настроим сеть. Я очень подробно рассмотрел вопрос настройки сети в CentOS 7 в своем отдельном материале. Рекомендую с ним ознакомиться. Здесь же я кратко выполню необходимые команды, без пояснений.

Сначала удаляем NetworkManager. Он нам не понадобится, выполним все настройки вручную. Иногда он может вызывать непонятные ошибки, я предпочитаю им не пользоваться:

# systemctl stop NetworkManager.service
# systemctl disable NetworkManager.service

Теперь включаем классическую службу сети в CentOS 7:

# systemctl enable network.service

Настраиваем сетевые интерфейсы:

# mcedit /etc/sysconfig/network-scripts/ifcfg-eth0

HWADDR=00:15:5D:01:0F:06
TYPE="Ethernet"
BOOTPROTO="dhcp"
DEFROUTE="yes"
PEERDNS="yes"
PEERROUTES="yes"
NAME="eth0"
UUID="4e65030c-da90-4fb8-bde4-028424fe3710"
ONBOOT="yes"
# mcedit /etc/sysconfig/network-scripts/ifcfg-eth1

DEVICE=eth1
HWADDR=00:15:5d:01:0f:12
TYPE=Ethernet
ONBOOT=yes
IPADDR=192.168.10.1
NETMASK=255.255.255.0

Перезапускаем службу сети:

# systemctl restart network.service

Смотрим, что получилось:

# ip a

Вы настраивайте сеть в зависимости от своих условий. Если внешний адаптер получает настройки не по dhcp, как у меня, а в статике, то не забудьте настроить шлюз по-умолчанию и dns сервер. Как это сделать написано в моей статье о сетевых параметрах, ссылку на которую я приводил выше.

Прежде чем двигаться дальше, убедитесь, что вы все верно настроили – на сервере работает интернет, компьютеры из локальной сети пингуют сервер по адресу на eth1.

Сохранение введенных правил при перезагрузке

Все введенные в консоли правила – после перезагрузки ОС будут сброшены в первоначальное состояние (читай – удалены). Для того чтобы сохранить все введенные команды iptables, существует несколько путей. Например, один из них – задать все правила брандмауэра в файле инициализации rc.local.

Но у данного способа есть существенный недостаток: весь промежуток времени с запуска сетевой подсистемы, до запуска последней службы и далее скрипта rc.local из SystemV операционная система будет не защищена. Представьте ситуацию, например, если какая-нибудь служба (например NFS) стартует последней и при ее запуске произойдет какой-либо сбой и до запуска скрипта rc.local. Соответственно, rc.local так и не запуститься, а наша система превращается в одну большую дыру.

Поэтому самой лучшей идеей будет инициализировать правила netfilter/iptables при загрузке сетевой подсистемы. Для этого в Debian есть отличный инструмент – каталог /etc/network/if-up.d/, в  который можно поместить скрипты, которые будут запускаться при старте сети. А так же есть команды iptables-save и iptables-restore, которые

сохраняют

 создают дамп правил netfilter из ядра на 

 и восстанавливают в ядро правила со 

 соответственно.

Итак, алгоритм сохранения iptables примерно следующий:

Удаление правил iptables

Если нужно удалить все правила и прописать все заново с чистого листа, можно воспользоваться командой очистки (flush):

sudo iptables -F

Она удаляет все существующие правила. Если вам нужно удалить конкретное правило, воспользуйтесь опцией -D. Сначала при помощи опции —line-numbers выведите пронумерованный список всех правил:

sudo iptables -L --line-numbers

Настройка Linux-файрвола с помощью iptables в CentOS / RHEL 7 | Windows для системных администраторов
Для удаления правила нужно указать цепочку и номер в списке. В нашем случае это цепочка INPUT и номер 3.

sudo iptables -D INPUT 3

результат

Шаг 2 – определение правил

Определение правила означает внесение его в список (цепочку). Вот пример команды Iptables с обычными опциями. Некоторые из них не являются обязательными.

sudo iptables -t <таблица> -A <цепочка>  -i <интерфейс> -p <протокол (tcp/udp) > -s <источник> --dport <номер порта>  -j <целевое действие>

Опция  -A означает “append”, добавление правила в конец цепочки. Очень важным моментом является то, что правила в цепочке применяются последовательно, и если пакет удовлетворяет условиям одного из них, последующие применяться не будут. Это всегда нужно помнить при создании наборов правил.

Таблица означает таблицу, в которой редактируются цепочки. По умолчанию это filter. Цепочка — имя цепочки, к которой мы добавляем правило. Интерфейс — сетевой интерфейс, для которого выполняется фильтрация трафика. Протокол указывает сетевой протокол, пакеты которого вы хотите фильтровать, источник — IP-адрес отправителя пакета, номер порта — порт на вашем сервере, для которого применяется правило.

man iptables

Оставьте комментарий