Настройка DMZ при помощи if_bridge во FreeBSD

Автор: dikens3.

Решил сделать Демилитаризованную зону (DMZ) при помощи if_bridge.

Для чего? Есть у меня 2 WEB-Сервера и 1 почтовый сервер. Все они находятся внутри локальной сети и в случае какого-либо взлома одного из них, кулхацкер получит доступ к локальному IP-Адресу. А там дело техники, как попасть на File-Server и стащить базу клиентов.

Что такое DMZ? Изолированный диапазон IP-Адресов. В моём случае будем его изолировать с помощью ipfw. Необходимо предоставить доступ пользователям к почте, WEB-Серверам, но никак не серверам к нашей сети, да и вообще куда либо соединяться.

Что имеем в наличии:

FreeBSD 5.5

Три интерфейса: rl0 - Инет, fxp0 - Лок. Сеть, fxp1 - DMZ

Выделенный диапазон адресов: 195.28.77.64/28 и шлюз по умолчанию 195.28.77.65

Присваиваем IP-Адреса:

rl0 - 195.28.77.66/29 (т.е. 195.28.77.65-195.28.77.70)

fxp0 - 192.168.10.0/24

fxp1 - 195.28.77.73/29

WEB-Server + он же почтовый - 195.28.77.76

Ещё 1 Web-Server - 195.28.77.77

rc.conf

defaultrouter="195.28.77.65"

hostname="Имя тут какое-нибудь"

ifconfig_rl0="inet 195.28.77.66 netmask 255.255.255.248"

ifconfig_fxp0="inet 192.168.10.1 netmask 255.255.255.0"

ifconfig_fxp1="inet 195.28.77.73 netmask 255.255.255.248"

cloned_interfaces="bridge0"

ifconfig_bridge0="addm rl0 addm fxp1 up"

gateway_enable="YES"

firewall_enable="YES"

firewall_script="/etc/myfirewall"

Тут отдельный прикол возник, после перезагрузки мост не поднялся.

Интерфейс появился, но находился в down'е

Вобщем пришлось прописать up для него и поместить

настройки моста после настроек интерфейсов.

sysctl.conf

#Для фильтрации пакетов на интерфейсах

net.link.bridge.pfil_member=1

#Для фильтрации пакетов на созданнном интерфейсе bridge0 (1- вкл. 0 - выкл.)

net.link.bridge.pfil_bridge=0

Добавляем в ядро, пересобираем и перезагружаемся.

device if_bridge

Проверяем, появился ли интерфейс:

# ifconfig

rl0: flags=18943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST,POLLING> mtu 1500

options=48<VLAN_MTU,POLLING>

inet 195.28.77.66 netmask 0xfffffff8 broadcast 195.28.77.71

ether 00:c1:28:00:f1:35

media: Ethernet autoselect (100baseTX <full-duplex>)

status: active

fxp0: flags=18843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,POLLING> mtu 1500

options=48<VLAN_MTU,POLLING>

inet 192.168.10.1 netmask 0xffffff00 broadcast 192.168.10.255

ether 00:a0:c9:93:87:ca

media: Ethernet autoselect (100baseTX <full-duplex>)

status: active

fxp1: flags=18943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST,POLLING> mtu 1500

options=48<VLAN_MTU,POLLING>

inet 195.28.77.73 netmask 0xfffffff8 broadcast 195.28.77.79

ether 00:d0:43:7a:ca:ea

media: Ethernet autoselect (100baseTX <full-duplex>)

status: active

lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384

inet 127.0.0.1 netmask 0xff000000

bridge0: flags=8043<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500

ether ac:de:48:2d:1a:dd

priority 32768 hellotime 2 fwddelay 15 maxage 20

member: fxp1 flags=3<LEARNING,DISCOVER>

member: rl0 flags=3<LEARNING,DISCOVER>

А теперь напишем правила для ipfw, natd использоваться не будет, смысла нет:

/etc/myfirewall

#!/bin/sh -

# Настройки для DMZ

ifdmz="fxp1"

dmz_web_mail_server="195.28.77.76"

dmz_oldweb_server="195.28.77.77"

#

ifout="rl0"

iflan="fxp0"

mylan="192.168.10.0/24"

allowgoodhosts="195.28.84.160/32"

mydns="IP-Адреса DNS серверов"

# 1 таблица, таких ip в инете нет.

fwtable="/sbin/ipfw table"

${fwtable} 1 f

NETS=" 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 0.0.0.0/8 169.254.0.0/16

192.0.2.0/24 224.0.0.0/4 240.0.0.0/4 "

for lan in ${NETS}

do

${fwtable} 1 add $lan

done

fwcmd="/sbin/ipfw -q"

${fwcmd} -f flush

# Переходы для DMZ, порядок строк имеет значение (Шлюз, наша сеть, инет)

# Исходящий траффик со шлюза в DMZ (DMZ. интерфейс исходящий)

${fwcmd} add skipto 27000 all from me

to ${dmz_web_mail_server},${dmz_oldweb_server} out via ${ifdmz}

# Входящий траффик с DMZ на шлюз (DMZ. интерфейс входящий)

${fwcmd} add skipto 28000 all from ${dmz_web_mail_server},

${dmz_oldweb_server} to me in via ${ifdmz}

# Входящий траффик на DMZ с нашей сети (Lan. интерфейс входящий)

${fwcmd} add skipto 25000 all from ${mylan}

to ${dmz_web_mail_server},${dmz_oldweb_server} in via ${iflan}

# Разрешаем исходящие пакеты принятые на интерфейсе iflan, обработанные файрволом,

# и выходящие с интерфейса ifdmz

${fwcmd} add pass all from ${mylan} to ${dmz_web_mail_server},

${dmz_oldweb_server} out recv ${iflan} xmit ${ifdmz}

# Исходящий траффик с DMZ в нашу сеть (DMZ. интерфейс входящий)

${fwcmd} add skipto 26000 all from ${dmz_web_mail_server},

${dmz_oldweb_server} to ${mylan} in via ${ifdmz}

# Разрешаем исходящие пакеты принятые на интерфейсе ifdmz, обработанные файрволом,

# и выходящие с интерфейса iflan

${fwcmd} add pass all from ${dmz_web_mail_server},

${dmz_oldweb_server} to ${mylan} out recv ${ifdmz} xmit ${iflan}

# DMZ для в(c) инет(а)

# Входящий траффик на DMZ с инета (ifout - входящий интерфейс)

${fwcmd} add skipto 29000 all from any

to ${dmz_web_mail_server},${dmz_oldweb_server} in via ${ifout}

# Разрешаем исходящие пакеты принятые на интерфейсе ifout, обработанные файрволом,

# и выходящие с интерфейса ifdmz

${fwcmd} add pass all from any to

${dmz_web_mail_server},${dmz_oldweb_server} out recv ${ifout} xmit ${ifdmz}

# Исходящий траффик с DMZ в инет (DMZ - входящий интерфейс)

${fwcmd} add skipto 31000 all from ${dmz_web_mail_server},

${dmz_oldweb_server} to any in via ${ifdmz}

# Разрешаем исходящие пакеты принятые на интерфейсе ifdmz, обработанные файрволом,

# и выходящие с интерфейса ifout

${fwcmd} add pass all from ${dmz_web_mail_server},

${dmz_oldweb_server} to any out recv ${ifdmz} xmit ${ifout}

#################################################################################

# Входящий траффик на DMZ с нашей сети (Lan. интерфейс входящий)

# Пропускаем траффик, с уже установленным соединением

${fwcmd} add 25000 pass tcp from ${mylan}

to ${dmz_web_mail_server},${dmz_oldweb_server} in via ${iflan} established

# Разрешаем установку соединения на 21,22,25,80,110,995 порты наших серверов в DMZ

${fwcmd} add pass tcp from ${mylan} 1024-65535

to ${dmz_web_mail_server},${dmz_oldweb_server} 21,22,25,80,110,995

in via ${iflan} setup

# Пропускаем ICMP-только нужные

${fwcmd} add pass icmp from ${mylan}

to ${dmz_web_mail_server},${dmz_oldweb_server} in via ${iflan} icmptype 8

# Разрешённые UDP

# ${fwcmd} add pass udp from ${mylan}

# to ${dmz_web_mail_server},${dmz_oldweb_server} in via ${iflan}

# Всё остальное убиваем и пишем в log

${fwcmd} add deny log all from any to any

# Исходящий траффик с DMZ в нашу сеть (DMZ. интерфейс входящий)

# Пропускаем траффик, с уже установленным соединением

${fwcmd} add 26000 pass tcp from ${dmz_web_mail_server},${dmz_oldweb_server}

to ${mylan} in via ${ifdmz} established

# Выпускаем ICMP-только нужные

${fwcmd} add pass icmp from ${dmz_web_mail_server},${dmz_oldweb_server}

to ${mylan} in via ${ifdmz} icmptype 0

# Разрешённые UDP

# ${fwcmd} add pass udp from ${mylan}

# to ${dmz_web_mail_server},${dmz_oldweb_server} in via ${ifdmz}

# Всё остальное убиваем и пишем в log

${fwcmd} add deny log all from any to any

#################################################################################

# Исходящий траффик со шлюза в DMZ (DMZ. интерфейс исходящий)

# Все соединения разрешены

${fwcmd} add 27000 pass tcp from me

to ${dmz_web_mail_server},${dmz_oldweb_server} out via ${ifdmz}

# Выпускаем ICMP со шлюза на DMZ

${fwcmd} add pass icmp from me

to ${dmz_web_mail_server},${dmz_oldweb_server}

out via ${ifdmz} icmptype 0,3,4,8,11

# Разрешаем шлюзу отвечать по 123 порту (время)

${fwcmd} add pass udp from me 123

to ${dmz_web_mail_server},${dmz_oldweb_server} 123 out via ${ifdmz}

# Всё остальное убиваем и пишем в log

${fwcmd} add deny log all from any to any

