Настраиваем фаервол PF во FreeBSD

9th Май 2010 | Метки: , ,
Опубликовал: Dmitriy [dk] Kalinin

Если рассматривать фаерволы под ОС FreeBSD — то два основных претендента это pf (портирован из OpenBSD) и ipfw (родной штатный фаервол FreeBSD).

Оба этих инструмента достаточно мощные, но в данной статье мы рассмотри фаервол pf.

Придумаем для начала тестовую задачу, у нас есть есть маршрутизатор, который одним концом вставлен в нашу личную локальную сеть, другим концом — в локальную сеть провайдера. Интернет поступает на маршрутизатор через PPPoE соединение. В локальной сети провайдера живут адреса 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 (RFC1918). В нашей личной локальной сети живут адреса 192.168.0.1/24. Зарисуем схему:

В нашем маршрутизаторе есть два сетевых адаптера: xl0 и xl1. xl0 — смотрит в локальную сеть провайдера, xl1 — смотрит в личную локальную сеть. Присваиваем адреса этим сетевым интерфейсам, для этого вносим изменения в файл /etc/rc.conf:

# network interfaces
ifconfig_xl0="inet 10.2.2.10 netmask 255.255.254.0"
ifconfig_xl1="inet 192.168.0.1 netmask 255.255.255.0"

IP-адрес нашего маршрутизатор в сети провайдера — 10.2.2.10, в личной сети — 192.168.0.1.

Чтоб пакеты из нашей ЛВС попадали в ЛВС провайдера и интернет — необходимо разрешать передачу пакетов между сетевыми интерфейсами на маршрутизаторе, для этого вносим еще одну строчку в /etc/rc.conf

gateway_enable="yes"

Перезагружаться нам неохота, поэтому включаем форвардинг пакетов через sysctl:

[root@relay ~]# sysctl net.inet.ip.forwarding=1
net.inet.ip.forwarding: 0 -> 1
[root@relay ~]#

Полные радости, пробуем пропинговать какой-нибудь компьютер в сети провайдера из нашей локальной сети:

C:\>ping 10.2.2.1
 
Обмен пакетами с 10.2.2.1 по 32 байт:
 
Превышен интервал ожидания для запроса.
Превышен интервал ожидания для запроса.
Превышен интервал ожидания для запроса.
Превышен интервал ожидания для запроса.
 
Статистика Ping для 10.2.2.1:
    Пакетов: отправлено = 4, получено = 0, потеряно = 4 (100% потерь),
 
C:\>

Хм, неудача, начинаем разбираться, запускаем снифер на локальном интерфейсе:

[root@relay ~]# tcpdump -n -i xl1 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on msk0, link-type EN10MB (Ethernet), capture size 96 bytes
21:45:23.136279 IP 192.168.0.20 > 10.2.2.1: ICMP echo request, id 768, seq 3072, length 40
21:45:28.398501 IP 192.168.0.20 > 10.2.2.1: ICMP echo request, id 768, seq 3328, length 40
21:45:33.898540 IP 192.168.0.20 > 10.2.2.1: ICMP echo request, id 768, seq 3584, length 40
21:45:39.399884 IP 192.168.0.20 > 10.2.2.1: ICMP echo request, id 768, seq 3840, length 40
^C
4 packets captured
355 packets received by filter
0 packets dropped by kernel
[root@relay ~]#

На внутреннем интерфейсе пакеты есть, смотрим что творится на внешнем:

[root@relay ~]# tcpdump -n -i xl0 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on xl0, link-type EN10MB (Ethernet), capture size 96 bytes
21:48:12.263060 IP 192.168.0.20 > 10.2.2.1: ICMP echo request, id 53798, seq 4096, length 40
21:48:17.401550 IP 192.168.0.20 > 10.2.2.1: ICMP echo request, id 53798, seq 4352, length 40
21:48:22.901604 IP 192.168.0.20 > 10.2.2.1: ICMP echo request, id 53798, seq 4608, length 40
21:48:28.401631 IP 192.168.0.20 > 10.2.2.1: ICMP echo request, id 53798, seq 4864, length 40
^C
4 packets captured
6547 packets received by filter
0 packets dropped by kernel
[root@relay ~]#

На внешнем тоже пакеты есть, правда странные 192.168.0.20 > 10.2.2.1. Разумеется сеть провайдера понятия не имеет о нашем адресе 192.168.0.20, поэтому ответа и нет. Максимум провайдер знает про наш адрес 10.2.2.10.
Итак, мы убедились, что пакеты из нашей уютненькой локалки попадают в локалку провайдера. Но в текущем виде — это бестолку, ибо ответа на эти пакеты не будет. Для решения это проблемы существует NAT. Что же он делает? При прохождении пакета запоминается, что пакет шел от 192.168.0.20 на адрес 10.2.2.1, затем в пакете заменяется адрес 192.168.0.20 на нужный адрес и пихается дальше. В нашем случае — нужный адрес будет 10.2.2.10. Когда вернется обратно — наш маршрутизатор будет помнить об этом, и вернет пакет как следует, тому кто запросил его, а именно 192.168.0.20. Чуть позже это будет показано.
Сделали выводы — что нам потребуется NAT для нормальной работы.

Нужен, так нужен, ничего не поделать. Из названия следует — что NAT мы будем делать с помощью pf. Для этого как минимум нам потребуется использовать pf. Собираем pf модулем:

[root@relay ~]# cd /usr/src/sys/modules/pf
[root@relay /usr/src/sys/modules/pf]# make
...
 
[root@relay /usr/src/sys/modules/pf]# make install
install -o root -g wheel -m 555   pf.ko /boot/kernel
kldxref /boot/kernel
[root@relay /usr/src/sys/modules/pf]# make cleandir
rm -f export_syms pf.ko pf.kld pf.o pf_if.o pf_subr.o pf_osfp.o pf_ioctl.o pf_norm.o pf_table.o pf_ruleset.o in4_cksum.o opt_pf.h opt_inet.h opt_inet6.h opt_bpf.h
rm -f @ machine
rm -f .depend GPATH GRTAGS GSYMS GTAGS
[root@relay /usr/src/sys/modules/pf]#

Загружаем pf:

[root@relay /boot/kernel]# cd /usr/src/sys/modules/pf
[root@relay /usr/src/sys/modules/pf]# kldload pf
[root@relay /usr/src/sys/modules/pf]# kldstat |grep "pf"
 9    1 0xffffffff808c4000 46770    pf.ko
[root@relay /usr/src/sys/modules/pf]#

Фаервол загружен, теперь разрешим загружать его вместе с системой. Внесем строчку в файл /boot/loader.conf:

pf_load="yes"

Фаервол загружен, но еще не активен, пожалуй мы не будем пока его активировать, а сначала составим правила для него.
Продолжение тут

Пока комментариев нет.
Вы должны авторизоваться для отправки комментария.