iptables и динамические правила (keep state)

Такого понятия как динамические правила в iptables не существует. Правильно называть — отслеживание состояния keep state.

В Iptables существуют такие типа состояния (доступно, если модуль ‘state‘ загружен с помощью ‘-m state‘):

NEW — Все пакеты устанавливающие новое соединение (Например, запрос на установление соединения)

ESTABLISHED — Все пакеты принадлежащие установленному соединению (Например, GET ответ web-сервера)

RELATED — Пакеты, не принадлежащие установленному соединению (то есть те пакеты, которые являются частью новых соединений, которые было инициированы уже установленным ESTABLISHED соединением), но связанные с ним. (Например — FTP в активном режиме использует разные соединения для передачи данных. Эти соединения связанны.)

INVALID — Пакеты, которые не могут быть по тем или иным причинам идентифицированны. Например ICMP ошибки не принадлежащие существующим соединениям

Теперь перейдём к созданию правил. Первым делом изменим политики по умолчанию:

iptables -P INPUT DROP
iptables -P OUTPUT DROP

Нужно ещё не забыть разрешить трафик по петлевому интерфейсу (что бы сервер сас с собой мог общаться по адресу 127.0.0.1):

iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

И напоследок — правил отслеживающие состояние:

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

Этим мы создали полностью закрытый файервол. Теперь осталось добавлять разрешающие правила. Вот несколько примеров:

— разрешаем только исходящие пинги

iptables -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type echo-request -j ACCEPT

— разрешаем доступ к серверу по ssh:

iptables -A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT

А вот полный листинг нашего файервола:

iptables -F
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT
iptables -A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type echo-request -j ACCEPT

Ложка дёгтя.

Дело в том, что при таких правилах файервол не разъединяет ESTABLISHED соединения. Если вы хотите принудительно это сделать — лучший вариант:

iptables -I INPUT 1 -s 10.10.10.10 -m state --state ESTABLISHED,RELATED -j DROP

где 10.10.10.10 — адрес, который установил соединение.

Примечание.

Если вы используете цепочку FORWARD, то для неё будут нужны такие правила:

iptables -P FORWARD DROP
iptables -A FORWARD -i $INET_IFACE -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i $LAN_IFACE -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *