Настройка роутера на базе FreeBSD


В данной статье мы расскажем о настройке роутера на базе FreeBSD выполняющего роль шлюза в инернет с установкой firewall-a, и поддерживающем статическую arp таблицу mac адресов в локальной сети.
Речь пойдет о IPFW который в FreeBSD служит верой и правдой уже много лет, тем более что в последней версии в составе c FreeBSD 4.0 исправленны ошибки и добавленна корректная возможность ограничивать полосу пропускания по интерфейсу (использование pipe с опцией bw).
Предположим что мы имеет роутер с тремя сетевыми платами одна из которых (назовем ее vx0, IP 200.200.200.1) смотрит в сторону Internet-a а
вторая (назовем ее vx1, IP 200.200.200.2) смотрит в сторону локальной сети с реальными 18 IP адресами (subnet 200.200.200.0/28 netmask
255.255.255.240). К третьей сетевой карточке (vx2 IP 192.168.1.1 и сеть 192.168.1.0/28) подключена 10Mb сеть соседнего офисса.
Задачи перед нами поставленны следующие :
1. Закрыть доступ во внутренюю сеть извне по портам 135,137,139
2. Дать возможность пользователям локальной сети работать с почтой и работать с в броузере с WWW,FTP серверами других компаний.
3. Закрыть на роутере возможность атаки типа SYN Flood, ICMP Flood.
4. Закрыть доступ к корпоративному WWW,FTP серверу (200.200.200.5) используемый для работы с отчетами выставленными на этот WWW server только в пределах локальной сети и доступа из филиала который имеет IP 190.190.190.5
5. Открыть доступ для конфигурирования этого роутера с определеного хоста системного администратора.
6. Обеспечить подсчет трафика по IP адресам в локальной сети чтобы впоследствии доказать что Вася весь месяц только и занимался скачиванием c www.playboy.com картинок сомнительного содержания.
7. Ограничить трафик 64Kb на третьей сетевой карточке для дружественного клиента компании находящемуся в том же здании и подключенному по 10Mb к нашему роутеру и закрыть доступ с их стороны в локальную сеть нашей компании.


Итак приступим.
1. Конфигурирование ядра и опций запукаемых скриптов.
В ядро необходимо занести следующие опции :
options IPFIREWALL (включает в ядро код для фильтрации пакетов)
options IPFIREWALL_VERBOSE (включает возможность вести логи по правилам фильтрации и проходящих пакетов)
options IPFIREEWALL_VERBOSE_LIMIT=10 (ограничение списка числа пакетов записываемых в лог для того чтобы не зафлудили syslog)
options TCP_DROP_SYNFIN (отбрасывает TCP пакеты с SYN и FIN)
В итоге при перезагрузке системы мы получим firewall который по умолчанию закрывает прохождение любого IP трафика по всем интерфейсам. Далее мы определим правила которые откроют только те порты TCP или UDP которые нужны для работы пользователей. Если Вы придерживаетесь другого подхода - "сначала все откроем а потом будем закрывать" то вам необходимо указать
следующую опцию в ядре :
options IPFIREWALL_DEFAULT_TO_ACCEPT

В /etc/defaults/rc.conf указываем следующее :
tcp_extensions="NO" (отключаем "опасные" из RFC1323 расширения TCP)
tcp_drop_synfin="YES" (отбрасывем SYN + FIN)
icmp_drop_redirect="YES" (игнорируем перенаправленные ICMP пакеты)
icmp_log_redirect="YES" (включаем логинг ICMP REDIRECT)
firewall_enable="YES" (включаем использование firewall)
firewall_type="Company" (указываем что наши настройки firewalla находятся в rc.firewall в разделе "Company")
defaultrouter="199.199.199.1" (шлюз до нашего ISP)

2. Конфигурирование IPFW.
Теперь приступаем к написанию правил IPFW. Более побдробное описание синтактиса можно прочитать в handbook или man ipfw.
Поскольку мы создаем свою конфигурацию ("Company") то делаем ее описание в rc.firewall :

[Cc][Oo][Mm][Pp][Aa][Nn][Yy]

# Описываем сеть и интерфейсы
fw="200.200.200.1"
local="200.200.200.2"
client="192.168.1.1"
net="200.200.200.0/28"
mask="255.255.255.255.240"

# Разрешаем трафик по local интерфейсу
${fwcmd} add pass all from any to any via lo0

# Разрешаем трафик только в пределах локальной сети
${fwcmd} add pass all from any to any via vx1

# Запрещаем прохождение фрагментированных пакетов
${fwcmd} add deny icmp from any to any frag

# Разрешаем прохождение ICMP пакетов
${fwcmd} add pass ICMP from any to any

# Разрешаем работу с SMTP протоколом
${fwcmd} add pass tcp from any to any 25 out
${fwcmd} add pass tcp from any 25 to any out

# Разрешаем работу с HTTPS протоколом
${fwcmd} add pass tcp from any to any 443 out
${fwcmd} add pass tcp from any 443 to any out

# Запрещаем работу снаружи с внутреним сервером компании
${fwcmd} add pass tcp from 199.199.199.10 to 200.200.200.5 80 via vx0
${fwcmd} add pass tcp from 200.200.200.5 80 to 199.199.199.10 via vx0

# Запрещаем работу снаружи с внутреним сервером компании
${fwcmd} add deny tcp from any to 200.200.200.5 80 in via vx0

# Разрешаем работу с HTTP протоколом
${fwcmd} add pass tcp from any to any 80 out via vx1
${fwcmd} add pass tcp from any 80 to any out via vx1

# Разрешаем работу по всем протоколам в пределах
# только локальной сети нашей компании
${fwcmd} add allow all from any to any via vx1

# Разрешаем работу с DNS серверами
${fwcmd} add pass udp from any to any 53
${fwcmd} add pass udp from any 53 to any

# Разрешаем работу с NEWS Серверами
${fwcmd} add pass udp from any to any 119 out via vx1
${fwcmd} add pass udp from any 119 to any out via vx1

# Разрешаем забор почты по POP3 протоколу
${fwcmd} add pass udp from any to any 110
${fwcmd} add pass udp from any 110 to any

# Разрешаем работу с FTP серверами
# Обратите внимание что 20 порт протокола TCP используется для
# передачи данных, помимо 21 порта.
${fwcmd} add pass tcp form any 21 to any
${fwcmd} add pass tcp from any to any 21
${fwcmd} add pass tcp from any 20 to any
${fwcmd} add pass tcp from any to any 20

# Разрешаем доступ по ssh с домашней машины
# администратора имеющей IP 200.200.200.15
${fwcmd} add pass tcp from 200.200.200.15 22 to {isp}
${fwcmd} add pass tcp from {isp} to 200.200.200.15 22

# Ограничиваем трафик с сетевой карточки vx2 в локальную сеть
# нашей компании
${fwcmd} add deny all from 192.168.1.0/24 to ${net}:${mask} via vx1
${fwcmd} add deny all from ${net}:${mask} to 192.168.1.0/24 via vx1

# Разрешаем работу по базовым портам TCP на интерфейсе vx2
${fwcmd} add pass tcp from 192.168.1.0/24 to any 25 via vx2
${fwcmd} add pass tcp from any 25 to 192.168.1.0/24 via vx2
${fwcmd} add pass tcp from 192.168.1.0/24 to any 110 via vx2
${fwcmd} add pass tcp from any 110 to 192.168.1.0/24 via vx2
${fwcmd} add pass udp from 192.168.1.0/24 to any 53 via vx2
${fwcmd} add pass udp from any 53 to 192.168.1.0/24 via vx2
${fwcmd} add pass tcp from 192.168.1.0/24 to any 80 via vx2
${fwcmd} add pass tcp from any 80 to 192.168.1.0/24 via vx2

# Ограничиваем полосу пропускания на интерфейсе vx2 в 64 Kb. для входящего трафика
${fwcmd} add pipe 1 ip from any to any in via vx0
${fwcmd} add pipe 1 config bw 64Kbit/s

# Ограничиваем полосу пропускания на интерфейсе vx2 в 64 Kb. для исходящего трафика
${fwcmd} add pipe 2 ip from any to any out via vx0
${fwcmd} add pipe 2 config bw 64Kbit/s


Для проверки работы правил вы можете воспользоваться популярным сканером TCP/IP NMAP (входит в состав FreeBSD) дав например команду :
nmap 200.200.200.1 или nmap 200.200.200.2 находясь за пределами диапазона адресов вашей сети, или попросив об этом вашего ISP.

