Убунтология

Популярное содержимое

Брандмауэр - внешняя защита компьютера (iptables)

 

Автор статьи: forkostya

 

Наша задача - установить политику обработки сетевых пакетов по умолчанию в положение "не пропускать", и добавить минимальный набор правил, разрешающий ходить только определенным пакетам.

Немного теории

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

Какие критерии могут быть - конечно же, соответствующие информации, идущей с сетевым пакетом:

  • Протокол (-p)
  • Ip-адрес отправителя (-s)
  • Порт отправителя (--sport)
  • Ip-адрес получателя (-d)
  • Порт получателя (--dport)
  • Состояние (новый, ответный и т.п.) (-m state --state)
  • На какой интерфейс пришло (-i)
  • С какого интерфейса уходит (-o)
  • и прочее

Полученный файерволом пакет проходит некоторые цепочки правил, в зависимости от этих данных.

Таблиц с цепочками всего 3:

Таблица mangle, её цепочки:

  • PREROUTING
  • INPUT
  • FORWARD
  • OUTPUT
  • POSTROUTING

Таблица nat, её цепочки:

  • PREROUTING
  • OUTPUT
  • POSTROUTING

Таблица filter, её цепочки:

  • INPUT
  • FORWARD
  • OUTPUT

В данном разделе мы будем рассматривать упрощенный вариант: только таблицу filter, цепочки INPUT и OUTPUT.

Входящий пакет проходит filter INPUT. Исходящий, соответственно, filter OUTPUT.

Действий, которые совершаются над пакетами (политики), довольно много, мы будем использовать следующие:

  • Пропустить/разрешить (ACCEPT)
  • Отбросить без уведомления (DROP)
  • Отбросить с уведомлением (REJECT)

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

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

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

Немного практики

Обычно, для настройки той или иной утилиты в ОС Linux достаточно изменить её файл конфигурации и перезагрузить её. Но это не наш случай. У утилиты iptables нет своего конфигурационного файла и ей можно управлять исключительно выполняя команды из консоли. Команда имеет следующий вид:

iptables [ -t ТАБЛИЦА ] ДЕЙСТВИЕ ЦЕПОЧКА [НОМЕР] КРИТЕРИЙ1 [ КРИТЕРИЙ2 КРИТЕРИЙ3 ... ] -j ПОЛИТИКА [ ОПЦИИ ]

В квадратных скобках обозначены не обязательные параметры. Если не указать таблицу, то выбирается таблица filter, как раз то, что нам нужно. Опции мы не будем использовать в этой главе. Действия могут быть такими:

  • Добавить правило в конец цепочки (-A)
  • Удалить правило из цепочки (-D), можно указать номер правила в цепочке, а можно и само правило
  • Добавить правило в цепочку (-I), необходимо указать после имени цепочки номер правила, перед которым оно встанет
  • Установить политику по-умолчанию (-P). Для этого КРИТЕРИЙ и -j указывать не нужно.

Просмотр состояния файервола выполняется так: iptables -nvL или iptables -t nat -nvL

 

  • L - LISTING - вывод информации
  • n - чтобы вывод был только числовой, без перевода ip в доменное имя, портов в их названия и т.п.
  • v - чтобы вывод был более информативным (verbose)

Предостережение

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

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

Шаг №2 - установить политики по-умолчанию для всех цепочек в DROP (отбрасывать без уведомления).

Шаг №3 - по очереди добавлять правила, разрешая тот или иной необходимый трафик.

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

Разрешаем ssh-доступ к серверу

Какими критериями мы можем манипулировать:

  • Протокол - tcp
  • Порт получателя - 22
  • IP-адрес получателя - адрес нашего сервера 192.168.0.1
  • IP-адрес отправителя - наш адрес 192.168.0.2

Наше правило будет выглядеть так:

iptables -A INPUT -p tcp -d 192.168.0.1 -s 192.168.0.2 --dport 22 -j ACCEPT
iptables -A OUTPUT -p tcp -s 192.168.0.1 -d 192.168.0.2 --sport 22 -j ACCEPT

Все очень просто. Результат можно сразу посмотреть iptables -nvL

Устанавливаем политики по-умолчанию на "отбрасывание"

Если мы все сделали правильно, то можно приступать к блокировке политик по-умолчанию:

iptables -P INPUT DROP
iptables -P OUTPUT DROP

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

Что мы получили: сервер, у которого открыт на прием только 22 порт протокола tcp и только для компьютера 192.168.0.2 плюс на отдачу только с 22 порта протокола tcp и только для компьютера 192.168.0.2. Очень защищенный сервер. Далее по аналогии можно открывать/закрывать те или иные соединения.

Обратите внимание на особенности некоторых соединений, а именно: ftp и pptp (vpn).

