Организация VPN доступа с помощью OpenVPN

Понадобилось организовать VPN сервер, для подключения сотрудников из дома в RDP сессии к своим компьютерам на работе. Для решения подходит OpenVPN. Было решено использовать стоящий в DMZ с реальным внешним адресом сервисный сервер, имеющий один интерфейс.
В качестве виртуальной vpn-сети используем 192.168.33.0/24 (Здесь необходимо обратить внимание на то, что OpenVPN поддерживает для создания виртуальных сетей только приватные адресные пространства, как то 192.168.0.0, 10.0.0.0, 172.16... Произвольные значения не работают). Локальная сеть имеет тривиальную адресацию 192.168.1.0/24.
Так как сервер имеет только один интерфейс, то его маршрутизатор должен знать, что все пакеты для 192.168.33.0/24 нужно отправлять на реальный IP-фдрес vpn-сервера. Сам vpn-сервер будет пробрасывать эти пакеты в виртуальную vpn-сеть.
У меня в качестве центрельного маршрутизатора выступает cisco, мне было достаточно добавить один маршрут:
ip route 192.168.33.0 255.255.255.0 78.109.91.136

Так же в /etc/rc.conf необходимо добавить опцию маршрутизации пакетов между интерфейсами vpn-сервера, иначе пакеты из виртуальной сети в реальную и обратно ходить не будут:
gateway_enable="YES"

Устанавливаем порт
/usr/ports/securitu/openvpn
make
make install
make clean
rehash

Идем в каталог /usr/local/share/doc/openvpn/easy-rsa/ и делаем все скрипты в корне этого каталога запускаемые, присвоим им бит исполняемых.

Правим файл vars поставив значения переменных так:
export KEY_DIR=D$/keys/server
export KEY_COUNTRY=RU
export KEY_PROVINCE=MO
export KEY_CITY=MOSCOW
export KEY_ORG="myvpnserver.mydomain.ru"
export KEY_EMAIL="vpnadmin@mydomain.ru"
Значения страны, региона, города, сервера, почты нужно, по понятным причинам поставить свои.

Оставаясь в директории /usr/local/share/doc/openvpn/easy-rsa/ меняем оболочку на sh (в любом случае, даже если по умолчанию уже sh)
#sh

Исполняем скрипт vars
#. ./vars
Точка с пробелом перед ./vars обязательны!
Получаем ответ об успешной отработке скрипта:
NOTE: when you run ./clean-all, I will be doing a rm -rf on /usr/local/share/doc/openvpn/easy-rsa/keys/server

Далее, не смотря на отсутствие ключей при первой установке, рекомендуется сделать команду очистки ключей:
#./clean-all
в директории /keys/server должны остаться только index.txt и serial (если их нет, то нужно создать вручную 644 root:wheel. Файлы пустые.)

Генерируем ключ корневого сервера сертификации (Certificate Authority) ca.key:
#./build-ca

