"Огненная стена" или строим файрвол на базе iptables Версия для печати   


1. Установка netfilter/iptables.
В комплект поставки любого современного дистрибутива Linux (с версией ядра 2.4.x и 2.6.x) входит система сетевой защиты netfilter/iptables. Основная часть кода этих программных продуктов непосредственно включена в код ядра, а часть - исполняемые файлы, библиотеки, устанавливается в виде обычных файлов. Если вы используете достаточно современный дистрибутив, не собираетесь использовать экзотического программного обеспечения и не предъявляете жесткиx требований к безопасности, то скорее всего вы сможете ограничиться возможностями rpm-пакетов, входящих в комплект поставки дистрибутива. Проверьте, установлен ли пакет iptables:
[root@homerouter root]# rpm -qa | grep iptables
iptables-1.2.6a-1.asp
Если пакет не установлен, то установите его:
[root@homerouter root]# rpm -ihv iptables-version.rpm
Если у поставщика дистрибутива или сторонних производителей имеется более свежая версия пакета, то обновите его:
[root@homerouter root]# rpm -Uhv iptables-version.rpm
При этом может потребоваться установка пакетов, удовлетворяющих зависимости, например, пакетов, содержащих исходные коды ядра.

Если вы уверены в своих силах, то более правильным будет установка netfilter/iptables из исходных кодов, при этом вы сможете:
- использовать последнюю (наиболее надежную, понравившуюся вам и т.п.) версию netfilter/iptables;
- избавиться от зависимости от поставщика дистрибутива и сторонних производителей rpm-пакетов;
- повысить производительность и надежность вашей системы за счет включения в нее тех и только тех фрагментов кода netfilter/iptables, которые нужны для решения только ваших задач;
- использовать (изучить, протестировать и т.п.) новые возможности фильтрации и управления пакетами, имеющиеся в последних версиях netfilter/iptables.

Для установки netfilter/iptables как минимум необходимы следующие пакеты:
- архив с исходными кодами iptables-version.tar.bz2, которые могут быть получены с сервера разработчиков (алиас );
- патч для модификации исходных кодов ядра patch-o-matic-YYYYMMDD.tar.bz2, который так же может быть получен с ;
- архив с исходными кодами ядра linux-version.tar.bz2 , который может быть получен с ;
- контрольные значения md5sum или GPG сигнатур ( ) для всех приведенных выше архивов с исходными кодами.
Для установки netfilter/iptables из исходных кодов необходимо выполнить следующие операции. Приведенное ниже описание инсталляции было протестировано на ASPLinux 7.3, для ядер версии 2.4.18, 2.4.25.

Шаг 1
Проверьте целостность и подлинность скачанных архивов - patch-o-matic-YYYYMMDD.tar.bz2, iptables-version.tar.bz2, linux-version.tar.bz2 с использованием md5sum или GPG сигнатур. Подробно процедура проверки целостности и подлинности описана здесь .

Шаг 2
Распакуйте исходные коды ядра в каталоге /usr/src:
[root@homerouter src]# bzip2 -d linux-version.tar.bz2
[root@homerouter src]# tar xpf linux-version.tar.bz2

Шаг 3
Определите, какие фрагменты кода, с точки зрения решаемых вами задач, и в каком виде (модули или монолитно) должны быть включены в новое ядро. На работоспособность и функциональные возможности netfilter/iptables в основном влияют параметры конфигурации исходных кодов ядра в разделах:
Networking options;
IP: Netfilter Configuration.
Подробное описание всех опций конфигурации, используемых в этих разделах, содержатся в исходных кодах ядра. В ядре версии 2.4.x в файле Documentation/Configure.help, в версии 2.6.x в файлах /net/ipv4/Kconfig и net/ipv4/netfilter/Kconfig.

Шаг 4
Разработка netfilter/iptables и ядра ведутся разными, но взаимодействующими между собой, командами разработчиков. Части кода netfilter/iptables, по мнению разработчиков должны быть включены в ядро, содержатся в патче patch-o-matic-YYYYMMDD (патч patch-o-matic-20031219 применим только к ядрам ветви 2.4 версии 2.4.17 и старше). Некоторые из этих изменений принимаются разработчиками ядра и включаются в последующие версии, некоторые не принимаются разработчиками ядра и вы можете использовать их на свой страх и риск. Дополнительная информация может быть найдена в документации ion-howto .
Патчи входящие в состав patch-o-matic-YYYYMMDD делятся на ряд категорий, при этом наиболее часто используемыми на практике являются:
- optimizations - оптимизационные патчи, включение которых в коды ядра ожидается;
- pending - патчи, включение которых в коды ядра ожидается;
- submitted - патчи, включенные в последнюю (на момент выхода patch-o-matic) версию ядра;
- base - патчи, мнению разработчиков netfilter/iptables, без проблем взаимодействующие друг с другом.

Для применения патча patch-o-matic-YYYYMMDD необходимо выполнить следующие операции.
Раскройте архив с исходными кодами patch-o-matic.
[root@homerouter iptables]# bzip2 -d patch-o-matic-20031219.tar.bz2
[root@homerouter iptables]# tar xpvf patch-o-matic-20031219.tar
перейдите во вновь созданный каталог:
[root@homerouter iptables]# cd patch-o-matic
и запустите сценарий runme, сообщив ему где находятся исходные коды ядра и какую категорию патчей вы желаете использовать, например:
[root@homerouter patch-o-matic]# KERNEL_DIR=/usr/src/linux-2.4.25 ./runme pending
далее в рамках диалога вам будет предложено протестировать применимость, установить или пропустить установку всех патчей из выбранной ранее категории (процесс напоминает конфигурирование исходных кодов ядра при использовании make config).
По окончании внесения изменений в исходные коды, откомпилируйте и проинсталлируйте ядро, проверьте его работоспособность.

Шаг 5
Удалите, если они установлены, пакеты iptables, ipchains и используцемые вместе с ними конфигураторы системы сетевой защиты.

Шаг 6
Распакуйте архив с частью исходных кодов iptables/netfilter устанавливаемых в виде обычных файлов:
[root@homerouter iptables]# bzip2 -d iptables-1.2.9.tar.bz2
[root@homerouter iptables]# tar xpvf iptables-1.2.9.tar
Перейдите во вновь созданный каталог:
[root@homerouter iptables]# cd iptables-1.2.9
Откомпилируйте и проинсталируйте iptables/netfilter, создайте и сохраните список проинсталлированных файлов:
[root@homerouter iptables-1.2.9]# make KERNEL_DIR=/usr/src/linux-2.4.25 BINDIR=/sbin LIBDIR=/lib/ MANDIR=/usr/share/man/
[root@homerouter iptables-1.2.9]# find /* > ../iptables1
[root@homerouter iptables-1.2.9]# make KERNEL_DIR=/usr/src/linux-2.4.25 BINDIR=/sbin LIBDIR=/lib/ MANDIR=/usr/share/man/ install
[root@homerouter iptables-1.2.9]# find /* > ../iptables2
[root@homerouter iptables-1.2.9]# cd ..
[root@homerouter iptables]# diff iptables1 iptables2 > iptables.installed.YYYY.MM.YY

Шаг 7
Создайте файл сценария /etc/init.d/iptables, содержащий:
как минимум две строки необходимые для нормальной работы утилиты chkconfig, содержащей информацию о уровнях на которых должен работать netfilter/iptables, приоритетности выполнения сценария при загрузке и разгрузке системы:
# chkconfig: 2345 08 98
# description: Start and stop filtering and mangling packets;
команды загрузки модулей netfilter/iptables (если соотвествующие фрагменты кода не вкомпилированы непосредственно в ядро) вида:
/sbin/modprobe <имя модуля>;
команды, передающие ядру определенные параметры, например, для включения пересылки пакетов между различными сетевыми интерфейсами, необходимыми для нормальной работы шлюза используется команда:
/sbin/sysctl -w net.ipv4.ip_forward = 1
команды, реализующие фильтрацию и другие манипуляции с пакетами, которые в общем случае имеют вид:
/sbin/iptables <строка с правилом>
методология формирования правил приведена ниже.

Шаг 8
Определите права доступа и владельца файла /etc/init.d/iptables:
[root@homerouter iptables]# chmod 700 /etc/init.d/iptables
[root@homerouter iptables]# chown root.root /etc/init.d/iptables

Шаг 9
Если вы хотите, что бы netfilter/iptables запускался при загрузке системы (это в большинстве случаев правильное решение) создайте соответствующие ссылки:
[root@homerouter iptables]# chkconfig --add iptables

2. Инициализация брандмауэра.
Работой брадмауэра управлет набор правил, которые определяются с помощью опций программы iptables. Инициализация брандмауэра включает в себя следующие операции: определение констант, используемых при работе сценария; удаление существующих правил из сценария; определение политики по умолчанию; востановление состояния интерфейса обратной петли, используемого для выполнения системных операций; блокирование узлов,доступ к которым вы собираетесь запретить; определение основных правил, предотвращающих прохождение пакетов с некорректными адресами источника и защищающих серверы, работающие через непривелигерованные порты.

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

 
IPT="/sbin/iptables" 
IPTS="/sbin/iptables-save" 
IPTR="/sbin/iptables-restore" 
 
EXTERNAL_INTERFACE="eth0"	# интерефейс подключенный к интеренету 
LOOPBACK_INTERFACE='lo'		# интерфейс обратной петли 
IP_ADDR="213.87.X.X"		# IP-адрес вашего компьютера 
ANYWHERE="any/0"			# произвольный IP-адрес 
MY_ISP="my.isp.address.range"	# диапазон IP-адресов провайдера 
LOOPBACK="127.0.0.0/8"		# диапазон IP-адресов обратной петли 
CLASS_A="10.0.0.0/8"	# адреса класса А, предназначенные для
                        # внутреннего использования 
CLASS_B="172.16.00/22"	# адреса класса B, предназначенные для              
                        # внутреннего использования 
CLASS_C="192.168.0.0/16"# адреса класса C, предназначенные для
                        # внутреннего использования 
CLASS_D="244.0.0.0/4"	# адреса класса А, предназначенные для
                        # группового вещания 
CLASS_E="240.0.0.0/5"	# зарезервированные адреса класса Е  
BROADCAST_SRC="0.0.0.0"	# исходный широковещательный 
BROADCAST_DST="255.255.255.255"# целевой широковешательные 
PRIVPORTS="0:1023"      # номера привелегированных портов 
UNPRIPORTS="1024:65535"	# номера непривелегированных портов 


Удаление существующих правил и установка политики по умолчанию.
# Сбрасываеим все правила  
$IPT -P INPUT ACCEPT 
$IPT -P FORWARD ACCEPT 
$IPT -P OUTPUT ACCEPT 
$IPT -t nat -P PREROUTING ACCEPT 
$IPT -t nat -P POSTROUTING ACCEPT 
$IPT -t nat -P OUTPUT ACCEPT 
$IPT -t mangle -P PREROUTING ACCEPT 
$IPT -t mangle -P OUTPUT ACCEPT 
# Удаление правил  
$IPT -F 
$IPT -t nat -F 
$IPT -t mangle -F 
# Очищаем нестандартные правила 
$IPT -X 
$IPT -t nat -X 
$IPT -t mangle -X 


Теперь когда сброс всех правил осуществен, необходимо определить политику брандмауэра по умолчанию. Есть несколько вариантов начальной политики, и вам выбирать. Мой десктоп, не имеющий за собой локальной сети имеет политику по умолчанию
 
$IPT -P INPUT DROP 
$IPT -P FORWARD DROP 
$IPT -P OUTPUT DROP 
$IPT -A INPUT -p ALL -i $LOOPBACK_INTERFACE -j ACCEPT 
$IPT -A OUTPUT -p ALL -o $LOOPBACK_INTERFACE -j ACCEPT 


Написание правил на что не забыть обратить внимание.

А начать придется с сождания собственных Таблиц. А так же написать правила запрещающие прохождение через интерфей EXTERNAL_INTERFACE любой информации от сетей CLASS_A, СLASS_B, CLASS_C,
 
$IPT -N bad_packets 
$IPT -N bad_tcp_packets 
$IPT -N icmp_packets 
$IPT -N udp_inbound 
$IPT -N udp_outbound 
$IPT -N tcp_inbound 
$IPT -N tcp_outbound 

3. Атаки с целью вывода системы из строя.
Атака произволится путем "наводнения" системы пакетами определенного типа.

SYN - наводнение (Syn Flooding)
Приводит к связыванию системных ресурсов, так что реальных обмен данными становится не возможным. Клиентская часть с ложным IP-адресом отправляет SYN пакет и сервер отвечает SYN-ACK, но так как адрес был ложным таким образом соединединие не устанавливается и остается в "полуоткрытом состоянии"

Подробности по теме :
ftp://info.cert.org./pub/cert_advisories/CA-96.21.tcp_syn_fl ooding

 
$IPT -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j LOG \ 
    --log-prefix "fp=bad_tcp_packets:1 a=DROP " 
$IPT -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j DROP 
 
# All good, so return 
$IPT -A bad_tcp_packets -p tcp -j RETURN 


ping - наводнение

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

Подробности по теме :
Denial of Service
 
$IPT -A icmp_packets --fragment -p ICMP -j LOG \ 
    --log-prefix "fp=icmp_packets:1 a=DROP " 
$IPT -A icmp_packets --fragment -p ICMP -j DROP 

UDP - наводнение
Службы использующие UDP, очень часто становятся мишенью для атак с целью вывода системы из строя. В отличие от ТСР, в протоколе UDP не придусмотрено установление соединения, поэтому флаги, определяющие состояние соединения, отсутствуют. Принимающий узел не имеет ни какой информации щ ещь какой пакет должен следовать за только что принятым. Таким образом возникакет возможность организовать атаку таким образом, что вся пропускная способность линии будет использоваться только на передачу ответов на поступающие UDP -пакет..
Подробности по теме :
UDP Port Denial-of-Service attack
 
$IPT -A udp_inbound -p UDP -s 0/0 --destination-port 137 -j DROP 
$IPT -A udp_inbound -p UDP -s 0/0 --destination-port 138 -j DROP 
$IPT -A udp_inbound -p UDP -s 0/0 --destination-port 113 -j REJECT 
$IPT -A udp_inbound -p UDP -s 0/0 --source-port 67 --destination-port 68 \ 
     -j ACCEPT 
$IPT -A udp_inbound -p UDP -j RETURN 
$IPT -A udp_outbound -p UDP -s 0/0 -j ACCEPT 

ICMP - перенаправление

ICMP- сообщение типа 5 указывает системе изменить содержимое таблиц маршрутизации с тем, что бы направлять пакеты по более короткому маршруту. Если вы используете routed или gated. То не забывайте, что есть возможность перенаправления трафика на удаленную машину, а так же для взломшика есть возможность определить свою машину, как одну из вашил локальных, стояших за сервером.
 
$IPT -A icmp_packets --fragment -p ICMP -j LOG \ 
    --log-prefix "fp=icmp_packets:1 a=DROP " 
$IPT -A icmp_packets --fragment -p ICMP -j DROP 
 
