Наконец то дошли руки, до воссоздания манула по настройке фаервола на базе системы FreeBSD, который помимо стабильности, надежности и безопасности отличается еще одним немаловажным, для многих компаний, качеством – это бесплатный фаервол.
Большая часть настроек выработана годами опытной эксплуатации, так что они означают уже припомнить довольно сложно, да и к тому же займет еще полстатьи, так что вероятнее всего часть настроек, которые я не рассматривал в данной статье, я распишу несколько позднее.
Переведем данное мероприятие сразу же в плоскость экономической выгоды для сисадмина, ибо на мой взгляд, настройка программного брандмауэра находится на втором месте, после лечения компьютера от вирусов, и перед восстановлением данных- по соотношению заработанных средств к затраченному времени. Поскольку на настройку программного фаервола на базе FreeBSD тратится от 6 до 10 часов, с момента как вы включили пустую машину, до момента когда вы можете уже включать данный сервер в разрез сети. Естественно, что поднять сам фаервол займет от силы полтора-два часа на создание и обкатку правил: большую часть времени занимает пересборка и апгрейд системы.
Также надо отметить, что данный пост повествует исключительно о настройке фаервола, а не унифицированного средства защиты с потоковым антивирусом и IPS, о которых я возможно поговорю позднее.
Итак, настраиваем программный фаервол на базе FreeBSD.
Ставить буду ipfilter, исключительно по идейным соображениям работы ipfw с NAT и тем что сам функционал ipfilter для меня проще и давно изучен (опять же про установку PF расскажу как нить позже, но его ставить на конторский фаервол усомнился, так как имеются траблы с многопоточностью). Описывать процедуры я буду не полностью, так как, о части работ я уже писал ранее, так что просто отошлю к этим постам.
Для начала поднимаем сервер FreeBSD (я для последнего раза выбрал систему FreeBSD 8.2), на котором проводим обновление системы и дерева портов, после чего раздракониваем нашу систему на предмет повышения безопасности. После этого пересобираем ядро системы, отключая не нужные нам дрова (тут не лишне будет перелопатить dmesg на предмет наличия устройств, чтобы не забанить что-нить архиважное- например IPv4 вместо IPv6), и предварительно включив в ядре поддержку ipfilter:
options IPFILTER # поддержка IPFilter options IPFILTER_LOG # поддержка логирования IPFilter options IPFILTER_DEFAULT_BLOCK# блокируем все пакеты по умолчанию options IPFILTER_LOOKUP
также, если не добавляли при настройке усиленной системы, то ставим следующие опции ядра
options IPSTEALTH# не увеличивает счетчик TTL при прохождении пакета options TCP_DROP_SYNFIN# дропаем SYN/FIN пакеты, но не работает вроде как с 7 ветки options SC_DISABLE_REBOOT# запрет перезагрузки сервера через Ctrl+Alt+Del options SOFTUPDATES# включение технологиии softupdate для тюнинга работы системы
По хорошему, перед правкой ядра стоит на всякий случай почитать следующие файлы, хотя бы для повышения личной образованности, а уж в случае наличия ошибок при сборке ядра- однозначно:
/usr/sys/UPDATING /usr/src/sys/conf/NOTES
Пересборку ядра проводим с включенными опами, только в случае локальной установки, в случае же удаленной установки, от греха- сначала настраиваем правила ipf и врубаем поддержку фаервола в rc.conf, только после чего пересобираем ядро, чтобы не получилось лока фаервола в удаленном офисе, что является классическим косяком удаленного админа.
Затем включаем в системе поддержку фаервола, путем добавления следующих операндов в файл
#cat /etc/rc.conf ipfilter_enable=”YES” ipnat_enable=”YES” ipfilter_rules=”/etc/ipf.rules” ipnat_rules=”/etc/ipnat.rules” gateway_enable=”YES” icmp_bmcastecho=”YES” ipmon_enable=”YES” ipmon_flags=”-D /var/log/ipmon.log &”
Создаем вышеупомянутые файлы ipf.rules и ipnat.rules, делаем их владельцем root и задаем на них права 644. Затем создаем правило полного доступа для всех в файле /etc/ipf.rules
Естественно что помимо lo0, добавляем все имеющиеся в системе интерфейсы и особенно те, через которые мы и настраиваем сервер- в моем случае это внутренний интерфейс rl0.
#################################
pass in quick on lo0 all
pass out quick on lo0 all
pass out quick on rl0 all
pass in quick on rl0 all
#################################
После этого можем пересобирать ядро и перегружать машину с тем, чтобы инстальнуть новое ядро, а затем, сыграв победное соло на бубне, по корректной загрузке машины, продолжить настройку остальных опций.
Далее несколько подправляем работу ядра через файл настроек /etc/sysctl.conf
для добавления всяческих фич противодействия DoS и DDoS атакам, а также повышению безопасности системы, которые сохраняются, благодаря файлу, в системе и после перезагрузки. Здесь их подробно описывать не буду, а как нить позже приведу полный разбор полетов- пока просто вписываем в указанный файл следующие значения (файл создаем при его отсутствии):
net.inet6.ip6.redirect=0 kern.ipc.somaxconn=32768 net.inet.tcp.blackhole=1 net.inet.udp.blackhole=1 net.inet.tcp.msl=7500 net.inet.tcp.sendspace=32768 net.inet.tcp.recvspace=32768 net.inet.tcp.syncookies=1 net.inet.tcp.log_in_vain=1 net.inet.udp.log_in_vain=1 net.inet.tcp.sack.enable=1 net.link.ether.inet.max_age=1200 net.inet.ip.redirect=0 net.inet.ip.sourceroute=0 net.inet.ip.accept_sourceroute=0 net.inet.ip.ttl=64 net.inet.ip.random_id=1 net.inet.ip.forwarding=1 net.inet.ip.check_interface=1 net.inet.icmp.bmcastecho=0 net.inet.icmp.maskrepl=0 net.inet.icmp.maskrepl=0 net.inet.icmp.icmplim=30 net.inet.icmp.icmplim_output=0 net.inet.icmp.drop_redirect=1 net.inet.icmp.log_redirect=1 net.inet.tcp.drop_synfin=1# если подключили в ядре опцию TCP_DROP_SYNFIN
Затем настраиваем ротацию логов фаервола, для чего устанавливаем пакет logrotate:
# cd /usr/ports/sysutils/logrotate/ # make && make install && make clean
Создаем и настраиваем конфиг ротации логов:
# cp /usr/local/etc/logrotate.conf.sample /usr/local/etc/logrotate.conf
добавляем в файл logrotate.conf следующие строки
logrotate.conf /var/log/ipmon.log { Daily # какова периодичность ротации логов rotate 14 # какое количество логов хранить missingok # игнорировать отсуствие файла ipmon.log notifempty # не обрабатывать лог файл, если он пустой noolddir # содержать все файлы логов в одном каталоге compress # сжимать обработанные логи postrotate # описание что делать с ipmon после ротации /sbin/killall -HUP ipmon # в нашем случае перезапустить ipmon endscript# конец описания действия после ротации } # конец описания ротации файла протокола ipfilter
Добавляем наш ротатор логов в крон:
0 1 * * * /usr/local/sbin/logrotate -s /var/lib/logrotate.status /usr/local/etc/logrotate.conf
Создаем сам лог файл через команду
# touch /var/log/ipmon.log
ибо автоматом он не создастся, и с чувством глубокого удовлетворения переходим к настройке правил фаервола и адрес-трансляции пакетов.
Начем с правил NAT ибо их меньше и они проще (предположим что внешний интерфейс fxp0. Надо отметить что правило проксирования исходящих ftp-сессий ставится первым, за ним идут адрес-трансляции для внутренних серверов (адрес Server-FW_external_IP поднимается алиасом на внешнем интерфейсе фаервола), если их необходимо представить в инете, а за ними уже следуют правила ната для сетки:
#cat /etc/ipnat.rules
map fxp0 internal_NET_IP/24 -> FW_external_IP/32 proxy port ftp ftp/tcp # Безусловная трансляция на внутренний адрес (в этом случае нет необходимости поднимать IP алиасом на внешнем интерфейсе) map fxp0 Server_exnternal_IP/32 -> Server-FW_external_IP/32 bimap fxp0 Server_external_IP/32 -> Server-FW_external_IP/32 # Редирект порта с внешнего интерфейса фаервола на внутреннюю машину (как пример RDP) rdr fxp0 external_GW_IP port 3389 -> Server_internal_IP port 3389 tcp ######### map fxp0 internal_NET_IP/24 -> 0.0.0.0/32 map fxp0 internal_NET_IP/24 -> FW_external_IP/32 portmap tcp/udp 20000:64000# натим порты ############################
Теперь переходим к настройке самого муторного- правилам фаервола. Помним о том, что в классическом фаерволе перебор правил идет сверху вниз, поэтому все блокировки помещаем вниз, кроме единственных закрывающих атаки cifs. Также разрешаем внутрисетевой трафик в нашей локальной сети, что мы уже определили первыми правилами в самом начале ( rl0 у нас внутренний интерфейс ):
#cat /etc/ipf.rules # Разрешаем внутрисетевой трафик pass in quick on lo0 all pass out quick on lo0 all pass out quick on rl0 all pass in quick on rl0 all # Лочим все прорезки в виндовые уязвимости block in log quick on fxp0 proto tcp from any to any port = 113 block in log quick on fxp0 proto tcp/udp from any to any port = 135 block in log quick on fxp0 proto tcp/udp from any to any port = 136 block in log quick on fxp0 proto tcp/udp from any to any port = 137 block in log quick on fxp0 proto tcp/udp from any to any port = 138 block in log quick on fxp0 proto tcp/udp from any to any port = 139 block out log on fxp0 proto tcp/udp from any to any port = 135 block out log on fxp0 proto tcp/udp from any to any port = 136 block out log on fxp0 proto tcp/udp from any to any port = 137 block out log on fxp0 proto tcp/udp from any to any port = 138 block out log on fxp0 proto tcp/udp from any to any port = 139 block out log on fxp0 proto tcp/udp from any to any port = 445 # Разрешаем NS-запросы из сети pass out quick on fxp0 proto tcp from any to DNS1 port = 53 flags S keep state keep frags pass out quick on fxp0 proto udp from any to DNS1 port = 53 keep state keep frags pass out quick on fxp0 proto tcp from any to DNS2 port = 53 flags S keep state keep frags pass out quick on fxp0 proto udp from any to DNS2 port = 53 keep state keep frags # Разрешаем выход пассивного FTP протокола pass out quick on fxp0 proto tcp from any to any port = 20 flags S keep state keep frags pass out quick on fxp0 proto tcp from any to any port = 21 flags S keep state keep frags # Разрешаем работу по ssh на нашем фаерволе на своем порту pass in quick on fxp0 proto tcp from any to any port = 19212 flags S keep state # Разрешаем протокол smtp только к почтовому серверу, для предотвращения работы потенциальных спам-ботов pass out quick on fxp0 proto tcp from any to MAIL_SERVER_IP port = 25 flags S keep state keep frags # Разрешаем работу whois из сети pass out quick on fxp0 proto tcp from any to any port = 43 flags S keep state keep frags # Разрешаем просмотр сайтов по http pass out quick on fxp0 proto tcp from any to any port = 80 flags S keep state keep frags # Получаем почту по pop3 pass out quick on fxp0 proto tcp from any to any port = 110 flags S keep state keep frags # Разрешаем работу по протоколу https pass out quick on fxp0 proto tcp from any to any port = 443 flags S keep state keep frags pass out quick on fxp0 proto tcp from any to any port = 591 flags S keep state keep frags # Разрешаем работу по FTP в пассивном режиме, когда сервер выбирает порт для работы pass out quick on fxp0 proto tcp from any to any port > 1023 flags S keep state keep frags # Разрешаем работу traceroute pass out quick on fxp0 proto udp from any to any port 33434 >< 33525 keep state keep frags # Разрешаем пинг во вне pass out quick on fxp0 proto icmp from any to any keep state keep frags # Разрешаем вход внутрь сетки по RDP pass in log quick on fxp0 proto tcp from any to RDP_Server_IP port = 3389 flags S keep state keep frags # Разрешаем из сети работу линейки pass out quick in fxp0 proto tcp/udp from Client_IP to 217.117.182.1 port > 10 keep state pass in quick on fxp0 proto tcp/udp from 217.117.182.1 to GW_internal_IP port > 10 keep state pass out quick in fxp0 proto tcp/udp from any to any port = 2106 keep state pass in quick on fxp0 proto tcp/udp from any to any port = 2106 keep state # Обрабатываем работу icmp протокола pass in on fxp0 proto icmp from any to any icmp-type echo pass in on fxp0 proto icmp from any to any icmp-type echorep pass in quick on fxp0 proto icmp from any to any icmp-type 3 keep state keep frags pass in quick on fxp0 proto icmp from any to any icmp-type 11 keep state keep frags block return-icmp (3) in proto udp from any to any port > 30000 block return-icmp (3) in on fxp0 proto icmp from any to any icmp-typenunreach code 3 block in proto icmp all # Блокируем все остальное block out log first quick on fxp0 all block in quick on fxp0 from 192.168.0.0/16 to any #RFC 1918 private IP block in quick on fxp0 from 172.16.0.0/12 to any #RFC 1918 private IP block in quick on fxp0 from 10.0.0.0/8 to any #RFC 1918 private IP block in quick on fxp0 from 127.0.0.0/8 to any #loopback block in quick on fxp0 from 0.0.0.0/8 to any #loopback block in quick on fxp0 from 169.254.0.0/16 to any #DHCP auto-config block in quick on fxp0 from 192.0.2.0/24 to any #reserved for docs block in quick on fxp0 from 204.152.64.0/23 to any #Sun cluster interconnect block in quick on fxp0 from 224.0.0.0/3 to any #Class D & E multicast block in log quick on fxp0 all with frags block in log quick on fxp0 proto tcp all with short block in log quick on fxp0 all with opt lsrr block in log quick on fxp0 all with opt ssrr block in log first quick on fxp0 proto tcp from any to any flags FUP block in log quick on fxp0 all with ipopts block in log quick on fxp0 proto icmp all icmp-type 8 block in log first quick on fxp0 all block in log all block out log all #####################
Также добиваем сюда правила необходимые для вашей локальной сети, например банки-клиенты, специфические программы- игрушки, и добавляем их в секцию разрешенных пакетов. Только мой совет- обязательно описывайте отдельно все порты отличные от стандартных, ибо в большой сети, через полгода опытной эксплуатации фаервола- смотреть на фаервольные правила можно будет только сквозь слезы и с вооружившись бутылкой коньяка. Если что то не работает или не понимаете как ЭТО следует разрешать, то отсматривайте логи- обычно инфы о блокировках из них вполне достаточно для того, чтобы понять что именно следует разрешать.
Хотелось бы также заметить следующий момент- при любых правках вносимых в таблицу правил, создавайте ревизию, и тогда в случае ошибки, вы сможете максимально быстро откатиться к предыдущей версии и после этого уже искать случайно поставленный или, наоборот, забытый символ, ибо правила также считываются от начала файла, и как только пакет встречает не разрешимый символ или выражение применение правил заканчивается и вы получаете только тот набор правил, что успели всосаться в систему.
З.Ы. Хотел написать об этом моменте в отдельном посте, но решил что это будет не очень корректно, так что привожу в виде небольшого послесловия. Дело в том, что файл правил фаервола ipf поддерживает набор переменных, что конечно же гораздо удобнее для системного администратора, так как позволяет переносить файл правил с одного шлюза на другой, корректируя только объявления переменных в самом начале файла. Одна беда, что сам пакет ipf не понимает переменные и файл с ними надо сохранять в отдельный скрипт /etc/ipf.rules.script , запуская который пользователь создает или обновляет правила в файле ipf.rules. В сам скрипт пишется следующее:
ipf.rules.script # Описание переменных oif=”fxp0″ # имя внешнего интерфейса odns=”DNS1-IP”# IP адрес внешного DNS сервера mynet=”172.168.0.0″# Внутренняя сетка ks=”keep state” fsks=”flags S keep state” ### cat > /etc/ipf.rules << EOF # Доступ из сети к внешнему DNS серверу pass out quick on $oif proto tcp from any to $odns port = 53 $fks pass out quick on $oif proto udp from any to $odns port = 53 $ks # Разрешить выход из сети во вне по http pass out quick on $oif proto tcp from $mynet to any port = 80 $fks # ну и так далее
После изменения правил фаервола необходимо запустить данный скрипт, что бы правила перечитались и файл ipf.rules обновился:
# sh /etc/ipf.rules.script