Здесь нам пригодятся те переменные, которые мы заранее определили в vars - значения по умолчанию берутся из vars, и их можно не вводить.
На запрос Common Name нужно ввести имя сервера, на котором развертываем vpn. Я предпочитаю использовать FQDN. Получаем вот такой диалог:
Generating a 1024 bit RSA private key
........++++++
...++++++
writing new private key to 'ca.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [RU]:
State or Province Name (full name) [MO]:
Locality Name (eg, city) [MOSCOW]:
Organization Name (eg, company) [myvpnserver.mydomain.ru]:
Organizational Unit Name (eg, section) []:IT
Common Name (eg, your name or your server's hostname) []:myvpnserver.mydomain.ru
Email Address [vpnadmin@mydomain.ru]:

в директории /keys/server появились сертификат и ключ корневого сервера сертификации ca.crt и ca.key

Создаем самоподписанный сертификат X.509 для подписывающего сервера (в нашем вырожденном случае это один и тот же сервер). Common Name так же заполняем именем сервера vpn, да и остальные значения как и при генерации корневого сертификата. В дополнительных параметрах нужно будет указать challenge password (любой, желательно его запомнить):
#./build-key-server server
диалог:

Generating a 1024 bit RSA private key
..................................++++++
................................++++++
writing new private key to 'server.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [RU]:
State or Province Name (full name) [MO]:
Locality Name (eg, city) [MOSCOW]:
Organization Name (eg, company) [myvpnserver.mydomain.ru]:
Organizational Unit Name (eg, section) []:IT
Common Name (eg, your name or your server's hostname) []:myvpnserver.mydomain.ru
Email Address [vpnadmin@mydomain.ru]:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:superchallengepassword
An optional company name []:MYCOMPANY
Using configuration from /usr/local/share/doc/openvpn/easy-rsa/openssl.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName :PRINTABLE:'RU'
stateOrProvinceName :PRINTABLE:'MO'
localityName :PRINTABLE:'MOSCOW'
organizationName :PRINTABLE:'myvpnserver.mydomain.ru'
organizationalUnitName:PRINTABLE:'IT'
commonName :PRINTABLE:'myvpnserver.mydomain.ru'
emailAddress :IA5STRING:'vpnadmin@mydomain.ru'
Certificate is to be certified until Jan 17 09:48:37 2020 GMT (3650 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

Хранилище сертификатов /keys/server пополняется запросами, ключами и сертификатами подписывающего сервера сертификации:
01.pem
server.crt
server.csr
server.key
а в index.txt появляется запись о сгенерированном ключе, значение serial увеличивается на 1.

Теперь генерируем ключи для клиента, заполняя поля точно так же, однако на этот раз Common Name - заполняем именем клиента (можно любое, главное уникальное. Я пользуюсь так же FQDN):
#./build-key client
Диалог:
Generating a 1024 bit RSA private key
...........................++++++
........................++++++
writing new private key to 'client.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [RU]:
State or Province Name (full name) [MO]:
Locality Name (eg, city) [MOSCOW]:
Organization Name (eg, company) [myvpnserver.mydomain.ru]:
Organizational Unit Name (eg, section) []:IT
Common Name (eg, your name or your server's hostname) []:myclient.provider.ru
Email Address [vpnadmin@mydomain.ru]:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:superchallengepassword
An optional company name []:MYCOMPANY
Using configuration from /usr/local/share/doc/openvpn/easy-rsa/openssl.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName :PRINTABLE:'RU'
stateOrProvinceName :PRINTABLE:'MO'
localityName :PRINTABLE:'MOSCOW'
organizationName :PRINTABLE:'myvpnserver.mydomain.ru'
organizationalUnitName:PRINTABLE:'IT'
commonName :PRINTABLE:'myclient.provider.ru'
emailAddress :IA5STRING:'vpnadmin@mydomain.ru'
Certificate is to be certified until Jan 17 09:58:01 2020 GMT (3650 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

Видим так же в хранилище новые сертификаты, ключи. Видим что serial еще увеличился на 1, а index.txt пополнила запись о выданном сертификате клиента.
Файлы клиента в директории /keys/server:
02.pem
client.crt
client.csr
client.key

Создаем ключ Диффи-Хеллмана
#./build-dh
Видим примерно следующий отчет о генерации случайного ключа:

Generating DH parameters, 1024 bit long safe prime, generator 2
This is going to take a long time
...+......................+.......................................+.......................+...................+......+...........................................................+.......................................+.............+.....................................................................+..............+....................................................................................................................................................+........+............................................................++*++*++*

В директории /keys/server появится ключ:
dh1024.pem

Выходим из sh
#exit
пригласительная строка сменится на стандартную. У меня это sh: vpnserver#

Генерируем ключ для tls-аутентификации (тогда обмен ключами клиента уже будет производиться по закрытому каналу):
openvpn --genkey --secret keys/server/ta.key
Видим, что он создался в директории /keys/server

Далее, нужно отдать нужные ключи серверу, и нужные ключи клиенту.
Создаем директории:
/usr/local/etc/openvpn
/usr/local/etc/openvpn/keys

В директорию /usr/local/etc/openvpn/keys копируем ключи сервера, DH и tls:
ca.crt
dh1024.pem
server.crt
server.key
ta.key

В директории /usr/local/etc/openvpn создаем конфигурационный серверный файл server.conf (по умолчанию это openvpn.conf, тогда можно в rc.conf не указывать опцию configfile):
port 32165
proto udp
dev tun0
ca /usr/local/etc/openvpn/keys/ca.crt
cert /usr/local/etc/openvpn/keys/server.crt
key /usr/local/etc/openvpn/keys/server.key
dh /usr/local/etc/openvpn/keys/dh1024.pem
server 192.168.33.0 255.255.255.0
push "route 192.168.3.0 255.255.255.0"
client-config-dir ccd
tls-server
tls-auth keys/ta.key 0
tls-timeout 120
auth MD5
cipher BF-CBC
keepalive 10 120
comp-lzo
max-clients 100
user nobody
group nobody
persist-key
persist-tun
status /var/log/openvpn/openvpn-status.log
log /var/log/openvpn/openvpn.log
verb 3

Каталоги и логфайлы из конфига так же необходимо создать вручную:
/var/log/openvpn/openvpn-status.log
/var/log/openvpn/openvpn.log

В etc/rc.conf добавляем записи для запуска сервера OpenVPN
openvpn_enable="YES"
openvpn_if="tun"
openvpn_dir="/usr/local/etc/openvpn"
openvpn_configfile="/usr/local/etc/openvpn/server.conf"

Теперь из хранилища ключей передаем ключи клиенту:
ca.crt
dh1024.pem
client.crt
client.key
ta.key
После их выдачи, нужно перенести в субконтейнер (я использую для каждого клиентского ключа отдельный произвольный каталог, например /usr/local/share/doc/openvpn/easy-rsa/keys/myclient1, myclient2 и т.д.) ключ, запрос и сертификат client.crt, client.csr, client.key, удалив их в исходном каталоге, ибо на их место при новой генерации будут созданы новые ключи клиента.
Новому клиенту так же передается та же связка, но со своим клиентским ключом client.key и сертификатом client.crt
Если вы передаете ключи не лично а через сеть (что не рекомендуется), не забывайте что на файлах ключей значение атрибутов 600, и не каждый их может прочитать.

Настраиваем клиента Windows.
Качаем OpenVPN клиент, например отсюда: http://openvpn.se/download.html
Устанавливаем все по умолчанию.
Создаем конфигурационный файл openvpn.ovpn в папке config (по умолчанию C:\Program Files\OpenVPN\config):
dev tun
proto udp
remote 78.109.91.136
port 32165
client
resolv-retry infinite
ca ca.crt
cert client.crt
key client.key
tls-client
tls-auth ta.key 1
auth MD5
cipher BF-CBC
ns-cert-type server
comp-lzo
persist-key
persist-tun
verb 3

В эту же папку копируем полученный набор ключей и сертификатов
ca.crt
dh1024.pem
client.crt
client.key
ta.key

Запускаем OpenVPN GUI, правой кнопкой по иконке в трее - connect. Наблюдаем успешное рукопожатие клиента и сервера ключами и сертификатами, получаем туннельный интерфейс с IP из подсети 192.168.33.0/24 и наслаждаемся жизнью :)
OpenVPN работает.

Проверяем пинги и RDP коннекты на подсеть 192.168.1.0/24, убеждаемся что все ок.

Теперь, если мы хотим отозвать сертификаты, делаем это так:
В каталоге /usr/local/share/doc/easy-rsa
входим в sh, подгружаем vars и запускаем скрипт отзыва сертификата (необходимо помнить имя клиента, или его можно посмотреть в index.txt)
sh
#. ./vars
#./revoke-full myclient.provider.ru
Видим успешную операцию отзыва "Revoking Certificate ... Data Base Updated"
Получаем список отозванных сертификатов crl.pem в хранилище ключей, идем в конфиг /usr/local/etc/openvpn/server.conf и добавляем строку
crl-verify /usr/local/etc/openvpn/crl.pem
Копируем crl.pem из хранилища сертификатов в /usr/local/etc/openvpn/ и выставляем ему права 644 вместо 600 по умолчанию. Рестартуем OpenVPN сервер.

При создании статьи, использовался материал http://www.lissyara.su/articles/freebsd/security/openvpn/

Поделиться

Опубликовать в Facebook
Опубликовать в LiveJournal

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>