Настройка OpenVPN с использованием сертификатов X.509 [2007]
Постановка задачи
Необходимо создать виртуальную частную сеть между несколькими офисами компании, подключенными к Интернет. Как известно, существует множество решений данного вопроса, которые многократно сравнивались по соотношениям функциональности / надежности / стоимости. Рекомендую Вам прочитать статью А. Бешкова Создаем кроссплатформенную виртуальную частную сеть VPN на основе OpenVPN. В ней описано очень простое, но достаточно надежное решение на базе бесплатного пакета OpenVPN, использующее статические ключи для шифрования трафика. OpenVPN позволяет разворачивать гораздо более гибкие конфигурации и использовать сертификаты TLS/SSL вместо статических ключей. В данной статье рассмотрена одна из таких конфигураций.
Исходные данные
Имеется сервер с FreeBSD, находящийся на входе подсети центрального офиса. На нем мы развернем сервер OpenVPN. Имеется два удаленных филиала, на входе сетей которых установлены серверы с FreeBSD (они будут клиентами OpenVPN) и компьютер системного администратора с Windows XP (он также будет клиентом OpenVPN). Локальная подсеть центрального офиса имеет адрес 192.168.0.0/24; локальная подсеть филиала № 1 - 192.168.1.0/24; локальная подсеть филиала № 2 - 192.168.2.0/24. Необходимо создать виртуальную частную сеть routed-типа (т.е. не пропускающую широковещательный трафик), имеющую топологию Point-To-Multi-Point (один сервер и несколько клиентов), использующую для шифрования трафика TLS/SSL и обеспечивающую следующую политику маршрутизации между локальными подсетями: из локальной подсети центрального офиса доступны компьютеры локальных подсетей обоих филиалов, из локальных подсетей филиалов доступны компьютеры локальной подсети центрального офиса, c компьютера удаленного системного администратора доступны компьютеры локальных подсетей центрального офиса и обоих филиалов:
При реализации того, что описано ниже я пользовался документом OpenBSD Installation (настоятельно рекомендую Вам изучить этот документ), а также материалами Форума OpenNET.
Установка сервера OpenVPN
Для установки сервера OpenVPN необходимо выполнить следующую последовательность действий: добавить в файл конфигурации ядра строку pseudo-device tun, если таковая отсутствует, пересобрать ядро, перезагрузить систему. Затем нужно установить OpenVPN из портов:
cd /usr/ports/security/openvpn make install
Файлы конфигурация сервера OpenVPN хранятся в папке /usr/local/etc/openvpn. Для создания указанной папки, а также необходимых вложенных папок и файлов, необходимо выполнить следующую последовательность команд:
Указанные команды создают папку /usr/local/etc/openvpn; вложенные в нее папки: ccd (конфигурации удаленных клиентов), certs (сертификаты клиентов и сервера), crl (списки отзыва сертификатов), keys (закрытые ключи сертификатов клиентов и сервера), private (закрытый ключ самоподписного доверенного сертификата (CA), req (запросы на сертификаты); ограничивают права доступа к каталогам keys и private; создают базу данных сертификатов (файлы serial и index.txt).
Файл конфигурации OpenSSL
По умолчанию OpenSSL использует глобальный файл конфигурации /etc/ssl/openssl.cnf. Я рекомендую создать в папке /usr/local/etc/openvpn отдельный файл конфигурации OpenSSL для OpenVPN. Данный файл должен называться openssl.cnf и иметь следующее содержимое:
[ req_distinguished_name ] organizationName = Organization Name (must match CA) organizationName_default = Company organizationalUnitName = Location Name commonName = Common User or Org Name commonName_max = 64
[ server ] basicConstraints = CA:FALSE nsCertType = server
Создание самоподписного доверенного сертификата (CA)
Для создания самоподписного доверенного сертификата (CA) и закрытого ключа для него необходимо, находясь в каталоге /usr/local/etc/openvpn, выполнить команду:
Команда req заставляет OpenSSL создать сертификат, ключи: -new - cоздать запрос на сертификат, -nodes - не шифровать закрытый ключ, -x509 (совместно с -new) - создать самоподписной сертификат (CA), -keyout - задает местонахождение закрытого ключа, -out - задает местонахождение самоподписного сертификата, -days - задает время действия сертификата (365x10 дней, что приблизительно равно десяти годам). В процессе выполнения команды на экран будут выданы запросы о вводе таких параметров как: Country Name, State or Province Name; Locality Name; Organization Name; Organizational Unit Name; Common Name; Email Address. Самым важным параметром является значение Common Name. В данном случае оно должно совпадать с FQDN-именем сервера. Для просмотра результата генерации самоподписного сертификата и его закрытого ключа, находясь в каталоге /usr/local/etc/openvpn, можно выполнить команды:
openssl x509 -noout -text -in CA_cert.pem (для сертификата) openssl rsa -noout -text -in private/CA_key.pem (для закрытого ключа)
Создание сертификата сервера
Для создания сертификата сервера сначала нужно создать запрос на сертификат сервера и закрытый ключ сервера. Для этого, находясь в каталоге /usr/local/etc/openvpn, нужно выполнить команду:
Команда и ключи OpenSSL рассмотрены выше. В процессе выполнения комнды Вам опять придется ответить на вопросы. Ответы должны соответствовать ответам из предыдущего пункта. В ответ на дополнительные запросы "A challenge password []:" и "An optional company name []:" необходимо просто нажать <Enter>. Для просмотра результата генерации запроса на сертификат и закрытого ключа сервера, находясь в каталоге /usr/local/etc/openvpn, можно выполнить команды:
openssl req -noout -text -in req/server.pem (для запроса на сертификат) openssl rsa -noout -text -in keys/server.pem (для закрытого ключа)
Для создания сертификата сервера необходимо подписать запрос на сертификат сервера доверенным самоподписным сертификатом (CA). Для этого, находясь в каталоге /usr/local/etc/openvpn, нужно выполнить команду:
openssl ca -batch -config openssl.cnf -extensions server -out certs/server.pem \ -infiles req/server.pem
Команда ca заставляет OpenSSL подписать запрос на сертификат, ключи: -config задает местонахождение файла конфигурации OpenSSL, -extensions - задает секцию файла конфигурации OpenSSL, содержащую дополнительные параметры генерируемого сертификата, -out - задает местонахождение генерируемого сертификата, -infiles - задает местонахождение запроса на сертификат, -batch - избавляет Вас от ответов на дополнительные вопросы. В процессе выполнения команды Вам будет задан вопрос "Sign the certificate? [y/n]:", на который нужно ответить утвердительно, после чего произойдет генерация сертификата и обновление базы данных сертификатов (index.txt и serial). Для просмотра результата генерации сертификата, находясь в каталоге /usr/local/etc/openvpn, можно выполнить команду:
openssl x509 -noout -text -in certs/server.pem
Создание файла параметров Диффи-Хэлмана
Для создания файла параметров Диффи-Хэлмана, предназначенного для обеспечения более надежной защиты данных при установке соединения клиента с сервером, находясь в каталоге /usr/local/etc/openvpn, нужно выполнить команду:
openssl dhparam -out dh2048.pem 2048
Команда dhparam приказывает OpenSSL создать файл параметров Диффи-Хэлмана, число 2048 определяет разрядность в битах. Внимание: данная команда выполняется медленно даже на очень мощных компьютерах.
Создание клиентских сертификатов
Процедура создания клиентских запросов на сертификаты и закрытых ключей, подписания запросов на сертификаты и генерации сертификатов, а также просмотра запросов на сертификаты, сертификатов и закрытых ключей полностью аналогична соответствующей процедуре для сервера. Сделаю одно небольшое замечание: запросы на сертификаты, закрытые ключи и сертификаты должны иметь шаблонные имена, например, вида: req/RClient для запросов на сертификаты, keys/KClient для закрытых ключей и certs/CClient для сертификатов, соответственно. Слово Client должно быть заменено именем клиента, которое обязательно должно соответствовать значению параметра Common Name, вводимого при генерации запроса на сертификат для соответствующего клиента. Возможность дублирования Common Name у нескольких клиентов определяется конфигурацией сервера. Для генерации запроса на сертификат и закрытого ключа, а также подписания запроса на сертификат и генерации сертификата для клиента Client, находясь в каталоге /usr/local/etc/openvpn, нужно выполнить команды:
Для просмотра сгенерированных запроса на сертификат, закрытого ключа и сертификата клиента Client, находясь в каталоге /usr/local/etc/openvpn, можно выполнить команды:
openssl req -noout -text -in req/RClient.pem (для запроса на сертификат) openssl rsa -noout -text -in keys/KClient.pem (для закрытого ключа) openssl x509 -noout -text -in certs/CClient.pem (для сертификата)
На данном этапе для рассматриваемого случая необходимо создать три групы, состоящих из запроса на сертификат / закрытого ключа / сертификата, с именами Rclient1 / Kclient1 / Cclient1, Rclient2 / Kclient2 / Cclient2 и Rclient3 / Kclient3 / Cclient3 для филиала № 1 (Common Name - client1), для филиала № 2 (Common Name - client2) и для системного администратора (Common Name - client3), соответственно.
Создание списка отзыва сертификатов
Для создания списка отзыва сертификатов, находясь в каталоге /usr/local/etc/openvpn, нужно выполнить команду:
openssl ca -config openssl.cnf -gencrl -out crl/crl.pem
Команда ca с ключем -gencrl заставляет OpenSSL создать список отзыва сертификатов, ключи: -config рассмотрен выше, -out - задает местонахождение списка отзыва сертификатов. Данная команда создает пустой список отзыва сертификатов. Для того, чтобы отозвать сертификат клиента Client, находясь в каталоге /usr/local/etc/openvpn, нужно выполнить команду:
openssl ca -config openssl.cnf -revoke certs/CClient.pem
Команда ca с ключем -revoke заставляет OpenSSL отозвать заданный сертификат, ключ -config рассмотрен выше. Для просмотра списка отозванных сертификатов, находясь в каталоге /usr/local/etc/openvpn, можно выполнить команду:
openssl crl -noout -text -in crl/crl.pem
Создание статического ключа HMAC
Для создания статического ключа HMAC, обеспечивающего дополнительную защиту от DoS-атак и флудинга UDP-портов, находясь в каталоге /usr/local/etc/openvpn, нужно выполнить команду:
openvpn --genkey --secret ta.key
Файл конфигурации сервера
Конфигурация сервера OpenVPN хранится в файле openvpn.conf, который должен находится в папке /usr/local/etc/openvpn. В рассматриваемом случае файл конфигурации имеет следующий вид:
dev tun local <Внешний IP-адрес сервера> port 1194 proto udp server 10.0.0.0 255.255.255.0 push "route 10.0.0.0 255.255.255.0" route 192.168.1.0 255.255.255.0 route 192.168.2.0 255.255.255.0 client-config-dir ccd client-to-client tls-server dh /usr/local/etc/openvpn/dh2048.pem ca /usr/local/etc/openvpn/CA_cert.pem cert /usr/local/etc/openvpn/certs/server.pem key /usr/local/etc/openvpn/keys/server.pem crl-verify /usr/local/etc/openvpn/crl/crl.pem tls-auth /usr/local/etc/openvpn/ta.key 0 comp-lzo keepalive 10 120 tun-mtu 1500 mssfix 1450 persist-key persist-tun user openvpn group openvpn verb 3
В данном файле заданы следующие значения параметров сервера OpenVPN: dev - интерфейс OpenVPN, local и port - IP-адрес и порт, на которых OpenVPN принимает входящие соединения, proto - протокол (в данном случае UDP), server - пул IP-адресов, выделенный для виртуальной частной сети и автоматически распределяемый между клиентами, push - команда OpenVPN, передаваемая клиенту и выполняемая клиентом (в данном случае "route 10.0.0.0 255.255.255.0" добавляет на стороне клиента маршрут к виртуальной частной сети), route - добавляет на стороне сервера маршруты к локальным подсетям, находящимся за клиентами, client-config-dir - папка с файлами конфигурации клиентов, client-to-client - разрешение клиентам "видеть" друг друга (естественно, при наличии соответствующих правил маршрутизации), tls-server - включение поддержки TLS; dh - местонахождение файла параметров Диффи-Хэлмана, ca - местонахождение самоподписного доверенного сертификата (CA), cert - местонахождение сертификата сервера, key - местонахождение закрытого ключа сервера, crl-verify - местонахождение списка отзыва сертификатов, tls-auth - местонахождение статического ключа HMAC, comp-lzo - использование LZO-компрессии трафика, keeplive - поддержание соединения (в данном случае отправка пингов каждые 10 секунд, и закрытие соединения через две минуты после отсутствия ответных пакетов, как сервером, так и клиентами), tun-mtu и mssfix - параметры передачи данных по тоннелю, persist-tun - не закрывать / открывать по-новой tun-устройство при получении сигнала SIGUSR1 (перезапуск без привилегий root) или при выполнении ping-restarts, user и group - пользователь и группа, от имени которых работает OpenVPN после запуска (запуск выполняется под root'ом), verb - уровень детализации сообщений, выдаваемых OpenVPN в /var/log/messages.
Файлы конфигурации клиентов
Файлы конфигурации клиентов являются текстовыми файлами, находящимися в папке ccd. Данные файлы содержат одну или несколько команд, которые инициируют добавление маршрутов к соответствующим локальным подсетям на стороне клиентов, а также задают адреса локальных подсетей, находящихся за клиентами. В рассматриваемом случае необходимо создать в папке /usr/local/etc/openvpn/ccd файлы конфигурации клиентов client1-client3:
cd /usr/local/etc/openvpn/ccd touch client1 client2 client3
Файл client1 должен содержать две команды: добавляющую клиенту маршрут к локальной подсети центрального офиса, а также определяющую адрес локальной подсети, находящейся за клиентом:
Существуют и другие способы задания маршрутов, а также другие команды, которые могут присутствовать в файлах конфигурации клиентов. На этот счет лучше всего внимательно изучить OpenVPN Man Page и HOWTO.
Автоматический запуск сервера
Для автоматического запуска сервера OpenVPN при загрузке операционной системы необходимо добавить строку openvpn_enable="YES" в файл /etc/rc.conf.
Замечания по настройке брандмауэров
Для корректной работы сервера OpenVPN необходимо внести следующие изменения в настройки брандмауэра: 1. Разрешить прохождение любого трафика через интерфейс OpenVPN; 2. Разрешить прохождение UDP-трафика на внешний адрес сервера порт 1194; 3. Разрешить прохождение любого трафика из виртуальной частной сети в локальную подсеть; 4. Разрешить прохождение любого трафика из локальной подсети в виртуальную частную сеть; 5. Разрешить прохождение любого трафика из локальной подсети филиала № 1 в локальную подсеть; 6. Разрешить прохождение любого трафика из локальной подсети в локальную подсеть филиала № 1; 7. Разрешить прохождение любого трафика из локальной подсети филиала № 2 в локальную подсеть; 8. Разрешить прохождение любого трафика из локальной подсети в локальную подсеть филиала № 2. Для ipfw (мой случай) нужно добавить следующие правила:
/sbin/ipfw -q add pass ip from any to any via ${vif} /sbin/ipfw -q add pass udp from any to ${oip} 1194 in via ${oif} /sbin/ipfw -q add pass ip from ${vnet} to ${inet} out via ${iif} /sbin/ipfw -q add pass ip from ${inet} to ${vnet} in via ${iif} /sbin/ipfw -q add pass ip from 192.168.1.0/24 to ${inet} out via ${iif} /sbin/ipfw -q add pass ip from ${inet} to 192.168.1.0/24 in via ${iif} /sbin/ipfw -q add pass ip from 192.168.2.0/24 to ${inet} out via ${iif} /sbin/ipfw -q add pass ip from ${inet} to 192.168.2.0/24 in via ${iif}
Переменные shell имеют следующие значения: oip - внешний IP-адрес сервера, inet - адрес локальной подсети (в нашем случае - 192.168.0.0/24), vnet - адрес виртуальной частной сети (в нашем случае 10.0.0.0/24), iif - имя внутреннего интерфейса сервера (например, rl1), oif - имя внешнего интерфейса сервера (например, rl0), vif - имя интерфейса OpenVPN (например, tun0). Настройка брандмауэров клиентов выполняется аналогично. Правила, начиная с пятого, зависят от реализованной политики маршрутизации. Для нашего случая правила ipfw для клиента client1 будут иметь вид (не забудьте, что теперь переменная shell inet определяет адрес локальной подсети клиента client1 - 192.168.1.0/24):
/sbin/ipfw -q add pass ip from any to any via ${vif} /sbin/ipfw -q add pass udp from any to ${oip} 1194 in via ${oif} /sbin/ipfw -q add pass ip from ${vnet} to ${inet} out via ${iif} /sbin/ipfw -q add pass ip from ${inet} to ${vnet} in via ${iif} /sbin/ipfw -q add pass ip from 192.168.0.0/24 to ${inet} out via ${iif} /sbin/ipfw -q add pass ip from ${inet} to 192.168.0.0/24 in via ${iif}
Правила ipfw для клиента client2 не отличаются от правил для клиента client1 (не забудьте, что теперь переменная shell inet определяет адрес локальной подсети клиента client2 - 192.168.2.0/24).
Передача необходимых файлов клиенту
Для передачи файлов клиенту лучше использовать какой-либо твердый носитель, например дискету, но ни в коем случае не сеть Интернет. Чтобы скопировать файлы, необходимые клиенту Client, на дискету, нужно выполнить следующую последовательность команд:
Данные команды монтируют дискету к папке /mnt, копируют сертификат клиента, закрытый ключ клиента, самоподписной доверенный сертификат (CA) и статический ключ HMAC на дискету, а затем размонтируют ее.
Клиентское программное обеспечение
Если клиент работает под FreeBSD, то установка клиента OpenVPN ничем не отличается от установки сервера (используется тот же самый порт), если под Windows, есть два варианта. OpenVPN и OpenVPN GUI. Первый вариант больше подходит для постоянно включенных серверов (OpenVPN может быть установлена как служба Windows), второй - для мобильных клиентов, периодически подключающихся к корпоративной сети. Например, я использую на домашнем ноутбуке OpenVPN GUI, когда мне нужно подключиться к корпоративной сети. Во всех перечисленных случаях файлы конфигурации имеют один и тот же формат. Внимание: в случае использовании Windows-клиентов не забывайте использовать в файлах конфигурации двойные бэкслэши вместо одинарных слэшей, используемых в файлах конфигурации Unix-клиентов.
Файл конфигурации клиентского программного обеспечения
Конфигурация клиента OpenVPN хранится в файле openvpn.conf, который должен находится в папке /usr/local/etc/openvpn, если мы имеем дело с FreeBSD-клиентом, или в файле с произвольным именем и расширением .ovpn, который должен находиться в папке C:\Program Files\OpenVPN\config, если при установке OpenVPN (OpenVPN GUI) не был задан путь, отличный от предлагаемого по умолчанию. Рассмотрим файл конфигурации клиента client3, установленного на ноутбук с Windows XP. Клиент OpenVPN GUI установлен в каталог по умолчанию, а ключевые файлы, которые ранее были переписаны на дискету, сохранены на диске P: в папке OpenVPN (я предпочитаю шифровать этот диск). Для рассматриваемого случая файл конфигурация клиента OpenVPN имеет следующий вид:
client dev tun proto udp remote <IP-адрес сервера OpenVPN> tls-client tls-remote <FQDN сервера OpenVPN> ca "P:\\OpenVPN\\CA_cert.pem" cert "P:\\OpenVPN\\Ссlient3.pem" key "P:\\OpenVPN\\Kсlient3.pem" tls-auth "P:\\OpenVPN\\ta.key" 1 ns-cert-type server comp-lzo tun-mtu 1500 mssfix 1450 verb 3
В данном файле заданы следующие значения параметров клиента OpenVPN: client - упрощенный вариант указания того, что это файл конфигурации клиента, dev - устройство OpenVPN, proto - протокол (в данном случае UDP), remote - IP-адрес сервера OpenVPN, tls-client - включение поддержки TLS, tls-remote - Common Name сервера OpenVPN, ca - местонахождение самоподписного доверенного сертификата (CA), cert - местонахождение сертификата клиента, key - местонахождение закрытого ключа клиента, tls-auth - местонахождение статического ключа HMAC, comp-lzo, tun-mtu, mssfix и verb рассмотрены выше. Еще раз повторю, что файлы конфигурации FreeBSD-клиентов отличаются только форматом задания путей к файлам и именами файлов, содержащих сертификаты и закрытые ключи.
Заключение
С помощью описанной виртуальной частной сети ежедневно осуществляется работа с такими службами, как Remote Administrator, Wndows Terminal Services, OpenSSH, Telnet и т.д. Если в процессе настройки у Вас возникнут какие-либо проблемы, задавайте мне вопросы, внимательно анализируйте лог-файлы и читайте Форум OpenNET.