Вы здесь

Настройка VPN (использование pptpclient)

Многие провайдеры, т.н. ISP предлагают доступ в Интернет с использованием т.н. VPN. Это удобно для WINDOW$ машин-клиентов т.к. настройка VPN соединения производится в этих ОС как обычно, кликнуть мышкой тут, кликнуть там, не забыть выбрать галочку на одной вкладочке, войти в контекстное меню по правой кнопки мыши в следующем окошке итд. итп...

Что же нам предоставляет для этого Gentoo Linux? Исследование показало, что нам потребуется пакет net-dialup/pptpclient и его ближайщие зависимости, например, net-dialup/ppp. Пакет pptpclient предоставляет "консольный" интерфейс для управления VPN сессиями (настройка, подключение, отключение). В качестве графической оболочки могу назвать пакет net-dialup/pptpconfig, но в данный момент он "нестабильный" т.е. замаскаирван как ~x86. Мало того, я считаю, что GUI для такой простой задачи как запуск демона pppd совсвем не нужен, графические библиотеки могут и не быть установлены, например, на сервере. Я решил, что для "выхода в Интернет" лучше справится скрипт подобный тем, что распаложенны в каталоге "/etc/init.d". Таким образом, можно "включать" и "выключать" канал в Интернет стандартными средсвами не прибегая к несколько неудобному интерфейсу пакета pptpclient или даже включить запуск скрипта в процесс загрузки посредсвом утилиты rc-update. Ниже я приведу скрипт "/etc/init.d/pptp", который и реализует сервис VPN клиента на моих машинах и скромный конфигурационный файл с выбором провайдера "/etc/conf.d/pptp", если провайдеров несколько. Отмечу, что для работы VPN тунелей так же требуется поддержка протокола GRE и PPP в ядре .

В готвых сборках Gentoo в рамках проекта "Gentooth Live Linux" есть все заготовки скриптов, достаточно только "вписать" ваш login, пароль адреса сервера и быть может подредактировать ряд опций в конфигурационных файлах и скриптах.

Теперь немного о работе пакета pptpclient т.к. мой вариант стартового скрипта является лишь надстройкой над конфигурационными файлами получаемыми посредсвом утилиты pptp-command, входящей в пакет pptpclient. И так, с помощью утилиты pptp-command можно настроить набор конфигурационных файлов, что можно также сделать и "вручную" с использованием текстового редактора. Perl-скрипт pptp-command позволает настоить тунел, установить соединение, прервать соединение. Приведу свои соображение, что происходит, когда вы устанавливаете соединение с провайдером с помощью pptp-cmmand (опция меню - "start"). pptp-command главным образом от пользовате root запускает демон pppd, как говорят UNIX'оиды, "поднимающий" сетевой интерфейс ppp (Point-to-Point-Protocol). Опции для запуска демона pppd извлекаются из конфигурационного файла описывающего вашего провайдера из каталога /etc/ppp/peers/. По умолчанию используется файл "/etc/ppp/peers/__default", который является символической ссылкой на текстовый файл в этом же каталоге. Рассмотрим пример такого файла описывающего моего провайдера под условным номером 0:

cat /etc/ppp/peers/vpn.0

#
# PPTP Tunnel configuration for tunnel azorg
# Server IP: 192.168.7.254
# Route: add default TUNNEL_DEV
#

#
# Tags for CHAP secret selection
#

name azorg
remotename bastion

#
# Include the main PPTP configuration file
#
file /etc/ppp/options.pptp

Из файла видно, что используется имя (мой логин) 'azorg', имя ответной части 'bastion', позже узнаем где это используется. Остальные многочисленные опции для pppd извлекаются из файла "/etc/ppp/options.pptp". Таким образом, можно использовать одни и теже опции при использовании нескольких провайдеров. Прочитать про опции pppd можно выполнив `man pppd`.
Приведу пример опций, которые я использую при соединении со своим провайдером.

cat /etc/ppp/options.pptp

# Указать программу для общения с сервером.
# Здесь можно указать IP-адрес PPTP сервера.
# Так же можно указать это при вызове pppd.
# Надо отметить, что при "штатном" использовании программы pptp-command
# из пакета pptpclient указания данной опции НЕ требуется!
# Адрес сервера извлекается из комментариев в соответсвующих
# файлах /etc/ppp/peers/*
#pty "/usr/sbin/pptp 192.168.7.254 --nolaunchpppd"

