Я постоянно откладывал на будущее изучение iptables. Неужели я надеялся, что мне ни когда это знание не пригодится.
И вот случилось, на работе мне нужно разрешить прохождение почтового трафика через мой шлюз, на котором стоит кеширующий прокси сервер-squid
И так приступим к занимательному изучению iptables
- Блокирование заданного адреса
- Удаление правила
- Блокирование соединений по UID пользователя
- Включение логирование пакетов и определение состояния пакета
- Прозрачное проксирование с помощью Squid
- Отключение проксирования на локальный адрес
- Мои настройки фаервола для домашней сети
Предположим, вы обнаружили, что на внашем компьютере работает злой "хацкир". Судорожно вспоминаете сделан ли бекап, команды отрубающие юзера, молимся, котороче вы в панике.
Но можно вспомнить про 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
2015-09-10
Занятно...