Прежде чем двигаться дальше предупреждаю, что все работы по настройке фаервола должны производиться только если у вас есть доступ к консоли сервера, чтобы в случае ошибки и потери удаленного доступа вы смогли откатить изменения. Даже если вы абсолютно уверены в своих знаниях, вас может подвести банальная ошибка или опечатка. Я сам, к сожалению, сталкивался с такими ситуациями, поэтому считаю необходимым предупредить об этом вас.
Для управления правилами фаервола я использую скрипт. Создадим его:
# mcedit /etc/iptables.sh
Далее будем наполнять его необходимыми правилами. Я буду разбирать все значимые части скрипта, а полностью его приведу в виде текстового файла в конце статьи.
Первым делом зададим все переменные, которые будем использовать в скрипте. Это не обязательно делать, но рекомендуется, потому что удобно переносить настройки с сервера на сервер. Достаточно будет просто переназначить переменные.
#!/bin/bash
export IPT=»iptables»
# Внешний интерфейс
export WAN=eth0
export WAN_IP=192.168.1.52
# Для роутера. Для обычного компьютера и сервера данная часть не нужна.
# Локальная сеть
#export LAN1=eth1
#export LAN1_IP_RANGE=10.0.15.0/24
Перед применением новых правил, очищаем все цепочки:
# Очищаем правила
$IPT -F
#$IPT -F -t nat
$IPT -F -t mangle
$IPT -X
#$IPT -t nat -X
$IPT -t mangle -X
Блокируем весь трафик, который не соответствует ни одному из правил:
# Запрещаем все, что не разрешено
$IPT -P INPUT DROP
$IPT -P OUTPUT DROP
$IPT -P FORWARD DROP
Разрешаем весь трафик локалхоста и локалки:
# Разрешаем localhost
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT
# Разрешаем локалку
# Для роутера. Для обычного компьютера и сервера данная часть не нужна.
#$IPT -A INPUT -i $LAN1 -j ACCEPT
#$IPT -A OUTPUT -o $LAN1 -j ACCEPT
Разрешаем делать ping:
# Рзрешаем пинги
$IPT -A INPUT -p icmp —icmp-type echo-reply -j ACCEPT
$IPT -A INPUT -p icmp —icmp-type destination-unreachable -j ACCEPT
$IPT -A INPUT -p icmp —icmp-type time-exceeded -j ACCEPT
$IPT -A INPUT -p icmp —icmp-type echo-request -j ACCEPT
Если вам это не нужно, то не добавляйте разрешающие правила для icmp.
Открываем доступ в инет самому серверу:
# Разрешаем все исходящие подключения сервера
$IPT -A OUTPUT -o $WAN -j ACCEPT
Если вы хотите открыть все входящие соединения сервера, то добавляйте дальше правило:
# Разрешаем все входящие подключения сервера
#$IPT -A INPUT -i $WAN -j ACCEPT
Делать это не рекомендуется, привожу просто для примера, если у вас появится такая необходимость.
Дальше разрешим все установленные соединения и дочерние от них. Так как они уже установлены, значит прошли через цепочки правил, фильтровать их еще раз нет смысла:
# Разрешаем установленные подключения
$IPT -A INPUT -p all -m state —state ESTABLISHED,RELATED -j ACCEPT
$IPT -A OUTPUT -p all -m state —state ESTABLISHED,RELATED -j ACCEPT
$IPT -A FORWARD -p all -m state —state ESTABLISHED,RELATED -j ACCEPT
Теперь добавим защиту от наиболее распространенных сетевых атак. Сначала отбросим все пакеты, которые не имеют никакого статуса:
# Отбрасываем неопознанные пакеты
$IPT -A INPUT -m state —state INVALID -j DROP
$IPT -A FORWARD -m state —state INVALID -j DROP
Блокируем нулевые пакеты:
# Отбрасываем нулевые пакеты
$IPT -A INPUT -p tcp —tcp-flags ALL NONE -j DROP
Закрываемся от syn-flood атак:
# Закрываемся от syn-flood атак
$IPT -A INPUT -p tcp ! —syn -m state —state NEW -j DROP
$IPT -A OUTPUT -p tcp ! —syn -m state —state NEW -j DROP
Следом за этими правилами рекомендуется поставить правила на запрет доступа с определенных IP, если у вас имеется такая необходимость. Например, вас задолбал адрес 84.122.21.197 брутом ssh. Блокируем его:
# Блокируем доступ с указанных адресов
#$IPT -A INPUT -s 84.122.21.197 -j REJECT
Защита от сканеров портов:
# Закрываемся от сканеров портов.
$IPT -A INPUT -p tcp —tcp-flags SYN,ACK,FIN,RST RST -m limit —limit 1/s -j ACCEPT
$IPT -A INPUT -p tcp —tcp-flags SYN,ACK,FIN,RST RST -j DROP
Если вы не ставите ограничений на доступ из локальной сети, то разрешаем всем выход в интернет:
# Для роутера. Для обычного коомпьютера и сервера данная часть не нужна.
# Разрешаем доступ из локалки наружу
#$IPT -A FORWARD -i $LAN1 -o $WAN -j ACCEPT
Следом запрещаем доступ из инета в локальную сеть:
# Для роутера. Для обычного коомпьютера и сервера данная часть не нужна.
# Закрываем доступ снаружи в локалку
#$IPT -A FORWARD -i $WAN -o $LAN1 -j REJECT
Чтобы наша локальная сеть пользовалась интернетом, включаем nat:
# Для роутера. Для обычного коомпьютера и сервера данная часть не нужна.
# Включаем NAT
#$IPT -t nat -A POSTROUTING -o $WAN -s $LAN1_IP_RANGE -j MASQUERADE
Чтобы не потерять доступ к серверу, после применения правил, разрешаем подключения по ssh:
# открываем доступ к SSH
$IPT -A INPUT -i $WAN -p tcp —dport 22 -j ACCEPT
И в конце записываем правила, чтобы они применились после перезагрузки:
# Сохраняем правила
/sbin/iptables-save > /etc/iptables.rules
Мы составили простейший конфиг, который блокирует все входящие соединения, кроме ssh и разрешает доступ из локальной сети в интернет. Попутно защитились от некоторых сетевых атак.
Сохраняем скрипт, делаем исполняемым:
# chmod 0740 /etc/iptables.sh
Выполним просмотр правил и проверим, все ли правила на месте:
# iptables -L -v -n
Видим, что на настраиваемом роутере firewall полностью открыт. Теперь применим новые правила и посмотрим на результат:
# /etc/iptables.sh
Все в порядке, правила применились, доступ к серверу я не потерял.
Открытие портов.
Теперь немного расширим нашу конфигурацию и откроем в iptables порты для некоторых сервисов. Допустим, у нас работает веб-сервер и необходимо открыть к нему доступ из интернета. Добавляем правила для веб-трафика:
#Открываем доступ к web серверу
$IPT -A INPUT -p tcp -m tcp —dport 80 -j ACCEPT
$IPT -A INPUT -p tcp -m tcp —dport 443 -j ACCEPT
Было добавлено разрешение на входящие соединения по 80-му и 443-му портам, которые использует web сервер в своей работе.
Если у вас установлен почтовый сервер, то нужно разрешить на него входящие соединения по всем используемым портам:
# Открываем доступ к почтовому серверу
#$IPT -A INPUT -p tcp -m tcp —dport 25 -j ACCEPT
#$IPT -A INPUT -p tcp -m tcp —dport 465 -j ACCEPT
#$IPT -A INPUT -p tcp -m tcp —dport 110 -j ACCEPT
#$IPT -A INPUT -p tcp -m tcp —dport 995 -j ACCEPT
#$IPT -A INPUT -p tcp -m tcp —dport 143 -j ACCEPT
#$IPT -A INPUT -p tcp -m tcp —dport 993 -j ACCEPT
Для корректной работы DNS сервера, нужно открыть UDP порт 53
#Открываем доступ к DNS серверу
#$IPT -A INPUT -i $WAN -p udp —dport 53 -j ACCEPT
# Сохраняем правила
/sbin/iptables-save > /etc/iptables.rules
И так далее. По аналогии можете открыть доступ для всех необходимых сервисов.
В последней строчке скрипта есть команда:
/sbin/iptables-save > /etc/iptables.rules
С ее помощью готовый набор правил iptables выгружаются в файл. Нам нужно сделать так, чтобы эти правила применялись при включении сетевого интерфейса во время загрузки сервера. Для этого открываем файл interfaces на редактирование и добавляем в самый конец строчку:
# mcedit /etc/network/interfaces
post-up iptables-restore < /etc/iptables.rules
Для проверки перезагружаем шлюз и проверяем, все ли в порядке.
Если вы вдруг решите, что firewall вам больше не нужен, то отключить его можно следующим образом:
# systemctl stop iptables.service
Эта команда останавливает фаервол. А следующая удаляет из автозагрузки:
# systemctl disable iptables.service
Отключив сетевой экран, мы разрешили все соединения.
Проброс (forward) порта. (Для роутера.)
Рассмотрим ситуацию, когда необходимо выполнить проброс портов с внешнего интерфейса на какой-то компьютер в локальной сети. Допустим, вам необходимо получить rdp доступ к компьютеру 10.1.3.50 из интернета. Делаем проброс TCP порта 3389:
#$IPT -t nat -A PREROUTING -p tcp —dport 3389 -i ${WAN} -j DNAT —to 10.1.3.50
Если вы не хотите светить снаружи известным портом, то можно сделать перенаправление с нестандартного порта на порт rdp конечного компьютера:
#$IPT -t nat -A PREROUTING -p tcp —dport 23543 -i ${WAN} -j DNAT —to 10.1.3.50:3389
ВНИМАНИЕ.
Если вы пробрасываете порт снаружи внутрь локальной сети, то обязательно закомментируйте правило, которое блокирует доступ из внешней сети во внутреннюю. В моем примере это правило:
$IPT -A FORWARD -i $WAN -o $LAN1 -j REJECT
Либо перед этим правилом создайте разрешающее правило для доступа снаружи к внутреннему сервису, например вот так:
$IPT -A FORWARD -i $WAN -d 10.1.3.50 -p tcp -m tcp —dport 3389 -j ACCEPT
Включение логов.
Во время настройки полезно включить логи, чтобы мониторить заблокированные пакеты и выяснять, почему отсутствует доступ к необходимым сервисам, которые мы вроде бы уже открыли. Я отправляю все заблокированные пакеты в отдельные цепочки (block_in, block_out, block_fw), соответствующие направлению трафика и маркирую в логах каждое направление. Так удобнее делать разбор полетов. Добавляем следующие правила в самый конец скрипта, перед сохранением настроек:
# Включаем логирование.
#$IPT -N block_in
#$IPT -N block_out
#$IPT -N block_fw
#$IPT -A INPUT -j block_in
#$IPT -A OUTPUT -j block_out
#$IPT -A FORWARD -j block_fw
#$IPT -A block_in -j LOG —log-level info —log-prefix «—IN—BLOCK»
#$IPT -A block_in -j DROP
#$IPT -A block_out -j LOG —log-level info —log-prefix «—OUT—BLOCK»
#$IPT -A block_out -j DROP
#$IPT -A block_fw -j LOG —log-level info —log-prefix «—FW—BLOCK»
#$IPT -A block_fw -j DROP
Все заблокированные пакеты вы сможете отследить в файле /var/log/messages.
После того, как закончите настройку, закомментируйте эти строки, отключив логирование. Обязательно стоит это сделать, так как логи очень быстро разрастаются. Практического смысла в хранении подобной информации лично я не вижу.
ИСТОЧНИКИ.
Пошаговая настройка роутера на Debian.