# name in chap-secrets
# имя клиента в файле /etc/chap-secrets
# НЕ указывать! Оно указано в соответвующем
# файле /etc/ppp/peers/*
#name azorg

# turn pppd syslog debugging on
# Включить подробный отчет о соединении в логах
#debug #!!! раскоменируйте для поробных логов в случае проблемм

# Lock the port
# Попросить pppd блокировать последовательное устройство, используемое
# для соединения, для эксклюзивного использования
lock

# We don't need the tunnel server to authenticate itself
# Не требовать аутентификации от сервера, это сервер аутентифицирует нас
noauth

# Turn off transmission protocols we know won't be used

# Запретить использование BSD-компрессии
nobsdcomp

# Устанавливаем метод сжатия пакетов в 0.
nodeflate

# При разрыве соединения не завершать работу, а продолжать
# попытки соединения.
persist

# Прекратить попытки автосоединения после 5000 неудач.
#maxfail 5000

# Подождать 10 секунд после разрыва соединения перед
# повторным соединением
holdoff 10

# Если это не указать, параметр holdoff игнорируется
connect /bin/true

#
# Time this thing out of it goes poof
#
# Каждые 15 секунд посылать запросы серверу для проверки соединения
#lcp-echo-interval 15

# После 10 неудачных запросов разорвать соединение
#lcp-echo-failure 10

# We want MPPE
#mppe-40
#mppe-128
#mppe-stateless

# We want a sane mtu/mru
mtu 1000
mru 1000

Конечно мои настройки могут и не подойти Вам. Начните с того, что попробуйте с настройками Gentoo по-умолчанию. Здесь не обсуждаеются вопросы использования шифрования и сжатия при использовании VPN соединений. Внимательный читатель заметил, что IP адрес сервера моего провайдера (192.168.7.254) был указан в коментарии в файле "/etc/ppp/peers/vpn.0", а в /etc/ppp/options.pptp опция "pty" закоментирована. Сделано это неспроста! Так работает pptp-command! Уж простите, не я придумал. pptp-command извлекает адрес сервера из файла описывающего провайдера (что и логично) и подсовывает его pppd, а фалй "options.pptp" может быть один для нескольких провайдеров. Важной особенностью является то, что адрес сервера pptp-command извлекает именно из коментария файла провайдера (например "/etc/ppp/peers/vpn.0")! А где же хранится мой пароль? Мой пароль хранится в файле "/etc/ppp/chap-secrets":

cat /etc/ppp/chap-secrets

# Secrets for authentication using CHAP
# client        server          secret          IP addresses    # Comment
azorg           bastion         "пароль1"       *               # ISP #0
AlexZorg        *               "пароль2"       *               # ISP #1

Полагаю формат файла очевиден. Именно тут и используется имя моего сервера 'bastion', хотя все бы работало даже, если указать '*' во второй колонке. Имена серверам (вторая колоночка) придется давать, если вы используете одинаковое имя (логин) у разных провайдеров.

После успешного "поднятия" интерфейса ppp, который можно проконтролировать с помощью утилиты ifconfig запускается скрпипт "/etc/ppp/etc/ppp/ip-up", который в моем Gentoo "из коробки" вызывает скрипт "/etc/ppp/ip-up.local", который я и использовал для своих целей - настроийки маршрута по-умолчанию. Я решил, что первый ppp интерфейс, (т.е. ppp0) это и есть соединение с провайдером. Какой IP адрес мне дает провайдер я узнал с помощью ifconfig (можно было этого и не делать). Теперь привожу cвой "/etc/ppp/ip-up.local" в качестве примера:

cat /etc/ppp/ip-up.local

#!/bin/sh

# the followings parameters are available:
# $1 = interface-name      ('ppp0')
# $2 = tty-device          ('/dev/pts/2' or '')
# $3 = speed               ('115200')
# $4 = local-IP-address
# $5 = remote-IP-address
# $6 = ipparam             ('' ???)

