Такого понятия как динамические правила в 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