Как известно, межсетевой экран PF, портированный в FreeBSD из OpenBSD, не может корректно транслировать (NAT) GRE-протокол и, к примеру, из локальной сети невозможно создать несколько одновременных соединений к внешнему серверу VPN PPTP.Одним из способов решения проблемы является трансляция PPTP-соединений родным IPFW с "ядерным" NAT. При этом вовсе необязательно компилировать ядро. Все описанные действия проверены в FreeBSD версии 7.2. Но должно работать и в других версиях, где есть поддержка "ядерного" NAT для IPFW.
В /etc/rc.conf добавляем
#Включаем IPFW
firewall_enable="YES"
# Подгружаем модуль ядра ipfw_nat
firewall_nat_enable="YES"
# Указываем путь к скрипту загрузки правил
firewall_script="/etc/ipfw.script"Создаем файл /etc/ipfw.script
#!/bin/sh
/sbin/ipfw -q /dev/stdin <<RULES
flush
#em0 - внешний интерфейс шлюза
nat 10 config if em0
#Правила для трансляции PPTP-соединения
add 10 nat 10 gre from any to any
add 11 nat 10 tcp from any to any dst-port pptp
add 12 nat 10 tcp from any pptp to any
# Разрешаем весь трафик
add allow all from any to any
RULESДелаем скрипт исполняемым
# chmod +x /etc/ipfw.script
Добавляем в правила PF
# Запрещаем PF транслировать PPTP-соединения
no nat on $external_if proto gre all
no nat on $external_if proto tcp from any to any port = pptp
no nat on $external_if proto tcp from any port = pptp to any
... skip ...
# Пропускаем PPTP-соединения
pass quick on $external_if inet proto tcp from any to any port 1723
pass quick on $external_if inet proto tcp from any port 1723 to any
pass quick on $external_if inet proto gre from any to anyПосле всех сделанных изменений перезагружаемся.
URL: http://www.propheta.ru/2009/11/pptp-gre-pf.html
Обсуждается: http://www.opennet.me/tips/info/2245.shtml
> После всех сделанных изменений перезагружаемся.наследие off-topic?
>> После всех сделанных изменений перезагружаемся.
>
>наследие off-topic?Скорее - это привычка перестраховщика при правке /etc/rc.conf, не желающего чтобы его будили в 3 ночи или вызвали из отпуска из-за того, что после внеплановой перезагрузки что-то не поднялось как нужно.
опять же, почему просто не использовать ipfw вместо pf?
Потому что ipfw не нужен.
>Потому что ipfw не нужен.Работающий только на одном cpu pf не нужен.
http://forum.nag.ru/forum/index.php?showtopic=47497
>Потому что ipfw не нужен.в догонку: http://forum.nag.ru/forum/index.php?showtopic=49812
Над комментариями пользователей IPFW относительно PF я плакал.
дадада!я тоже плакал, но над наивностью тех, кто повелся на syntax sugar от pf:
>Добавлю свои пять копеек. :-) В свое время тоже повелся на pf (как же - написанный с нуля файрволл от команды OpenBSD!), однако отсутствие динамических пайпов по маскам не позволяло использовать его как шейпер - был pf на файрволл и нат и dummynet на шейп. В итоге с увеличением количества юзеров и полосы (3500+ и около 200-250 Мбит) все начало конкретно тормозить, что выливалось в потерю пакетиков. Сделал профилирование через hwpmc (кто не в курсе - http://wiki.freebsd.org/PmcTools) чего, кстати, желаю и всем остальным, кто хочет поближе узнать, чем занят комп в то время, которое в top'е обозначается как interrupt и т.п. :-) Так вот, в итоге выяснилось, что nat от pf - это такая жручая штука, что лучше потратить время и сделать адекватный набор правил для ipfw, чем насиловать систему этим pf.... Более подробно я писал об этом в этой теме - http://forum.nag.ru/forum/index.php?showtopic=47497
В итоге на основе личного опыта могу сказать, что pf - это действительно быстрый и удобный (пару строчек написать!) способ ненапряжно отфайрволлить/отнатить/зашейпить, например, офис. Или квартиру. Но для серьезной провайдерской работы он не годится принципиально. :-) ipfw - наше все! И с годами становится все лучше и лучше...
От себя добавлю: на стенде у меня получалась та же самая картина.
Резко появляются дропы, всё начинает тормозить, при этом загружено только одно ядро.
PS: да и размер правила у pf огромный - где-то 500байт.
http://shurik.kiev.ua/blog/index.php?/archives/9-FreeBSD_i_G...
+камент
народ, а у меня работает, у меня отдел бухов весь долбится для отправки платежек по pptp в банки. Чего я не так желаю?
Немного не по теме, но может кто подскажет... Почему через D'Link`овский PPPoE роутер может пролезть только два конекта на внешний PPTP сервак? При подключении третьего кого-нибудь отрубает :(
Странно, но у меня на FreeBSD 7.2-p5 amd64 при включенном PF, это не работает - к одному и тому же внешнему IP с двух "серых" адресов из локалки может подключиться только один, другим выдает Error 800. Пришлось вернуться к "костылю" с Frickin'ом. А жаль.
А у меня на 7.3 frickin не работает. Клиенту что-то не нравится в ответе сервера:
19:20:36.729571 IP 10.1.5.14.1609 > 193.16.x.x.1723: S 3359410257:3359410257(0) win 65535 <mss 1460,nop,nop,sackOK>
19:20:36.729619 IP 193.16.x.x.1723 > 10.1.5.14.1609: S 3430707049:3430707049(0) ack 3359410258 win 65535 <mss 1460,sackOK,eol>
19:20:36.730070 IP 10.1.5.14.1609 > 193.16.x.x.1723: P 1:157(156) ack 1 win 65535: pptp CTRL_MSGTYPE=SCCRQ PROTO_VER(1.0) FRAME_CAP(A) BEARER_CAP(A) MAX_CHAN(0) FIRM_
REV(2600) [|pptp]
19:20:36.829972 IP 193.16.x.x.1723 > 10.1.5.14.1609: . ack 157 win 65535
19:20:37.305707 IP 193.16.x.x.1723 > 10.1.5.14.1609: P 1:157(156) ack 157 win 65535: pptp CTRL_MSGTYPE=SCCRP PROTO_VER(1.0) RESULT_CODE(1) ERR_CODE(0) FRAME_CAP(AS) B
EARER_CAP(DA) MAX_CHAN(0) FIRM_REV(257) [|pptp]
19:20:37.306094 IP 10.1.5.14.1609 > 193.16.x.x.1723: P 157:325(168) ack 157 win 65379: pptp CTRL_MSGTYPE=OCRQ CALL_ID(32768) CALL_SER_NUM(28366) MIN_BPS(300) MAX_BPS(
100000000) BEARER_TYPE(Any) FRAME_TYPE(E) RECV_WIN(64) PROC_DELAY(0) PHONE_NO_LEN(0) [|pptp]
19:20:37.381694 IP 193.16.x.x.1723 > 10.1.5.14.1609: P 157:189(32) ack 325 win 65535: pptp CTRL_MSGTYPE=OCRP CALL_ID(5532) PEER_CALL_ID(32768) RESULT_CODE(1) ERR_CODE
(0) CAUSE_CODE(0) CONN_SPEED(64000) RECV_WIN(16) PROC_DELAY(1) PHY_CHAN_ID(131072)
19:20:37.382514 IP 193.16.x.x > 10.1.5.14: GREv1, call 32768, seq 0, length 54: LCP, Conf-Request (0x01), id 1, length 40
19:20:37.385422 IP 10.1.5.14.1609 > 193.16.x.x.1723: P 325:349(24) ack 189 win 65347: pptp CTRL_MSGTYPE=SLI PEER_CALL_ID(5532) SEND_ACCM(0xffffffff) RECV_ACCM(0xfffff
fff)
19:20:37.389421 IP 10.1.5.14 > 193.16.x.x: GREv1, call 5532, seq 0, length 37: LCP, Conf-Request (0x01), id 0, length 23
19:20:37.484755 IP 193.16.x.x.1723 > 10.1.5.14.1609: . ack 349 win 65535
19:20:39.389337 IP 10.1.5.14 > 193.16.x.x: GREv1, call 5532, seq 1, length 37: LCP, Conf-Request (0x01), id 1, length 23
19:20:39.398378 IP 193.16.x.x > 10.1.5.14: GREv1, call 32768, seq 1, length 54: LCP, Conf-Request (0x01), id 2, length 40
19:20:39.398826 IP 10.1.5.14 > 193.16.x.x: GREv1, call 5532, seq 2, ack 1, length 39: LCP, Conf-Reject (0x04), id 2, length 21
19:20:41.425357 IP 193.16.x.x > 10.1.5.14: GREv1, call 32768, seq 2, length 54: LCP, Conf-Request (0x01), id 3, length 40
19:20:41.425961 IP 10.1.5.14 > 193.16.x.x: GREv1, call 5532, seq 3, ack 2, length 39: LCP, Conf-Reject (0x04), id 3, length 21
19:20:42.404885 IP 10.1.5.14 > 193.16.x.x: GREv1, call 5532, seq 4, length 37: LCP, Conf-Request (0x01), id 2, length 23Если ппосадить клиента за обыйчный офисный DLink-роутер, то он успешно подключается.
добавьте правило в PFpass proto 47 all keep state
> добавьте правило в PF
> pass proto 47 all keep state"keep state" уже не обязательно — оно и так по дефолту у правил, если возможно, выставляется. //К.О.