На защиту сервера от внешних угроз в первую очередь встает межсетевой экран, который фильтрует входящий и исходящий траффик. Настройкой iptables — частного случая фаервола на CentOS я хочу заняться в данной статье, а также рассказать о его установке и отключении.
Iptables в настоящее время является стандартом де-факто в среде современных linux дистрибутивов. Так что любому администратору линукс приходится сталкиваться в своей работе с настройкой этого межсетевого экрана.
Первым делом отключим firewalld, который присутствует в centos 7 по-умолчанию сразу после установки:
systemctl stop firewalld
Теперь удалим его из автозагрузки, чтобы он не включился снова после рестарта:
# systemctl disable firewalld
После этого на сервере настройки сетевого экрана становятся полностью открытыми. Посмотреть правила iptables можно командой:
# iptables -L -v -n
На самом деле фаервол у нас на сервере уже стоит и работает, просто нет никаких правил, все открыто. Установить нам нужно будет дополнительные утилиты управления, без которых конфигурировать iptables невозможно. Например, нельзя будет перезапустить фаервол:
# systemctl restart iptables.service
Failed to issue method call: Unit iptables.service failed to load: No such file or directory.
Или добавить в автозапуск не получится:
# systemctl enable iptables.service
Failed to issue method call: No such file or directory
Чтобы подобных ошибок не было, установим необходимый пакет с утилитами:
# yum -y install iptables-services
Теперь можно добавить iptables в автозагрузку и запустить:
# systemctl enable iptables.service
# systemctl start iptables.service
Для управления правилами фаервола используем скрипт. Создадим его:
# mcedit /etc/iptables.sh
Далее будем наполнять его необходимыми правилами.
Мы рассмотрим ситуацию, когда сервер является шлюзом в интернет для локальной сети.
Первым делом зададим все переменные, которые будем использовать в скрипте. Это не обязательно делать, но рекомендуется, потому что удобно переносить настройки с сервера на сервер. Достаточно будет просто переназначить переменные.
#!/bin/bash
export ipt="iptables"
# Внешний интерфейс
export wan=eth0
export wan_ip=212.7.230.68
# Локальная сеть
export lan1=eth1
export lan1_ip_range=10.1.3.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
Разрешаем весь трафик локалхоста и локалки:
$ipt -A INPUT -i lo -j ACCEPT
$ipt -A INPUT -i $lan1 -j ACCEPT
$ipt -A OUTPUT -o lo -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 атак:
$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. Блокируем его:
$ipt -A INPUT -s 84.122.21.197 -j REJECT
Если вы не ставите ограничений на доступ из локальной сети, то разрешаем всем выход в интернет:
$ipt -A FORWARD -i $lan1 -o $wan -j ACCEPT
Следом запрещаем доступ из инета в локальную сеть:
$ipt -A FORWARD -i $wan -o $lan1 -j REJECT
Чтобы наша локальная сеть пользовалась интернетом, включаем nat:
$ipt -t nat -A POSTROUTING -o $wan -s $lan1_ip_range -j MASQUERADE
Чтобы не потерять доступ к серверу, после применения правил, разрешаем подключения по ssh:
$ipt -A INPUT -i $wan -p tcp --dport 22 -j ACCEPT
И в конце записываем правила, чтобы они применились после перезагрузки:
/sbin/iptables-save > /etc/sysconfig/iptables
Мы составили простейший конфиг, который блокирует все входящие соединения, кроме ssh и разрешает доступ из локальной сети в интернет. Попутно защитились от некоторых сетевых атак.
Сохраняем скрипт, делаем исполняемым и запускаем:
# chmod 0740 /etc/iptables.sh
# /etc/iptables.sh
Выполним просмотр правил и проверим, все ли правила на месте:
# iptables -L -v -n
Теперь немного расширим нашу конфигурацию и откроем в iptables порты для некоторых сервисов. Допустим, у нас работает веб-сервер и необходимо открыть к нему доступ из интернета. Добавляем правила для веб-трафика:
$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
$ipt -A INPUT -i $wan -p udp --dport 53 -j ACCEPT
Теперь рассмотрим ситуацию, когда необходимо выполнить проброс портов с внешнего интерфейса на какой-то компьютер в локальной сети. Допустим, вам необходимо получить 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 REJECT
Во время настройки полезно включить логи, чтобы мониторить заблокированные пакеты и выяснять, почему отсутствует доступ к необходимым сервисам, которые мы вроде бы уже открыли. Я отправляю все заблокированные пакеты в отдельные цепочки (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.
После того, как закончите настройку, закомментируйте эти строки, отключив логирование. Обязательно стоит это сделать, так как логи очень быстро разрастаются. Практического смысла в хранении подобной информации лично я не вижу.
Если вы вдруг решите, что firewall вам больше не нужен, то отключить его можно следующим образом:
# systemctl stop iptables.service
Эта команда останавливает фаервол. А следующая удаляет из автозагрузки:
# systemctl disable iptables.service
Отключив сетевой экран, мы разрешили все соединения.
Хочу еще раз обратить внимание, что при настройке iptables необходимо быть предельно внимательным. Не начинайте это дело, если не имеете доступа к консоли сервера.
Всем удачи.
Источник: https://serveradmin.ru/