Занятный iptables

Я постоянно откладывал на будущее изучение iptables. Неужели я надеялся, что мне ни когда  это знание не пригодится.
И вот случилось, на работе мне нужно разрешить прохождение почтового трафика через мой шлюз, на котором стоит кеширующий прокси сервер-squid
И так приступим к занимательному изучению iptables

  1. Блокирование заданного адреса
  2. Удаление правила
  3. Блокирование соединений по UID пользователя
  4. Включение логирование пакетов и определение состояния пакета
  5. Прозрачное проксирование с помощью Squid
  6. Отключение проксирования на локальный адрес
  7. Мои настройки фаервола для домашней сети

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

iptables -A INPUT -s адрес_хакира -j DROP

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


Идём далее, после того как мы залатали дыры. нам нужно удалить запрет "хакиру" подключаться к нашему компьютеру, а делается это так:

iptables-save

тут мы увидим список всех правил, в нём нужно определить номер правила для нашего "хакира" (предположим, что оно первое) и сделать так:

iptables -D INPUT 1

В iptables есть особо классная вещица: можно фильтровать по пользователям и это просто шикарно.
Например у меня в системе UID=2000, а у жены UID=2001
чтобы запретить ТОЛЬКО мне  появлятся на google.ru, я должен создать такое правило

iptables -A OUTPUT -d google.ru -m owner --uid-owner 2000 -j REJECT

действует это только на цепочку OUTPUT
работает это так
как только появляется пакет уходящий от НАС (OUTPUT)
мы проверяем адрес назначения, если он равняется google.ru И
подгружаем модуль -m owner  (должен быть собран с ядром) который проверяет
--uid-owner процесса пославшего пакет, если он равняется 2000 ТОГДА
мы делаем  -j REJECT, отправляем пакет с сообщение что адрес не доступен
это легко проверяется:
попробуйем самый простой способ проверки, скачать страничку с помощью wget с опцией отключающей прокси

wget google.ru --no-proxy
> --2008-07-04 20:32:41--  http://google.ru/
> Распознаётся google.ru... 72.14.221.104, 66.249.93.104, 216.239.59.104
> Устанавливается соединение с google.ru|72.14.221.104|:80... сбой: В соединении отказано.
> Устанавливается соединение с google.ru|66.249.93.104|:80... сбой: В соединении отказано.
> Устанавливается соединение с google.ru|216.239.59.104|:80... сбой: В соединении отказано.


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

ping google.ru  -c2
> PING google.ru (216.239.59.104) 56(84) bytes of data.
> 64 bytes from 216.239.59.104: icmp_seq=1 ttl=246 time=99.3 ms
> 64 bytes from 216.239.59.104: icmp_seq=2 ttl=246 time=91.3 ms

тут мы пингуем забаненный сервер гугла и отправляем ВСЕГО 2 пакета (-c2)
но о ужас, почему то сервер пингуется, хотя зайти на него ни как по другому нельзя
Но вспомните вы запретили пропускать пакеты до google.ru пользователю с UID=2000
а теперь посмотрите

ls -lah `which ping`

> -rwsr-xr-x 1 root root 30K Дек  8  2007 /bin/ping
программа-ping запускается с правами root, так как на ней стоит setuid, а значит UID процеса ping всегда будет равен 0


Имеется у iptables ещё интересная возможность: записывать пакеты по определённым правилам
например нам нужно записывать в журнал все входящие соединения на 22  порт
пишем правило:

iptables -A INPUT --dport 22 -t tcp  -j LOG --log-level=debug

тут мы все входящие TCP пакеты прогоняем через правило
--dport 22, тоесть порт назначения = 22, и если такие попадаются пишем сообщение в syslog
но представьте сколько там будет записей с всей ssh сессии, тысячи если не сотни тысяч,
Выходит, что нам необходимо записать только первый пакет,
добавляем в правило следующее -m state --state NEW
тут я подгрузил модуль state и указал фильтру отобрать только новый пакет TCP сессии

iptables -A INPUT --dport 22 -t tcp  -m state --state NEW  -j LOG --log-level=debug

Предположим у нас умеется следующая задача: разбросать один вид трафика по разным каналам, а другой заблокировать
имеется сервер с eth0 (172.19.145.99 слушает эту сеть ) на нём squid на 172.19.145.99:3128 и внешняя сетевая карта eth1 192.168.1.1
соединения http,xmmp,icq необходимо пропустить только через прокси
соединения ssh,pop3,https пропустить, а все остальные соединения заблокировать, делает это так

отбираем все tcp пакеты с eth0 идущие наружу на порты 80,5222 и применяем к ним задачу -j DNAT --to-destination 172.19.145.99:3128
перенаправляющую их на местный прокси сервер

iptables -t nat -A POSTROUTING -i eth0 -p tcp -m multiport --dports 80,5222 -j DNAT --to-destination 172.19.145.99:3128

отбираем все tcp пакеты с eth0 идущие наружу на порты 22,110,443 и применяем к ним задачу -j MASQUERADE
натящую их на внешную сетевую карту

iptables -t nat -A POSTROUTING -s 172.19.0.0/255.255.0.0 -o eth1 -p tcp -m multiport --dports 22,110,443 -j MASQUERADE

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

iptables -t nat -A PREROUTING  -i eth0 --destination \! 172.19.145.99 -p tcp -m multiport --dports 21,80,5222 -j DNAT --to-destination 172.19.145.99:3128

 

 


а вот так настроен мой домашний фаервол ( iptables v1.3.8 ), он маскарадит 443 порт, на этом порту работают обновления firefox, gmail и различные секурные(ssl) сервисы и редиректит 80 порт на находящийся тут же прокси сервер, причём игнорируя запросы на локальный веб сервер, на котором находятся зеркала наших сайтов, 

iptables -t nat -A PREROUTING -d ! 192.168.80.76 -i eth0 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 3128 
iptables -t nat -A POSTROUTING -o ppp0 -p tcp -m multiport --dports 443 -j MASQUERADE
Комментариев 3
Марина Глушкова
Марина Глушкова

2015-09-10

Спасибо, очень пригодилось!

Alex Mordvin
Alex Mordvin

2015-09-10

Занятно...

Нужна авторизация с помощью
Об авторе
Илья Илья

меня можно найти тут