3. Предотвращение подделки MAC адреса
Нам необходимо обезопасить наш роутер от возможности принятия пакетов с IP адресами которые могут попасть в локальную сеть извне под видом легальных пакетов TCP/IP входящие в диапазон сети 200.200.200.0/28.
Даже если это произойдет то на этот случай у нас есть жестко привязанная таблица IP адресов к MAC адресам сетевых карт и роутера нашего ISP.
Иногда это бывает необходимо как мера от нечистоплотных сотрудников которые меняют IP адресс своего хоста на адрес другого ПК, владелец
которого например находится в отпуске и шишки соотв. посыплятся на него ;)
Для начала вам нужно построить MAC таблицу адресов , где формат ее будет примерно таким:
petya 00:20:af:4a:3e:e3
vasya 00:20:fg:3a:3e:21
sasha 00:20:fg:3a:3e:21
marina 00:20:fg:3a:3e:21
и сохранить ее в файле например /etc/ethers.
Для того чтобы узнать Ethernet адрес хоста достаточно на нем набрать arp -a. При запуске на роутере arp -f /etc/ethers вся информация о соответствии IP адреса и MAC адреса сетевой карточки при работе протокола ARP будет браться из файла /etc/ether и замораживаться.
Это процесс можно автоматизировать запустив на роутере arpwatch (он есть в портах FreeBSD) и сделав на каждом хосте файл /etc/hosts с описанием пары name_hosts IP_adress и /etc/ethers с вышеприведенным форматом.
Когда появляется факт подмены IP адресса то arpwatch посылает письмо с описанием проишедшего и таблица arp замораживается.

4. Настраиваем статистику.
Для создания стратистики мы будем использовать ipfm входящий в состав пакетов FreeBSD. При инсталяции в /usr/local/etc/rc.d создается файл
ipfm.sh а в /usr/local/etc файл ipfm.conf. Его то как раз нам и нужно отредактировать. Итак приступим :

##### FIRST LOGGING CONFIGURATION #####
# Описывем внутреннюю сеть с которой снимаем статистику
LOG 200.200.200.0/255.255.255.240 NOT WITH 200.200.0.0/255.255.0.0
# Присваиваем название файлу для сбора статистики
FILENAME /var/log/ipfm/local_net-%d.%m-%H.%M.%S
# Устанавливаем период записи в лог в нашем случае лог будет обновляться еженедально
TIME 7 day
SORT IN
RESOLVE

##### SECOND LOGGING CONFIGURATION #####
NEWLOG
# Описывем внутреннюю сеть нашего клиента 192.168.1.0/24
subnet 192.168.1.0/255.255.255.0 NOT WITH 192.168.0.0/255.255.0.0
# Задаем период записи в лог в данном случае 1 день
FILENAME /var/log/ipfm/ipfm-%d.%m-%H.%M.%S
# Log on a period of one week
TIME 1 day
SORT IN
RESOLVE

Если же требуется более детальная информация по протоколам и количеству передаваемых пакетов то можно воспользоваться опцией count в ipfw :

# Подсчитываем входящий и исходящий трафик по HTTP протоколу
ipfw add count tcp from any to any 80 in via vx0
ipfw add count tcp from any to any 80 out via vx0

# Подсчитываем входящий и исходящий трафик по HTTP протоколу для клиентов
ipfw add count tcp from any to any 80 in via vx2
ipfw add count tcp from any to any 80 out via vx2
ipfw add count tcp from any to any 21 in via vx2
ipfw add count tcp from any to any 21 out via vx2

Еcли же вас интересует статистика с конкретного IP адреса то вы просто указываете так :

ipfw add count tcp from any to 200.200.200.3 in via vx1

где 200.200.200.3 это IP адрес пользователя например Васи который ежемесячно скачивает с www.playboy.com графические файлы.
Вы можете также закрыть доступ к этому сайту например таким способом :
ipfw add log deny all from any to www.playboy.com
с записью в лог попыток обращения к нему.

Графическая статистика строится с применением пакеты MRTG (Multi Router Transfeer Grapheer) при использовании агента snmp запущенного на роутере.
Также необходимо установить на роутере средства обнаружения атак, но это уже тема для другой статьи.

Обновлено: 12.03.2015