UMGUM.COM (лучше) 

Установка OpenVPN ( Инсталляция VPN сервера OpenVPN. )

25 марта 2010  (обновлено 29 декабря 2014)

OS: Debian Lenny.

Перед установкой OpenVPN необходимо озаботится поддержкой системой псевдо-устройства "tun". Мы будем использовать технологию Layer 3 based IP туннеля для пропускания IP трафика между клиентом и окружением сервера VPN (OpenVPN поддерживает и Layer 2 based Ethernet, но в нашем решении пропускание Ethernet совершенно ни к чему). Для Debian проверить его наличие и поддержку можно следующим образом:

# ls -l /dev/net/tun

Если мы получили примерно следующее, то устройство "tun" поддерживается и можно переходить к следующим шагам:

crw------- 1 root root 10, 200 ... /dev/net/tun

В противном случае будет не лишним создать файл устройства:


# mkdir -p /dev/net
# mknod /dev/net/tun c 10 200
# chmod 600 /dev/net/tun

Для работы с интерфейсом "tun" нам понадобится модуль ядра "tun". Проверяем, загружен ли он:

# lsmod | grep tun

Получаем что-то вроде:

tun ....

И переходим к дальнейшей конфигурации или, если модуль не загружен, создаем условия для его загрузки:

# modprobe tun
# echo tun >> /etc/modules

На самом деле во всех современных дистрибутивах поддержка "/dev/net/tun" осуществляется соответствующими скриптами, и, вместо грубого и прямолинейного создания файла устройства лучше бы поискать пути, предусмотренные создателями дистрибутива.

Инсталлируем OpenSSL, OpenVPN и библиотеку сжатия трафика LZO:

# aptitude install openvpn openssl liblzo2-2

Печально, что сборка OpenVPN от Debian 5 не предусматривает запуск от произвольного непривилегированного пользователя. Исправим это. Создадим пользователя и группу "openvpn":

# groupadd openvpn
# useradd --home-dir /etc/openvpn --shell /bin/false --gid openvpn openvpn

Создаем директорию для хранения журнальных файлов и файлов статистики:

# mkdir -p /var/log/openvpn
# chown -R openvpn /var/log/openvpn
# chgrp -R openvpn /var/log/openvpn

Следующий, очень ответственный этап - создание сертификатов и закрытых ключей серверов и клиентов. В большинстве дистрибутивов, а так же в комплекте с исходными кодами OpenVPN есть набор скриптов, позволяющий создать набор ключей. Можно пройти процедуры создания всех необходимых сертификатов и ключей вручную для более полного проникновения в суть механизмов защиты трафика между сервером и клиентом, но это тема для отдельного разговора. Скрипты и примеры от разработчиков находятся по адресу "/usr/share/doc/openvpn/examples", они корректно отрабатывают и имеют достаточный функционал для обеспечения всех наших нужд.

Создаем структуру директорий конфигурационных файлов сервисов:

# mkdir -p /etc/openvpn/crts   # сертификаты CA и серверов
# mkdir -p /etc/openvpn/keys   # закрытые ключи
# mkdir -p /etc/openvpn/out    # директория выходных файлов для клиентов

Ограничиваем доступ к директориям закрытых ключей:

# chmod 700 /etc/openvpn/crts
# chmod 700 /etc/openvpn/keys

Создаем служебный файл параметров "Диффи-Хэлмана", предназначающийся для обеспечения более надёжного шифрования соединения сервера и клиента:

# openssl dhparam -out dh2048.key 2048

Где:

"-out" - место расположения файла параметров;
"2048" - разрядность, длинна ключа, в битах.

Операция создания параметров "Диффи-Хэлмана" достаточно ресурсоёмкая, чтобы заставить нас ожидать даже у консоли весьма мощных компьютеров (на практике может генерироваться до двадцати минут).

Создаем служебный файл статического ключа "HMAC", обеспечивающего дополнительную защиту от DoS атак:

# openvpn --genkey --secret ta.key

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

Копируем себе поближе скрипты создания ключей:

# mkdir -p /etc/openvpn/easy-rsa
# cp /usr/share/doc/openvpn/examples/easy-rsa/2.0/* /etc/openvpn/easy-rsa

Готовим директорию для закрытых ключей сертификатов клиентов и серверов:

# mkdir -p /etc/openvpn/easy-rsa/keys

Упорядочиваем "правовые отношения":

# chown -R openvpn /etc/openvpn/easy-rsa
# chgrp -R openvpn /etc/openvpn/easy-rsa
# chmod -R go-rwx /etc/openvpn/easy-rsa

Переходим в рабочую директорию и запускаем скрипты в конструкции "./script", без использования полного пути к файлу. Такой способ запуска обеспечивает работу скриптов в одной, если так можно выразится, исполняемой среде с единым набором переменных, без инициирования новой копии "шелла". Если переменные не будут корректно экспортироваться в текущий "шелл", то можно запускать скрипты, работающие с переменными с помощью команды "source":

# cd /etc/openvpn/easy-rsa/

Корректируем значения переменных, изменённых для нашего случая, в файле "/etc/openvpn/easy-rsa/vars" до желаемых, например таких:

export EASY_RSA="/etc/openvpn/easy-rsa"
export KEY_DIR="$EASY_RSA/keys"
export KEY_SIZE=2048
export CA_EXPIRE=3650
export KEY_EXPIRE=3650
export KEY_COUNTRY="KZ"
export KEY_PROVINCE="Province"
export KEY_CITY="City"
export KEY_ORG="Organisation"
export KEY_EMAIL="admin@vpn.local"

Экспортируем значения переменных в оболочку, зачищаем место для работы и генерируем сертификат "CA":

# source ./vars
# ./clean-all
# ./build-ca

Ответим на ряд достаточно скромных и непринципиальных (лучше отвечать честно, но на работоспособности сервиса это никак не скажется) вопросов и получим в директории "/etc/openvpn/easy-rsa/keys" следующие файлы:

ca.crt      # сертификат CA, как таковой
ca.key      # закрытый ключ сертификата CA
index.txt   # файл индекса для будущих сертификатов, подписанных сертификатом CA
serial

Далее, с помощью умного скрипта, генерируем сертификат и закрытый ключ нашего сервера (где ключевое слово "server" - для подстановки, а именно, там должно быть название нашего сервера; укажем там доменное имя "vpn.local"):

# ./build-key-server server

Ответим на ряд очевидных, после исполнения предыдущих скриптов, вопросов, откажемся применить пароль к сертификату, пропустим запрос имени предприятия, подтвердим верность введённых данных и согласимся подписать сертификат нашего сервера. В директории "/etc/openvpn/easy-rsa/keys" обнаружим прирост из следующих, требующихся нам, файлов:

vpn.local.crt   # сертификат сервера, как такового
vpn.local.key   # закрытый ключ сервера

Следующий, логичный шаг - в создании уникальных сертификатов и ключей клиентов, подписанных нашим сертификатом CA (где "client.name" - для подстановки уникального имени клиента VPN):

# cd /etc/openvpn/easy-rsa/
# source ./vars
# ./build-key client.name

Аналогично процедуре создания сертификата и ключа сервера отвечаем на вопросы и соглашаемся всему, на что согласны. Получаем в директории "/etc/openvpn/easy-rsa/keys" файлы сертификата и закрытого ключа клиента:

client.name.crt
client.name.key

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

Раскладываем полученные сертификаты и ключи по соответствующим им местам:

# cp /etc/openvpn/easy-rsa/keys/ca.crt /etc/openvpn/crts
# cp /etc/openvpn/easy-rsa/keys/ca.key /etc/openvpn/keys
# cp /etc/openvpn/easy-rsa/keys/server.name.crt /etc/openvpn/crts
# cp /etc/openvpn/easy-rsa/keys/server.name.key /etc/openvpn/keys

Выводим клиентские файлы в соответствующие им директории:

# mkdir -p /etc/openvpn/out/client.name
# cp /etc/openvpn/easy-rsa/keys/ca.crt /etc/openvpn/out/client.name
# cp /etc/openvpn/ta.key /etc/openvpn/out/client.name
# cp /etc/openvpn/easy-rsa/keys/client.name.crt /etc/openvpn/out/client.name
# cp /etc/openvpn/easy-rsa/keys/client.name.key /etc/openvpn/out/client.name

Вместо использования на клиентах трёх раздельных файлов (ca.crt, client.name.crt, client.name.key) можно использовать единый файл формата "PKCS12". Для этого нужно генерировать ключи клиента скриптом из набора разработчиков:

# cd /etc/openvpn/easy-rsa/
# source ./vars
# ./build-key-pkcs12 client.name

На выходу будет создан как обычный комплект файлов, так и новый файл с расширением ".p12" - это и есть этот самый, комбинированный файл. Его можно использовать в конфигурационном файле клиента OpenVPN с помощью одной строки конфигурации с ключём "pkcs12" вместо трёх строк конфигурации с ключами ".ca", ".cert" и ".key".

Венцом освоения базовых навыков работы с сертификатами будет пополнение списка отозванных сертификатов пользователей, доступ которых мы хотели бы прекратить по тем или иным причинам. Воспользуемся скриптом из набора, созданного для нас разработчиками OpenVPN (имеем в виду, что содержимое файла "/etc/openvpn/easy-rsa/vars" уже приведено к желаемому нами виду):

# cd /etc/openvpn/easy-rsa/
# source ./vars
# ./revoke-full client.name

Получаем примерно следующее:

Using configuration from /etc/openvpn/easy-rsa/openssl.cnf
Revoking Certificate 04.
Data Base Updated
Using configuration from /etc/openvpn/easy-rsa/openssl.cnf
DEBUG[load_index]: unique_subject = "yes"
client.name.crt: /C=KZ/ST=NA/O=ITS/CN=client.name/emailAddress=admin@vpn.local
error 23 at 0 depth lookup:certificate revoked

Где последняя строчка с сообщением об ошибке как раз и говорит о том, что сертификат успешно отозван и его тестовая проверка после отзыва не прошла.

Скрипт "revoke-full" запишет данные об отозванном сертификате в файле "/etc/openvpn/easy-rsa/keys/crl.pem", располагающемся там в соответствии с настройками переменных в файлах "/etc/openvpn/easy-rsa/vars" и "/etc/openvpn/easy-rsa/openssl.conf". Если файла "/etc/openvpn/easy-rsa/keys/crl.pem" не обнаружится - он будет создан.

# chown openvpn /etc/openvpn/easy-rsa/keys/crl.pem
# chgrp openvpn /etc/openvpn/easy-rsa/keys/crl.pem
# chmod go-rwx /etc/openvpn/easy-rsa/keys/crl.pem

Переходим к конфигурированию OpenVPN как такового.
Используем шаблон конфигурационного файла OpenVPN от разработчиков:

# cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/
# gunzip /etc/openvpn/server.conf.gz

Приводим конфигурационный файл к виду, где ключевые параметры будут иметь следующие значения:

# cat /etc/openvpn/server.conf

dev               tun                               # включаем Layer 3 based IP туннель
dev-node          /dev/net/tun0                     # выбираем произвольное псевдоустроство в качестве интерфейса
local             IP                                # IP адрес прослушиваемого интерфейса
port              443                               # прослушиваемый порт
proto             tcp                               # используемый транспортный протокол
server            10.10.11.0 255.255.255.0          # диапазон адресов выделенный для раздачи клиентам
push              "route 10.0.0.0 255.0.0.0"        # команда, передаваемая клиенту
push              "route 192.168.0.0 255.255.0.0"
push              "dhcp-option DNS 10.0.0.1"        # команда, передаваемая клиенту, с указанием DNS сервера
push              "ping 10"                         # указываем клиенту проверять поддерживать соединение каждые 10 секунд
push              "ping-restart 60"                 # указываем клиенту на необходимость перезапустить сессию в том случае, если от сервера нет ответа в течении 60 секунд
client-config-dir /etc/openvpn/ccd                  # директория с конфигурациями клиентов
# client-to-client                                  # директива, разрешающая межклиентское взаимодействие, в нашем случае весь трафик от клиентов пойдет через VPN сервер
# duplicate-cn                                      # запрещаем использование разными клиентами одинаковых "Common Name"
max-clients       10                                # ограничиваем количество одновременных VPN подлючений
dh                /etc/openvpn/dh2048.key
ca                /etc/openvpn/crts/ca.crt
cert              /etc/openvpn/crts/server.name.crt
key               /etc/openvpn/keys/server.name.key
crl-verify        /etc/openvpn/easy-rsa/keys/crl.pem   # список отозванных сертификатов клиентов OpenVPN
tls-server                                          # включаем поддержку TLS
comp-lzo                                            # включаем сжатие трафика между сервером и клиентом
cipher            AES-256-CBC                       # включаем шифрование повышенного уровня относительно стандартного
keepalive         10 120                            # поддержание соединения путём ping каждые 10 секунд и закрытие соединения, если ответ не пришёл спустя 120 секунд
; tun-mtu           1500                            # определение параметров передачи данных по тоннелю
; mssfix            1450                            # определение параметров передачи данных по тоннелю
persist-key                                         # не перечитывать ключи при перезапуске сессии
persist-tun                                         # не перезагружать /dev/tun при перезапуске сессий
user              openvpn                           # перевод OpenVPN под указанного пользователя после запуска
group             openvpn
verb              3                                 # уровень детализации файлов журнала событий (от 0 до 9)
status            /var/log/openvpn/openvpn-status.log
log-append        /var/log/openvpn/openvpn.log

Можно попытаться заменить "шлюз по умолчанию" на компьютере клиента на свой, чтобы заворачивать весь сетевой трафик на VPN сервер. Надо заметить, что эта затея далеко не всегда проходит успешно, да и исправляется клиентом весьма просто - потому мы и не будем даже пытаться это делать, а выступим просто ещё одним подключением со своими маршрутами. Если есть желание, то замена шлюза на стороне клиента на свои значения достигаются размещением в конфигурационном файле одного из вариантов следующих строк:

push   "redirect-gateway def1 bypass-dhcp"   # назначаем у клиента шлюзом "по умолчанию" наш VPN сервер

push   "redirect-gateway local def1"   # назначаем у клиента шлюзом "по умолчанию" наш VPN сервер для всего трафика, включая и локальный

В конфигурационном файле сервера можно разместить опцию, указующую на размещение статического ключа "HMAC", обеспечивающего дополнительную защиту от "DoS" атак за счёт того, что соединение на порту принимается только в том случае, если клиент будет обращаться к серверу используя точно такой же статический ключ "HMAC" и отбрасывать соединения, без "подписи" этим ключём. За счёт этого сокращаются затраты ресурсов системы на обработку запросов сетевых сканеров и злоумышленников.

tls-auth   /etc/openvpn/ta.key 0

Файл статического ключа используется один и тот же на стороне сервера и клиента. На стороне клиентов необходимо использовать аналогичный ключ в конфигурационном файле, только значение "0" в конце строки заменить на "1".

К сожалению, в процессе эксплуатации схемы доступа VPN пришлось столкнуться с определёнными проблемами, до корней которой не удалось докопаться в силу закрытости одной из сторон - источников проблемы. Суть в том, что на одном из важных объектов, откуда необходимо было обеспечить доступ к серверам VPN, защитный экран периметра сети "злостно" блокировал трафик, связанный с прохождением именно этого статического ключа. Причину выявить не удалось в силу нежелания администраторов объекта вникать в проблемы, прямо не являющиеся их собственными, и пришлось элементарно отказаться от этого этапа защиты сервера.

Упомянутые выше в конфигурационном файле директория файлов конфигураций клиентов будет содержать файлы описаний сетевой конфигурации соединения, имеющие имена установленного вида; например, для клиента с "Common Name" имеющим значение "client.name" исполняется файл с именем "client.name". Файлы содержат команды сервера OpenVPN. В нашей конфигурации мы навязываем каждому клиенту свой IP адрес и адрес "шлюза" для того, чтобы можно было контролировать их трафик листами доступа.

Создаем директорию и файл настроек клиента:

# mkdir -p /etc/openvpn/ccd
# touch /etc/openvpn/ccd/client.name
# echo "ifconfig-push 10.10.11.6 10.10.11.5" > /etc/openvpn/ccd/client.name

Где:

"10.10.11.5" - IP виртуального "шлюза" на стороне VPN сервера;
"10.10.11.6" - IP "client.name" на стороне пользователя.

Необходимо иметь в виду то, что в режиме конфигурации Layer 3 based IP туннеля OpenVPN сервер эмулирует работу маршрутизатора, к портам которого подключены сервер и клиенты. При этом, каждому подключению выделяется, из описанного нами выше в конфигурационном файле диапазона, подсеть из четырёх IP адресов (подсеть /30, ограничиваемая маской 255.255.255.252), где (например):

"10.10.11.4" - адрес подсети 10.10.11.4/30;
"10.10.11.5" - адрес виртуального порта на стороне OpenVPN сервера;
"10.10.11.6" - адрес виртуального порта на стороне клиента;
"10.10.11.7" - адрес широковещательный (broadcast).

Надо заметить то, что непосредственно к портам виртуального маршрутизатора обратиться не получится, на запросы ping или tracert они не отвечают.

Закрываем конфигурацию от излишне любопытных:

# chown -R openvpn /etc/openvpn
# chgrp -R openvpn /etc/openvpn
# chmod -R go-rwx /etc/openvpn

Включаем IP forwarding. Для этого в файл "/etc/sysctl.conf" дописываем или открываем строку с параметром:

net.ipv4.ip_forward = 1

И выполняем команду, позволяющую немедленно включить IP forwarding:

# echo 1 > /proc/sys/net/ipv4/ip_forward

При этом вспоминаем о защитном экране, чётко описывающем разрешения для обращений на сетевых интерфейсах. Иначе, как бы не оказалась наша машина местом свободного провода трафика между соединяемыми ею подсетями.

Если мы устанавливали OpenVPN с помощью стандартной пакетной системы, то нам нет необходимости заботится о процедуре автоматического запуска и останова сервера, за нас уже создали необходимые скрипты. Управление OpenVPN сервером можно производить с помощью скрипта "/etc/init.d/openvpn {start|stop|restart}".

Запускаем наш сервер OpenVPN:

# /etc/init.d/openvpn start

Просмотр состояния сетевых интерфейсов должен показать нам наличие активного сетевого устройства с установленными нами параметрами:

# ifconfig tun0

Увидим что-то вроде следующего:

tun0  Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
      inet addr:10.10.10.1  P-t-P:10.10.10.2  Mask:255.255.255.255
      UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
      RX packets:0 errors:0 dropped:0 overruns:0 frame:0
      TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
      collisions:0 txqueuelen:100
      RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

Проверяем, слушает ли наш сервер OpenVPN указанные ему порты на соответствующих интерфейсах:

# netstat -ap | grep openvpn

В ответ должны увидеть примерно следующее:

tcp  0  0  *:https  *:*  LISTEN  2535/openvpn

Заглянув в журнальный файл увидим примерно следующее:

OpenVPN 2.1_rc11 i486-pc-linux-gnu [SSL] [LZO2] [EPOLL] [PKCS11] built on Sep 18 2008
Diffie-Hellman initialized with 2048 bit key
...
TUN/TAP device tun0 opened
TUN/TAP TX queue length set to 100
GID set to openvpn
UID set to openvpn
Listening for incoming TCP connection on [undef]:443
TCPv4_SERVER link local (bound): [undef]:443
TCPv4_SERVER link remote: [undef]
Initialization Sequence Completed

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


Заметки и комментарии к публикации:


Оставьте свой комментарий ( выразите мнение относительно публикации, поделитесь дополнительными сведениями или укажите на ошибку )