Некоторое время назад автору этих строк была поставлена задача поднять PPTP-сервер на FreeBSD. Обычно для этого используют mpd, но поскольку автор является "прожжёным линуксоидом" то он решил попробовать поднять привычный по Linux pptpd. Попытка увенчалась успехом и был получен простой в администрировании pptp-сервер. Далее будет приведено описание процесса настройки и запуска сервиса.
Настройка сервера
Подробная постановка задачи:
- сервер под управлением FreeBSD 8.1;
- сетевой интерфейс fxp0 на сервере с IP-адресом 1.2.3.4 и алиасом 1.2.3.5;
- клиенты должны подключаться к серверу на его алиас и иметь точкой выхода основной адрес сервера;
- трафик между клиентами и сервером должен шифроваться;
Приступаем к настройке. Первым делом запустим DNS-сервер. Для этого открываем файл "/etc/namedb/named.conf" и меняем строку:
	listen-on	{ 127.0.0.1; };
На:
	listen-on	{ any; };
Чтобы сервер слушал на всех доступных адресах и интерфейсах а не только на localhost, поскольку именно этот сервер в качестве DNS и будут использовать наши клиенты. Затем добавляем в файл /etc/rc.conf строку:
named_enable="YES"
И запускаем сервис:
/etc/rc.d/named start
Теперь нужно обновить дерево портов, чтобы быть уверенными что ставим всё самое свежее:
portsnap fetch extract
Сервер pptpd доступен в портах FreeBSD как net/poptop. Установим его:
cd /usr/ports/net/poptop && make install clean
Переходим к настройке. Клиентам мы будем выдавать адреса из сети 10.255.117.0/255.255.255.0. Для всех PPP-соединений на стороне сервера будет адрес 10.255.117.1.
Самая большая сложность при настройке возникла когда выяснилось что при использовании типовой конфигурации клиенты на Linux и Mac OS X не могли согласовать с сервером шифрование и потому хотя формально подключение и происходило - реально трафик не ходил. У клиентов под управлением Windows таких проблем не возникло.
Однако вдумчивое чтение документации и некоторые эксперименты с конфигурацией помогли решить эту проблему. Далее будет описано сразу готовое решение.
Создадим файл конфигурации pptpd "/usr/local/etc/pptpd.conf" следующего содержания:
noipparam logwtmp localip 10.255.117.1 remoteip 10.255.117.2-102 +chapms-v2 mppe-128 mppe-stateless nobsdcomp
Теперь нам нужно настроить подсистему ppp, надстройкой над которой и является pptpd. Здесь самым первым делом нужно привести файл "/etc/ppp/ppp.conf" к виду:
default:
 set log Phase Chat LCP IPCP CCP tun command
 disable ipv6cp
 ident user-ppp VERSION
 set device /dev/cuau1
 set speed 115200
 set dial "ABORT BUSY ABORT NO\\sCARRIER TIMEOUT 5 \
           \"\" AT OK-AT-OK ATE1Q0 OK \\dATDT\\T TIMEOUT 40 CONNECT"
 set timeout 180
 enable dns
papchap:
 set phone PHONE_NUM
 set authname USERNAME
 set authkey PASSWORD
 set ifaddr 10.0.0.1/0 10.0.0.2/0 255.255.255.0 0.0.0.0
 add default HISADDR
loop:
 set timeout 0
 set log phase chat connect lcp ipcp command
 set device localhost:pptp
 set dial
 set login
 # Здесь указываем:
 # 1. Адрес на стороне сервера для всех подключений
 # 2. Диапазон клиентских адресов
 # 3. Маску подсети
 set ifaddr 10.255.117.1 10.255.117.2-10.255.117.102 255.255.255.0
 add default HISADDR
 set server /tmp/loop "" 0177
loop-in:
 set timeout 0
 set log phase lcp ipcp command
 allow mode direct
pptp:
 load loop
 disable pap
 disable ipv6cp
 accept dns
 enable MSChapV2
 enable mppe
 disable deflate pred1
 deny deflate pred1
 add default HISADDR
 # Адрес DNS, выдаваемый клиентам.
 # Идеальный вариант - адрес сервера ("точка выхода")
 set dns 1.2.3.4
 set mppe 128 stateless
 set device !/etc/ppp/secure
Следующий шаг - создание скрипта "/etc/ppp/secure", управляющего ppp-соединенями:
#!/bin/sh exec /usr/sbin/ppp -direct loop-in
Создаём файл с логинами и паролями "/etc/ppp/ppp.secret":
# Логин и пароль. Адрес будет выдан динамически из пула сервера login1 pass1 # Логин и пароль со "ситатическим" адресом login2 pass2 10.255.117.200
Запускаем сервер:
echo pptpd_enable="YES" >> /etc/rc.conf && /usr/local/etc/rc.d/pptpd start
Настраиваем пакетный фильтр (файрволл). Опишем правила в файле /etc/pf.rules:
set limit { states 20000, frags 5000 }
set timeout { adaptive.start 6000, adaptive.end 12000 }
set skip on { lo0 }
# Базовые настройки
if_ext = "fxp0"
if_pptp = "tun"
table <pptp_users> { 10.255.117.0/24 }
set block-policy drop
set state-policy if-bound
scrub all reassemble tcp fragment reassemble
# NAT для клиентов PPTPD
nat on $if_ext inet from <pptp_users> -> ($if_ext:0)
pass quick on lo0 all
pass quick on tun all
# Разрешаем исходящий трафик
pass out quick on $if_ext inet proto tcp from ($if_ext) to any flags S/SA keep state
pass out quick on $if_ext inet proto { udp, icmp } from ($if_ext) to any keep state
pass out quick on $if_ext inet proto gre from ($if_ext) to any
# Разрешаем доступ к серверу по SSH
pass in quick on $if_ext inet proto tcp from any to ($if_ext) port 22 flags S/SA keep state
# Разрешаем подключение по PPTP
pass in quick on $if_ext inet proto tcp from any to ($if_ext) port 1723 flags S/SA keep state
pass in quick on $if_ext inet proto gre from any to ($if_ext) keep state
# Разрешаем ICMP
pass in quick on $if_ext inet proto icmp from any to ($if_ext)
# Разрешаем весь трафик наших клиентов
pass in quick inet from <pptp_users> to any
# Запрещаем весь остальной трафик
block drop all
Добавляем в файл "/etc/rc.conf" строки:
pf_enable="YES" pf_rules="/etc/pf.rules"
И запускаем пакетный фильтр:
/etc/rc.d/pf start
Казалось бы всё, но кое-что ещё не сделано. И это кое-что очень важное: мы не включили форвардинг (пересылку) пакетов. Без этого клиенты смогут подключаться к серверу, но их трафик дальше сервера не уйдёт.
Включаем форвардинг и сразу добавляем соответствующую строку в файл "/etc/sysctl.conf" чтобы он включался при загрузке:
sysctl net.inet.ip.forwarding=1 && echo net.inet.ip.forwarding=1 >> /etc/sysctl.conf
Вот теперь действительно всё. Сервером можно пользоваться.
Настройка клиентов
Настройка PPTP-соедения на Windows вещь элементарная и описывать её не стоит. Нужно только отметить что в качестве сервера для подключения нужно указывать авторой IP-адрес (алиас) сервера, а точкой выхода будет первый (основной) адрес. Шифрование в Windows включено и используется по умолчанию.
В Linux (при использовании Network Manager) шифрование по умолчанию выключено и потому его нужно включать самому. Для этого в свойствах соединения нужно нажать кнопку "Advanced" и включить "MPPE" и "stateful encryption":

После этого соединение проходит успешно и между клиентом и сервером ходит шифрованный трафик.
Генерация логинов и паролей
Ещё один интересный момент это быстрая генерация большого количества логинов и паролей для последующей раздачи клиентам. Автор этих строк для быстрой генерации сотни пар "логин-пароль" написал небольшой скрипт на bash:
#!/usr/local/bin/bash
# Уровень "случайности" пароля.
RND_LEVEL=8
# Длина пароля
PASS_LEN=8
for i in {1..100}; do
    echo user$i `head -c $RND_LEVEL /dev/urandom | md5 | cut -c 1-$PASS_LEN`
done
После запуска скрипт напечатает сотню пар "логин-пароль" на стандартный вывод. Вывод скрипт можно сразу перенаправить в файл /etc/ppp/ppp.secret.
На этом всё. Приятной работы!

morbo 2010-11-15 07:34:38 (#)
Кстати, сегодня появилась новость, что патчи для accel-pptp, работающего полностью в режиме ядра, войдут в официальное ядро Linux. После этого производительность pptpd в Linux и mpd в FreeBSD должны сравняться.