Введение в IPTables, Описание работы и введение в синтаксис

Автор | 24.09.2008

Прежде всего:

http://iptables-tutorial.frozentux.net/ipt…s-tutorial.html (англ)

http://gazette.linux.ru.net/rus/articles/i…s-tutorial.html (русс)

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

Что такое firewall знают многие, однако мало кто знает очень хорошо, как он работает. И вообще, как проходят пакеты через сам сервер, через маршрутизацию и через цепочки firewall’а.

Объясняю популярно. Есть сервер — роутер, есть клиент и есть сайт mail.ru.

Когда клиент набирает в браузере адрес сайта www.mail.ru, его компьютер в первую очередь отправляет запрос к его DNS серверу (к DNS серверу провайдера, а тот в свою очередь уже ищет IP-адрес у мирового DNS, затем у DNS самого mail.ru). Этот процесс нас особо не интересует. Идём дальше.

Получив IP-адрес сайта mail.ru, компьютер клиента отправляет на него запрос (т.е. tcp пакет, т.к. http протокол работает по 80-му и протоколу tcp) по HTTP протоколу (попросту GET http://www.mail.ru/ — просит выдать ему страничку).

У всех пакетов есть заголовок и данные. В заголовке храниться информация о IP-клиента (source ip address — исходный ip), IP-адрес сайта mail.ru (destination ip адрес — IP адрес получателя пакета/запроса), протокол (tcp), порт клиента, т.е. порт, откуда отправили запрос (он всегда меняется, может быть примено где то 30000 +- 10000). И порт получателя, т.е. mail.ru — тут он будет 80-й. Т.к. пакет у нас — запрос к веб серверу по протоколу http (tcp/80). Далее ещё идёт в заголовке всякая служебная информация, например контрольная сумма пакета и т.д. С данными всё понятно — там идёт просто текст в формате http протокола: GET http://www.mail.ru/ плюс информация о клиентском браузере и версии ОС.

После того, как mail.ru получил этот пакет, он проверяет, на какой сайт отправили запрос (на mail.ru, на list.ru или на что там). И отдаёт клиенту уже html-код страницы mail.ru. Опять таки отсылается пакет, но тут уже исходный адрес (source) — IP-адрес mail.ru, адрес получателя (destination) — IP-клиента, исходный порт (source port) уже 80! А порт назначения — порт клиента, откуда был отправлен пакет, т.к. 30000 +- 10000 или даже больше.

Именно так видит пакеты сервера, которые стоят между клиентом и самим mail.ru.

Когда пакет от клиента проходит через сервер, на котором мы настраиваем файрволл, мы должны понимать, какие source/destination IP-адреса и порты указаны в каких пакетах. Например чтобы закрыть доступ к веб серверу сайта mail.ru (т.е. просто закрыть этот сайт), достаточно команд:

блокируем запросы от клиента на mail.ru

iptables -A FORWARD -s 217.29.125.1 -d 194.67.57.26 -p tcp –dport 80 -j DROP

блокируем ответы от mail.ru клиенту 

iptables -A FORWARD -s 194.67.57.26 -d 217.29.125.1 -p tcp --sport 80 -j DROP

Здесь: 217.29.125.1 — IP-адрес клиента, 194.67.57.26 — IP адрес сервера mail.ru, а 80 — порт веб сервера http. Как видите, я не указываю порта клиента, т.к. невозможно заранее предугадать, какой он будет (т.к. он постоянно меняется). Зато есть порт самого веб сервера, который мы и используем.

Теперь введение в синтаксис IPTables.

Во первых, у iptables есть три таблицы: mangle, nat и filter.

Таблица mangle нужна, чтобы менять что-то в заголовках пакетов. TOS и TTL нас пока не интересует. А вот с помощью MARK — можно выбрать правило таблицы маршрутизации, через который пакет будет переслан на сам сайт mail.ru. Это нужно когда у нас два провайдера, и мы тут можем выбирать, через какого из них пойдёт запрос к mail.ru. Пример:

iptables -t mangle -A PREROUTING -s 217.29.125.1 -d 194.67.57.26 -p tcp --dport 80 -j MARK --set-mark 0x64

А в правилах маршрутизации, таблица 0x64 — у нас провайдер УзПАК (например). Маршрутизацию пока трогать не будем. Просто я показал, что можно делать с помощью mangle.

Далее, таблица nat используется, чтобы менять source/destination IP-адреса в заголовках пакетов. Т.е. можно вместо mail.ru (194.67.57.26) отправить запрос на наш веб-сервер 217.29.124.3 (www.tps.uz). И тогда вместо mail.ru, будет открываться сайт нашего провайдера. Очень классно, когда нужно накрутить рейтинг в веб-счётчиках wink.gif

Синтаксис: 

iptables -t nat -A PREROUTING -s 217.29.125.1 -d 194.67.57.26 -j DNAT --to-destination 217.29.124.3

Клиенту тогда откроется вместо сайта mail.ru, сайт www.tps.uz wink.gif

В практике это можно применить, для того, чтобы закрыть доступ в интернет для локальной сети, открывая вместо реальных сайтов — страничку, где будет написано, что у Вас только локалка и доступ в интернет Вам закрыт. Либо когда падает интернет канал, то провайдер таким образом сможет оповещать своих клиентов в режиме он-лайн о текущих проблемах сети. Это более приятный способ взаимоотношений с клиентами, чем если бы они видели просто “Сервер не найден”.

Теперь попробуем замену исходных IP-адресов — Source Network Address Translation — SNAT. Она нужна, когда у Вас в локалке используются нереальные (невалидные) IP-адреса, которые не смогут работать в интернете. В этом случае Вы просто заменяете их на реальный IP-адрес сервера и во всём мире клиентов будет видно под айпишников вашего сервера. Это довольно часто применяемая технология. Теперь пример:

iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -d ! 192.168.0.0/24 -j SNAT --to-source 217.29.124.1

Итак, 192.168.0.0/24 — это IP-сеть нашей локалки. Почему я указал в параметре IP-адресов получаетелей ! 192.168.0.0/24?.. Это просто означает, что все IP-адреса, кроме сети 192.168.0.0/24. Т.е. в этом случае, нам нет необходимости преобразовывать локальные IP-адреса в реальный, если они попытаются посылать пакеты через сервер так же на локальные IP-адреса своей же сети. Ну и 217.29.124.1 — это тот IP-адрес, под которым Ваши локальные компьютеры будут видны в интернете. Т.е. это реальный IP-адрес сервера.

Вы наверное заметили, что в случае с DNAT использовался PREROUTING, а с SNAT — POSTROUTING?.. Чем же это объяснить?..

Всё дело в том, что PREROUTING работает как только пакет пришел на сервер, до того, как он пройдёт через машрутизацию, а POSTROUTING — уже после маршрутизации. Дело в том, что для iptables требуется сначала заменить IP-адрес получателя (destination) , а потом уже осуществлять маршрутизацию. К примеру тот же случай, когда сайт mail.ru надо пускать через другого провайдера. Как он пойдёт через другого провайдера, если он уже пошел через первого?..

К примеру, нам нужно, чтобы кому-то из клиентов вместо mail.yandex.ru открывался mail.ru. Причём mail.yandex.ru идёт через первого провайдера, а mail.ru полюбому для всех идёт через второго провайдера. С помощью DNAT, мы перенаправляем пакеты, идущие на mail.yandex.ru на mail.ru:

iptables -t nat -A PREROUTING -s 217.29.125.1 -d 213.180.194.65 -p tcp --dport 80 -j DNAT --to-destination 194.67.57.26
А затем, с помощью mangle, мы отправляем все пакеты идущие на mail.ru через второго провайдера: 

iptables -t mangle -A PREROUTING -s 217.29.125.1 -d 194.67.57.26 -j MARK --set-mark 0x64

Если бы DNAT был в POSTROUTING, тоесть после маршрутизации, то мы уже не смогли бы пустить запрос на mail.yandex.ru, перенаправленный на mail.ru через другой провайдер, т.к. POSTROUTING запускается полюбому после PREROUTING.

Как видите — всё достаточно сложно и знать один только синтаксис — бесполезно. Нужно ещё чётко представлять, как пакеты проходят через таблицы и цепочки.

А в случае с SNAT — всё просто, сначала выполняются все передряги с пусканием через разных провайдеров в mangle PREROUTING, а потом уже мы просто меняем исходный локальный айпишник на реальный и отправляем пакет в мир (нужно не забывать, кто тут source а кто destination — в данном случае, source — это локальный IP-адрес клиента, а destination — реальный адрес веб-сервера. Это в случае с SNAT, а в случае с DNAT — source — уже реальный IP-адрес клиента и это другой случай, когда у клиента реальные IP-адреса уже. А если Вам нужно работать одновременно и с DNAT и с SNAT — это гораздо сложнее и это мы пока рассматривать не будем, т.к. тут и любой профессиональный админ может запутаться).

Тут я вкраце объяснил, зачем нужны mangle и nat. Перейдём к filter. Для тех, кто не понял на счёт mangle/nat — не расстраивайтесь, главное понять как работает filter. И только после этого уже можно считать свой уровень профессионализма достаточным для nat, а с mangle — нужно ещё подучиться.

Итак, таблица filter имеет три цепочки:

INPUT — входящий трафик на сам сервер

FORWARD — трафик, проходящий через сервер

OUTPUT — исходящий трафик с сервера самого.

INPUT, OUTPUT — это правила для самого сервера. Тоесть мы тут блокируем только пакеты идущие на/с сервер/а. А FORWARD — это трафик проходящий через сервер и на нём можно блокировать уже тех, кто подключён к этому серверу и выходит через него в мир.

Рассмотрим синтаксис: 

iptables -A INPUT -s 217.29.125.1 -j DROP

Вы уже заметили, что в случае с таблицей filter, указывать явно iptables -t filter — не обязательно, а вот с таблицами nat и mangle — надо обяхательно: iptables -t nat, iptables -t mangle.

Далее идёт действие с цепочкой:

-A — append — добавить это действие в конец цепочки

-I — insert — вставить это действие в начало цепочки

-D — delete — удалить это действие

-F — flush– очистить всю цепочку

-X — delete-chain — удалить цепочку

-L — list — просмотреть правила цепочки

И т.д. Полное описание в таблице 6.2 Команды в iptables tutorial.

Далее идёт название цепочки — INPUT

Следущий параметр уже может варьироваться, это может быть source/destination ip, source/destination port, protocol или вообще может не присутствовать:

-s — source IP — исходный IP-адрес

-d — destination IP — IP-адрес получателя

После параметра -s или -d может использоваться символ !, он означает логическое условие НЕ. Тоесть ! 192.168.0.0/24 — означает все IP-сети, кроме 192.168.0.0/24.

-j — означает действие этого правила цепочки:

DROP — отбрасывать пакеты, т.е. просто игнорировать их или удалять

ACCEPT — принимать пакеты, но дальше по цепочке они уже не пойдут!

RETURN — выйти из текущей цепочки и продолжить выполнение дальше

И т.д.

Можно ещё указывать -p tcp, -p udp, -p icmp — протоколы, –sport 80 — исходный (source) порт 80-й, –dport 80 — порт получателя (destination), -i eth0 — входной сетевой интерфейс eth0, -o eth0 — исходный сетевой интерфейс eth0 и многое другое.

Замечание: –sport и –dport могут использоваться, только если указан простокол -p tcp или -p udp. Причём не следует путать разные протоколы и порты. Например -p udp –dport 80 — ошибка, т.к. HTTP не работает по udp! А работает только по tcp.

Список соответствий между портами и протоколами можно посмотреть в файле /etc/services. Например:

CODE 

 

<!--ec1-->ftp-data         20/tcp    #File Transfer [Default Data]

ftp-data         20/udp    #File Transfer [Default Data]

ftp              21/tcp    #File Transfer [Control]

ftp              21/udp    #File Transfer [Control]

ssh              22/tcp    #Secure Shell Login

ssh              22/udp    #Secure Shell Login

telnet           23/tcp

telnet           23/udp

smtp             25/tcp    mail         #Simple Mail Transfer

smtp             25/udp    mail         #Simple Mail Transfer

domain           53/tcp    #Domain Name Server

domain           53/udp    #Domain Name Server

http             80/tcp    www www-http         #World Wide Web HTTP

http             80/udp    www www-http         #World Wide Web HTTP

pop3            110/tcp    #Post Office Protocol - Version 3

pop3            110/udp    #Post Office Protocol - Version 3

https           443/tcp

https           443/udp

ircd            6667/tcp   #Internet Relay Chat (unoffical)


Однако, следует помнить, хоть порт 80-й по протоколу udp зарезервирован для HTTP — но он его реально не использует. Зато DNS активно использует порт 53 по протоколу udp. И пинги (плюс служебные команды traceroute’а) используют протокол icmp. К тому же сам traceroute использует порты выше 30000 по протоколу udp.

Теперь осталось самое простое.

Закрываем некоторые важные порты с мира, оставляя их доступными только с определённых IP-адресов.

iptables -A INPUT -s ! 192.168.0.1 -p tcp --dport 22 -j DROP # закрываем SSH со всех айпишников, кроме 192.168.0.1 

iptables -A OUTPUT -d ! 192.168.0.1 -p tcp --sport 22 -j DROP # закрываем ответы с сервера по SSH для всех айпишников, кроме 192.168.0.1

iptables -A INPUT -p tcp --dport 23 -j DROP # закрываем Telnet вообще для всех айпишников 

iptables -A OUTPUT -p tcp --sport 23 -j DROP # и закрываем ответы сервера по телнет для всех айпишников.

И т.д.

Теперь рассмотрим, как закрыть доступ к некоторым портам/айпишникам с самого сервера.

iptables -A INPUT -s 192.168.0.1 -p tcp --sport 22 -j DROP # закрываем ответы с сервера 192.168.0.1 пришедшие по ssh 

iptables -A OUTPUT -d 192.168.0.1 -p tcp --dport 22 -j DROP # закрываем возможность заходить с этого сервера, на сервер 192.168.0.1 по SSH

Можно вообще заблокировать всё с конкретного IP-адреса:

iptables -A INPUT -s 192.168.0.1 -j DROP # вообще закрываем все пакеты, пришедшие на этот сервер, с сервера 192.168.0.1 

iptables -A OUTPUT -d 192.168.0.1 -j DROP # закрываем все пакеты от нашего сервера на 192.168.0.1

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

Поэтому нужно использовать и таблицу FORWARD чтобы вообще заблокировать всё для 192.168.0.1: 

iptables -A FORWARD -s 192.168.0.1 -j DROP # блокируем все пакеты с 192.168.0.1 в мир

iptables -A FORWARD -d 192.168.0.1 -j DROP # блокируем все пакеты на 192.168.0.1 с мира

Теперь вернёмся к нашему первому примеру с mail.ru. На сервере видно, что пакеты от клиента 217.29.125.1 (source IP) к сайту mail.ru (destination IP) идут от какого-то порта (source port), на 80-й порт (destination port) по протоколу tcp. А ответы от mail.ru (source IP) идут уже от 80-го порта (source port) на какой то порт клиента (destination port) клиента 217.29.125.1 (destination ip).

Именно поэтому, выглядеть блокировка mail.ru для клиента будет так: 

iptables -A FORWARD -s 217.29.125.1 -d 194.67.57.26 -p tcp --dport 80 -j DROP # блокировка трафика от клиента на mail.ru

iptables -A FORWARD -s 194.67.57.26 -d 217.29.125.1 -p tcp --sport 80 -j DROP # блокировка трафика от mail.ru клиенту.

Теперь понятно, какими должны быть source IP, destination IP, source port и destination port и в каких случаях?..

На основе всего вышесказанного, можно уже строить собственные правила firewall’а. Однако следует помнить, что любая неверно написанная команда может привести к тому, что Вы потеряете удалённый доступ к серверу!

P.S. Остались нерассмотренными:

1. Связка iptables+mark+iproute2

2. Действия ACCEPT, RETURN

3. Команды INSERT, FLUSH, DELETE-CHAIN, ZERO, NEW-CHAIN

 

 

Взято отсюда

Залишити відповідь