Доброго времени суток, %username%!
В один прекрасный момент ко мне подошел начальник и сказал, что необходимо поднять шлюз с FreeBSD+IPFW на борту. Начальство сказало — надо делать, даже ни смотря на то, что до этого момента мое общение с фрёй было чрезвычайно эпизодично.
Итак, мы имеем:
Для начала была установлена ОСь (FreeBSD 8.1). Тут почти все стандартно, внимание стоит обратить, пожалуй, только вот на что. При разметке не стоит принебрегать советами хэндбука и жалеть место под корневой раздел, дайте ему 1Gb, в противном случае не исключены проблемы при пересборке ядра.
ОСь стоит, теперь надо сделать так, чтобы можно было работать с IPFW. Тут есть два варианта: включить файрволл в ядре, либо загружать его модулем. Я выбрал первый вариант, ибо так спокойнее и надежнее, имхо! Тут я не буду рассказывать, как пересобирать ядро, так как статей на эту тему хватает. Но вот перечислить, какие опции нужно дописать, стоит:
Если последнюю опцию вы не указывали, то будте внимательны, потому что после перезагрузки все коннекты обрубятся и, если вы работаете удаленно, на этом моменте ваша работа приостановится! Ну и как всегда, допишем пару строк в /etc/rc.conf:
Файрволл устанвлен и работает, но у него пока только одно правило — запрет всего. Значит, надо правила добавить. И опять же, у нас есть два пути: набирать все ручками, причем после каждого ребута — заново, либо же записать все правил в файл и загружать их оттуда. Мы, как ленивые и неглупые, выбираем второй способ.
Небольшая тонкость по поводу записи правил в файл. У меня правил получилось достаточно много, плюс комменты, итого выходит достаточно немаленький файл, который листать совсем неудобно. Поэтому я сделал так: разбил все правила на логические блоки (DNS, форвардинг, запреты и т.п.), блоки записал в отдельные файлы и написал простейший скрипт, который эти файлы склеивает в один файл и запускает на исполнение. Итого получаем примерно 5-20 файлов с правилами (количество зависит от конкретных условий) и скрипт, который все это дело собирает и запускает.
Теперь листинг. Полный список правил я сюда выкладывать не буду, так как там много однотипных, но, в общем, все это взято с рабочего шлюза. В сетке крутится почтовый сервер и терминал-сервер, плюс стандартное — инет юзерам, аська, джабер, фтп, торрент, ну и еще парочка специфичных программ, которых ходят по своим портам.
Теперь пару слов о NAT'е. «Ядерным» NAT'ом я не пользуюсь, и не потому, что демон чем-то лучше, а просто потому, что по natd в сети попалось больше информации. Да и проблем с ним, тьфу-тьфу-тьфу, не было. Итак, в rc.conf есть команда на запуск скритика /etc/natd.sh, а вот что в этом скрипте:
О синтаксисе: «redirect_port „протокол“ „IP_назначения“:»порт_назначения" «порт_обращения»". IP_назначения — это компьютер в локалке, на который мы перенаправляем пакеты, соответственно, порт_назначения — порт это компа в локалке. А порт_обращения — внешний порт шлюза, на который приходит пакет из инета. Ну и пару примеров использования natd:
Для начала этого должно хватить. Я не рассматривал в примере использование динамических правил и ограничения траффика, дабы не запутывать и не усложнять. И, да, это мой первый опыт постоения шлюзов на FreeBSD, поэтому конструктивная критика и предложения приветствуются!
При настройке шлюза и подготовке статьи активно пользовался хендбуком и лиссярой, это кладези информации для начинающего фряшника!
Спасибо за внимание, искренне надеюсь, что эта статья поможет кому-то разобраться в непонятном и сэкономит время.
В один прекрасный момент ко мне подошел начальник и сказал, что необходимо поднять шлюз с FreeBSD+IPFW на борту. Начальство сказало — надо делать, даже ни смотря на то, что до этого момента мое общение с фрёй было чрезвычайно эпизодично.
Итак, мы имеем:
- офис на ~50 компов, с одной стороны
- интернет, с другой
- среднестатистический офисный комп (2Hz,2Gb,80Gb) между всем этим безобразием.
Для начала была установлена ОСь (FreeBSD 8.1). Тут почти все стандартно, внимание стоит обратить, пожалуй, только вот на что. При разметке не стоит принебрегать советами хэндбука и жалеть место под корневой раздел, дайте ему 1Gb, в противном случае не исключены проблемы при пересборке ядра.
ОСь стоит, теперь надо сделать так, чтобы можно было работать с IPFW. Тут есть два варианта: включить файрволл в ядре, либо загружать его модулем. Я выбрал первый вариант, ибо так спокойнее и надежнее, имхо! Тут я не буду рассказывать, как пересобирать ядро, так как статей на эту тему хватает. Но вот перечислить, какие опции нужно дописать, стоит:
options IPFIREWALL # сам файрволл
options IPFIREWALL_VERBOSE # логгинг пакетов, если в правиле указано `log`
options IPFIREWALL_VERBOSE_LIMIT=100 # ограничение повторяющихся логов - на случай атак типа флудинга
options IPFIREWALL_FORWARD # форвардинг пакетов
options IPDIVERT # если нужен NAT (я пользуюсь natd, но альтернатива - это хорошо)
options DUMMYNET # если надо ограничивать скорость инета "избранным" (у меня до этого руки не дошли)
options IPFIREWALL_DEFAULT_TO_ACCEPT # дефолтовое правило. Если указать - файрволл по умолчанию открытый
Если последнюю опцию вы не указывали, то будте внимательны, потому что после перезагрузки все коннекты обрубятся и, если вы работаете удаленно, на этом моменте ваша работа приостановится! Ну и как всегда, допишем пару строк в /etc/rc.conf:
#firewall_type="/etc/rc.firewall" # файл с правилами файрволла. Я загружаю правил из файла так:
/etc/rc.fw # да, это, скорее всего, не правильно, но мне так удобнее
#firewall_nat_enable="YES" # запуск ipfw-шного NAT'a ("ядерный" NAT)
natd_program="/sbin/natd" # программа для NAT'a
natd_enable="YES" # запуск natd
/etc/natd.sh # файл с настройками ната
Файрволл устанвлен и работает, но у него пока только одно правило — запрет всего. Значит, надо правила добавить. И опять же, у нас есть два пути: набирать все ручками, причем после каждого ребута — заново, либо же записать все правил в файл и загружать их оттуда. Мы, как ленивые и неглупые, выбираем второй способ.
Небольшая тонкость по поводу записи правил в файл. У меня правил получилось достаточно много, плюс комменты, итого выходит достаточно немаленький файл, который листать совсем неудобно. Поэтому я сделал так: разбил все правила на логические блоки (DNS, форвардинг, запреты и т.п.), блоки записал в отдельные файлы и написал простейший скрипт, который эти файлы склеивает в один файл и запускает на исполнение. Итого получаем примерно 5-20 файлов с правилами (количество зависит от конкретных условий) и скрипт, который все это дело собирает и запускает.
Теперь листинг. Полный список правил я сюда выкладывать не буду, так как там много однотипных, но, в общем, все это взято с рабочего шлюза. В сетке крутится почтовый сервер и терминал-сервер, плюс стандартное — инет юзерам, аська, джабер, фтп, торрент, ну и еще парочка специфичных программ, которых ходят по своим портам.
### Определяем переменные
#
# Ключ -q лучше указыать, иначе при каждом перезапуске списка правил будет обрубать SSH.
fw="/sbin/ipfw -q add"
# Интерфейс смотрит в инет.
lanout="re0"
# Интерфейс смотрит в локалку.
lanin="vr0"
# Внешний IP.
ipout="111.111.111.111"
# Внутренний IP.
ipin="192.168.1.254"
# Внутренняя сеть.
netin="192.168.1.0/24"
# Внешняя сеть.
netout="111.111.111.0/24"
# Шаблон внутреннего адреса.
ip_lan="192.168.1"
# Кому из локалки разрешен доступ к шлюзу по SSH.
ip_allow_in="192.168.1.11,192.168.1.250,192.168.1.100"
# То же самое, но из инета.
ip_allow_out="123.156.089.147,159.147.123.214"
# Порты http,ftp.
port="80,20,21"
# Сервер DNS.
dns_ip="192.168.1.10,192.168.1.210"
# Кому разрешен FTP.
all_lan="192.168.1.254,192.168.1.11,192.168.1.250,192.168.1.249,192.168.1.200,192.168.1.202,192.168.1.205"
# FTP passive mode
port_ftp_d="49152-65535"
# Кому в сети разрешен джаббер.
ip_jabber="192.168.1.250,192.168.1.43,192.168.1.41,192.168.1.50,192.168.1.35"
#
ip_admins="192.168.1.11,192.168.1.250"
# rAdmin,RDP,SSH,Telnet и еще что-то, уже не помню что.
port_admins="4899,3389,22,23,2593,2710,5003,8080"
# Steam (без коментариев).
steam_udp_1="27000-27015"
steam_udp_2="27015-27030"
steam_tcp="27014-27050"
steam_udp="4380"
# mail_server
ip_mail="192.168.1.248"
# Аська у нас одна - Miranda, и ходит она по 443.
# Дабы пользователи не шалили и не ставили свои альтернативные клиенты,
# 5190 закрыт, а так же заблочены IP login.icq.com.
ip_icq_bad="64.12.202.116,205.188.251.43,64.12.161.164,64.12.161.185"
#
#
# Сброс всех правил.
/sbin/ipfw -f -q flush
#
# Проверка динамических правил. Я их не использовал, в основном, из-за незнания на тот момент.
${fw} 10 check-state
#
# Разрешаем траффик по внутреннему интерфейсу.
${fw} 20 allow ip from any to any via lo0
#
# Запрещаем откуда-то лезть на внутренний интерфейс и с него лезть куда-то.
# Вообще я не видел срабатываний этих правил, но пусть лучше будет, спокойней так.
${fw} 30 deny ip from any to 127.0.0.0/8
${fw} 35 deny ip from 127.0.0.0/8 to any
#
# Запрещаем пакеты с внутренней сети на внешнем интерфейсе и с внешней сети на внутреннем интерфейсе.
${fw} 40 deny ip from ${netin} to any in via ${lanout}
${fw} 45 deny ip from ${netout} to any in via ${lanin}
#
#
### Учет траффика ###
# Совершенно дубовый способ считать траффик.
# Собственно, правило count - это счетчик. На выходе получаем колчиество байт,
# подошедших под это правило, делим на 1048576 - получаем мегабайты.
# Весь траффик.
${fw} 50 count ip from any to any in via ${lanout} # скачано
${fw} 51 count ip from any to any out via ${lanout} # передано
#
# WEB
${fw} 52 count ip from any to any 80,443 out via ${lanout}
${fw} 53 count ip from any 80,443 to any in via ${lanout}
#
#
# Кому нельзя в инет. Тут можно было обойтись одним правилом:
# все IP загнать в переменную и указыать ее, но мне удобнее как есть,
# потому что тут сразу видно, кто стоит в блок-листе и его легко править.
# Иванов
${fw} 106 deny tcp from ${ip_lan}.26 to any ${port} in via ${lanin}
# Петров
${fw} 107 deny tcp from ${ip_lan}.66 to any ${port} in via ${lanin}
# Сидоров
${fw} 108 deny tcp from ${ip_lan}.27 to any ${port} in via ${lanin}
#
# Блокировка ICQ.
${fw} 140 deny tcp from ${netin} to ${ip_icq_bad} in via ${lanin}
${fw} 141 deny tcp from ${netin} to any 5190 in via ${lanin}
#
# Серверам (некоторым) в инет не надо.
# backup
${fw} 170 deny ip from ${ip_lan}.201 to any in via ${lanin}
${fw} 171 deny ip from any to ${ip_lan}.201 out via ${lanin}
# sql
${fw} 175 deny ip from ${ip_lan}.205 to any in via ${lanin}
${fw} 176 deny ip from any to ${ip_lan}.205 out via ${lanin}
#
#
# Весь траффик по 80 порту заворачиваем в Squid, а там уже лекго установить, кому куда можно.
${fw} 190 skipto 200 tcp from ${ip_admins} to any 80 # Админам можно везде, да и зачем
# заваливать логи никому ненужной инфой. Я и сам знаю, где лазею!
${fw} 195 fwd 127.0.0.1,3128 tcp from ${netin} to any 80 #,443
#
#
# Режем частные сетина внешнем интерфейсе
${fw} 200 deny ip from any to 10.0.0.0/8 in via ${lanout}
${fw} 210 deny ip from any to 172.16.0.0/12 in via ${lanout}
#${fw} 220 deny ip from any to 192.168.0.0/16 in via ${lanout} # У меня есть впн, тоже 192.168,
# поэтому это правило не подходит.
${fw} 230 deny ip from any to 0.0.0.0/8 in via ${lanout}
${fw} 240 deny ip from any to 169.254.0.0/16 in via ${lanout}
${fw} 250 deny ip from any to 224.0.0.0/4 in via ${lanout}
${fw} 260 deny ip from any to 240.0.0.0/4 in via ${lanout}
# рубим фрагментированные icmp
${fw} 270 deny icmp from any to any frag
${fw} 280 deny icmp from any to 255.255.255.255 in via ${lanout}
${fw} 290 deny icmp from any to 255.255.255.255 out via ${lanout}
${fw} 300 deny ip from 10.0.0.0/8 to any out via ${lanout}
${fw} 310 deny ip from 172.16.0.0/12 to any out via ${lanout}
#${fw} 320 deny ip from 192.168.0.0/16 to any out via ${lanout} # Читай выше
${fw} 330 deny ip from 0.0.0.0/8 to any out via ${lanout}
${fw} 350 deny ip from 169.254.0.0/16 to any out via ${lanout}
${fw} 360 deny ip from 224.0.0.0/4 to any out via ${lanout}
${fw} 370 deny ip from 240.0.0.0/4 to any out via ${lanout}
#
#
# NAT
${fw} 400 divert natd ip from ${netin} to any out via ${lanout}
${fw} 410 divert natd ip from any to ${ipout} in via ${lanout}
#
# Отправляем запросы с админских компов ЗА блокирующее правило. Пускай там варятся отдельно!
${fw} 445 skipto 50010 all from ${ip_admins} to any ${port_admins}
#
# FTP Active
${fw} 446 allow tcp from any 21,20 to ${ip_admins} in via ${lanout}
${fw} 448 allow tcp from me 1024-65535 to any 21,20 out via ${lanout}
# FTP Passive
${fw} 455 allow tcp from me 1024-65535 to any 1024-65535 out via ${lanout}
#
# Пропускает пакеты по уже установленным соединениям. Если соединение установлено,
# то оно попало хотя бы под одно правло.
${fw} 459 allow tcp from any to any established
#
#
# Снаружи нас пинговать нельзя. А вот мы должны иметь возможность пускать пинги в инет.
${fw} 510 allow icmp from any to any out icmptypes 8
${fw} 520 allow icmp from any to any in via ${lanin} icmptypes 8
${fw} 530 allow icmp from any to any out via ${lanin} icmptypes 0
${fw} 540 allow icmp from any to any in icmptypes 0
${fw} 550 allow icmp from any to any out via ${lanin} icmptypes 3
${fw} 580 deny icmp from any to any in via ${lanout} icmptypes 8
${fw} 590 deny icmp from any to any out via ${lanout} icmptypes 3
#
#
# Разрешаем траффик внутренней сети на внутреннем интерфейсе.
${fw} 610 allow ip from ${netin} to me in via ${lanin}
${fw} 630 allow ip from me to ${netin} out via ${lanin}
${fw} 640 allow ip from any to ${netin} in via ${lanin}
${fw} 650 allow ip from any to ${netin} out via ${lanin}
${fw} 680 allow ip from ${netin} to any in via ${lanin}
#
#
# DNS
${fw} 700 allow udp from ${ipout} to any 53 out via ${lanout}
${fw} 710 allow udp from any 53 to ${ipout} in via ${lanout}
${fw} 720 allow udp from any 53 to ${dns_ip} in via ${lanout}
${fw} 730 allow udp from any 53 to any in via ${lanout}
#
#
# OpenVPN (5555). На всякий случай оставил, просто для примера.
${fw} 800 allow udp from any to me 5555 in via ${lanout}
${fw} 810 allow udp from me 5555 to any out via ${lanout}
${fw} 850 allow all from 192.168.5.0/24 to 192.168.1.0/24
#
#
# mail. Стандартные 25 и 110, плюс есть веб-морда - отсюда еще и 80.
# WEB-сервера в локалке нет, так что все запросы на 80 спокойно форвардятся на mail-сервер.
${fw} 1000 allow tcp from any to ${ip_mail} 25,110 in via ${lanout}
${fw} 1015 allow tcp from me to any 110,25 out via ${lanout}
${fw} 1025 allow tcp from ${ip_mail},194.190.90.142 to any 53,110
${fw} 1035 allow tcp from 194.190.90.142 to any 80 out via ${lanout}
${fw} 1060 allow tcp from any to ${ip_mail} 80,110,25 in via ${lanout}
#
#
# NTP
${fw} 1104 allow udp from me to any 123 out via ${lanout}
#
#
# Форвардинг. Точнее, просто разрешающее правило, а само перенаправление
# указывается в NAT'е. Это правило для rAdmin'а (4899), если нужено RDP - указываем 3389.
${fw} 1240 allow tcp from any to ${ip_lan}.8 4899
#
#
# http,https,ftp
${fw} 2214 allow tcp from me to any ${port} out via ${lanout}
#
# FTP passive mode
${fw} 2240 allow tcp from any to any ${port_ftp_d} via ${lanout}
${fw} 2246 allow tcp from any ${port_ftp_d} to me
#
#
# ICQ
${fw} 2500 allow tcp from me to 205.188.0.0/16 443 out via ${lanout}
${fw} 2510 allow tcp from me to 64.12.0.0/16 443 out via ${lanout}
#
#
# Jabber
${fw} 2600 allow tcp from me to any 6118,6119 out via ${lanout}
#
#
# Steam
${fw} 20000 allow udp from me to any ${steam_udp_1}
${fw} 20010 allow udp from me to any ${steam_udp_2}
${fw} 20020 allow udp from me to any ${steam_udp}
${fw} 20030 allow tcp from me to any ${steam_tcp}
#
#
# torrents
${fw} 30000 deny udp from me 51216 to any out via ${lanout}
${fw} 30010 deny udp from any to ${ip_lan}.250 51216 in via ${lanout}
#
#
# UDP 80. Мне просто интересна активность на этом порту, потому что как-то
# заметил в логах сликом много обращений на UDP80
${fw} 30200 deny udp from any to me 80 in via ${lanout}
#
#
# ICQ 5190. Блокируем 5190.
${fw} 30400 deny tcp from me to any 5190
#
#
# Блок всего с занесением в лог
${fw} 39999 deny log all from any to any
#
#
# admins
${fw} 50010 allow all from ${ip_admins} to any ${port_admins} in via ${lanin}
${fw} 50011 allow all from ${ip_admins} to any ${port_admins}
${fw} 50013 allow all from me to any ${port_admins}
${fw} 50015 deny all from any to any
#
# ->200
${fw} 50020 allow all from any to any
${fw} 50025 deny all from any to any
#
echo "IT WORKS!"
Теперь пару слов о NAT'е. «Ядерным» NAT'ом я не пользуюсь, и не потому, что демон чем-то лучше, а просто потому, что по natd в сети попалось больше информации. Да и проблем с ним, тьфу-тьфу-тьфу, не было. Итак, в rc.conf есть команда на запуск скритика /etc/natd.sh, а вот что в этом скрипте:
/sbin/natd -f /etc/natd.conf -n re0
О синтаксисе: «redirect_port „протокол“ „IP_назначения“:»порт_назначения" «порт_обращения»". IP_назначения — это компьютер в локалке, на который мы перенаправляем пакеты, соответственно, порт_назначения — порт это компа в локалке. А порт_обращения — внешний порт шлюза, на который приходит пакет из инета. Ну и пару примеров использования natd:
# RDP
# Иванов
redirect_port tcp 192.168.1.40:3389 1234
# Петров
redirect_port tcp 192.168.1.41:3389 2345
Для начала этого должно хватить. Я не рассматривал в примере использование динамических правил и ограничения траффика, дабы не запутывать и не усложнять. И, да, это мой первый опыт постоения шлюзов на FreeBSD, поэтому конструктивная критика и предложения приветствуются!
При настройке шлюза и подготовке статьи активно пользовался хендбуком и лиссярой, это кладези информации для начинающего фряшника!
Спасибо за внимание, искренне надеюсь, что эта статья поможет кому-то разобраться в непонятном и сэкономит время.