Iptables forwarding и nat примеры. Предоставление доступа к сервисам в локальной сети

Основная задача файрвола (межсетевого экрана) фильтрация и обработка пакетов, проходящих через сеть. При анализе входного пакета файрвол принимает решение о судьбе этого пакета: выбросить пакет (DROP ), принять пакет (ACCEPT ) или сделать с ним еще что-то.

В Linux файрвол является модулем ядра, называемым netfilter и представляет собой набор хуков (hooks) для работы с сетевым стеком. Интерфейсом для модификации правил, по которым файрвол обрабатывает пакеты, служит утилита iptables для IPv4 и утилита ip6tables для IPv6.

Всю работу по фильтрации трафика выполняет ядро системы. Iptables не является демоном и не создает новых процессов в системе. Включение или выключение iptables это всего лишь отправка сигнала в ядро. Большая скорость фильтрации достигается за счёт анализа только заголовков пакетов.

К основным возможностям iptables относиться:

  • фильтрация трафика на основе адресов отправителя и получателя пакетов, номеров портов;
  • перенаправление пакетов по определенным параметрам;
  • организация доступа в сеть (SNAT);
  • проброс портов из глобальной сети в локальную (DNAT);
  • ограничение числа подключений;
  • установление квот трафика;
  • выполнение правил по расписанию;

Рассмотрим основной процесс работы iptables (источник картинки rigacci.org ).

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

В iptables используется три вида таблиц:

  1. mangle – используется для внесения изменений в заголовок пакета;
  2. nat – используется для трансляции сетевых адресов;
  3. filter – для фильтрации трафика;

Таблица mangle

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

  • установка бита Type Of Service;
  • установка поля Time To Live;
  • установка метки на пакет, которая может быть проверена в других правилах;

Цепочки в таблице mangle :

  • PREROUTING - используется для внесения изменений в пакеты на входе в iptables, перед принятием решения о маршрутизации;
  • POSTROUTING - используется для внесения изменений в пакеты на выходе из iptables, после принятия решения о маршрутизации;
  • INPUT - используется для внесения изменений в пакеты, перед тем как они будут переданы локальному приложению;
  • OUTPUT - используется для внесения изменений в пакеты, поступающие от приложения внутри iptables;
  • FORWARD - используется для внесения изменений в транзитные пакеты;

Таблица nat

Таблица используется для преобразования сетевых адресов (Network Address Translation) и когда встречается пакет, устанавливающий новое соединение. В этой таблице могут производиться следующие действия:

  • DNAT (Destination Network Address Translation) – преобразование адреса назначения в заголовке пакета;
  • SNAT (Source Network Address Translation) – изменение исходного адреса пакета;
  • MASQUERADE – используется в тех же целях, что и SNAT , но позволяет работать с динамическими IP-адресами;

Цепочки в этой таблице:

  • PREROUTING – используется для внесения изменений в пакеты на входе в iptables;
  • OUTPUT – используется для преобразования адресов в пакетах, перед дальнейшей маршрутизацией;
  • POSTROUTING – используется для преобразования пакетов, перед отправкой их в сеть;

Таблица filter

Таблица используется для фильтрации пакетов. В этой таблице есть три цепочки:

  1. INPUT – цепочка для входящих пакетов;
  2. FORWARD – цепочка для пересылаемых (транзитных) пакетов;
  3. OUTPUT – цепочка для исходящих пакетов;

Пакет, проходящий через эти цепочки, может подвергаться действиям: ACCEPT , DROP , REJECT , LOG .

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

Цепочка Таблица
filter nat mangle
INPUT + +
FORWARD + +
OUTPUT + + +
PREROUTING + +
POSTROUTING + +

Утилита iptables

Установка iptables

# под Arch Linux yaourt -S iptables # под Ubuntu sudo apt-get install iptables

Запуск iptables

# под Arch Linux sudo systemctl enable iptables sudo systemctl start iptables # под Ubuntu sudo service iptables start

Сохранение правил

# под Arch Linux sudo sh -c "iptables-save > /etc/iptables/iptables.rules" # под Ubuntu sudo sh -c "iptables-save > /etc/iptables.rules"

Восстановление правил из файла

Iptables-restore < firewall-config

Каждое правило в iptables - это отдельная строка, сформированная по определенным правилам и содержащая критерии и действия. В общем виде правило имеет такой формат:

Iptables [-t table] command

  • t table - задает имя таблицы, для которой будет создано правило;
  • command - команда, которая определяет действие iptables - добавить правило, удалить правило и т. д.;
  • match - задает критерии проверки, по которым определяется, попадает ли пакет под действие правила или нет;
  • target/jump - какое действие должно быть выполнено при выполнении критерия;

Команды iptables:

  • -A - добавление правила в цепочку, правило будет добавлено в конец цепочки;
  • -D - удаление правила из цепочки;
  • -R - заменить одно правило другим;
  • -I - вставить новое правило в цепочку;
  • -L - вывод списка правил в заданной цепочке;
  • -F - сброс всех правил в заданной цепочке;
  • -Z - обнуление всех счетчиков в заданной цепочке;
  • -N - создание новой цепочки с заданным именем;
  • -X - удаление цепочки;
  • -P - задает политику по умолчанию для цепочки;
  • -E - переименование пользовательской цепочки;

Примеры команд iptables

Пакеты можно фильтровать по таким параметрам:

Источник пакета

Для фильтрации по источнику используется опция -s . Например запретим все входящие пакеты с узла 192.168.1.95:

Iptables -A INPUT -s 192.168.1.95 -j DROP

Можно использовать доменное имя для указания адреса хоста:

Iptables -A INPUT -s test.host.net -j DROP

Также можно указать целую под сеть:

Iptables -A INPUT -s 192.168.1.0/24 -j DROP

Также вы можете использовать отрицание (знак!). Например, все пакеты с хостов отличных от 192.168.1.96 будут уничтожаться:

Iptables -A INPUT ! -s 192.168.1.96 -j DROP

Разрешаем хождение трафика по localhost:

Iptables -A INPUT 1 -i lo -j ACCEPT

Логируем попытки спуфинга с префиксом "IP_SPOOF A: " и дропаем соединение

Iptables -A INPUT -i eth1 -s 10.0.0.0/8 -j LOG --log-prefix "IP_SPOOF A: " iptables -A INPUT -i eth1 -s 10.0.0.0/8 -j DROP

Адрес назначения

Для этого нужно использовать опцию -d . Например запретим все исходящие пакеты на хост 192.168.1.95:

Iptables -A OUTPUT -d 192.168.156.156 -j DROP

Запретить доступ к ресурсу

Iptables -A OUTPUT -d vk.com -j REJECT

Как и в случае с источником пакета можно использовать адреса под сети и доменные имена. Отрицание также работает.

Протокол

Опция -p указывает на протокол. Можно использовать all, icmp, tcp, udp или номер протокола (из /etc/protocols ).

Разрешаем входящие эхо-запросы

Iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT

Порт источника

Разрешаем все исходящие пакеты с порта 80:

Iptables -A INPUT -p tcp --sport 80 -j ACCEPT

Заблокировать все входящие запросы порта 80:

Iptables -A INPUT -p tcp --dport 80 -j DROP

Для указания порта необходимо указать протокол (tcp или udp). Можно использовать отрицание.

Открыть диапазон портов

Iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 7000:7010 -j ACCEPT

Порт назначения

Разрешить подключения по HTTP

Iptables -A INPUT -p tcp --dport 80 -j ACCEPT iptables -A INPUT -p tcp -i eth0 --dport 22 -j ACCEPT

Разрешаем получать данные от DHCP-сервера

Iptables -A INPUT -p UDP --dport 68 --sport 67 -j ACCEPT

  • Удаленная эксплуатация ошибок в ПО с целью привести его в нерабочее состояние;
  • Flood - посылка на адрес жертвы огромного количества бессмысленных пакетов. Целью флуда может быть канал связи или ресурсы машины. В первом случае поток пакетов занимает весь пропускной канал и не дает атакуемой машине возможность обрабатывать легальные запросы. Во втором - ресурсы машины захватываются с помощью многократного и очень частого обращения к какому-либо сервису, выполняющему сложную, ресурсоемкую операцию. Это может быть, например, длительное обращение к одному из активных компонентов (скрипту) web-сервера. Сервер тратит все ресурсы машины на обработку запросов атакующего, а пользователям приходится ждать. Флуд бывает разным: ICMP-флуд, SYN-флуд, UDP-флуд и HTTP-флуд

Сбор информации о сетевых соединениях

Просмотр открытых соединений

Netstat -ntu | awk "{print $5}" | cut -d: -f1 | sort | uniq -c | sort -n

Количество подключений к 80 порту

Netstat -na | grep ":80\ " | wc -l

TCP-дамп подключений (на какой домен чаще всего идут запросы)

Tcpdump -npi eth0 port domain

SYN-флуд можно проверить через подсчет числа полуоткрытых TCP-соединений

Netstat -na | grep ":80 " | grep SYN_RCVD

Защита от разных видов флуда.

ICMP-флуд. Очень примитивный метод забивания полосы пропускания и создания нагрузок на сетевой стек через монотонную посылку запросов ICMP ECHO (пинг). Легко обнаруживается с помощью анализа потока трафика в обе стороны: во время атаки типа ICMP-флуд они практически идентичны. Почти безболезненный способ абсолютной защиты основан на отключении ответов на запросы ICMP ECHO:

Sysctl net.ipv4.icmp_echo_ignore_all=1

Или с помощью iptabels :

Iptables -A INPUT -p icmp -j DROP --icmp-type 8

SYN-флуд. Один из распространенных способов не только забить канал связи, но и ввести сетевой стек операционной системы в такое состояние, когда он уже не сможет принимать новые запросы на подключение. Основан на попытке инициализации большого числа одновременных TCP-соединений через посылку SYN-пакета с несуществующим обратным адресом. После нескольких попыток отослать ответный ACK-пакет на недоступный адрес большинство ОС ставят неустановленное соединение в очередь. И только после n-ой попытки закрывают соединение. Так как поток ACK-пакетов очень велик, вскоре очередь оказывается заполненной, и ядро дает отказ на попытки открыть новое соединение. Наиболее умные DoS-боты еще и анализируют систему перед началом атаки, чтобы слать запросы только на открытые жизненно важные порты. Идентифицировать такую атаку просто: достаточно попробовать подключиться к одному из сервисов.

Я несколько раз сталкивался с тем, что даже неглупые в общем-то люди делают совершенно непростительные ошибки. Например, открывают всему интернету порт, на котором крутится база данных. Часто так бывает у начинающих DevOps, которые всю жизнь писали код, а теперь в их обязанности входит еще и настройка серверов. В сети есть хорошие туториалы по базовой настройке фаервола в Linux и других *nix, но часто это простыни на множество экранов. Так что, надеюсь, этот более лаконичный туториал кому-нибудь пригодится.

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

Небольшое замечание по терминологии. Фаервол, встроенный в ядро Linux, называется Netfilter, а iptables — утилита для управления этим фаерволом. Многие ошибочно полагают, что фаервол называется iptables. Это не так. Говоря что-нибудь наподобие «я фильтрую пакеты с помощью iptables», вы показываете окружающим свою безграмотность.

Вообще, какие примерно задачи можно решать с помощью Netfilter:

  • Разрешать/запрещать входящий трафик на определенные порты по определенным протоколам (IPv4/IPv6, TCP/UDP) с указанных адресов (IP, MAC) или подсетей;
  • Все то же самое в отношении исходящего трафика;
  • Можно, например, полностью игнорировать все ICMP пакеты;
  • Настройка NAT, см статью про роутер на базе Raspberry Pi ;
  • Слышал, что настоящие гуру умеют настраивать защиту от DDoS и брутфорса, ограничивать доступ в сеть конкретным приложениям, пользователям или группам, и делать другие чумовые вещи;

Отмечу, что утилита iptables мне лично первое время казалась исключительно неудобной по сравнению с ipfw во FreeBSD . К счастью, поработав с ней какое-то время, все это множество флагов вроде -A, -D, -j и прочих становятся привычны, так что, наберитесь терпения. Рассмотрим основные команды.

Показать все правила:

iptables -L -n

Вы можете заметить, что в Netfilter есть какие-то «цепочки» (chains) — как минимум INPUT, OUTPUT и FORWARD. У меня лично на машине есть еще и цепочка DOCKER. На первое время можно думать о первых двух, как обо всем входящем и исходящем трафике соответственно, а об остальных временно забыть. Велика вероятность, что они вообще никогда вам не понадобятся.

Удалить все правила:

iptables -F

Изменить политику (поведение по умолчанию) цепочки:

iptables -P INPUT DROP
iptables -P INPUT ACCEPT

Запретить доступ с хоста/подсети:

iptables -A INPUT -s 123.45.67.89 -j DROP
iptables -A INPUT -s 123.45.0.0/ 16 -j DROP

Также можно использовать доменные имена:

iptables -A INPUT -s example.ru -j DROP

Запрет исходящих соединений:

iptables -A OUTPUT -d 123.45.67.89 -j DROP

В правилах можно использовать отрицания:

iptables -A INPUT ! -s 123.45.67.89 -j DROP

Удаление правила по его номеру в цепочке:

iptables -D INPUT 1

Удаление правила на основе того, что оно делает:

iptables -D INPUT -s 123.45.67.89 -j DROP

Опция -p указывает на протокол. Можно использовать all, icmp, tcp, udp или номер протокола из /etc/protocols. Флаг - -sport указывает порт, с которого был прислан пакет, а - -dport указывает порт назначения:

iptables -A INPUT -p tcp --sport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT

Вставка (insert) правила в начало цепочки:

iptables -I INPUT ...

Или можно указать конкретную позицию:

iptables -I INPUT 3 ...

iptables-save > / etc/ iptables.rules

Восстановить правила:

iptables-restore < / etc/ iptables.rules

Теперь рассмотрим несколько практических примеров. Так, например, выглядит эмуляция нетсплита в тесте, проверяющем поведение приложения, в котором используется Akka Cluster :

run(node1, s"iptables -A INPUT -s $node2 -j DROP" )
run(node1, s"iptables -A INPUT -s $node3 -j DROP" )
run(node1, s"iptables -A OUTPUT -d $node2 -j DROP" )
run(node1, s"iptables -A OUTPUT -d $node3 -j DROP" )

Восстановление происходит точно так же, только флаг -A заменяется на флаг -D.

Другой пример. Требуется выяснить, какие порты прослушиваются на машине, и закрыть лишние. Заходим на машину и говорим:

netstat -tuwpln

Пример вывода:

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Prog name
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 3210/nginx
tcp 0 0 0.0.0.0:4369 0.0.0.0:* LISTEN 1789/epmd
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 797/sshd
tcp 0 0 127.0.0.1:5432 0.0.0.0:* LISTEN 990/postgres

Nginx и SSHd смотрят в интернет, это нормально. PostgreSQL слушает только локальный интерфейс, поэтому с ним тоже проблем нет. А вот epmd торчит наружу (можно проверить telnet’ом с другой машины), и это никуда не годится. Можно закрыть только порт 4369. Как это сделать, было показано выше. Или можно пойти еще дальше и запретить все соединения извне на порт 81 и старше.

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

Настройка netfilter/iptables для рабочей станции

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

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

Netfilter:~# iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination

Это значит, что политика по умолчанию для таблицы filter во всех цепочках - ACCEPT и нет никаких других правил, что-либо запрещающих. Поэтому давайте сначала запретим ВСЁ , и пакеты (не вздумайте это делать удаленно-тут же потеряете доступ):

Netfilter:~# iptables -P INPUT DROP netfilter:~# iptables -P OUTPUT DROP netfilter:~# iptables -P FORWARD DROP

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

Netfilter:~# ping -c2 127.0.0.1 PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data. ping: sendmsg: Operation not permitted ping: sendmsg: Operation not permitted --- localhost ping statistics --- 2 packets transmitted, 0 received, 100% packet loss, time 1004ms

На самом деле это полностью не функционирующая сеть и это не очень хорошо, т.к. некоторые демоны используют для обмена между собой петлевой интерфейс, который после проделанных действий более не функционирует. Это может нарушить работу подобных сервисов. Поэтому в первую очередь в обязательно разрешим передачу пакетов через входящий петлевой интерфейс и исходящий петлевой интерфейс в таблицах INPUT (для возможности получения отправленных пакетов) и OUTPUT (для возможности отправки пакетов) соответственно. Итак, обязательно выполняем:

Netfilter:~# iptables -A INPUT -i lo -j ACCEPT netfilter:~# iptables -A OUTPUT -o lo -j ACCEPT

После этого пинг на локалхост заработает:

Netfilter:~# ping -c1 127.0.0.1 PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data. 64 bytes from 127.0.0.1 (127.0.0.1): icmp_seq=1 ttl=64 time=0.116 ms --- 127.0.0.1 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 116ms rtt min/avg/max/mdev = 0.116/0.116/0.116/0.116 ms

Если подходить к настройке файервола не шибко фанатично, то можно разрешить работу протокола ICMP:

Netfilter:~# iptables -A INPUT -p icmp -j ACCEPT netfilter:~# iptables -A OUTPUT -p icmp -j ACCEPT

Более безопасно будет указать следующую аналогичную команду iptables:

Netfilter:~# iptables -A INPUT -p icmp --icmp-type 0 -j ACCEPT netfilter:~# iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT netfilter:~# iptables -A OUTPUT -p icmp -j ACCEPT

Данная команда разрешит типы ICMP пакета эхо-запрос и эхо-ответ, что повысит безопасность.

Зная, что наш комп не заражен (ведь это так?) и он устанавливает только безопасные исходящие соединения. А так же, зная, что безопасные соединения - это соединения из т.н. эфимерного диапазона портов , который задается ядром в файле /proc/sys/net/ipv4/ip_local_port_range, можно разрешить исходящие соединения с этих безопасных портов:

Netfilter:~# cat /proc/sys/net/ipv4/ip_local_port_range 32768 61000 netfilter:~# iptables -A OUTPUT -p TCP --sport 32768:61000 -j ACCEPT netfilter:~# iptables -A OUTPUT -p UDP --sport 32768:61000 -j ACCEPT

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

Netfilter:~# iptables -A OUTPUT -j ACCEPT netfilter:~# # или просто задать политику по умолчанию ACCEPT для цепочки OUTPUT netfilter:~# iptables -P OUTPUT ACCEPT

Далее, зная что в netfilter сетевые соединения имеют 4 состояния (NEW, ESTABLISHED, RELATED и INVALID ) и новые исходящие соединения с локального компьютера (с состоянием NEW) у нас разрешены в прошлых двух командах iptables, что уже установленные соединения и дополнительные имеют состояния ESTABLISHED и RELATED, соответственно, а так же зная, что к локальной системе приходят через , можно разрешить попадание на наш компьютер только тех TCP- и UDP-пакетов, которые были запрошены локальными приложениями:

Netfilter:~# iptables -A INPUT -p TCP -m state --state ESTABLISHED,RELATED -j ACCEPT netfilter:~# iptables -A INPUT -p UDP -m state --state ESTABLISHED,RELATED -j ACCEPT

Это собственно, все! Если на десктопе все же работает какая-то сетевая служба, то необходимо добавить соответствующие правила для входящих соединений и для исходящих. Например, для работы ssh-сервера , который принимает и отправляет запросы на 22 TCP-порту, необходимо добавить следующие iptables-правила :

Netfilter:~# iptables -A INPUT -i eth0 -p TCP --dport 22 -j ACCEPT netfilter:~# iptables -A OUTPUT -o eth0 -p TCP --sport 22 -j ACCEPT

Т.е. для любого сервиса нужно добавить по одному правилу в цепочки INPUT и OUTPUT, разрешающему соответственно прием и отправку пакетов с использованием этого порта для конкретного сетевого интерфейса (если интерфейс не указывать, то будет разрешено принимать/отправлять пакеты по любому интерфейсу).

Настройка netfilter/iptables для подключения нескольких клиентов к одному соединению.

Давайте теперь рассмотрим наш Linux в качестве шлюза для локальной сети во внешнюю сеть Internet . Предположим, что интерфейс eth0 подключен к интернету и имеет IP 198.166.0.200, а интерфейс eth1 подключен к локальной сети и имеет IP 10.0.0.1. По умолчанию, в ядре Linux пересылка пакетов через цепочку FORWARD (пакетов, не предназначенных локальной системе) отключена. Чтобы включить данную функцию, необходимо задать значение 1 в файле :

Netfilter:~# echo 1 > /proc/sys/net/ipv4/ip_forward

Чтобы форвардинг пакетов сохранился после перезагрузки, необходимо в файле /etc/sysctl.conf раскомментировать (или просто добавить) строку net.ipv4.ip_forward=1 .

Итак, у нас есть внешний адрес (198.166.0.200), в локальной сети имеется некоторое количество гипотетических клиентов, которые имеют и посылают запросы во внешнюю сеть. Если эти клиенты будут отправлять во внешнюю сеть запросы через шлюз "как есть", без преобразования, то удаленный сервер не сможет на них ответить, т.к. обратным адресом будет получатель из "локальной сети". Для того, чтобы эта схема корректно работала, необходимо подменять адрес отправителя, на внешний адрес шлюза Linux. Это достигается за счет (маскарадинг) в , в .

Netfilter:~# iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT netfilter:~# iptables -A FORWARD -m conntrack --ctstate NEW -i eth1 -s 10.0.0.1/24 -j ACCEPT netfilter:~# iptables -P FORWARD DROP netfilter:~# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

Итак, по порядку сверху-вниз мы разрешаем уже установленные соединения в цепочке FORWARD , таблице filter , далее мы разрешаем устанавливать новые соединения в цепочке FORWARD , таблице filter , которые пришли с интерфейса eth1 и из сети 10.0.0.1/24. Все остальные пакеты, которые проходят через цепочку FORWARD - отбрасывать. Далее, выполняем маскирование (подмену адреса отправителя пакета в заголовках) всех пакетов, исходящих с интерфейса eth0.

Примечание. Есть некая общая рекомендация: использовать правило -j MASQUERADE для интерфейсов с динамически получаемым IP (например, по DHCP от провайдера). При статическом IP, -j MASQUERADE можно заменить на аналогичное -j SNAT -to-source IP_интерфейса_eth0. Кроме того, SNAT умеет "помнить" об установленных соединениях при кратковременной недоступности интерфейса. Сравнение MASQUERADE и SNAT в таблице:

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

