Прежде всего:
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
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, будет открываться сайт нашего провайдера. Очень классно, когда нужно накрутить рейтинг в веб-счётчиках
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
В практике это можно применить, для того, чтобы закрыть доступ в интернет для локальной сети, открывая вместо реальных сайтов — страничку, где будет написано, что у Вас только локалка и доступ в интернет Вам закрыт. Либо когда падает интернет канал, то провайдер таким образом сможет оповещать своих клиентов в режиме он-лайн о текущих проблемах сети. Это более приятный способ взаимоотношений с клиентами, чем если бы они видели просто “Сервер не найден”.
Теперь попробуем замену исходных 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
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. Например:
<!--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 в мир, если правильно настроена маршрутизация.
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).
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
Взято отсюда