# Echo - uncomment to allow your system to be pinged. 
# Uncomment the LOG command if you also want to log PING attempts 
# 
# $IPT -A icmp_packets -p ICMP -s 0/0 --icmp-type 8 -j LOG \ 
#    --log-prefix "fp=icmp_packets:2 a=ACCEPT " 
# $IPT -A icmp_packets -p ICMP -s 0/0 --icmp-type 8 -j ACCEPT 
 
# Time Exceeded 
$IPT -A icmp_packets -p ICMP -s 0/0 --icmp-type 11 -j ACCEPT 
 
# Not matched, so return so it will be logged 
$IPT -A icmp_packets -p ICMP -j RETURN



4. NAT в IPTables.
Маскарадинг (masquerading) и трансляция ip-адресов (NAT) в Linux. Что это такое, что можно и что нельзя.

Если у Вас есть локальная сеть, подключенная к сети Интернет через linux сервер, и в этой локальной сети используются «серые» ip адреса, то одним из способов выхода в Интернет может стать использование NAT. Или наоборот, с помощью NAT можно осуществить доступ из Интернет например к web серверу расположенному в локальной сети и не имеющему реального ip-адреса.

Этот документ содержит несколько терминов, которые следует пояснить прежде, чем вы столкнетесь с ними.

1. «Серый» IP адрес (он же приватный, он же фейковый он же частный) - IP адрес из специально выделенных подсетей, которые не используются в сети Интернет, и зарезервированы для использования в локальных сетях (intranet). В каждом классе (A B С) зарезервировано по одной подсети:

Класс А 10.0.0.0 - 10.255.255.255
Класс B 172.16.0.0 - 172.31.255.255
Класс C 192.168.0.0 - 192.168.255.255

2. «Белый» IP адрес (он же реальный, он же публичный) – IP адрес, не входящий в «серые» подсети и использующийся в сети Интернет.

3. Маскарад (MASQUERADE) - замена сетевого адреса получателя в заголовке пакета на адрес, находящийся на исходящем интерфейсе машины, выполняющей маскарад, и соответственно обратная операция при получении ответного пакета. Маскарад применяется в тех же целях, что и SNAT, но в отличие от последней, MASQUERADE дает более сильную нагрузку на систему. Происходит это потому, что каждый раз, когда требуется выполнение этого действия - производится запрос IP адреса для указанного в действии сетевого интерфейса, в то время как для SNAT IP адрес указывается непосредственно. Однако, благодаря такому отличию, MASQUERADE может работать в случаях с динамическим IP адресом, т.е. когда вы подключаетесь к Интернет, скажем через PPP, SLIP или DHCP.

4. Трансляция адресов (NAT – network address translation) – замена сетевого адреса получателя в заголовке пакета на любой указанный, и соответственно обратная операция при получении ответного пакета.

5. DNAT - от англ. Destination Network Address Translation - изменение сетевого адреса получателя. DNAT - это изменение адреса назначения в заголовке пакета. Зачастую используется в паре с SNAT. Основное применение - предоставление дополнительных сетевых услуг внешним клиентам.

6. SNAT - от англ. Source Network Address Translation - изменение сетевого адреса отправителя. SNAT - это изменение исходного адреса в заголовке пакета. Основное применение - использование единственного реального IP-адреса несколькими компьютерами для выхода в Интернет.

Общие положения

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

Порядок движения транзитных пакетов в iptables.

В упрощенном варианте, касающемся NAT, это выглядит так – кабель – сетевой интерфейс – цепочка PREROUTING таблицы nat – принятие решения о маршрутизации – цепочка POSTROUTING таблицы nat – сетевой интерфейс.

Как вы можете видеть, пакет проходит несколько этапов, прежде чем он будет передан далее. На каждом из них пакет может быть остановлен. Заметьте, что нет каких либо цепочек, специфичных для отдельных интерфейсов или чего-либо подобного. Цепочку FORWARD проходят ВСЕ пакеты, которые движутся ЧЕРЕЗ ваш роутер. Не используйте цепочку INPUT для фильтрации транзитных пакетов, они туда просто не попадают! Через эту цепочку движутся только те пакеты, которые предназначены данному хосту!

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

modprobe iptable_nat

Для трансляции некоторых определенных протоколов необходимо загрузить дополнительные модули – например для ftp это модуль ip_nat_ftp.

Так как при перезагрузке эти команды сбросятся то их необходимо прописать в автозагрузку, например в / etc/ rc. d/ rc. local.

Так как все операции необходимые для трансляции адресов происходят в таблице nat и двух ее цепочках – PREROUTING и POSTROUTING, то мы рассматриваем только их.

Цепочка POSTROUTING

Действие SNAT

SNAT используется для преобразования сетевых адресов (Source Network Address Translation), т.е. изменения исходящего IP адреса в IP заголовке пакета. Например, это действие можно использовать для предоставления выхода в Интернет другим компьютерам из локальной сети, имея лишь один реальный IP адрес. Для этого необходимо включить пересылку пакетов (forwarding) в ядре и затем создать правила, которые будут транслировать исходящие IP адреса нашей локальной сети в реальный внешний адрес. В результате, внешний мир ничего не будет знать о нашей локальной сети, он будет считать, что запросы пришли с нашего брандмауэра.
SNAT допускается выполнять только в таблице nat, в цепочке POSTROUTING. Другими словами, только здесь допускается преобразование исходящих адресов. Если первый пакет в соединении подвергся преобразованию исходящего адреса, то все последующие пакеты, из этого же соединения, будут преобразованы автоматически и не пойдут через эту цепочку правил.

Ключ -- to- source

Пример:

iptables - t nat - A POSTROUTING - p tcp - o eth0 - j SNAT -- to- source 194.236.50.155-194.236.50.160:1024-32000
Ключ -- to- source используется для указания адреса, который присваивается пакету. Все просто, вы указываете IP адрес, который будет подставлен в заголовок пакета в качестве исходящего. Если вы собираетесь перераспределять нагрузку между несколькими брандмауэрами, то можно указать диапазон адресов, где начальный и конечный адреса диапазона разделяются дефисом, например: 194.236.50.155-194.236.50.160. Тогда, конкретный IP адрес будет выбираться из диапазона случайным образом для каждого нового потока. Дополнительно можно указать диапазон портов, которые будут использоваться только для нужд SNAT. Все исходящие порты будут после этого перекартироваться в заданный диапазон. Если диапазон портов не задан, то исходные порты ниже 512 перекартируются в диапазоне 0-511, порты в диапазоне 512-1023 перекартируются в диапазоне 512-1023, и, наконец порты из диапазона 1024-65535 перекартируются в диапазоне 1024-65535. Что касается портов назначения, то они не подвергаются перекартированию.

Действие MASQUERADE

Маскарадинг в основе своей представляет то же самое, что и SNAT только не имеет ключа --to-source. Причиной тому то, что маскарадинг может работать, например, с dialup подключением или DHCP, т.е. в тех случаях, когда IP адрес присваивается устройству динамически. Если у вас имеется динамическое подключение с меняющимся ip адресом, то нужно использовать маскарадинг, если же у вас статическое IP подключение, то бесспорно лучшим выходом будет использование действия SNAT.
Маскарадинг подразумевает получение IP адреса от заданного сетевого интерфейса, вместо прямого его указания, как это делается с помощью ключа --to-source в действии SNAT. Действие MASQUERADE имеет хорошее свойство - "забывать" соединения при остановке сетевого интерфейса.

Действие MASQUERADE допускается указывать только в цепочке POSTROUTING таблицы nat, так же как и действие SNAT. MASQUERADE имеет ключ, описываемый ниже, использование которого необязательно.

Ключ --to-ports

Пример:

iptables -t nat -A POSTROUTING -p TCP -j MASQUERADE --to-ports 1024-31000
Ключ --to-ports используется для указания порта источника или диапазона портов исходящего пакета. Можно указать один порт, например: --to-ports 1025, или диапазон портов как здесь: --to-ports 1024-3000. Этот ключ можно использовать только в правилах, где критерий содержит явное указание на протокол TCP или UDP с помощью ключа -- protocol.

Цепочка PREROUTING

В данной цепочке выполняется преобразование сетевых адресов (DNAT) перед тем как пакеты попадут в цепочку INPUT или FORWARD.

Действие DNAT

DNAT (Destination Network Address Translation) используется для преобразования адреса места назначения в IP заголовке пакета. Если пакет подпадает под критерий правила, выполняющего DNAT, то этот пакет, и все последующие пакеты из этого же потока, будут подвергнуты преобразованию адреса назначения и переданы на требуемое устройство, хост или сеть. Данное действие может, к примеру, успешно использоваться для предоставления доступа к вашему web-серверу, находящемуся в локальной сети, и не имеющему реального IP адреса. Для этого вы строите правило, которое перехватывает пакеты, идущие на HTTP порт брандмауэра и выполняя DNAT передаете их на локальный адрес web-сервера. Для этого действия так же можно указать диапазон адресов, тогда выбор адреса назначения для каждого нового потока будет производиться случайным образом.
Действие DNAT может выполняться только в цепочках PREROUTING и OUTPUT таблицы nat, и во вложенных под-цепочках. Важно запомнить, что вложенные подцепочки, реализующие DNAT не должны вызываться из других цепочек, кроме PREROUTING и OUTPUT.

К люч --to-destination

Пример :

iptables -t nat -A PREROUTING -p tcp -d 15.45.23.67 --dport 80 -j DNAT --to-destination 192.168.1.1-192.168.1.10

Ключ -- to - destination указывает, какой IP адрес должен быть подставлен в качестве адреса места назначения. В выше приведенном примере во всех пакетах, пришедших на адрес 15.45.23.67, адрес назначения будет изменен на один из диапазона от 192.168.1.1 до 192.168.1.10. Как уже указывалось выше, все пакеты из одного потока будут направляться на один и тот же адрес, а для каждого нового потока будет выбираться один из адресов в указанном диапазоне случайным образом. Можно также определить единственный IP адрес. Можно дополнительно указать порт или диапазон портов, на который (которые) будет перенаправлен траффик. Для этого после ip адреса через двоеточие укажите порт, например --to-destination 192.168.1.1:80, а указание диапазона портов выглядит так: --to-destination 192.168.1.1:80-100. Указание портов допускается только при работе с протоколом TCP или UDP, при наличии опции --protocol в критерии.
Действие DNAT достаточно сложно в использовании и требует дополнительного пояснения. Рассмотрим простой пример. У нас есть WEB сервер и мы хотим разрешить доступ к нему из Интернет. Мы имеем только один реальный IP адрес, а WEB-сервер расположен в локальной сети. Реальный IP адрес $INET_IP назначен брандмауэру, HTTP сервер имеет локальный адрес $HTTP_IP и, наконец брандмауэр имеет локальный адрес $LAN_IP. Для начала добавим простое правило в цепочку PREROUTING таблицы nat:
iptables -t nat -A PREROUTING --dst $INET_IP -p tcp --dport 80 -j DNAT \
--to-destination $HTTP_IP

В соответствии с этим правилом, все пакеты, поступающие на 80-й порт адреса $INET_IP перенаправляются на наш внутренний WEB-сервер. Если теперь обратиться к WEB-серверу из Интернет, то все будет работать прекрасно. Но что же произойдет, если попробовать соединиться с ним из локальной сети? Соединение просто не установится. Давайте посмотрим как маршрутизируются пакеты, идущие из Интернет на наш WEB-сервер. Для простоты изложения примем адрес клиента в Интернет равным $EXT_BOX.
1. Пакет покидает клиентский узел с адресом $EXT_BOX и направляется на $INET_IP

2. Пакет приходит на наш брандмауэр.

3. Брандмауэр, в соответствии с вышеприведенным правилом, подменяет адрес назначения и передает его дальше, в другие цепочки.

4. Пакет передается на $HTTP_IP.

5. Пакет поступает на HTTP сервер и сервер передает ответ через брандмауэр, если в таблице маршрутизации он обозначен как шлюз для $EXT_BOX. Как правило, он назначается шлюзом по-умолчанию для HTTP сервера.

6. Брандмауэр производит обратную подстановку адреса в пакете, теперь все выглядит так, как будто бы пакет был сформирован на брандмауэре.

7. Пакет передается клиенту $EXT_BOX.

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

1. Пакет покидает $LAN_BOX.

2. Поступает на брандмауэр.

3. Производится подстановка адреса назначения, однако адрес отправителя не подменяется, т.е. исходный адрес остается в пакете без изменения.

4. Пакет покидает брандмауэр и отправляется на HTTP сервер.

5. HTTP сервер, готовясь к отправке ответа, обнаруживает, что клиент находится в локальной сети (поскольку пакет запроса содержал оригинальный IP адрес, который теперь превратился в адрес назначения) и поэтому отправляет пакет непосредственно на $LAN_BOX.

6. Пакет поступает на $LAN_BOX. Клиент "путается", поскольку ответ пришел не с того узла, на который отправлялся запрос. Поэтому клиент "сбрасывает" пакет ответа и продолжает ждать "настоящий" ответ.

Проблема решается довольно просто с помощью SNAT. Ниже приводится правило, которое выполняет эту функцию. Это правило вынуждает HTTP сервер передавать ответы на наш брандмауэр, которые затем будут переданы клиенту.
iptables -t nat -A POSTROUTING -p tcp --dst $HTTP_IP --dport 80 -j SNAT \
--to-source $LAN_IP

Так как цепочка POSTROUTING обрабатывается самой последней и к этому моменту пакет уже прошел процедуру преобразования DNAT, поэтому критерий строится на базе адреса назначения $HTTP_IP.

Если вы думаете, что на этом можно остановиться, то вы ошибаетесь! Представим себе ситуацию, когда в качестве клиента выступает сам брандмауэр. Тогда, к сожалению, пакеты будут передаваться на локальный порт с номером 80 самого брандмауэра, а не на $HTTP_IP. Чтобы разрешить и эту проблему, добавим правило:
iptables -t nat -A OUTPUT --dst $INET_IP -p tcp --dport 80 -j DNAT \
--to-destination $HTTP_IP

Действие REDIRECT

Действие REDIRECT выполняет перенаправление пакетов и потоков на другой порт той же самой машины. К примеру, можно пакеты, поступающие на HTTP порт перенаправить на порт HTTP proxy. Действие REDIRECT очень удобно для выполнения "прозрачного" проксирования (transparent proxying), когда машины в локальной сети даже не подозревают о существовании прокси.

REDIRECT может использоваться только в цепочках PREROUTING и OUTPUT таблицы nat.

Ключ : --to-ports

Пример :

iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080

Ключ --to-ports определяет порт или диапазон портов назначения. Без указания ключа --to-ports, перенаправления не происходит, т.е. пакет идет на тот порт, куда и был назначен. В примере, приведенном выше, --to-ports 8080 указан один порт назначения. Если нужно указать диапазон портов, то мы должны написать нечто подобное --to-ports 8080-8090. Этот ключ можно использовать только в правилах, где критерий содержит явное указание на протокол TCP или UDP с помощью ключа --protocol.

Вот мы и рассмотрели основные моменты касающиеся трансляции адресов с помощью linux iptables .

Советы и основные ошибки допускаемые при настройке NAT :

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