Раньше я думал, что для соединения по протоколу FTP необходимо два tcp порта: 20 и 21. Как оказалось, не все так просто. При соединении на этих портах сервер и клиентская машина "созваниваются" и договариваются, на каком порту они будут работать дальше. То есть мы этого не можем знать заранее. Как же быть? У пакетов могут быть различные состояния, которые и могут нам помочь.

NEW. Признак NEW сообщает о том, что пакет является первым для данного соединения. Это означает, что это первый пакет в данном соединении, который увидел модуль трассировщика. Например если получен SYN пакет являющийся первым пакетом для данного соединения, то он получит статус NEW. Однако, пакет может и не быть SYN пакетом и тем не менее получить статус NEW. Это может породить определенные проблемы в отдельных случаях, но может оказаться и весьма полезным, например когда желательно "подхватить" соединения, "потерянные" другими брандмауэрами или в случаях, когда таймаут соединения уже истек, но само соединение не было закрыто.

RELATED. Состояние RELATED одно из самых "хитрых". Соединение получает статус RELATED если оно связано с другим соединением, имеющим признак ESTABLISHED. Это означает, что соединение получает признак RELATED тогда, когда оно инициировано из уже установленного соединения, имеющего признак ESTABLISHED. Хорошим примером соединения, которое может рассматриваться как RELATED, является соединение FTP-data, которое является связанным с портом FTP control, а так же DCC соединение, запущенное из IRC. Обратите внимание на то, что большинство протоколов TCP и некоторые из протоколов UDP весьма сложны и передают информацию о соединении через область данных TCP или UDP пакетов и поэтому требуют наличия специальных вспомогательных модулей для корректной работы.

ESTABLISHED. Состояние ESTABLISHED говорит о том, что это не первый пакет в соединении. Схема установки состояния ESTABLISHED достаточна проста для понимания. Единственное требование, предъявляемое к соединению, заключается в том, что для перехода в состояние ESTABLISHED необходимо чтобы узел сети передал пакет и получил на него ответ от другого узла (хоста). После получения ответа состояние соединения NEW или RELATED будет изменено на ESTABLISHED.

INVALID. Признак INVALID говорит о том, что пакет не может быть идентифицирован и поэтому не может иметь определенного статуса. Это может происходить по разным причинам, например при нехватке памяти или при получении ICMP-сообщения об ошибке, которое не соответствует какому либо известному соединению. Наверное наилучшим вариантом было бы применение действия DROP к таким пакетам.

RELATED и ESTABLISHED - это как раз наш случай. Соединение на 20 и 21 портах tcp протокола, разрешенное нашим файерволом, инициировало новое соединение на других портах. Команды, разрешающие трафик, подходящий под эти критерии, будут такими:

iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

Соединение по протоколу pptp (vpn) тоже имеет свои подводные камни. Идем в энциклопедию и видим:

«PPTP работает, устанавливая обычную PPP сессию с противоположной стороной с помощью протокола Generic Routing Encapsulation. Второе соединение на TCP-порту 1723 используется для инициации и управления GRE-соединением. PPTP сложно перенаправлять за сетевой экран, так как он требует одновременного установления двух сетевых сессий.»

Со вторым соединением все понятно - -p tcp --dport 1723 -j ACCEPT, а вот что это за GRE? Идем в /etc/protocols и видим
gre 47 GRE # General Routing Encapsulation

Обязательно нужно проверить, не закомментирована ли эта строчка (# в начале строки отсутствует). Хорошо, как нам теперь разрешить подключения по этому протоколу:

iptables -A INPUT -p 47 -j ACCEPT
iptables -A OUTPUT -p 47 -j ACCEPT

Пример скрипта

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

Создаем директорию /etc/iptables/ и в ней файл iptables.data. В этом файле мы опишем те необходимые данные, с которыми мы будем работать в скриптах файервола.

# Internet
INTIF="eth0"
INTIP="62.5.246.190"
INTMASK="255.255.255.240"
INTGW="62.5.246.189"
INTDNS1="62.5.246.105"
INTDNS2=$INTGW

# Localnet
LANIF="eth1"
LANIP="192.168.0.1"
LANMASK="255.255.255.0"
LAN="192.168.0.0/24"

# LoopBack
LOIF="lo"
LOIP="127.0.0.1"
LOMASK="255.0.0.0"
LO="127.0.0.0/8"

# Ports
SSH="22"
HTTP="80"
DNS="53"
SMTP="25"
POP3="110"
FTP="20:21"

Следующим будет файл с функциями /etc/iptables/iptables.rules

#!/bin/sh
ipt_clear()
{
echo -n " Clearing rules, stoping firewall"
$IPT -t filter -F
$IPT -t filter -X
$IPT -t nat -F
$IPT -t nat -X
}

start_nat()
{
$IPT -t nat -A POSTROUTING -o $INTIF -s $LAN1 -j MASQUERADE
}

start_wall()
{
echo -n " Closing ports"
$IPT -P INPUT DROP
$IPT -P FORWARD ACCEPT
$IPT -P OUTPUT DROP
success
}

start_nowall()
{
echo -n " Opening all ports"
$IPT -P INPUT ACCEPT
$IPT -P FORWARD ACCEPT
$IPT -P OUTPUT ACCEPT
}


start_input_open()
{
# Open all ports for lo (127.0.0.0/8)
$IPT -A INPUT -s $LO -d $LOIP -i $LOIF -j ACCEPT

# Open all ports for localnet (192.168.2.0/24)
$IPT -A INPUT -s $LAN -d $LANIP -j ACCEPT

# ssh
$IPT -A INPUT -p tcp --sport 22 -j ACCEPT
$IPT -A INPUT -p tcp --sport 2222 -j ACCEPT

# sshd
$IPT -A INPUT -p tcp -d $FTPIP --dport $SSH -j ACCEPT

# pptpd
$IPT -A INPUT -i $INTIF -p 47 -j ACCEPT
$IPT -A INPUT -p tcp --dport $PPTPD -j ACCEPT

# DNS
$IPT -A INPUT -p udp --sport $DNS -j ACCEPT
$IPT -A INPUT -p tcp --sport $DNS -j ACCEPT

# DNS (NAMED, BIND9)
$IPT -A INPUT -p udp --dport $DNS -j ACCEPT
$IPT -A INPUT -p tcp --dport $DNS -j ACCEPT

# http
$IPT -A INPUT -p tcp --sport $HTTP -j ACCEPT

# apache
$IPT -A INPUT -p tcp --dport $HTTP -j ACCEPT
}

start_output_open()
{
# Open all ports for lo (127.0.0.0/8)
$IPT -A OUTPUT -d $LO -s $LOIP -o $LOIF -j ACCEPT

# Open all ports for localnet (192.168.2.0/24)
$IPT -A OUTPUT -d $LAN -s $LANIP -j ACCEPT

# ssh
$IPT -A OUTPUT -p tcp --dport 22 -j ACCEPT
$IPT -A OUTPUT -p tcp --dport 2222 -j ACCEPT

# sshd
$IPT -A OUTPUT -p tcp -s $FTPIP --sport $SSH -j ACCEPT

# pptpd
$IPT -A OUTPUT -o $INTIF -p 47 -j ACCEPT
$IPT -A OUTPUT -p tcp --sport $PPTPD -j ACCEPT

# DNS
$IPT -A OUTPUT -p udp --dport $DNS -j ACCEPT
$IPT -A OUTPUT -p tcp --dport $DNS -j ACCEPT

# DNS (NAMED, BIND9)
$IPT -A OUTPUT -p udp --sport $DNS -j ACCEPT
$IPT -A OUTPUT -p tcp --sport $DNS -j ACCEPT

# http
$IPT -A OUTPUT -p tcp --dport $HTTP -j ACCEPT

# apache
$IPT -A OUTPUT -p tcp --sport $HTTP -j ACCEPT
}

и так далее по образу и подобию. А теперь создаем файл /etc/init.d/rc.iptables и редактируем его.

#!/bin/sh

DIR=/etc/iptables/
. $DIR/iptables.rules
. $DIR/iptables.data

case "$1" in
start)
start_wall
start_input_open
start_output_open
start_nat
;;
stop)
start_nowall
;;
restart)
$0 stop
$0 start
;;
save)
iptables-save > /etc/iptables/rules-save
;;
load)
cat /etc/iptables/rules-save | iptables-restore
;;
status)
$IPT -L -n -v
;;
*)
echo -e "\n rc.iptables - firewall script"
echo " Usage:"
echo " rc.iptables start"
echo " rc.iptables stop"
echo " rc.iptables restart"
echo " rc.iptables save"
echo " rc.iptables load"
echo " rc.iptables status"
;;
esac

Сначала мы указали в скрипте, какие дополнительные файлы подключить. Без этого система выдаст нам ошибку "не знаю что за функция start_wall", равно как и остальные функции. После этого мы делаем выбор входного параметра. Любой скрипт можно запускать передав ему параметр или параметры опциями. Делается это так: /etc/init.d/somescript option1 option2 option3. В нашем случае мы хотим сделать так, чтобы запуск с опцией start запускал наш файервол, stop - останавливал, restart - перезапускал, save - сохранил, load - загрузил, status - показал состояние файервола. Работать с входными параметрами можно через сочетание символов $1 – первый входной параметр, $2 – второй, и так далее. При вводе опции load у нас выполняется комманда cat /etc/iptables/rules-save | iptables-restore, это означает, что сначала мы выводим содержимое файла, а затем перенаправляем его в другую комманду. После многочисленных проверок ставим скрипт в автозагрузку системы.

 
Магазин коллективных покупок, купоны на скидку в Москве Mos-Holidays. Ru. пленка ПВХ, неликвидные остатки химической продукции со складов заводов