# Входящий траффик с DMZ на шлюз (DMZ. интерфейс входящий)

# Пропускаем траффик на шлюз, с уже установленным соединением

${fwcmd} add 28000 pass tcp from ${dmz_web_mail_server},

${dmz_oldweb_server} to me in via ${ifdmz} established

# Выпускаем ответы ICMP на шлюз, и возможность пинговать шлюз

${fwcmd} add pass icmp from ${dmz_web_mail_server},${dmz_oldweb_server}

to me in via ${ifdmz} icmptype 0,8

# Разрешаем сверять время с нашим шлюзом, он сервером времени работает

${fwcmd} add pass udp from ${dmz_web_mail_server},${dmz_oldweb_server} 123

to me 123 in via ${ifdmz}

# Всё остальное убиваем и пишем в log

${fwcmd} add deny log all from any to any

##################################################################################

# Входящий траффик на DMZ с инета (ifout - входящий интерфейс)

# Пропускаем траффик, с уже установленным соединением

${fwcmd} add 29000 pass tcp from any

to ${dmz_web_mail_server},${dmz_oldweb_server} in via ${ifout} established

# Разрешаем установку соединения на 80 порт наших почтовых серверов

${fwcmd} add pass tcp from any 1024-65535

to ${dmz_web_mail_server},${dmz_oldweb_server} 80 in via ${ifout} setup

# Разрешаем установку соединения на 25 порт нашего почтового сервера

${fwcmd} add pass tcp from any 1024-65535

to ${dmz_web_mail_server} 25 in via ${ifout} setup limit dst-port 100

# Разрешаем ДНС, вписаны статические DNS Адреса

${fwcmd} add pass udp from ${mydns} 53

to ${dmz_web_mail_server},${dmz_oldweb_server} 1024-65535 in via ${ifout}

# Для TraceRoute

${fwcmd} add unreach port udp from any

to ${dmz_web_mail_server},${dmz_oldweb_server} 33435-33524 in via ${ifout}

# Разрешаем SSH, для некоторых внешних IP-Адресов.

# (Из дома к примеру можно будет подключаться)

# ${fwcmd} add pass tcp from ${allowgoodhosts} 1024-65535

# to ${dmz_web_mail_server},${dmz_oldweb_server} 22 in via ${ifout} setup

# Пропускаем ICMP, ответы на ping, возможность пинговать DMZ.

${fwcmd} add pass icmp from any

to ${dmz_web_mail_server},${dmz_oldweb_server}

in via ${ifout} icmptype 0,3,4,8,11

# Всё остальное убиваем и пишем в log

${fwcmd} add deny log all from any to any

# Исходящий траффик с DMZ в инет (DMZ - входящий интерфейс)

# Пропускаем траффик, с уже установленным соединением

${fwcmd} add 31000 pass tcp from ${dmz_web_mail_server},${dmz_oldweb_server}

to any in via ${ifdmz} established

# Прибиваем ненужный трафик

${fwcmd} add deny log all from ${dmz_web_mail_server},${dmz_oldweb_server}

to table(1) in via ${ifdmz}

# Разрешаем серверам обращаться к внешним ДНС, вписаны статические DNS Адреса

${fwcmd} add pass udp from ${dmz_web_mail_server},

${dmz_oldweb_server} 1024-65535 to ${mydns} 53 in via ${ifdmz}

# Разрешаем TraceRoute

${fwcmd} add pass udp from ${dmz_web_mail_server},

${dmz_oldweb_server} to any 33435-33524 in via ${ifdmz}

# Разрешаем установку соединения на 25 порты внешних серверов

# для нашего почтового сервера

${fwcmd} add pass tcp from ${dmz_web_mail_server} 1024-65535

to any 25 in via ${ifdmz}

# Пропускаем ICMP, ответы на ping, возможность самим пинговать IP-Адреса в инете.

${fwcmd} add pass icmp from ${dmz_web_mail_server},${dmz_oldweb_server}

to any in via ${ifdmz} icmptype 0,8

# Разрешаем серверам отвечать на запросы к 22 порту,

# для некоторых внешних IP-Адресов.

# Данное правило не будет работать так как 31000 правилом пакет уже будет принят.

# Оставлено для понимания, что можно,

# и лучше указывать откуда и куда должен идти пакет.

# Т.е. с 22 порта на 1024-65535

# ${fwcmd} add pass tcp from ${dmz_web_mail_server},${dmz_oldweb_server}

# 22 to ${allowgoodhosts} 1024-65535 in via ${ifdmz} established

# Всё остальное убиваем и пишем в log

${fwcmd} add deny log all from any to any

Ну вот и всё, всё работает, все ходят куда позволено.

В данной конфигурации сервера в DMZ не могут ничего скачать

(обновить порты к примеру).

С одной стороны нужно, с другой, если кто-либо вам зальёт на WEB-SERVER

WEB-PROXY, то радостного здесь будет мало.

P.S. Все IP-Адреса вымышленные и не имеют ничего общего с реальными. :-)

Обновлено: 12.03.2015