[pf] Шлюз в инет с помощью pf, pfnat, squid

Обновлена 7.06.2010

Внимание!

Перед установкой следует позаботиться о достаточном количестве файловых дескрипторов для пользователя, от которого работает squid, при включённом кешировании.

1) В 9.2-Stable обнаружен баг: любое создание интерфейса вырубало форвардинг, устанавливало параметр net.inet.ip.forwarding в 0. Что бы этого не было, нужно устанавливать gateway_enable=»YES» в rc.conf

2) Что бы работал прозрачный прокси, нужно дать устройству /dev/pf права на чтения для всех (если у вас squid работает не из-под root’a):

# chmod o+r /dev/pf

 

1) Включаем pf.

Включить его можно 2 способами: добавив в rc.conf или пересобрать ядро. Выбирайте тот, который вам будет удобнее. Я же опишу оба.

— Через rc.conf

Добавляем следующие строчки в файл /etc/rc.conf:

pf_enable="YES"
pf_rules="/etc/pf.rules"
pflog_enable="YES"

После этого запускаем сам pf:

#/etc/rc.d/pf start

Через пересбор ядра.

Для этого добавляем в файл ядра следующие опции:

device          pf
device          pflog
options         ALTQ

Так же добавим такое в /etc/rc.conf (для указания правил):

pf_rules="/etc/pf.rules"

Пересобираем ядро, и перегружаем машину. Получаем работающий файервол.

2) Установка squid.

Про установку и настройку можно почитать здесь. Единственно, что нужно будет учесть, так это устанавливать squid с опцией SQUID_PF.

3) NAT

Будем использовать pfnat. Для этог добавим в список правил строчку:

nat on $ext_if from $local_network/$netmask to any -> ($ext_if)

Например,

nat on rl0 from 192.168.0.0/24 to any -> (rl0)

Примечание: когда указывается название интерфейса для трансляции адресов, как в примере выше, то IP адрес определяется в pf.conf во время загрузки, а не на «лету». Если вы используетеDHCP для настройки ваших внешних интерфейсов, это может оказаться проблемой. Если ваши присваиваемые IP адреса меняются, NAT будет продолжать преобразовывать исходящие пакеты используя старый IP адрес. Это приведёт к остановке функционирования исходящих соединений. Чтобы этого избежать, вы можете сказать PF автоматически обновлять преобразуемый адрес, указав круглые скобки вокруг названия интерфейса:

4) Форвардинг пакетов между сетевухами, подсетями.

Для того, что бы сервер пересылал пакеты между подсетями, нужно в /etc/rc.conf добавить такую строку (и перегрузить сервак):

gateway_enable="YES"

5) Правила файеврола.

Для самой простой конфигурации достаточно такого списка:

# пускаем тех, кому нужно ходить мимо прокси
no rdr on $int_if inet proto {tcp,udp} from 192.168.0.33/32 to any

# squid
rdr on $int_if inet proto tcp from 192.168.0.0/24 to any port 80 -> 127.0.0.1 port 3128

# проброс порта для rdesktop
rdr on $ext_if inet proto tcp from any to xx.xx.xx.xx port 3389 -> 192.168.0.2 port 3389

# nat
nat on $ext_if from 192.168.0.0/24 to any -> (rl0)

pass all

Примечание.

В новых версиях pf’a вместо rdr для заворота на proxy лучше использовать использовать divert-to/divert-reply. Объяснение оставлю без перевода, так как не правильно передать смысл на русском не смогу:

rdr-to is a general purpose address translation and can forward to 
either the local machine or a different machine. By a small hack 
(using the «bitmask» option) it’s also possible to rewrite destination 
ports and keep the original address. It rewrites addresses in the 
packets, so it’s more suited to «port forwarding». It can been used 
to implement transparent proxies, but requires looking up the original 
destination address using a state table lookup (DIOCNATLOOK), but 
this is relatively complex and requires privileges to access /dev/pf. 

For transparent proxies, divert-to is simpler. It only works on the 
local machine. It preserves the original destination address in the 
packet, allowing a simple method (getsockname) for proxy software 
to retrieve it without needing any special privileges. 

Вот пример как использовать для работы squid’a

Выдержка из man’a pf.conf:

divert-to <host> port <port>
           Used to redirect packets to a local socket bound to host and port.
           The packets will not be modified, so getsockname(2) on the socket
           will return the original destination address of the packet.

divert-reply
           Used to receive replies for sockets that are bound to addresses
           which are not local to the machine.  See setsockopt(2) for 
           information on how to bind these sockets.

6) Ротация логов squid’a

Не забываем добавить ротацию логов в cron:

59   23   *   *   *   root   /usr/loca/sbin/squid -k rotate

[pf] Шлюз в инет с помощью pf, pfnat, squid: 2 комментария

  1. Виталий

    А случалось ли вам настраивать на шлюзе с PF локальную политику для доступа в инет? Ну тоесть есть шлюз/фаер на фре/опенбзде, который натит LAN и дает инет. Но как на самом шлюзе запретить на выход все кроме необходимого для работы portsnap, freebsd-update, ntpd?

    1. skeletor Автор записи

      Да, случалось. Просто нужно правильно настроить файервол и оставить только нужные порты.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *