MPD 5.7 настройка VPN-сервера в FreeBSD

Настраиваем MPD5 в качестве VPN-сервера для подключений Windows-клиентов к офисной сети по протоколу PPTP.

MPD5 также может использоваться в качестве VPN-клиента для доступа к удаленной сети, или подключения к интернет провайдеру.

Для объединения нескольких сетей через интернет обратите внимание на OpenVPN. Ключевые отличия OpenVPN: туннель по UDP или TCP протоколу, TLS-шифрование, возможность задать клиенту маршруты к обслуживаемым сетям.

Содержание

Установка MPD5

Устанавливаем пакет:

pkg install mpd5

Для установки из коллекции портов, обновляем коллекцию:

portsnap fetch && portsnap update || portsnap extract

Затем, устанавливаем порт:

cd /usr/ports/net/mpd5
make install clean

Настройка MPD5

Переходим в папку с файлами конфигурации:

cd /usr/local/etc/mpd5

В папке имеются следующие файлы:

  • mpd.conf.sample - шаблон файла конфигурации,
  • mpd.script.sample - скрипты для модемов,
  • mpd.secret.sample - пример списка пользователей и паролей.

Копируем файл конфигурации из шаблона:

cp mpd.conf.sample mpd.conf

Открываем в редакторе:

ee mpd.conf

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

Удаляем все секции кроме startup, default и pptp_server. Для удаления строк в ee используем Ctrl+K. Также конфиг можно создать копипастом приведенного ниже листинга.

Задаем параметры. Строки, требующие корректировки, выделены жирным шрифтом:

#Секция startup загружается при запуске MPD5
startup:
   #Протоколировать IP-адреса, с которых выполняются подключения
   log +PHYS2
   #Параметры http и telnet доступа для мониторинга и оперативного управления.
   #Задать логин, пароль и роль администратора
   set user пользователь пароль admin
   #Задать пользователя, доступны роли operator и user, по умолчанию подразумевается user
   #set user foo1 bar1
   #Открыть локальный telnet доступ, порт 5005
   set console self 127.0.0.1 5005
   set console open
   #Открыть веб-админку на всех интерфейсах, порт 5006
   set web self 0.0.0.0 5006
   set web open

#Если в команде запуска MPD не задана конфигурация, обрабатывается секция default.
default:
    #Загрузить секцию pptp_server
    load pptp_server

pptp_server:
    #Пул динамических IP-адресов, начальный и конечный адрес
    set ippool add pool1 192.168.1.50 192.168.1.99

    #Создать динамический пучок (bundle) с именем B.
    #Сетевые интерфейсы будут создаваться динамически при подключении клиента
    create bundle template B

    #Если IP-адрес клиента принадлежит локальной подсети, присвоить ему MAC-адрес
    set iface enable proxy-arp

    #Отключать клиента при отсутствии трафика в течение заданного количества секунд
    #set iface idle 1800

    #Корректировать размер пакета TCP-соединений через туннель,
    #в случае если он превышает заданный MTU (TCP Maximum Segment Size Fix)
    set iface enable tcpmssfix

    #Разрешить сжатие заголовков TCP
    set ipcp yes vjcomp

    #IP-адрес для сервера и клиентов
    #Адрес сервера: 192.168.1.1
    #Для клиентов используем пул: "pool1", объявленный ранее
    set ipcp ranges 192.168.1.1/32 ippool pool1

    #Задать DNS-серверы для клиентов
    set ipcp dns 192.168.1.3 192.168.2.3
    #Задать WINS-серверы для клиентов
    #set ipcp nbns 192.168.1.4

    #Использовать шифрование Microsoft
    #Протокол сжатия Microsoft в базовой поставке не поддерживается, требуется пересборка ядра со сторонним модулем.
    set bundle enable compression
    set ccp yes mppc
    #Разрешить 40-битное и 128-битное шифрование Microsoft
    #set mppc yes e40
    set mppc yes e128
    #Разрешить безстатусный (stateless) режим шифрования.
    #Повышает устойчивость к потерям, ценой повышенной загрузки на процессор.
    set mppc yes stateless

    #Создать динамическую PPTP линию
    create link template L pptp

    #Связать с пучком B
    set link action bundle B

    #Использовать фрагментацию, если размер пакета превышает MTU
    set link enable multilink

    #Разрешить сжатие некоторых полей в заголовке, экономит от 1 до 3 байт на пакет
    set link yes acfcomp protocomp

    #Использовать CHAP авторизацию, протоколы: Microsoft CHAP v2, Microsoft CHAP, CHAP MD5.
    set link no pap chap eap
    set link enable chap

    #Отправлять LCP эхо запрос каждые 10 секунд, если ответа не последует в течение 60 секунд, считать соединение разорванным.
    #Не работает вплоть до версии 5.5, LCP-пинг отправляется раз в минуту
    #set link keep-alive 10 60

    #Максимальный размер пакета
    #Стандарт для VPN - 1400
    #Если VPN-соединение разрывается при передаче большого объема данных, следует уменьшить значение параметров, а также убедиться что работает Multilink
    set link mtu 1402
    set link mru 1400

    #Принимать PPTP подключения на всех интерфейсах
    set pptp self 0.0.0.0
    set link enable incoming

Задаем список пользователей нашего VPN-сервера в файле mpd.secret:

ee mpd.secret

Задаем имена пользователей, пароли, при необходимости, присваиваем фиксированные IP-адреса. Имя пользователя и пароль чувствительны к регистру.

#login    password    ip
user1     pass1      192.168.0.193
user2     pass2  

Ограничиваем доступ к файлу:

chmod 600 mpd.secret

Включение маршрутизации

Проверяем, включена ли маршрутизация, командой:

sysctl net.inet.ip.forwarding

Если в результате видим: "net.inet.ip.forwarding: 1", значит маршрутизация включена, переходим к следующему разделу.

Если видим: "net.inet.ip.forwarding: 0", значит в /etc/rc.conf необходимо добавить параметр: gateway_enable="YES":

printf '\ngateway_enable=\"YES\"\n' >>/etc/rc.conf

Перезагружаем систему:

reboot

Проверяем, включена ли маршрутизация:

sysctl net.inet.ip.forwarding

В результате получаем:

net.inet.ip.forwarding: 1

Настройка брандмауэра

Для приема PPTP-подключений необходимо открыть входящие TCP-соединения на порт 1723 и разрешить GRE-трафик.
Для IPFW правила будут примерно следующие:

allow tcp from any to me dst-port 1723 setup keep-state
allow gre from any to me
allow gre from me to any

Подключенным клиентам также необходимо открыть доступ к локальной сети. В простейшем варианте, для пула 192.168.1.50 - 192.168.1.99, открываем полный доступ для всех локальных подключений, независимо от интерфейсов:

allow all from 192.168.1.0/24 to 192.168.1.0/24

Настройка логов MPD5

Для записи логов MPD5 использует syslog. Идентификатор источника сообщений задается ключом командной строки "--syslog-ident", значение по умолчанию - "mpd".

Редактируем syslog.conf:

ee /etc/syslog.conf

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

!mpd
*.*                                             /var/log/mpd.log
!*

Таким образом, все сообщения от источника "mpd" будут направлены в mpd.log.

Задаем параметры ротации логов:

ee /etc/newsyslog.conf

Ежедневная ротация в полночь с сохранением 7-ми логов в сжатом формате:

/var/log/mpd.log                        600  7     *    @T00  JC

Альтернативный вариант, с ежемесячной ротацией и хранением логов за последние три месяца:

/var/log/mpd.log                        600  3    *    $M1D0 JC

Подробнее о файле конфигурации читаем в справке: man newsyslog.conf.

Создаем лог-файл:

touch /var/log/mpd.log

Перезагружаем конфигурацию syslog:

service syslogd reload

Запуск MPD5

Разрешаем запуск MPD, добавляем в /etc/rc.conf параметр: mpd_enable="YES":

printf '\nmpd_enable=\"YES\"\n' >>/etc/rc.conf

Запускаем службу:

service mpd5 start

Проверяем, запущена ли служба и параметры запуска:

ps -ax | grep mpd5

В результате получаем:

1274  -  Ss    0:00.00 /usr/local/sbin/mpd5 -p /var/run/mpd5.pid -b

Проверяем, слушается ли порт:

netstat -an | grep 1723

Результат должен быть следующим:

tcp4       0      0 *.1723                 *.*                    LISTEN

Проверяем сообщения в лог-файле:

cat /var/log/mpd.log

В случае успешного старта видим следующий текст:

Multi-link PPP daemon for FreeBSD                                               
                                                                                
process 1274 started, version 5.7 (root@10i386-default-job-10 21:06 12-Jun-2014)
CONSOLE: listening on 127.0.0.1 5005                                            
web: listening on 0.0.0.0 5006                                                  
PPTP: waiting for connection on 0.0.0.0 1723                                   

Заходим браузером в веб-админку: http:/адрес.сервера:5006, проверяем параметры соединений.

Создаем подключение в Windows, либо настраиваем на удаленной стороне MPD-клиент и пробуем подключиться. При настройке клиентского подключения в Windows, чтобы предотвратить туннелирование всего интернет трафика в удаленную сеть, в дополнительных настройках протокола TCP/IP, необходимо отключить флажок "Использовать основной шлюз в удаленной сети". В этом случае будет туннелироваться только трафик удаленной подсети в соответствии с ее классом.

В случае проблем используем tcpdump.

Мониторим физический канал:

tcpdump -v -ni интерфейс tcp port 1723 or proto gre

Мониторим туннель:

tcpdump -ni ng0

Возможные проблемы

Ошибка: "Can't create socket node: No such file or directory. Netgraph initialization failed", может возникнуть после установки новой версии системы. Проблема возникает из-за линковки программы со старыми системными библиотеками. В этом случае необходимо переустановить или пересобрать MPD.

Анализ логов MPD5

Чтобы быть в курсе как используется наш VPN-сервер, организуем ежедневную отправку на почту отчета по сессиям. Для получения административных почтовых уведомлений по протоколу POP3 потребуется установить Dovecot или Qpopper.

Готового решения на все случаи жизни мне найти не удалось. Рассмотрим примеры скриптов, которые можно взять за основу для построения своего анализатора.

Простейший отчет по сессиям

Сканируем лог за прошедший день командой grep, выбираем сообщения о подключении, отключении клиентов и имена пользователей. Ротация логов должна быть ежедневной.

Результат работы выдает следующий:

Jun 14 18:10:20 bsd-10 mpd: pptp0: attached to connection with 92.68.55.2 2539
Jun 14 18:10:23 bsd-10 mpd: [L-1]   MESG: MSRASV5.20
Jun 14 18:10:23 bsd-10 mpd: [L-1]   MESG: MSRAS-0-DESKTOP
Jun 14 18:10:23 bsd-10 mpd: [L-1]   Name: "user1"
Jun 14 18:15:19 bsd-10 mpd: pptp0-0: call cleared by peer
Jun 14 18:15:19 bsd-10 mpd: pptp0-0: killing channel

Добавим в /usr/local/etc/periodic/daily скрипт с именем 800.mpd:

ee /usr/local/etc/periodic/daily/800.mpd

Со следующим содержимым:

#!/bin/sh
echo
echo PPTP connections
bzgrep -E '(mpd: pptp)|(MESG:)|(Name)' /var/log/mpd.log.0.bz2

Задаем права доступа:

chmod 755 /usr/local/etc/periodic/daily/800.mpd

Mpdstat

Единственный готовый скрипт, который мне удалось накопать на просторах интернета.

Сайт проекта: http://code.google.com/p/mpdstat/.

Perl-скрипт интегрируется в periodic, выдает следующий результат:

user1
        duration: 0d 00:04:56   link: [L-1]
        from: Jun 14 18:10:23   to: Jun 14 18:15:19

Active Session Report

User Report
       user1: total: 0d 03:53:41           5times

Устанавливаем Perl:

pkg install perl5

Создаем папку для загрузки в пользовательском профиле:

mkdir -p ~/src

Загружаем Mpdstat:

svnlite checkout http://mpdstat.googlecode.com/svn/trunk/ ~/src/mpdstat

Переходим в папку с программой:

cd ~/src/mpdstat

Выполняем установку:

make install

В случае ошибки установки, переименовываем файл  900.mpdstatus в 900.mpdstat и запускаем установку повторно:

mv 900.mpdstatus 900.mpdstat
make install

Открываем /etc/periodic.conf, если файл отсутствует в вашей системе, создаем его:

ee /etc/periodic.conf

Разрешаем исполнения скрипта и задаем путь к лог файлам:

daily_status_security_mpdstatus_enable="YES"
daily_status_security_logdir="/var/log"

Выполняем тестовый запуск:

periodic security

Скрипт ищет лог за прошедший день, если он не найден, обрабатывает mpd.log.

Парсер на PHP

Я использую свой парсер на PHP, генерирующий следующий вывод:

L1> Jun 14 18:10:20      92.68.55.2 00:04:59 user1           static.kpn.net MSRASV5.20
L1> Jun 14 18:15:51      92.68.55.2 00:04:01 user1           static.kpn.net MSRASV5.20
L1> Jun 14 18:20:12      92.68.55.2 01:47:45 user1           static.kpn.net MSRASV5.20
L1> Jun 14 21:53:35      92.68.55.2 01:56:10 user1           static.kpn.net MSRASV5.20
L1> Jun 14 23:50:37      92.68.55.2 00:00:55 user1           static.kpn.net MSRASV5.20

Скрипт отображает IP-адреса, с которых устанавливаются соединения, и выполняет реверсные DNS-запросы. Параметр "log +PHYS2" должен быть включен в mpd.conf.

Устанавливаем PHP:

pkg install php5 php5-bz2

Создаем папку программы в профиле пользователя и переходим в нее:

mkdir /root/Programs
cd /root/Programs

Загружаем архив:

fetch http://itadept.ru//files/freebsd-mpd5-server/MpdLogParser-0.1.tar.bz2

Распаковываем:

tar -xf MpdLogParser-0.1.tar.bz2

Переходим в папку с программой:

cd MpdLogParser

Создаем файл конфигурации:

cp MpdLogParser_Config.php.sample MpdLogParser_Config.php

Редактируем конфиг:

ee MpdLogParser_Config.php

Задаем параметры:

/* Часовой пояс из списка: http://php.net/manual/ru/timezones.php */

date_default_timezone_set("Europe/Moscow");

/* Путь к лог-файлу */
define('LOG_PATH',"/var/log/mpd.log.0.bz2");

/* IP-адреса, исключаемые из списка */
$IgnoreIP=array(
//    "1.2.3.4",
//    "5.6.7.8",
);

Выполняем пробный запуск, лог-файл, заданный в конфиге (mpd.log.0.bz2) должен существовать, автопоиск не предусмотрен:

./MpdLogParser.php

Добавим в /usr/local/etc/periodic/daily скрипт с именем 800.mpd:

ee /usr/local/etc/periodic/daily/800.mpd

Со следующим содержимым:

#!/bin/sh
echo
echo PPTP connections
/usr/local/bin/php /root/Programs/MpdLogParser/MpdLogParser.php

Задаем права доступа:

chmod 755 /usr/local/etc/periodic/daily/800.mpd

Выполняем тестовый запуск:

periodic daily

Вывод команды будет отправлен на почту пользователя root.

Настройка завершена.

Ссылки

Сайт проекта: http://mpd.sourceforge.net
Документация к 5 версии: http://mpd.sourceforge.net/doc5/mpd.html
Установка с модулем сжатия: http://www.lissyara.su/articles/freebsd/security/vpn_mpd5/

Комментарии:

RSS
  • Алексей
    20.09.2014 17:06
    Добрый день! Перешёл на FreeBSD 9.3 и у меня с mpd такая проблема случилась:

    uname:
    9.3-RELEASE-p2 FreeBSD 9.3-RELEASE-p2 #0: Mon Sep 15 16:44:27 UTC 2014 root@amd64-builder.daemonology.net:/usr/obj/usr/src/sys/GENERIC amd64 GENERIC


    messages:
    Sep 20 20:49:06 router kernel: pf: state key linking mismatch! dir=OUT, if=sis0, stored af=2, a0: 80.253.237.5, a1
    : 80.100.154.56, proto=47, found af=2, a0: 93.88.162.194:443, a1: 172.16.2.5:52134, proto=6.
    Sep 20 20:49:06 router kernel: pf: state key linking mismatch! dir=OUT, if=sis0, stored af=2, a0: 80.253.237.5, a1
    : 80.100.154.56, proto=47, found af=2, a0: 93.88.162.194:443, a1: 172.16.2.5:52134, proto=6.
    Sep 20 20:49:06 router kernel: pf: state key linking mismatch! dir=OUT, if=sis0, stored af=2, a0: 80.253.237.5, a1
    : 80.100.154.56, proto=47, found af=2, a0: 93.88.162.194:443, a1: 172.16.2.5:52134, proto=6.
    Sep 20 20:49:06 router kernel: pf: state key linking mismatch! dir=OUT, if=sis0, stored af=2, a0: 80.253.237.5, a1
    : 80.100.154.56, proto=47, found af=2, a0: 93.88.162.194:443, a1: 172.16.2.5:52134, proto=6.

    Если я подключаюсь из дома к офису, то в лог валятся такие сообщения. Да и вообще всё тормозить начинает.

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

    pkg info mpd5
    mpd5-5.7_1
    Name : mpd5
    Version : 5.7_1

    mpd.conf:

    pptp_server:
    set ippool add poolsat 172.16.2.5 172.16.2.20
    create bundle template B
    set iface enable proxy-arp
    set iface idle 0
    set iface enable tcpmssfix
    set ipcp yes vjcomp
    set ipcp ranges 172.16.2.1/32 ippool poolsat
    set ipcp dns 77.88.8.88
    set bundle enable compression
    set ccp yes mppc
    set mppc yes e128
    set mppc yes stateless
    create link template L pptp
    set link enable multilink
    set link yes acfcomp protocomp
    set link action bundle B
    set link no pap chap
    set link enable chap
    set link enable chap-msv1
    set link enable chap-msv2
    set link mtu 1460
    set pptp self 0.0.0.0
    set link enable incoming

    pf.conf:

    table const {10/8, 172.16/12, 192.168/16}
    table {1.1.1.1}
    table persist
    table persist file "/etc/pf.badhost"
    set block-policy drop
    set skip on lo
    scrub in all
    nat on $ext_if from $local_net to !$local_net -> $ext_if:0
    nat on $ext_if from $vpn_net to !$local_net -> $ext_if:0
    antispoof quick for $ext_if
    block inet6
    block in quick on {$ext_if} from to any label "Ssh bruteforce"
    block quick from label "Block badhost"
    block in on {$ext_if}
    block out on {$ext_if} from to any label "Block out private addr"
    pass in on {$ext_if} from label "Trust hosts"
    pass in on {$ext_if} proto tcp to port ssh
    pass in on {$ext_if} inet proto icmp from any to any icmp-type $icmp_types label "Allow ICMP"
    pass out on {$ext_if}


    Поделитесь мыслями по этому поводу. В интернете не нашёл ответов. За ранее спасибо!
    • IT Adept
      21.09.2014 16:35

      Проблема в PF.

      Лечится комментированием строки вывода ошибки и пересборкой ядра:

      /usr/src/sys/contrib/pf/net/pf.c:
                      /* mismatch. must not happen. */
                      printf("pf: state key linking mismatch! dir=%s, "
                          "if=%s, stored af=%u, a0: ",
                          dir == PF_OUT ? "OUT" : "IN", kif->pfik_name, a->af);
      

      Подробности: FreeBSD Bugzilla - Bug 163208 - [pf] PF state key linking mismatch

      Сам не проверял, поскольку использую IPFW. Напишите работает ли решение.

      • Алексей
        25.09.2014 08:19
        Такое решение встречал и ранее, по мне это просто закрывание глаз на проблему :). Хотелось бы знать какое конкретно правило вызывает такую реакцию и что с ним не так. Ну да ладно.
        Решение проверил. В результате сообщения в messages не сыпятся, система не тормозит. Получается что тормоза были из-за интенсивной записи в лог?

        В общем решение рабочее. Спасибо!
  • do0b
    14.08.2014 23:19
    Есть вопрос: 192.168.1.1 - реальный ip-адрес сервера в сети, к которой подключаемся удаленно или вымышленный?

    Если адрес вымышленный (например, 192.168.1.1), а локальная сеть 10.10.10.0/24, то недостаточно иметь в rc.conf опцию gateway_enable="YES" и нужно натить трафик с помощью natd, к примеру?
    • IT Adept
      15.08.2014 00:38
      Подразумевается VPN-доступ к сети 192.168.1.0/24.

      Если в вашем случае сеть 10.10.10.0/24, значит для клиентов задаем адреса из пула 10.10.10.0/24.

      IP-адрес сервера, заданный в mpd.conf, выдается клиенту в качестве адреса удаленного сервера внутри PPP-туннеля. Он может совпадать с реальным адресом сервера, или быть абсолютно любым. При наличии доступа к локальной сети для Windows-клиентов он не играет никакой роли, для клиентов на FreeBSD выступает в качестве шлюза в таблице маршрутизации клиента.

      Если вы хотите выделить VPN-клиентов в отдельную сеть, потребуется настройка маршрутизации к этой сети.

      NAT имеет смысл поднимать только если необходим доступ в интернет.
      • do0b
        20.08.2014 22:19
        Настройку маршрутизации к выделенной под VPN сети нужно выполнять на Каждом хосте, к которому/c которого хотим иметь доступ? А если таких хостов ни один, ни два?..

        Не удобнее ли в этом случае заворачивать исходящий от VPN-клиентов трафик на внутренний интерфейс VPN-сервера?

        зы доступ в Интернет удаленным VPN-клиентам не нужен, нужен только доступ к ресурсам внутренней сети.
        • IT Adept
          20.08.2014 22:44
          Настройка маршрутизации к выделенной VPN-сети выполняется на маршрутизаторе. Хосты штатно отправляют нелокальные пакеты на шлюз, далее маршрутизатор уже знает куда их пересылать. Дополнительная настройка клиентов не требуется.

          Проще всего завернуть на внутренний интерфейс. Выделенная сеть не требуется, без особой на то необходимости.
  • Спасибыч
    01.11.2013 17:12
    Сделал на FreeBSD 9.2. Всё отличное работает. Спасибо.
  • Antonio
    27.05.2012 18:18
    Хорошая статья, спасибо

Добавить комментарий для Antonio Отменить ответ


Вы не бот: