Тут приводятся примеры настройки для различных ситуаций. Про структуруIPTABLES, управление, архитектуру и прочее — смотрите в цикле Linux: IPTABLES — руководство: часть 1 — основы IPTABLES.
Настройка осуществляется на:
# lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux 6.0.7 (squeeze)
Release: 6.0.7
Codename: squeeze
Создаём файл настроек для IPTABLES:
# touch /etc/network/if-up.d/iptables.conf
Разрешаем его запуск:
# chmod +x /etc/network/if-up.d/iptables.conf
ВАЖНО: некоторые опции указываются с двумя тире — хотя в примерах они отображаются как одно! Учтите это, если копируете правила прямо из блога:
— — state
— — dport
— — tcp-flags
— — reject-with
В него добавляем:
#!/bin/bash
# Задаём путь к исполняемому файлу IPTABLES
IPTABLES=’/sbin/iptables’
# Сбрасываем существующие правила для всех таблиц и цепочек
$IPTABLES -F
$IPTABLES -X
# Задаём правила по-умолчанию (если не сработало не одно правило из цепочки — сработает правило отсюда)
$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT ACCEPT
$IPTABLES -P FORWARD ACCEPT
# Разрешаем весь трафик по loopback интерфейсу lo0
$IPTABLES -A INPUT -i lo -j ACCEPT
# Разрешаем трафик уже установленным и создающим новые подключения соединениям:
$IPTABLES -A INPUT -m state —state RELATED,ESTABLISHED -j ACCEPT
# Разрешаем входящий SSH через интерфейс eth0
$IPTABLES -A INPUT -p tcp -i eth0 —dport 22 -j ACCEPT
Теперь разберём созданные правила подробнее.
В IPTABLES используется три вида таблиц:
- Mangle — обычно эта цепочка используется для внесения изменений в заголовок пакета, например для изменения битов TOS и пр.
- Nat — эта цепочка используется для трансляции сетевых адресов (Destination Network Address Translation). Source Network Address Translation выполняется позднее, в другой цепочке. Любого рода фильтрация в этой цепочке может производиться только в исключительных случаях.
- Filter — здесь производится фильтрация трафика. Помните, что все входящие пакеты, адресованные нам, проходят через эту цепочку, независимо от того с какого интерфейса они поступили.
Соответственно, нас интересует третья таблица Filter. В этой таблицы имеются три встроенные цепочки:
- INPUT — для входящих пакетов.
- FORWARD — для проходящих через данную машину к другой.
- OUTPUT — для исходящих.
Пакет, проходящий через эти цепочки, исходя из правила может быть пропущен (ACCEPT) или отброшен (DROP):
- ACCEPT — пропустить пакет; просмотр таблицы завершается
- DROP — выбросить молча; просмотр завершается не только для текущей цепочки, но и для других таблиц
- REJECT — выбросить, известив отправителя (—reject-with тип-извещения)
Первое созданное нами правило для цепочки INPUT задаёт поведение по-умолчанию для пакетов, проходящих через этот фильтр. В случае, если ни одно из правил, заданных ниже не будет применено к пакету — он будет отброшен (DROP) без уведомления отправителя:
$IPTABLES -P INPUT DROP
Пакеты, проходящие фильтр OUTPUT соответственно будут пропущены:
То же самое касается «транзитных» пакетов:
$IPTABLES -P OUTPUT ACCEPT
Следующее правило:
$IPTABLES -A INPUT -i lo -j ACCEPT
Задаёт пользовательское правило (-A) в фильтр INPUT для пакетов, проходящих через интерфейс (-i) loopback (lo) и выполняет цель (-j) «принять» (ACCEPT).
В следующем правиле используется модуль (-m) state, который проверяет состояние устанавливаемого соединения — RELATED или ESTABLISHED и если соединение подходит под это правило — разрешает его:
$IPTABLES -A INPUT -m state —state RELATED,ESTABLISHED -j ACCEPT
Возможные состояния: INVALID — пакет не связан с каким-либо известным соединением, ESTABLISHED— пакет связан с соединением, по которому уже проходили пакеты в обоих направлениях, NEW — пакет инициирует новое соединение, либо связан с соединением, по которому ещё не проходили пакеты в обоих направлениях , RELATED — пакет инициирует новое соединение, но также связан с уже существующим соединением, например при передаче данных по FTP или сообщении об ошибке ICMP, SNAT — виртуальное состояние, положительный результат выдаётся если исходный адрес источника отличен от адреса, который должен получить ответ, DNAT — виртуальное состояние, положительный результат выдаётся если исходный адрес получателя отличен от адреса отправителя ответа.
В следующем правиле для фильтра входящих соединений INPUT мы указываем:
$IPTABLES -A INPUT -p tcp -i eth0 —dport 22 -j ACCEPT
Протокол (-p) TCP, интерфейс (-i) eth0, и порт назначения, т.е. порт на нашем сервере, к которому устанавливается соединение (—dport) 22.
Добавим ещё несколько правил:
#Делаем защиту от DOS атак:
$IPTABLES -A INPUT -p tcp -m tcp —tcp-flags SYN,ACK,FIN,RST RST -m limit —limit 1/s -j ACCEPT
# Разрешаем FTP
$IPTABLES -A INPUT -i eth0 -p tcp —dport 21 -j ACCEPT
# Разрешаем HTTP
$IPTABLES -A INPUT -i eth0 -p tcp —dport 80 -j ACCEPT
# Разрешаем HTTPS
$IPTABLES -A INPUT -i eth0 -p tcp —dport 443 -j ACCEPT
# Разрешаем SMTP только из сети 77.120.***.1/24
$IPTABLES -A INPUT -s 77.120.***.1/24 -i eth0 -p tcp —dport 25 -j ACCEPT
# Разрешаем SMTP всем, но запрещаем отправку для адреса 77.120.***.46
$IPTABLES -A INPUT -s ! 77.120.***.46 -i eth0 -p tcp —dport 25 -j ACCEPT
# РазрешаемPOP3 только с IP 77.120.***.46
$IPTABLES -A INPUT -s 77.120.***.46 -i eth0 -p tcp —dport 110 -j ACCEPT
# Разрешаем DNS
$IPTABLES -A INPUT -i eth0 -p udp —sport 53 -j ACCEPT
# Доступ к портам 8081 и 8082 разрешаем только из сетей 91.***.**.0/24, 195.***.***.0/23 и IP 37.***.**.174
for net in 91.***.**.0/24 195.***.***.0/23 37.***.**.174; do
$IPTABLES -A INPUT -p tcp -m tcp -s $net -m multiport —dports 8081,8082 -j ACCEPT
done
$IPTABLES -A INPUT -p tcp -m tcp -m multiport —dports 8081,8082 -j DROP
# Разрешаем ping
$IPTABLES -A INPUT -p icmp -j ACCEPT
Перезапустим скрипт, что бы правила вступили в силу, заодно проверим ошибки:
# /etc/network/if-up.d/iptables.conf reload
В случае ошибок — будет указано в какой строке какая ошибка. Например:
iptables v1.4.8: unknown protocol `tcp—dport’ specified
Пропущен пробел после tcp.
Посмотреть текущие правила можно с помощью опции —list:
# iptables —list
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT all — anywhere anywhere
ACCEPT all — anywhere anywhere state RELATED,ESTABLISHED
ACCEPT tcp — anywhere anywhere tcp dpt:ssh
ACCEPT tcp — anywhere anywhere tcp flags:FIN,SYN,RST,ACK/RST limit: avg 1/sec burst 5
ACCEPT tcp — anywhere anywhere tcp dpt:ftp
ACCEPT tcp — anywhere anywhere tcp dpt:www
ACCEPT tcp — anywhere anywhere tcp dpt:https
ACCEPT tcp — 0.***.***.77.colo.static.dc.volia.com/24 anywhere tcp dpt:smtp
ACCEPT tcp — !0.***.***.77.colo.static.dc.volia.com/24 anywhere tcp dpt:smtp
ACCEPT tcp — 46.***.***.77.colo.static.dc.volia.com anywhere tcp dpt:pop3
ACCEPT udp — anywhere anywhere udp spt:domain
ACCEPT tcp — 91.***.**.0/24 anywhere tcp multiport dports tproxy,8082
ACCEPT tcp — 195.***.***.0/23 anywhere tcp multiport dports tproxy,8082
ACCEPT tcp — 37.***.***.174 anywhere tcp multiport dports tproxy,8082
DROP tcp — anywhere anywhere tcp multiport dports tproxy,8082
ACCEPT icmp — anywhere anywhere icmp echo-request
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Ещё несколько примеров использования.
Проверить статус IPTABLES:
# iptables -L -n -v
Chain INPUT (policy DROP 176 packets, 36734 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all — lo * 0.0.0.0/0 0.0.0.0/0
179K 40M ACCEPT all — * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
1 100 ACCEPT tcp — eth0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
0 0 ACCEPT tcp — eth0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:21
3 180 ACCEPT tcp — eth0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
1 28 ACCEPT icmp — * * 0.0.0.0/0 0.0.0.0/0
1 60 ACCEPT tcp — * * 195.191.226.102 0.0.0.0/0 tcp dpt:514
0 0 ACCEPT tcp — * * 91.218.228.236 0.0.0.0/0 tcp dpt:514
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 180K packets, 12M bytes)
pkts bytes target prot opt in out source destination
Ключи:
-L: показать список правил;
-v: выводить дополнительную информацию;
-n: отображать ip адрес и порт числами, а не перобразовывать в FQDN-имя.
Вывести текущие правила, только INPUT:
# iptables -L INPUT -n -v
Или только OUTPUT:
# iptables -L OUTPUT -n -v
Добавление и удаление правил.
Вывести текущие правила INPUT с указанием строк (номеров правил):
# iptables -L INPUT -n —line-numbers
Chain INPUT (policy DROP)
num target prot opt source destination
1 ACCEPT all — 0.0.0.0/0 0.0.0.0/0
2 ACCEPT all — 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
3 ACCEPT tcp — 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
4 ACCEPT tcp — 0.0.0.0/0 0.0.0.0/0 tcp dpt:21
5 ACCEPT tcp — 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
6 ACCEPT icmp — 0.0.0.0/0 0.0.0.0/0
7 ACCEPT tcp — 195.191.226.102 0.0.0.0/0 tcp dpt:514
8 ACCEPT tcp — 91.218.228.236 0.0.0.0/0 tcp dpt:514
Что бы добавить правило перед 5:
# iptables -I INPUT 5 -i eth0 -p tcp —dport 8080 -j ACCEPT
Проверяем:
# iptables -L INPUT -n —line-numbers | grep 80
5 ACCEPT tcp — 0.0.0.0/0 0.0.0.0/0 tcp dpt:8080
6 ACCEPT tcp — 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
Старое правло «подвинулось» на 6 строку, новое — стало 5.
Заблокировать входящие соединения для IP 8.8.8.8:
# iptables -I INPUT 7 -s 8.8.8.8 -j DROP
Проверяем:
# iptables -L INPUT -n —line-numbers | grep 8.8.8.8
7 DROP all — 8.8.8.8 0.0.0.0/0
Заблокировать исходящий ICMP на facebook.com:
# iptables -A OUTPUT -p icmp -d www.facebook.com -j DROP
Пробуем:
# ping 173.252.101.26
PING 173.252.101.26 (173.252.101.26) 56 (84) bytes of data.
ping: sendmsg: Operation not permitted
ping: sendmsg: Operation not permitted
Посмотрим в правилах:
# iptables -L OUTPUT -n —line-numbers
Chain OUTPUT (policy ACCEPT)
num target prot opt source destination
1 DROP tcp — 0.0.0.0/0 173.252.101.26
Использование MAC-адреса в правилах — разрешаем SSH только с MAC 00:60:ef:0b:f6:1a:
# iptables -A INPUT -p tcp —destination-port 22 -m mac —mac-source 00:60:ef:0b:f6:1a -j ACCEPT
Разрешить SSH с адресов начиная от 10.0.0.5 и до 10.0.0.10 включительно:
# iptables -A INPUT -p tcp —destination-port 22 -m iprange —src-range 10.0.0.5-10.0.0.10 -j ACCEPT
Ограничить количество параллельных соединений к серверу для одного адреса
Для ограничений используется connlimit модуль. Чтобы разрешить только 3 SSH соединения на одного клиента:
# iptables -A INPUT -p tcp —syn —dport 22 -m connlimit —connlimit-above 3 -j REJECT
Установить количество запросов HTTP до 20:
# iptables -p tcp —syn —dport 80 -m connlimit —connlimit-above 20 —connlimit-mask 24 -j DROP
Опции:
—connlimit-above 3: указывает, что правило действует только если количество соединений превышает 3;
—connlimit-mask 24: указывает маску сети.
Ссылки по теме:
http://konungr.ru
http://www.doless.ru
http://nikmy.ru
http://www.iptables.ru
http://www.opennet.ru
http://www.opennet.ru
http://rus-linux.net
http://cartmanees.blogspot.com
http://rusua.org.ua
http://www.fullautomatic.ru