Настраиваем PF (Packet Filter) на FreeBSD.

11th Январь 2011 | Метки: , , , , ,
Опубликовал: Andrey [rtty] Shidakov

Продолжение, начало тут

Вспомним нашу схемку:

Итак, составим правила для PF:

1. Конфигурация PF.

/etc/firewall/pf.conf:

# Не фильтруем lo0
set skip on lo0

# nat rules
nat-anchor "rules/*"

# redirect rules
rdr-anchor "rules/*"

# rules
anchor "rules/*"

### deny all ###
block all

### rules ###
load anchor "rules/gif0" from "/etc/firewall/pf.xl0" # Загружаем блок правил для xl0
load anchor "rules/gif1" from "/etc/firewall/pf.xl1" # Загружаем блок правил для xl1
# Для каждого нового интерфейса добавляем свой блок, например для OpenVPN:
#load anchor "rules/gif1" from "/etc/firewall/pf.tap0"

Файлик: /etc/firewall/pf.xl0:

# Сеть провайдера
if="xl0"
ip="10.2.2.10" # IP
gw="10.2.2.1" # Шлюз провайдера

# nat
nat on $if from !$ip -> $ip  # Включаем NAT

# rdr
# Пример: пробросим порт 26770 (tcp, udp) с внешнего адреса
# на компьютер в локальной сети с IP 192.168.0.2
rdr on $if inet proto { tcp, udp } to $ip port 26770 -> 192.168.0.2

# rules
# Разрешаем весь исходящий
pass out quick on $if
# Разрешаем icmp трафик
pass in quick on $if reply-to($if $gw) inet proto icmp to $ip
# Разрешаем ftp и блок PassivePort
pass in quick on $if reply-to($if $gw) inet proto tcp to $ip port { 21, 43000:44000 }
# Разрешаем ssh
pass in quick on $if reply-to($if $gw) inet proto tcp to $ip port 22
# Разрешаем www
pass in quick on $if reply-to($if $gw) inet proto tcp to $ip port 80
block in quick on $if

Файлик: /etc/firewall/pf.xl1:

# Локальная сеть
if="xl1"
ip="192.168.0.1"

# rdr
# Пример редиректа для прозрачного прокси
#rdr on $if inet proto tcp to port 80 -> 127.0.0.1 port 3129 

# rules
pass quick on $if

Простейшие конфиги написаны, можно загружать правила:

pfctl -f /etc/firewall/pf.conf
pfctl -e

Для загрузки правил в автомате добавляем в /etc/rc.conf:

### PF
pf_enable="YES"
pf_rules="/etc/firewall/pf.conf"

Убедившись, что внутрисеть провайдера доступна с локальной сети, приступим к настройке pppoe.

2. Настройка PPPOE.

2.1 Устанавливаем MPD:

cd /usr/ports/mpd5
make
make install clean

2.2 Добавляем в автозагруку:

echo 'mpd_enable="YES"' >> /etc/rc.conf
echo 'mpd_flags="-b"' >> /etc/rc.conf

2.3 Файлы конфигурации

Главный конфигурационный файл /usr/local/etc/mpd5/mpd.conf:

startup:
    set user admin 01345 admin
    set console self 127.0.0.1 5005
    set console open

default:
    load pppoe_stream

pppoe_client_common:
    set link max-redial 0
    set link keep-alive 10 60

pppoe_stream:
    create bundle static Bstream
    set iface enable tcpmssfix
    set iface route default  # Добавляет маршрут по умолчанию
    set iface up-script /usr/local/etc/mpd5/scripts/inet.stream.up.sh
    set iface down-script /usr/local/etc/mpd5/scripts/inet.stream.down.sh
    create link static Lstream pppoe
    set link action bundle Bstream
    set auth authname "000011111"  # Ваш логин
    set auth password "112233445"  # Ваш пароль
    load pppoe_client_common
    set pppoe iface re0    # Название сетевого интерфейса
    set pppoe service ""
    open

Файлик /usr/local/etc/mpd5/scripts/inet.stream.up.sh:

#!/bin/sh
if=$1
ip=$3
gw=$4
pfctl=/sbin/pfctl
ifconfig=/sbin/ifconfig
### pf ###
echo -e "
# nat
nat on $if from !$ip -> $ip

# rdr
rdr pass on $if inet proto tcp from any to $if port 26770 -> 192.168.0.2

# rules
pass out quick on $if
pass in quick on $if reply-to($if $gw) inet proto icmp
pass in quick on $if reply-to($if $gw) inet proto tcp to $ip port 22 # ssh
pass in quick on $if reply-to($if $gw) inet proto tcp to $ip port 80 # web
pass in quick on $if reply-to($if $gw) inet proto tcp to $ip port { 21, 24000:24050 }

block in quick on $if
" | $pfctl -a "rules/stream" -f -
######

### routes ###
# Добавляем нужные маршруты.
route=/sbin/route
route delete default
route add 10/8 10.2.2.1
route add default $gw

Файлик /usr/local/etc/mpd5/scripts/inet.stream.down.sh:

#!/bin/sh
if=$1
ip=$3
gw=$4
pfctl=/sbin/pfctl
ifconfig=/sbin/ifconfig
# route
$route delete default
$route add default 10.2.2.1
### pf ###
$pfctl -a "rules/stream" -F all
######

Запускаем:

service mpd5 start
  1. Михаил
    21st Декабрь 2011 в 22:12

    листинг фалов конфигураций в норму бы привести, что с переносом все исказилось.

  2. xrensgory
    26th Декабрь 2011 в 17:52

    Как-то не очень красиво nat on $if from !$ip -> $ip

    nat on ng0 from xl1:network -> (ng0)

  3. 6th Январь 2012 в 19:29

    @xrensgory
    «(ng0)» — периодически пф будет пытаться определить адрес (ip) интерфейса. в пределах сессии адрес точно известен, как и то — что в пределах он не изменится. поэтому использование адреса предпочтительнее использования «($if)».
    натить всю предположительную подсеть конечно можно, а если сетей несколько? Теоретически, весь мир, который находится за $if нам известен только через адрес, который был присвоен — $ip. Любой другой адрес прочий мир к нашей системе не относит. Т.е. по факты любой выходящий пакет нужно натить адресом, который выдали, в независимости откуда пакет пришел. Если пакет выходит через этот интерфейс — у него только один выход — странслироваться в присвоенный адрес. Поэтому условие «from …» можно просто убрать.

  4. 6th Январь 2012 в 20:09

    @Михаил
    Извиняюсь за задержку, это что-то походу в geshi перекосило. Убрал подсветку, вроде все норм теперь.

  5. Acden
    20th Ноябрь 2012 в 19:38

    Уважаемый автор блога, я зарегался лишь чтобы выразить Вам благодарность за эту статью!

    Всё получилось с первого раза на FreeBSD 9.

    А как добавить правило для пропускания порта https?!

  6. 6th Январь 2013 в 07:44

    Спасибо :-) Рад что заметка кому-то еще помогла.

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