Netfilter:~# iptables -P INPUT DROP netfilter:~# iptables -P OUTPUT DROP netfilter:~# iptables -A INPUT -i lo -j ACCEPT netfilter:~# iptables -A OUTPUT -o lo -j ACCEPT netfilter:~# iptables -A INPUT -p icmp --icmp-type 0 -j ACCEPT netfilter:~# iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT netfilter:~# iptables -A OUTPUT -p icmp -j ACCEPT netfilter:~# cat /proc/sys/net/ipv4/ip_local_port_range 32768 61000 netfilter:~# iptables -A OUTPUT -p TCP --sport 32768:61000 -j ACCEPT netfilter:~# iptables -A OUTPUT -p UDP --sport 32768:61000 -j ACCEPT netfilter:~# iptables -A INPUT -p TCP -m state --state ESTABLISHED,RELATED -j ACCEPT netfilter:~# iptables -A INPUT -p UDP -m state --state ESTABLISHED,RELATED -j ACCEPT

В результате, если один из хостов локальной сети, например 10.0.0.2, попытается связаться с одним из интернет-хостов, например, 93.158.134.3 (ya.ru), при , их исходный адрес будет подменяться на внешний адрес шлюза в цепочке POSTROUTING таблице nat, то есть исходящий IP 10.0.0.2 будет заменен на 198.166.0.200. С точки зрения удаленного хоста (ya.ru), это будет выглядеть, как будто с ним связывается непосредственно сам шлюз. Когда же удаленный хост начнет ответную передачу данных, он будет адресовать их именно шлюзу, то есть 198.166.0.200. Однако, на шлюзе адрес назначения этих пакетов будет подменяться на 10.0.0.2, после чего пакеты будут передаваться настоящему получателю в локальной сети. Для такого обратного преобразования никаких дополнительных правил указывать не нужно - это будет делать все та же операция MASQUERADE , которая помнит какой хост из локальной сети отправил запрос и какому хосту необходимо вернуть пришедший ответ.

Примечание: желательно негласно принято, перед всеми командами iptables очищать цепочки, в которые будут добавляться правила:

Netfilter:~# iptables -F ИМЯ_ЦЕПОЧКИ

Предоставление доступа к сервисам на шлюзе

Предположим, что на нашем шлюзе запущен некий сервис, который должен отвечать на запросы поступающие из сети интернет. Допустим он работает на некотором TCP порту nn. Чтобы предоставить доступ к данной службе, необходимо модифицировать таблицу filter в цепочке INPUT (для возможности получения сетевых пакетов, адресованных локальному сервису) и таблицу filter в цепочке OUTPUT (для разрешения ответов на пришедшие запросы).

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

Netfilter:~# iptables -A INPUT -p TCP --dport nn -j ACCEPT netfilter:~# iptables -A OUTPUT -p TCP --sport nn -j ACCEPT

Данные правила разрешают входящие соединения по протоколу tcp на порт nn и исходящие соединения по протоколу tcp с порта nn. Кроме этого, можно добавить дополнительные ограничивающие параметры, например разрешить входящие соединения только с внешнего интерфейса eth0 (ключ -i eth0 ) и т.п.

Предоставление доступа к сервисам в локальной сети

Предположим, что в нашей локальной сети имеется какой-то хост с IP X.Y.Z.1, который должен отвечать на сетевые запросы из внешней сети на TCP-порту xxx. Для того чтобы при обращении удаленного клиента ко внешнему IP на порт xxx происходил корректный ответ сервиса из локальной сети, необходимо направить запросы, приходящие на внешний IP порт xxx на соответствующий хост в локальной сети. Это достигается модификацией адреса получателя в пакете, приходящем на указанный порт. Это действие называется DNAT и применяется в цепочке PREROUTING в таблице nat. А так же разрешить прохождение данный пакетов в цепочке FORWARD в таблице filter.

Опять же, пойдем по пути . Итак, мы имеем , который маскарадит (заменяет адрес отправителя на врешний) пакеты во внешнюю сеть. И разрешает принимать все установленные соединения. Предоставление доступа к сервису будет осуществляться с помощью следующих разрешающих правил:

Netfilter:~# iptables -t nat -A PREROUTING -p tcp -d 198.166.0.200 --dport xxx -j DNAT --to-destination X.Y.Z.1 netfilter:~# iptables -A FORWARD -i eth0 -p tcp -d X.Y.Z.1 --dport xxx -j ACCEPT

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

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

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

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

  • Настраиваем сетевой экран под свои нужны с помощью
  • создаем дамп созданный правил с помощью команды iptables-save > /etc/iptables.rules
  • создаем скрипт импорта созданного дампа при старте сети (в каталоге /etc/network/if-up.d/) и не забываем его сделать исполняемым:
# cat /etc/network/if-up.d/firewall #!/bin/bash /sbin/iptables-restore < /etc/iptables.rules exit 0 # chmod +x /etc/network/if-up.d/firewall

Дамп правил, полученный командой iptables-save имеет текстовый формат, соответственно пригоден для редактирования. Синтаксис вывода команды iptables-save следующий :

# Generated by iptables-save v1.4.5 on Sat Dec 24 22:35:13 2011 *filter:INPUT ACCEPT :FORWARD ACCEPT ....... # комментарий -A INPUT -i lo -j ACCEPT -A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT ........... -A FORWARD -j REJECT COMMIT # Completed on Sat Dec 24 22:35:13 2011 # Generated by iptables-save v1.4.5 on Sat Dec 24 22:35:13 2011 *raw ...... COMMIT

Строки, начинающиеся на # - комментарии, строки на * - это название таблиц, между названием таблицы и словом COMMIT содержатся параметры, передаваемые команде iptables. Параметр COMMIT - указывает на завершение параметров для вышеназванной таблицы. Строки, начинающиеся на двоеточие задают цепочки, в которых содержится данная таблица в формате:

:цепочка политика [пакеты:байты]

где цепочка - имя цепочки, политика - политика цепочки по-умолчанию для данной таблицы, а далее счетчики пакетов и байтов на момент выполнения команды.

В RedHat функции хранения команд iptables выполняемых при старте и останове сети выполняет файл /etc/sysconfig/iptables . А управление данным файлом лежит на демоне iptables.

Как еще один вариант сохранения правил, можно рассмотреть использование параметра up в файле /etc/network/interfaces с аргументом в виде файла, хранящего команды iptables, задающие необходимые правила.

Итог

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

С Уважением, Mc.Sim!

разработчик 80-го уровня 28 сентября 2010 в 19:47

Основы iptables на примере Debian глазами младенца

  • Чулан *

О чем же пойдёт речь

Всё очень просто, в очередной раз объясняя на форуме новичкам в мире Linux, что да как я понял, что на просторах интернет не найти собранную воедино статью с объяснением не только настройки iptables, но и некоторых сетевых основ.
Так что вашему вниманию я представляю небольшой экскурс по настройке firewall в Linux. Углубимся лишь в настройку netfilter/iptables, остальных прикладных вопросов мы несомненно тоже коснёмся, ведь нам не хватает именно комплексных ответов на наши вопросы… И я постараюсь ка можно более доходчиво здесь все изложить.

Как это выглядит

Мы будем рассматривать типичную схему для офисов и для квартир, да-да именно квартир! Мало у кого есть собственный маленький сервачок дома под столом, но у большинства интернет дома раздается через роутер и в большинстве своём они тоже прошиты Linux.
Это типичная схема малого офиса. Когда к интернет подключен 1 компьютер(сервер), а остальные подключаются к интернет уже через этот сервер.

Поехали, потихонечку...

И так что же мы имеем:
  • сервер с 2мя сетевыми картами и установленным на нём Debian Lenny
  • имеющийся по умолчанию в Debian Lenny firewall - netfilter/iptables
  • локальную сеть из N компьютеров, все соединены через коммутатор, в том числе и сервер
что такое 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 или подмена адреса источника). Т.е. в 99% случаев вся ваша контора выходит в интернет под 1 IP адресом, при этом внутри офиса у каждого он свой. О классах IP адресов вы сможете прочесть в интерне.

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

транзитный трафик
Все команды выполняются от имени root(суперпользователь). В Debian по умолчанию отключен так называемый транзитный трафик, т.е. по умолчанию предусмотрена работа только как единичная машина. Как вы уже догадались, без транзитного трафика нету и NAT. Для его включения достаточно изменить 1 цифру - $ echo 1 > /proc/sys/net/ipv4/ip_forward , но данная настройка слетит после перезагрузки, так что лучше поправить конфиг - $ nano /etc/sysctl.conf далее ищем строчку #net.ipv4.ip_forward=1 и убираем «решётку»(символ комментария) в начале строки и проверяем что значения равно 1! Теперь можно приступать непосредственно к конфигурированию iptables.
настраиваем iptables
В интернет, есть много статей о том как писать правила в iptables и что с их помощью можно творить, наиболее полным и приятным для чтения мне показалась .
И так приступим. Для начала очистим таблицы от лишних правил, вдруг там что было лишнего…
$ iptables -F
$ iptables -t nat -F
$ iptables -t mangle -F

Лишнее почистили. Очень важно понять и помнить, что правила в iptables применяются иерархически, т.е. правило стоящее выше выполнится раньше. Все цепочки по умолчанию имеют политику ACCEPT - разрешают всё. что не попало под правила данной цепочки.
Условимся, что интерфейс смотрящий в локальную сеть - eth0, а в интернет - eth1, локальная сеть имеет адреса 192.168.0.0/24, а провайдер выдал нам статический адрес 10.188.106.33(пускай и не «белый» - о типах ip адресов вы также можете посмотреть в интернет). И так пишем:
$ iptables -A FORWARD -i eth0 -o eth1 -s 192.168.0.0/24 -j ACCEPT
$ iptables -A FORWARD -i eth1 -o eth0 -d 192.168.0.0/24 -j ACCEPT
$ iptables -P FORWARD DROP

тем самым разрешили ходить транзитным пакетам через firewall для нашего диапазона ip адресов, а всё остальное запрещаем.
Теперь сам NAT:
$ iptables -A POSTROUTING -s 192.168.0.0/24 -o eth1 -j SNAT --to-source 10.188.106.33
Этого достаточно для того что бы у вас заработал NAT.
по мелочам...
На клиентах указываем ip из выбранного диапазона и указываем в качестве шлюза ip адрес нашего сервера(обычно его назначают первым из подсети - я оставлю это на ваше усмотрение). Все сетевые настройки на сервере можно провести так:
$ nano /etc/network/interfaces в нём указываются настройки ваших сетевых интерфейсов.
доступ в недры сети через шлюз или DNAT
И тут вы поняли, что в сети у вас есть Windows Server к которому у вас всегда был простой доступ по RDP, а тут вылез это назойливый шлюз на Debian! Всё очень просто - надо всего лишь добавить DNAT правило в наш iptables.
Что за зверь DNAT? DNAT (Destination NAT или подмена адреса получателя) - сетевые карты работают в таком режиме, что они принимают только пакеты адресованные именно им, а зайти на наш сервер если ip под которым он выходит в интернет сидят еще десяток машин в вашем офисе? Как запрос дойдёт именного до него? На самом деле все запросы такого рода упираются в наш шлюз. И всё что нам надо сделать это задать правила для работы с такими пакетами.
$ iptables -A PREROUTING -i eth1 -p tcp -m tcp --dport 3389 -j DNAT --to-destination 192.168.0.2
Это простое правило будет переадресовывать все пакеты приходящие на шлюз из интернет на порт TCP 3389(именно его использует RDP протокол) на ваш внутренний Windows Server. И, вуаля, у вас все работает.
итак что там с любимым squid
И хотя сейчас все работает, у всех есть интернет и все работает, некоторым всё же нужен прокси сервер. Я не буду рассказывать о настройке squid, я покажу правило которое позволит сделать его «прозрачным». В сквид надо лишь прописать волшебное слово transparent в нужном месте и он начнём корректно обрабатывать свалившееся на него запросы.
Пишем $ iptables -A PREROUTING -d! 192.168.0.0/24 -i eth0 -p tcp -m multiport --dports 80,443 -j REDIRECT --to-ports 3128 .
И что же нам это даёт? Теперь все запросы на web страницы с ваших рабочих мест по http((80) и https(443) протоколам будут перенаправляться на порт который слушает squid. Вы получает контентную фильтрацию, информацию о том кто где был и что делал в интернет, пользователь ни чего не подозревая работает как и раньше…
немного безопасности
Следует хоть минимально защитить свой шлюз поэтому добавим еще пару правил
$ iptables -A INPUT -i lo -j ACCEPT
$ iptables -A INPUT -i eth0 -s 192.168.0.0/24 -j ACCEPT
$ iptables -A INPUT -i eth1 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
$ iptables -P INPUT DROP

Тем самым запретили любое общение непосредственно с шлюзом, кроме уже установленных соединений, т.е. те что были инициированы вами и вы просто получаете на них ответы. Не бойтесь наш DNAT до этих правил просто не доходит…
почему так мало?
Статья не резиновая и обо всем все-равно не расскажешь… Я привел минимальный набор действий и понятий что бы вы могли начать осваивать такую махину как шлюз на Linux. Здесь можно говорить очень и очень долго, обсуждая многие аспекты и возможности netfilter.

Итого

Как мы видим все действительно просто! Главное это понять принцип функционирования сети и не боятся настраивать и читать большие мануалы.
Надеюсь мне удалось собрать воедино информацию достаточную для начала вашей дружбы с программными маршрутизаторами на основе Linux.

Теги: iptables, netfilter, NAT

Ликбез

Не смотря на то, что в интернете полно статей об Iptables, довольно часто вижу просьбы подсказать набор правил для конкретной ситуации. Так как ситуации довольно типичные, то можно давать ссылку на данную заметку без объяснений. Повторяю, это не пересказ , который обязателен к прочтению. Он и так достаточно хорош, а только наборы правил для начинающих с минимальными комментариями.
Кое-что, конечно, стоит сказать для понимания:
Policy, ключ -P . Цитата из туториала:

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

Другими словами, если пакет, пришедший на сетевой интерфейс, не описан ни одним правилом, то он обрабатывается политикой по умолчанию. Из этого следует, что настраивать Iptables (да и любой фаервол) можно двумя путями\политиками:
1. Разрешено все, что не запрещено. Т.е. разрешено вообще все.
2. Запрещено все, кроме того, что разрешено явно.
Очевидно, второй подход правильней, что и будет рассматриваться далее. Полиси для OUTPUT предлагаю оставить ACCEPT, иначе придется огрести много глюков. Когда ты будешь знать Iptables достаточно хорошо — сам поймешь почему и сможешь настроить в DROP.
И еще важное замечание. Подразумевается, что правила применяются скриптом, а не вводятся с консоли по очереди. В последнем случае, после команды iptable -P INPUT DROP потеряется коннект установленной SSH сессии. При применении правил скриптом сессия не разорвется, т.к. далее идет правило разрешения принимать уже установленные соединения.

Перед применением правил необходимо очистить все существующие цепочки, таблицы и политики:

Iptables -P INPUT ACCEPT iptables -P FORWARD ACCEPT iptables -P OUTPUT ACCEPT iptables -t nat -P PREROUTING ACCEPT iptables -t nat -P POSTROUTING ACCEPT iptables -t nat -P OUTPUT ACCEPT iptables -t mangle -P PREROUTING ACCEPT iptables -t mangle -P OUTPUT ACCEPT iptables -F iptables -t nat -F iptables -t mangle -F iptables -X iptables -t nat -X iptables -t mangle -X

Минимальный набор правил iptables для десктопа

Задача: запретить все входящие подключения. Исходящие не ограничены.

# Правила по умолчанию iptable -P INPUT DROP iptable -P FORWARD DROP iptable -P OUTPUT ACCEPT # Разрешить входящие соединения с локалхоста iptables -A INPUT -i lo -j ACCEPT # Разрешить уже установленные входящие соединения iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

Минимальный набор правил iptables для сервера с приложением

Задача: дать доступ до сервиса, пусть это будет веб сервер, работающий на 80 порту, все остальное запретить.
Так как это сервер, то необходимо разрешить коннект для управления по SSH. По аналогии можно открыть любой нужный порт или наборы портов.

# Правила по умолчанию iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT ACCEPT # Разрешить входящие соединения с локалхоста iptables -A INPUT -i lo -j ACCEPT # Разрешить уже установленные входящие соединения iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # Разрешить SSH iptables -A INPUT -p TCP --dport 22 -j ACCEPT # Разрешить HTTP порт iptables -A INPUT -p TCP --dport 80 -j ACCEPT

Минимальный набор правил iptables для шлюза

Задача: 1. Раздать интернет в локальную сеть при помощи NAT’а. 2. Разрешить обращение машин из локальной сети к внешним HTTP, HTTPS и DNS серверам 3. Пробросить порт на веб сервер, находящийся в этой локальной сети.

### Переменные # Интерфейс, смотрящий в интернет INET_IF="eth0" # Белый IP адрес, принадлежащий $INET_IF INET_IP="x.x.x.x" # TCP порты, по которым разрешено ходить в интернет машинам из локальной сети FORWARD_TCP_PORTS="53,80,443" # UDP порты, по которым разрешено ходить в интернет машинам из локальной сети FORWARD_UDP_PORTS="53" # Локальная сеть LOCAL_NET="192.168.0.0/24" # IP адрес локального веб сервера WEB_SERVER="192.168.0.10" # Путь до sysctl SYSCTL="/sbin/sysctl -w" # Включить в ядре форвард IPv4 пакетов if [ "$SYSCTL" = "" ] then echo "1" > /proc/sys/net/ipv4/ip_forward else $SYSCTL net.ipv4.ip_forward="1" fi ### Правила по умолчанию iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT ACCEPT ### INPUT # Разрешить входящие соединения с локалхоста iptables -A INPUT -i lo -j ACCEPT # Разрешить принимать уже установленные соединения iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # Разрешить SSH iptables -A INPUT -p TCP --dport 22 -j ACCEPT ### FORWARD # Разрешить уже установленные пересылаемые соединения iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # Разрешить машинам локальной сети ходить в интернет по указанным TCP портам iptables -A FORWARD -p TCP -s $LOCAL_NET -m multiport --dport $FORWARD_TCP_PORTS -j ACCEPT iptables -A FORWARD -p TCP -d $LOCAL_NET -m multiport --dport $FORWARD_TCP_PORTS -j ACCEPT # Разрешить машинам локальной сети ходить в интернет по указанным UDP портам iptables -A FORWARD -p UDP -s $LOCAL_NET -m multiport --dport $FORWARD_UDP_PORTS -j ACCEPT iptables -A FORWARD -p UDP -d $LOCAL_NET -m multiport --dport $FORWARD_UDP_PORTS -j ACCEPT ### NAT # Включить NAT для локальной подсети iptables -t nat -A POSTROUTING -s $LOCAL_NET -o $INET_IF -j SNAT --to-source $INET_IP # Пробросить порт на локальный веб сервер iptables -t nat -A PREROUTING -p TCP -d $INET_IP --dport 80 -j DNAT --to-destination $WEB_SERVER:80

Надо отметить, что если пробрасывается порт, отличный от списка $FORWARD_TCP_PORTS, то необходимо его туда добавить, т.к. он будет дропаться политикой по умолчанию.
В итоге, скрипт iptables для шлюза будет выглядеть следующим образом. Отличается от предыдущих правил.

#!/bin/sh # Очистить все правила iptables -P INPUT ACCEPT iptables -P FORWARD ACCEPT iptables -P OUTPUT ACCEPT iptables -t nat -P PREROUTING ACCEPT iptables -t nat -P POSTROUTING ACCEPT iptables -t nat -P OUTPUT ACCEPT iptables -t mangle -P PREROUTING ACCEPT iptables -t mangle -P OUTPUT ACCEPT iptables -F iptables -t nat -F iptables -t mangle -F iptables -X iptables -t nat -X iptables -t mangle -X ### Переменные # Интерфейс, смотрящий в интернет INET_IF="eth0" # Белый IP адрес, принадлежащий $INET_IF INET_IP="x.x.x.x" # Локальная сеть LOCAL_NET="192.168.0.0/24" # IP адрес локального веб сервера WEB_SERVER="192.168.0.10" # Включить в ядре форвард IPv4 пакетов # Путь до sysctl SYSCTL="/sbin/sysctl -w" if [ "$SYSCTL" = "" ] then echo "1" > /proc/sys/net/ipv4/ip_forward else $SYSCTL net.ipv4.ip_forward="1" fi ### Правила по умолчанию iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT ACCEPT ### INPUT # Разрешить входящие соединения с локалхоста iptables -A INPUT -i lo -j ACCEPT # Разрешить принимать уже установленные соединения iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # Разрешить SSH только из локальной сети iptables -A INPUT -p TCP -s $LOCAL_NET --dport 22 -j ACCEPT # Разрешить запросы к кэширующему DNS серверу только из локальной сети iptables -A INPUT -p TCP -s $LOCAL_NET --dport 53 -j ACCEPT iptables -A INPUT -p UDP -s $LOCAL_NET --dport 53 -j ACCEPT ### FORWARD # Разрешить уже установленные пересылаемые соединения iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # TCP порты, по которым разрешено ходить в интернет машинам из локальной сети FORWARD_TCP_PORTS="80,443" # Разрешить машинам локальной сети ходить в интернет по указанным TCP портам iptables -A FORWARD -p TCP -s $LOCAL_NET -m multiport --dport $FORWARD_TCP_PORTS -j ACCEPT iptables -A FORWARD -p TCP -d $LOCAL_NET -m multiport --dport $FORWARD_TCP_PORTS -j ACCEPT ### NAT # Включить NAT для локальной подсети iptables -t nat -A POSTROUTING -s $LOCAL_NET -o $INET_IF -j SNAT --to-source $INET_IP # Пробросить порт на локальный веб сервер на нестандартный порт iptables -t nat -A PREROUTING -p TCP -d $INET_IP --dport 80 -j DNAT --to-destination $WEB_SERVER:8090

Вывод текущих правил

Посмотреть правила для таблицы filter , т.е. команда покажет основные правила iptables:

Iptables -L -n

Для конкретной таблицы, например nat и mangle:

Iptables -t nat -L -n iptables -t mangle -L -n

Статьи по теме: