Недавно мне пришлось столкнуться с такой задачей: имеется локальная сеть с адресами 10.x.x.0/24 (рис. 1). Для работы с вышестоящим сервером корпоративной сети машины должны иметь адреса из этого диапазона, и пакеты в этом случае уходят непосредственно на Ethernet-порт коммутатора (точнее, заворачиваются туда правилами ipfw, работающего на сервере FreeBSD). Доступ в Интернет осуществляется с помощью трансляции адресов (NAT).
Однако для работы с некоторыми внешними серверами мне нужно было иметь реальный адрес, причем работа через NAT или proxy-сервер не поддерживалась. Ставить себе вторую сетевую карту и тащить отдельный сегмент до сервера, в который тоже пришлось бы устанавливать еще один (уже третий) сетевой адаптер, очень не хотелось. Вариант с назначением себе в каждый момент времени нужного адреса тоже не радовал (хоть Windows XP и не требует перезагрузки после изменения сетевых адресов, но все равно процедура не из приятных). Тогда было принято решение "пробросить" до сервера так называемую виртуальную частную сеть (VPN), о чем и пойдет речь в данной статье.
Прежде всего, нужно было поднять на FreeBSD VPN-сервер. Почитав немного про такие средства как poptop и mpd, свой выбор я остановил на последнем как более "родном" для FreeBSD. Mpd использует интерфейс netgraph, благодаря чему большинство операций выполняется на уровне ядра системы, тем самым повышая скорость работы. Как правило, специально включать поддержку netgraph в ядро не требуется - она подгружается и отлично работает в виде модулей, в чем можно убедиться с помощью команды kldstat (после того, как mpd будет установлен и запущен):
$ kldstat Id Refs Address Size Name 1 14 0xc0400000 370850 kernel 2 1 0xc16f3000 4000 if_vlan.ko 3 1 0xc1741000 2000 snake_saver.ko 4 1 0xc17d4000 4000 ng_socket.ko 5 8 0xc17d8000 12000 netgraph.ko 6 1 0xc17ef000 4000 ng_iface.ko 7 1 0xc17f3000 8000 ng_ppp.ko 8 1 0xc17fb000 4000 ng_bpf.ko 9 1 0xc17ff000 5000 ng_vjc.ko 10 1 0xc1d43000 5000 ng_pptpgre.ko 11 1 0xc1d48000 5000 ng_ksocket.ko 12 1 0xc1d4d000 4000 ng_mppc.ko 13 1 0xc1d51000 2000 rc4.ko
Однако при желании ядро можно и пересобрать, включив все опции, начинающиеся с "NETGRAPH_". В ряде случаев, особенно для старых версий FreeBSD (например, 3.х), это может дать дополнительный прирост быстродействия.
Для установки mpd проследуем в коллекцию портов и выполним там ряд нехитрых действий:
# cd /usr/ports/net/mpd # make # make install
Поскольку мы ничего не меняли, то исполнимые файлы будут помещены в /usr/local/sbin, а файлы конфигурации можно будет найти в /usr/local/etc/mpd - стандартная для FreeBSD раскладка. Сценарий автозапуска будет находиться в /usr/local/etc/rc.d. Сразу после инсталляции файлы конфигурации и сценарий будут иметь расширение ".sample", следовательно, их нужно переименовать, убедившись, что никакие исправления (например, другие пути) в них вносить не нужно.
Единственное, что от нас теперь требуется - отредактировать конфигурационные файлы для нашей задачи и запустить серверный процесс mpd. Файл mpd.conf примет примерно следующий вид:
#------------------- mpd.conf --- default: # Указываем, какую конфигурацию грузить #- (в принципе, все параметры можно задать #- и непосредственно в секции default): load pptp0 pptp0: # Объявляем новый интерфейс ng0: new -i ng0 pptp0 pptp0 # Поскольку мы никуда не звоним, то устанавливать #- соединение по требованию не нужно: set iface disable on-demand # Разрешаем прохождение arp-запросов: set iface enable proxy-arp # Запрещаем разрывать связь при простое: set iface idle 0 # Ограничение на размер исходящих пакетов #- значением MTU: set iface enable tcpmssfix # Указываем, что наше соединение - не мультилинк: set bundle disable multilink # Требуем шифрование: set bundle yes crypt-reqd # Включаем компрессию: set bundle enable compression set link yes acfcomp protocomp # Разрешаем только chap-авторизацию: set link no pap chap set link enable chap # Интервалы проверки линка на "жизнеспособность": set link keep-alive 10 60 # Размер "окна отсылки": set link mtu 1460 # Разрешаем компрессию TCP-заголовка: set ipcp yes vjcomp # Следующий параметр задает диапазоны IP-адресов #- на стороне сервера и на стороне клиентов в виде #- set ipcp ranges local[/width] remote[/width] #- В нашем случае серверу и клиенту назначается #- по одному адресу: set ipcp ranges 197.y.y.73 197.y.y.75 # Следующие четыре опции cpp определяют #- протоколы управления сжатием #- (compression control protocol) - #- для работы с Windows-клиентами: # Включаем поддержку сжатия MPPC #- (Microsoft Point-to-Point Compression): set ccp yes mppc # Поддержка 40-битного кодирования: set ccp yes mpp-e40 # Поддержка 128-битного кодирования: set ccp yes mpp-e128 # Stateless-режим, уменьшает время восстановления #- при сбросе (drop) пакета: set ccp yes mpp-stateless # Адрес, на котором VPN-сервер ждет соединения: set pptp self 10.х.х.254 # Разрешаем входящие соединения: set pptp enable incoming # Инициировать соединение со стороны mpd не нужно: set pptp disable originate
С остальными параметрами можно ознакомиться в достаточно подробной html-документации (см. /usr/ports/net/mpd/work/mpd-3.18/doc). В частности, может потребоваться прописать DNS-сервер, назначаемый устанавливаемому соединению.
В принципе, все можно оставить в таком же виде, изменив только IP-адреса на нужные. В качестве собственного адреса (pptp self) должен быть задан адрес интерфейса, на котором сервер будет ожидать входящие соединения (в моем случае это "внутренний" интерфейс FreeBSD, смотрящий в локальную сеть). В качестве адреса сервера для соединения VPN задан адрес "внешнего" интерфейса, маршрутизируемого в Интернет.
Поскольку со стороны VPN-сервера никуда дозваниваться не требуется, то настройки в mpd.script для нас несущественны. Остальные два конфигурационных файла будут выглядеть примерно так:
#--------------------- mpd.links --- pptp0: set link type pptp #------------------- mpd.secret --- username "userpassword" *
То есть в mpd.links просто описывается тип связи (pptp - point to point tunneling protocol). Строго говоря, не имеет особого значения, где именно описывать параметры линка - в mpd.links или непосредственно в mpd.conf (в нашем примере большинство команд set link размещены именно там). Это - вопрос удобства при работе с большим количеством разнообразных соединений. В mpd.secret перечисляем пользователей с паролями, которым нужно будет устанавливать VPN-соединения (в данном случае такой пользователь только один). Не забывайте исключить возможность чтения данного файла кем-то еще, кроме суперпользователя root. Теперь запускаем сервер:
# /usr/local/etc/rc.d/mpd.sh start
Чтобы убедиться, что сервер запустился и прослушивает порт 1723 (pptp) в ожидании подключений, выполните следующую команду:
$ netstat -a | grep pptp tcp4 0 0 10.x.x.254.pptp *.* LISTEN
Со стороны Windows никаких особых телодвижений не требуется - просто создаем соединение VPN, следуя указаниям мастера подключения. В качестве адреса назначения указывается "собственный" адрес VPN-сервера, то есть в нашем случае - 10.x.x.254. Теперь, когда нужно поработать с реальным адресом, просто устанавливается VPN-соединение, по окончании сеанса - закрывается.
В заключение хочется отметить еще одно полезное свойство VPN-соединения - экономию адресного пространства. Если поставленную задачу решать "классическим" способом - с помощью дополнительных сетевых карт, то понадобится выделить как минимум 4 IP-адреса - на сторону сервера, клиенту, и 2 адреса пропадут "впустую" - как адрес подсети и широковещательный адрес. В случае же VPN мы занимаем только 1 действительно нужный нам адрес - адрес клиента. На сервере мы привязываемся к существующему адресу внешнего интерфейса, а "служебные" адреса в данном случае вообще не требуются.
Источники дополнительной информации традиционны:
http://sourceforge.net/projects/mpd, http://www.dellroad.org/mpd/index, man mpd(8), man netgraph(4), man ng_ppp(4).
© Amsand, 2005 (вер. от 16.02.2006) mailto: amsand@yandex.ru |