o проверить, разрешена ли пересылка пакетов в ядре linux (сделать это можно командой cat /proc/sys/net/ipv4/ip_forward и если Вы получили 1 на выходе значит все в порядке) и если она выключена, тогда Вам нужно включить ее командой echo 1 >/proc/sys/net/ipv4/ip_forward. Так как при перезагрузке компьютера эта команда сбросится, ее необходимо прописать куда-нибудь в автозагрузку, например в / etc / rc . d / rc . local . В дистрибутивах, поддерживающих функцию sysctl , автоматическое включение пересылки в ядре можно реализовать, прописав в /etc/sysctl.conf строкуВарварварвар
o добавить в цепочку FORWARD необходимые разрешения для нужных Вам сетей. Например если Вы хотите чтобы адреса из вашей локальной сети (192.168.0.0/24) могли пересылаться от локального интерфейса наружу и обратно, необходимо добавить две строки: iptables – A FORWARD -s 192.168.0.0/24 -j ACCEPT (этой командой вы разрешили прохождение пакетов между сетевыми интерфейсами из локальной сети 192.168.0.0/24) и iptables -A FORWARD -d 192.168.0.0/24 -j ACCEPT (этой командой вы разрешили прохождение пакетов между сетевыми интерфейсами в локальную сеть 192.168.0.0/24). После этого можно приступать собственно к реализации трансляции адресов.

2. Если «теоретически» все сделали правильно но ничего не работает:

o Сохраните все ваши правила iptables куда-нибудь в файл ( iptables - save >/ file . txt ) и просмотрите их. В iptables пакет обрабатывается первым подходящим для него правилом, и поэтому может быть что ваш пакет просто не доходит до тех правил, которые Вы ему назначаете.
o Используйте для проверки утилиты, входящие в состав дистрибутива, такие как ping , которая позволяет показать доступен тот или иной хост или нет, traceroute , позволяющая проследить маршрут прохождения пакетов до заданного хоста.

5. Пример скрипта iptables, позволяющего обеспечивать некоторый (вполне достаточный)уровень безопасности для одиночной рабочей станции.

Набор правил позволяет обеспечивать некоторый (вполне достаточный)уровень безопасности для одиночной рабочей станции(не для шлюза в домашнюю сеть).Поддерживается работа FTP и HTTP-серверов и наиболее употребительных клиентов в локальной сети и Интернет.
Для инсталляции сценария необходимо выполнить следующие операции

Шаг 1
Подредактировать сценарий всоответствии с решаемыми задачами и потребностями.

Шаг 2
Поместить сценарий в файл /etc/init.d/iptables

Шаг 3
Назначить владельцем файла пользователя root, установить права доступак файлу 700 и сделать его загружаемым автоматически при загрузке системы.

Пример скрипта iptables, позволяющего обеспечивать некоторый (вполне достаточный)уровень безопасности для одиночной рабочей станции(не для щлюза в семейную сеть). Скрипт нгужно подредактировать под свои параметры (см. комментарии) На RH-based дистрибутивах скрипт нужно положить скрипт в каталог /etc/init.d/, дать ему имя iptables, назначить его владельцем пользователя root, права доступа 700, и сделать его автоматически запускаемым при загрузке системы.



#!/bin/sh
#
# Invoked from /etc/rc.d/init.d/iptables.
# chkconfig: - 60 95
# description: Starts and stops the IPTABLES packet filter \
# used to provide firewall network services.

# Source function library.
. /etc/rc.d/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
if [ ${NETWORKING} = "no" ]
then
exit 0
fi

if [ ! -x /sbin/iptables ]; then
exit 0
fi

# See how we were called.
case "$1" in
start)
echo -n "Starting Firewalling: "

# ------------------------------------------------------------ ----------------
# Some definitions for easy maintenance.
# EDIT THESE TO SUIT YOUR SYSTEM AND ISP.

IPADDR="192.168.XXX.XXX"
EXTERNAL_INTERFACE="eth0" # Infoline connected interface
INTERNET_INTERFACE="ppp+" # Internet interface up when pptp up
LOOPBACK_INTERFACE="lo" # Your local naming convention
PRIMARY_NAMESERVER="194.135.60.3" # Your Primary Name Server
SECONDARY_NAMESERVER="194.135.61.3" # Your Secondary Name Server Internal Server
SMTP_SERVER="195.2.72.152" # Your Central Mail Hub Server

LOOPBACK="127.0.0.0/8" # Reserved loopback addr range
CLASS_A="10.0.0.0/8" # Class A private networks
CLASS_B="172.16.0.0/12" # Class B private networks
CLASS_C="192.168.0.0/16" # Class C private networks
CLASS_D_MULTICAST="224.0.0.0/4" # Class D multicast addr
CLASS_E_RESERVED_NET="240.0.0.0/5" # Class E reserved addr
BROADCAST_SRC="0.0.0.0" # Broadcast source addr
BROADCAST_DEST="255.255.255.255" # Broadcast destination addr
PRIVPORTS="0:1023" # Privileged port range
UNPRIVPORTS="1024:65535" # Unprivileged port range

# ------------------------------------------------------------ ----------------
# The SSH client starts at 1023 and works down to 513 for each
# additional simultaneous connection originating from a privileged port.
# Clients can optionally be configured to use only unprivileged ports.
SSH_LOCAL_PORTS="1022:65535" # Port range for local clients
SSH_REMOTE_PORTS="513:65535" # Port range for remote clients

# traceroute usually uses -S 32769:65535 -D 33434:33523
TRACEROUTE_SRC_PORTS="32769:65535"
TRACEROUTE_DEST_PORTS="33434:33523"
# ------------------------------------------------------------ ----------------

# Default policy is DENY
# Explicitly accept desired INCOMING & OUTGOING connections

# Remove all existing rules belonging to this filter
iptables -F

# Remove any existing user-defined chains.
iptables -X

# Set the default policy of the filter to deny.
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP

# ------------------------------------------------------------ ----------------
# LOOPBACK
# --------
# Unlimited traffic on the loopback interface.

iptables -A INPUT -i $LOOPBACK_INTERFACE -j ACCEPT
iptables -A OUTPUT -o $LOOPBACK_INTERFACE -j ACCEPT

# ------------------------------------------------------------ ----------------
# ------------------------------------------------------------ ----------------
#Для VPN
iptables -A INPUT -p 47 -m state --state ESTABLISHED,RELATED -i eth0 -j ACCEPT
iptables -A OUTPUT -p TCP --dport 1723 -o eth0 -j ACCEPT
iptables -A OUTPUT -p 47 -o eth0 -j ACCEPT

# ------------------------------------------------------------ ----------------
# Network Ghouls
# Deny access to jerks
# --------------------
# /etc/rc.d/rc.firewall.blocked contains a list of
# iptables -A INPUT -i $EXTERNAL_INTERFACE -s address -j DROP
# rules to block from any access.
# Refuse any connection from problem sites
if [ -f /etc/rc.d/rc.firewall.blocked ]; then
deny_file="/etc/rc.d/rc.firewall.blocked"
temp_file="/tmp/temp.ip.addresses"
cat $deny_file | sed -n -e "s/^[ ]*\([0-9.]*\).*$/\1/p" \
| awk ' $1 ' > $temp_file
while read ip_addy
do
case $ip_addy in
*) iptables -A INPUT -i $EXTERNAL_INTERFACE -s $ip_addy -j DROP
iptables -A INPUT -i $EXTERNAL_INTERFACE -d $ip_addy -j DROP
iptables -A OUTPUT -o $EXTERNAL_INTERFACE -s $ip_addy -j REJECT
iptables -A OUTPUT -o $EXTERNAL_INTERFACE -d $ip_addy -j REJECT
;;
esac
done < $temp_file
rm -f $temp_file > /dev/null 2>&1
unset temp_file
unset deny_file
fi

# ------------------------------------------------------------ ----------------
# SPOOFING & BAD ADDRESSES
# Refuse spoofed packets.
# Ignore blatantly illegal source addresses.
# Protect yourself from sending to bad addresses.
# Refuse incoming packets pretending to be from the external address.
iptables -A INPUT -s $IPADDR -j DROP
# Refuse incoming packets claiming to be from a Class A, B or C private network
iptables -A INPUT -s $CLASS_A -j DROP
iptables -A INPUT -s $CLASS_B -j DROP
#iptables -A INPUT -s $CLASS_C -j DROP

# Refuse broadcast address SOURCE packets
iptables -A INPUT -s $BROADCAST_DEST -j DROP
iptables -A INPUT -d $BROADCAST_SRC -j DROP

# Refuse Class D multicast addresses
# Multicast is illegal as a source address.
# Multicast uses UDP.
iptables -A INPUT -s $CLASS_D_MULTICAST -j DROP

# Refuse Class E reserved IP addresses
iptables -A INPUT -s $CLASS_E_RESERVED_NET -j DROP

# Refuse special addresses defined as reserved by the IANA.
# Note: The remaining reserved addresses are not included
# filtering them causes problems as reserved blocks are
# being allocated more often now. The following are based on
# reservations as listed by IANA as of 2001/01/04. Please regularly
# check at for the latest status.

# Note: this list includes the loopback, multicast, & reserved addresses.
# 0.*.*.* - Can't be blocked for DHCP users.
# 127.*.*.* - LoopBack
# 169.254.*.* - Link Local Networks
# 192.0.2.* - TEST-NET
# 224-255.*.*.* - Classes D & E, plus unallocated.

iptables -A INPUT -s 0.0.0.0/8 -j DROP
iptables -A INPUT -s 127.0.0.0/8 -j DROP
iptables -A INPUT -s 169.254.0.0/16 -j DROP
iptables -A INPUT -s 192.0.2.0/24 -j DROP
iptables -A INPUT -s 224.0.0.0/3 -j DROP

# ------------------------------------------------------------ ----------------
# UDP TRACEROUTE
# --------------
# Traceroute usually uses -S 32769:65535 -D 33434:33523
iptables -A INPUT -i $INTERNET_INTERFACE -p udp \
--source-port $TRACEROUTE_SRC_PORTS \
--destination-port $TRACEROUTE_DEST_PORTS -j DROP

iptables -A OUTPUT -o $INTERNET_INTERFACE -p udp \
--source-port $TRACEROUTE_SRC_PORTS \
--destination-port $TRACEROUTE_DEST_PORTS -j ACCEPT

#Для локалки
iptables -A INPUT -i $EXTERNAL_INTERFACE -p udp \
--source-port $TRACEROUTE_SRC_PORTS \
-d $IPADDR --destination-port $TRACEROUTE_DEST_PORTS -j DROP

iptables -A OUTPUT -o $EXTERNAL_INTERFACE -p udp \
-s $IPADDR --source-port $TRACEROUTE_SRC_PORTS \
--destination-port $TRACEROUTE_DEST_PORTS -j ACCEPT
# ------------------------------------------------------------ ----------------
# DNS forward-only nameserver (53)
# --------------------------------
iptables -A INPUT -i $INTERNET_INTERFACE -p udp \
-s $PRIMARY_NAMESERVER --source-port 53 \
--destination-port $UNPRIVPORTS -j ACCEPT
iptables -A OUTPUT -o $INTERNET_INTERFACE -p udp \
--source-port $UNPRIVPORTS \
-d $PRIMARY_NAMESERVER --destination-port 53 -j ACCEPT
iptables -A INPUT -i $INTERNET_INTERFACE -p tcp ! --syn \
-s $PRIMARY_NAMESERVER --source-port 53 \
--destination-port $UNPRIVPORTS -j ACCEPT
iptables -A OUTPUT -o $INTERNET_INTERFACE -p tcp \
--source-port $UNPRIVPORTS \
-d $PRIMARY_NAMESERVER --destination-port 53 -j ACCEPT
iptables -A INPUT -i $INTERNET_INTERFACE -p udp \
-s $SECONDARY_NAMESERVER --source-port 53 \
--destination-port $UNPRIVPORTS -j ACCEPT
iptables -A OUTPUT -o $INTERNET_INTERFACE -p udp \
--source-port $UNPRIVPORTS \
-d $SECONDARY_NAMESERVER --destination-port 53 -j ACCEPT

iptables -A INPUT -i $INTERNET_INTERFACE -p tcp ! --syn \
-s $SECONDARY_NAMESERVER --source-port 53 \
--destination-port $UNPRIVPORTS -j ACCEPT

iptables -A OUTPUT -o $INTERNET_INTERFACE -p tcp \
--source-port $UNPRIVPORTS \
-d $SECONDARY_NAMESERVER --destination-port 53 -j ACCEPT

# ------------------------------------------------------------ ------
# HTTP server (80)
# ----------------
#iptables -A INPUT -i $EXTERNAL_INTERFACE -p tcp \
# --source-port $UNPRIVPORTS \
# -d $IPADDR --destination-port 80 -j ACCEPT
#iptables -A OUTPUT -o $EXTERNAL_INTERFACE -p tcp ! --syn \
# -s $IPADDR --source-port 80 \
# --destination-port $UNPRIVPORTS -j ACCEPT

# ------------------------------------------------------------ ------
# HTTPS server (443)
# ------------------

#iptables -A INPUT -i $EXTERNAL_INTERFACE -p tcp \
# --source-port $UNPRIVPORTS \
# -d $IPADDR --destination-port 443 -j ACCEPT

#iptables -A OUTPUT -o $EXTERNAL_INTERFACE -p tcp ! --syn \
# -s $IPADDR --source-port 443 \
# --destination-port $UNPRIVPORTS -j ACCEPT

# ------------------------------------------------------------ ------
# MySQL server (3306)
# -------------------

# iptables -A INPUT -i $EXTERNAL_INTERFACE -p tcp \
# --source-port $UNPRIVPORTS \
# -d $IPADDR --destination-port 3306 -j ACCEPT

# iptables -A OUTPUT -o $EXTERNAL_INTERFACE -p tcp ! --syn \
# -s $IPADDR --source-port 3306 \
# --destination-port $UNPRIVPORTS -j ACCEPT

# ------------------------------------------------------------ ------
# SSH server (22)
# ---------------

#iptables -A INPUT -i $EXTERNAL_INTERFACE -p tcp \
# --source-port $SSH_REMOTE_PORTS \
# -d $IPADDR --destination-port 22 -j ACCEPT

#iptables -A OUTPUT -o $EXTERNAL_INTERFACE -p tcp ! --syn \
# -s $IPADDR --source-port 22 \
# --destination-port $SSH_REMOTE_PORTS -j ACCEPT

# SSH client (22)
# ---------------

iptables -A OUTPUT -o $INTERNET_INTERFACE -p tcp \
--source-port $SSH_LOCAL_PORTS \
--destination-port 22 -j ACCEPT

iptables -A INPUT -i $INTERNET_INTERFACE -p tcp ! --syn \
--source-port 22 \
--destination-port $SSH_LOCAL_PORTS -j ACCEPT
#Для внутренней сетки
iptables -A INPUT -i $EXTERNAL_INTERFACE -p tcp ! --syn \
--source-port 22 \
-d $IPADDR --destination-port $SSH_LOCAL_PORTS -j ACCEPT

iptables -A OUTPUT -o $EXTERNAL_INTERFACE -p tcp \
-s $IPADDR --source-port $SSH_LOCAL_PORTS \
--destination-port 22 -j ACCEPT

# ------------------------------------------------------------ ------
# IMAP server (143)
# -----------------
# iptables -A INPUT -i $EXTERNAL_INTERFACE -p tcp \
# --source-port $UNPRIVPORTS \
# -d $IPADDR --destination-port 143 -j ACCEPT

# iptables -A OUTPUT -o $EXTERNAL_INTERFACE -p tcp ! --syn \
# -s $IPADDR --source-port 143 \
# --destination-port $UNPRIVPORTS -j ACCEPT

# IMAP client (143)
# -----------------
# iptables -A INPUT -i $EXTERNAL_INTERFACE -p tcp ! --syn \
# --source-port 143 \
# -d $IPADDR --destination-port $UNPRIVPORTS -j ACCEPT

# iptables -A OUTPUT -o $EXTERNAL_INTERFACE -p tcp \
# -s $IPADDR --source-port $UNPRIVPORTS \
# --destination-port 143 -j ACCEPT

# ------------------------------------------------------------ ------
# SMTP client (25)
# ----------------

iptables -A INPUT -i $INTERNET_INTERFACE -p tcp ! --syn \
--source-port 25 \
--destination-port $UNPRIVPORTS -j ACCEPT

iptables -A OUTPUT -o $INTERNET_INTERFACE -p tcp \
--source-port $UNPRIVPORTS \
--destination-port 25 -j ACCEPT


# ------------------------------------------------------------ ------
# POP client (110)
# ----------------

iptables -A INPUT -i $INTERNET_INTERFACE -p tcp ! --syn \
--source-port 110 \
--destination-port $UNPRIVPORTS -j ACCEPT

iptables -A OUTPUT -o $INTERNET_INTERFACE -p tcp \
--source-port $UNPRIVPORTS \
--destination-port 110 -j ACCEPT

# ------------------------------------------------------------ ------
# HTTP client (80)
# ----------------

iptables -A INPUT -i $INTERNET_INTERFACE -p tcp ! --syn \
--source-port 80 \
--destination-port $UNPRIVPORTS -j ACCEPT

iptables -A OUTPUT -o $INTERNET_INTERFACE -p tcp \
--source-port $UNPRIVPORTS \
--destination-port 80 -j ACCEPT

iptables -A INPUT -i $INTERNET_INTERFACE -p tcp ! --syn \
--source-port 8083 \
--destination-port $UNPRIVPORTS -j ACCEPT

iptables -A OUTPUT -o $INTERNET_INTERFACE -p tcp \
--source-port $UNPRIVPORTS \
--destination-port 8083 -j ACCEPT

iptables -A INPUT -i $INTERNET_INTERFACE -p tcp ! --syn \
--source-port 8080 \
--destination-port $UNPRIVPORTS -j ACCEPT

iptables -A OUTPUT -o $INTERNET_INTERFACE -p tcp \
--source-port $UNPRIVPORTS \
--destination-port 8080 -j ACCEPT

#Для внутренней сетки
# ----------------
iptables -A INPUT -i $EXTERNAL_INTERFACE -p tcp ! --syn \
--source-port 80 \
-d $IPADDR --destination-port $UNPRIVPORTS -j ACCEPT

iptables -A OUTPUT -o $EXTERNAL_INTERFACE -p tcp \
-s $IPADDR --source-port $UNPRIVPORTS \
--destination-port 80 -j ACCEPT

# ------------------------------------------------------------ ------
# ------------------------------------------------------------ ------
# HTTPS client (443)
# ----------------
iptables -A INPUT -i $INTERNET_INTERFACE -p tcp ! --syn \
--source-port 443 \
--destination-port $UNPRIVPORTS -j ACCEPT

iptables -A OUTPUT -o $INTERNET_INTERFACE -p tcp \
--source-port $UNPRIVPORTS \
--destination-port 443 -j ACCEPT
# ------------------------------------------------------------ ------

# IRC client (6667)
# -----------------
iptables -A INPUT -i $INTERNET_INTERFACE -p tcp ! --syn \
--source-port 6667 \
--destination-port $UNPRIVPORTS -j ACCEPT

iptables -A OUTPUT -o $INTERNET_INTERFACE -p tcp \
--source-port $UNPRIVPORTS \
--destination-port 6667 -j ACCEPT

iptables -A INPUT -i $INTERNET_INTERFACE -p tcp \
--source-port $UNPRIVPORTS \
--destination-port $UNPRIVPORTS -j ACCEPT

iptables -A OUTPUT -o $INTERNET_INTERFACE -p tcp \
--source-port $UNPRIVPORTS \
--destination-port $UNPRIVPORTS -j ACCEPT

# ------------------------------------------------------------ ------
# IRC client (6667) Для внутренней сетки
# -----------------

iptables -A INPUT -i $EXTERNAL_INTERFACE -p tcp ! --syn \
--source-port 6667 \
-d $IPADDR --destination-port $UNPRIVPORTS -j ACCEPT

iptables -A OUTPUT -o $EXTERNAL_INTERFACE -p tcp \
-s $IPADDR --source-port $UNPRIVPORTS \
--destination-port 6667 -j ACCEPT

iptables -A INPUT -i $EXTERNAL_INTERFACE -p tcp \
--source-port $UNPRIVPORTS \
-d $IPADDR --destination-port $UNPRIVPORTS -j ACCEPT

iptables -A OUTPUT -o $EXTERNAL_INTERFACE -p tcp \
-s $IPADDR --source-port $UNPRIVPORTS \
--destination-port $UNPRIVPORTS -j ACCEPT

# ------------------------------------------------------------ ------
# ------------------------------------------------------------ ------

# FTP server (21)
# ---------------

# incoming request
#iptables -A INPUT -i $EXTERNAL_INTERFACE -p tcp \
# --source-port $UNPRIVPORTS \

# -d $IPADDR --destination-port 21 -j ACCEPT

#iptables -A OUTPUT -o $EXTERNAL_INTERFACE -p tcp ! --syn \
# -s $IPADDR --source-port 21 \
# --destination-port $UNPRIVPORTS -j ACCEPT

# PORT MODE data channel responses
#iptables -A OUTPUT -o $EXTERNAL_INTERFACE -p tcp \
# -s $IPADDR --source-port 20 \
# --destination-port $UNPRIVPORTS -j ACCEPT

#iptables -A INPUT -i $EXTERNAL_INTERFACE -p tcp ! --syn \
# --source-port $UNPRIVPORTS \
# -d $IPADDR --destination-port 20 -j ACCEPT

# PASSIVE MODE data channel responses
#iptables -A INPUT -i $EXTERNAL_INTERFACE -p tcp \
# --source-port $UNPRIVPORTS \
# -d $IPADDR --destination-port $UNPRIVPORTS -j ACCEPT

#iptables -A OUTPUT -o $EXTERNAL_INTERFACE -p tcp ! --syn \
# -s $IPADDR --source-port $UNPRIVPORTS \
# --destination-port $UNPRIVPORTS -j ACCEPT

# ------------------------------------------------------------ ------
# SYSLOG client (514)
# -------------------

# iptables -A OUTPUT -o $EXTERNAL_INTERFACE -p udp \
# -s $IPADDR --source-port 514 \
# -d $SYSLOG_SERVER --destination-port $UNPRIVPORTS -j ACCEPT
# ------------------------------------------------------------ ------

# FTP client (21)
# ---------------
# outgoing request
iptables -A OUTPUT -o $INTERNET_INTERFACE -p tcp \
--source-port $UNPRIVPORTS \
--destination-port 21 -j ACCEPT

iptables -A INPUT -i $INTERNET_INTERFACE -p tcp ! --syn \
--source-port 21 \
--destination-port $UNPRIVPORTS -j ACCEPT

# PORT mode data channel
iptables -A INPUT -i $INTERNET_INTERFACE -p tcp \
--source-port 20 \
--destination-port $UNPRIVPORTS -j ACCEPT

iptables -A OUTPUT -o $INTERNET_INTERFACE -p tcp ! --syn \
--source-port $UNPRIVPORTS \
--destination-port 20 -j ACCEPT

# ---------------
#Для внутренней сетки
# outgoing request
iptables -A OUTPUT -o $EXTERNAL_INTERFACE -p tcp \
-s $IPADDR --source-port $UNPRIVPORTS \
--destination-port 21 -j ACCEPT

iptables -A INPUT -i $EXTERNAL_INTERFACE -p tcp ! --syn \
--source-port 21 \
-d $IPADDR --destination-port $UNPRIVPORTS -j ACCEPT

# PORT mode data channel
iptables -A INPUT -i $EXTERNAL_INTERFACE -p tcp \
--source-port 20 \

-d $IPADDR --destination-port $UNPRIVPORTS -j ACCEPT

iptables -A OUTPUT -o $EXTERNAL_INTERFACE -p tcp ! --syn \
-s $IPADDR --source-port $UNPRIVPORTS \
--destination-port 20 -j ACCEPT

# ------------------------------------------------------------ ------
# ------------------------------------------------------------ ----------------
# ICMP
# ----

# To prevent denial of service attacks based on ICMP bombs, filter
# incoming Redirect (5) and outgoing Destination Unreachable (3).
# Note, however, disabling Destination Unreachable (3) is not
# advisable, as it is used to negotiate packet fragment size.

# For bi-directional ping.
# Message Types: Echo_Reply (0), Echo_Request (8)
# To prevent attacks, limit the src addresses to your ISP range.
#
# For outgoing traceroute.
# Message Types: INCOMING Dest_Unreachable (3), Time_Exceeded (11)
# default UDP base: 33434 to base+nhops-1
#
# For incoming traceroute.
# Message Types: OUTGOING Dest_Unreachable (3), Time_Exceeded (11)
# To block this, deny OUTGOING 3 and 11

# 0: echo-reply (pong)
# 3: destination-unreachable, port-unreachable, fragmentation-needed, etc.
# 4: source-quench
# 5: redirect
# 8: echo-request (ping)
# 11: time-exceeded
# 12: parameter-problem

iptables -A INPUT -i $INTERNET_INTERFACE -p icmp \
--icmp-type echo-reply \
-j ACCEPT

iptables -A INPUT -i $INTERNET_INTERFACE -p icmp \
--icmp-type destination-unreachable \
-j ACCEPT

iptables -A INPUT -i $INTERNET_INTERFACE -p icmp \
--icmp-type source-quench \
-j ACCEPT

iptables -A INPUT -i $INTERNET_INTERFACE -p icmp \
--icmp-type time-exceeded \
-j ACCEPT

iptables -A INPUT -i $INTERNET_INTERFACE -p icmp \
--icmp-type parameter-problem \
-j ACCEPT

iptables -A OUTPUT -o $INTERNET_INTERFACE -p icmp \
--icmp-type fragmentation-needed -j ACCEPT

iptables -A OUTPUT -o $INTERNET_INTERFACE -p icmp \
--icmp-type source-quench -j ACCEPT

iptables -A OUTPUT -o $INTERNET_INTERFACE -p icmp \
--icmp-type echo-request -j ACCEPT

iptables -A OUTPUT -o $INTERNET_INTERFACE -p icmp \
--icmp-type parameter-problem -j ACCEPT

# ------------------------------------------------------------ ----------------
#Для внутренней сетки
iptables -A INPUT -i $EXTERNAL_INTERFACE -p icmp \
--icmp-type echo-reply \
-d $IPADDR -j ACCEPT

iptables -A INPUT -i $EXTERNAL_INTERFACE -p icmp \
--icmp-type destination-unreachable \
-d $IPADDR -j ACCEPT

iptables -A INPUT -i $EXTERNAL_INTERFACE -p icmp \
--icmp-type source-quench \
-d $IPADDR -j ACCEPT

iptables -A INPUT -i $EXTERNAL_INTERFACE -p icmp \
--icmp-type time-exceeded \
-d $IPADDR -j ACCEPT

iptables -A INPUT -i $EXTERNAL_INTERFACE -p icmp \
--icmp-type parameter-problem \
-d $IPADDR -j ACCEPT

iptables -A OUTPUT -o $EXTERNAL_INTERFACE -p icmp \
-s $IPADDR --icmp-type fragmentation-needed -j ACCEPT

iptables -A OUTPUT -o $EXTERNAL_INTERFACE -p icmp \
-s $IPADDR --icmp-type source-quench -j ACCEPT

iptables -A OUTPUT -o $EXTERNAL_INTERFACE -p icmp \
-s $IPADDR --icmp-type echo-request -j ACCEPT

iptables -A OUTPUT -o $EXTERNAL_INTERFACE -p icmp \
-s $IPADDR --icmp-type parameter-problem -j ACCEPT

# ------------------------------------------------------------ ----------------
# Enable logging for selected denied packets

iptables -A INPUT -i $INTERNET_INTERFACE -p tcp -j DROP

iptables -A INPUT -i $INTERNET_INTERFACE -p udp \
--destination-port $PRIVPORTS -j DROP

iptables -A INPUT -i $INTERNET_INTERFACE -p udp \
--destination-port $UNPRIVPORTS -j DROP

iptables -A INPUT -i $INTERNET_INTERFACE -p icmp \
--icmp-type 5 -j DROP

iptables -A INPUT -i $INTERNET_INTERFACE -p icmp \
--icmp-type 13/255 -j DROP

iptables -A OUTPUT -o $INTERNET_INTERFACE -j REJECT

#Для локальной сети
iptables -A INPUT -i $EXTERNAL_INTERFACE -p tcp -j DROP

iptables -A INPUT -i $EXTERNAL_INTERFACE -p udp \
--destination-port $PRIVPORTS -j DROP

iptables -A INPUT -i $EXTERNAL_INTERFACE -p udp \
--destination-port $UNPRIVPORTS -j DROP

iptables -A INPUT -i $EXTERNAL_INTERFACE -p icmp \
--icmp-type 5 -j DROP

iptables -A INPUT -i $EXTERNAL_INTERFACE -p icmp \
--icmp-type 13/255 -j DROP

iptables -A OUTPUT -o $EXTERNAL_INTERFACE -j REJECT

# ------------------------------------------------------------ ----------------

;;
stop)
echo -n "Shutting Firewalling: "

# Remove all existing rules belonging to this filter
iptables -F

# Delete all user-defined chain to this filter
iptables -X

# Reset the default policy of the filter to accept.
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT

;;
status)
status iptables
;;
restart|reload)
$0 stop
$0 start
;;
*)
echo "Usage: iptables {start|stop|status|restart|reload}"
exit 1
esac
echo "done"

exit 0

6. Список авторов.

Sv. Bambr aka Sv. Bambr (http://www.bruy.info)
Alexei Dmitriev aka Dr.Spectre (http://www.linuxportal.ru)
Andrew Kuznetsoff aka Разгильдяй на обкуренной кошке (http://www.kuznetsoff.fromru.com)


7. Использованная литература.

1. IPTables-Howto
2. Linux 2.4 Packet-filtering-HOWTO
3. Firewall-HOWTO
4. NAT-HOWTO
5. Netfilter-hacking-HOWTO
6. Iptables-tutorial
7. Роберт Л. Зинглер Брандмауэры в Linux 2001

Опубликовал: Alexey Dmitriev
Дата: 15.03.2005
постоянный адрес статьи: http://linuxportal.ru/entry.php/P1730_0_3_0/