export PATH=/sbin:/usr/sbin:/usr/local/sbin:/bin:/usr/bin:/usr/local/bin

# if ppp0 is external interface set it to default route
if [ "$5" = "172.16.1.254" ] ||
   [ "$5" = "10.1.1.254" ] ||
   [ "$5" = "192.168.254.254" ]
then
  if [ "$1" = "ppp0" ]; then
    #echo "-$1-$2-$3-$4-$5-$6-" >> /_ppp_ #!!! debug
    route del $5
    [ -n "$(route -n | awk '{print $1}' | grep '0.0.0.0')" ] && route del default
    route add default dev $1
  fi
fi

Отмечу сразу, что 172.16.1.254, 10.1.1.254 и 192.168.254.254 это IP адреса которые могут назначать себе мои провайдеры "на другом конце тунеля". Необходимость включения такого `if` возникла по причине того, что на моей машине могут "подниматься" и другие "серверные" ppp интерфейсы (ppp1, ppp2, ppp3, итд) в случаях когда мой хост является сервер-провайдером для домашних ПК в домашней сети, конечно в простейшем случае, если у вас нет шлюза по-умолчанию (указанного например в "/etc/conf.d/net"), то вам хватит строчки с `/sbin/route add default dev $1`. Немного о DNS, я использую фиксированный DND сервер, который указал в "/etc/resolve.conf", а "лишний" код получения IP адреса DNS от провайдера в сценарии "/etc/ppp/ip-up" я закоментировал.
При рызрыве соединения (при "падении" интерфейса ppp0) в моем Gentoo Linux запускаются скрипты "/etc/ppp/ip-down" и "/etc/ppp/ip-down.local" соответсвенно. Вот мой "/etc/ppp/ip-down.local", для примера:

cat /etc/ppp/ip-down.local

#!/bin/sh

# the followings parameters are available:
# $1 = interface-name      ('ppp0')
# $2 = tty-device          ('/dev/pts/2' or '')
# $3 = speed               ('115200')
# $4 = local-IP-address
# $5 = remote-IP-address
# $6 = ipparam             ('' ???)

# Default gateway if ppp0 unavaiable
#GATEWAY="192.168.30.254"

export PATH=/sbin:/usr/sbin:/usr/local/sbin:/bin:/usr/bin:/usr/local/bin

# if ppp0 was external interface set another default route
if [ "$5" = "172.16.1.254" ] ||
   [ "$5" = "10.1.1.254" ] ||
   [ "$5" = "192.168.254.254" ]
then
  if [ "$1" = "ppp0" ]; then
    if [ -n "$GATEWAY" ]; then
      [ -n "$(route -n | awk '{print $1}' | grep '0.0.0.0')" ] && route del default
      route add default gw $GATEWAY
    fi
  fi
fi

Теперь о том, что же я предлагаю. Вот обещанный initrc скрипт для соединения с провайдером:

cat /etc/init.d/pptp

#!/sbin/runscript
# System init script for start/stop PPTP based VPN client under Gentoo Linux
# (C) 2004 Alex Zorg
# Distributed under the terms of the GNU General Public License v2
# Config is in /etc/conf.d/pptp

opts="start stop"

depend() {
  before ntp-client
  need net
}

checkconfig() {
  if [ ! -x "$(which pppd)" ] ||  [ ! -x "$(which pptp)" ] ||
     [ ! -x "$(which ifconfig)" ]
  then
    eerror "pppd, pptp, ifconfig needs to be installed (pptpclient package)"
    return 1
  fi

  if [ "${FUNCT}" = "start" ] &&
     [ -e "/var/run/ppp-ppp0.pid" -o -e "/var/run/ppp0.pid" ]
  then
    eerror "ppp0 is already up"
    return 1
  fi

  PEER=${PEER:-'__default'}
  PEER_FILE="/etc/ppp/peers/$PEER"

  if [ ! -f "$PEER_FILE" ]; then
    eerror "Error of config pptp! Can't read '$PEER_FILE' file"
    return 1
  fi

  PEER_IP=`grep "Server IP:" "$PEER_FILE" | \
           sed 's/^.*Server IP: *//' | awk '{print $1}'`

  if [ -z "$PEER_IP" ]; then

    eerror "Can't specify 'Server IP:' from '$PEER_FILE!'"
    return 1
  fi
}

start() {
  checkconfig || return 1

  ebegin "Starting pptp  (VPN based client) Connect to $PEER_IP"
    if [ -n "$(ifconfig | grep ppp0)" ]; then
      ewarn "Interface ppp0 seems to be already up"
      exit 1
    fi

    # bringing ppp0 up over PPTP-tunnel (VPN)
    pppd pty "/usr/sbin/pptp $PEER_IP --nolaunchpppd" call "$PEER"
  eend $?
}

stop() {
  checkconfig || return 1

  ebegin "Stopping pptp  (VPN based client)"
    if [ -z "$(ifconfig | grep ppp0)" ]; then
      ewarn "Interface ppp0 seems to be already down"
    else
      ifconfig ppp0 down
    fi

    if [ -e /var/run/ppp-ppp0.pid ]; then
      kill $(grep -v "ppp0" /var/run/ppp-ppp0.pid)
    elif [ -e /var/run/ppp0.pid ]; then
      kill $(grep -v "ppp0" /var/run/ppp0.pid)
    fi
  eend $?
}

Если не существует символическая ссылка "/etc/ppp/peers/__default" на файл провайдера, например "/etc/ppp/peers/vpn.0", то файл провайдера можно указать в файле "/etc/conf.d/pptp", привожу для примера:

cat /etc/conf.d/pptp

# /etc/conf.d/pptp
# Config file for /etc/init.d/pptp
# (C) 2004 Alex Zorg
# Distributed under the terms of the GNU General Public License v2

# Define peer (aka ISP)
# by default used /etc/ppp/peers/__default symbolic link
# For setup your Poin-To-Point connection you may use pptp-command
#PEER="MyISP"
#!!!
PEER="vpn.0"

Надеюсь я помог Русскому сообществу Gentoo Linux. А еще бы хорошо, чтобы подобный скрипт включили при установке пакета pptpclient его "Мэйнтейнеры" в Gentoo. Был приятно удивлен, когда обнаружил в один прекрасный момент после обновления Gentoo сценарий "/etc/init.d/pptpd", который был почти что копией того скрипта (и назывался так же!), который я использовал для "поднятия" VPN серверов.

Огромное спасибо NeKto <nekto@unsorted.ru> за помощь настройки VPN несколько лет назад.


Alex Zorg © 2005

Ставил по этой инструкции соединение устанавливалось но пакеты не ходили пока вручную не прописал отдельно маршрут до VPN сервера

Есть более элегантный способ установки VPN с помощью /etc/conf.d/net. Фактически все сетевые настройки можно делать там.

Не грусти, товарищ! Всё хорошо, beautiful good!

Замечательная статья. Доступно и понятно. Сделал как описано -все заработало с первого раза.
Спасибо автору

Все сделал как описано. Заработало сходу. Спасибо автору.

Аналогично! Сделал все бонусы букмекеровчетко, как написано в инструкции, правда заработало пари на матчине спервого раза, но всему виной моя невнимательность..Ошибко нашел практически сразу. Спасиба

тоже сделал настройку по статье и все заработало спасибо большое!

извините за офтоп, но есть проблемка с использованием параметров lcp-echo-interval и lcp-echo-failure... можно ли устраивать реконекты подключения в случае обвала другим способом? вся проблема в том что я пользую accel-pptp, по сути используется pptpclient, но в конфиге подключения вместо pty малость другая схема оформления и прописывается плагином либа pptp.so из accel-pptp... проблема в том что я не могу использовать lcp-echo-interval и lcp-echo-failure, потому что в силу особенности, как я понял, моего провайдера это приводит к глухому вешанью ядра, ну а без них не происходит реконект и впридачу при разрыве зашкаливают показатели отдачи и закача на неотвалившемся ppp0 интерфейсе цп на 100 (почему так происходит впринципе выяснил, но решение до сих пор не найдено, если есть идеи или интересно, вот открытая тема с полным описанием ситуации и до сих пор открытым вопросом http://gentoo.ru/node/25786)... как альтернатива решения, а вернее велосипед, это сделать проверку соединения другим способом, каким манцем - выгуглить не получилось