OpenVPN
OpenVPN
OpenVPN — свободная реализация технологии Виртуальной Частной Сети (VPN) с открытым исходным кодом для создания зашифрованных каналов типа точка-точка или сервер-клиенты между компьютерами. Она позволяет устанавливать соединения между компьютерами, находящимися за NAT-firewall, без необходимости изменения их настроек.
Варианты применения данной статьи
- Хотим соединить в одну виртуальную сеть несколько локальных сетей в офисах, географически расположенных в разных местах, посредством Интернета.
- Хотим иметь доступ в рабочую локальную сеть из дома или в поездке
- Имея сервер с белым IP есть желание выходить в сеть с этого IP (например если этот IP за пределами страны или сети, в которой блокируются определенные ресурсы в Интернете)
Исходные данные
Локальная сеть 1
192.168.1.0/24 192.168.1.1
Белый внешний IP (здесь будет сервер OpenVPN)
Внутренний IP сервера OpenVPN - 192.168.1.100
Локальная сеть 2
192.168.0.0/24 192.168.0.1
Динамический IP (или даже серый - не важно для клиента OpenVPN)
Внутренний IP клиента OpenVPN - 192.168.0.100. Клиент в данном случае будет являться шлюзом для устройств в своей подсети.
Настройка OpenVPN
Все действия проводятся с правами суперпользователя root.
sudo -i
Установка
И на сервере и на клиенте ставим один и тот же пакет.
apt-get install openvpn
Создание сервера
Создание ключей и сертификатов
Защита соединения в OpenVPN в данном случае строится на использовании сертификатов и ключей для сервера и для клиентов. Для их генерации в пакете OpenVPN имеются специальные скрипты, расположенные в /usr/share/doc/openvpn/examples/easy-rsa/2.0 Перед началом работы скопируем их, чтобы не изменять оригиналы.
(для 12.04 LTS)
mkdir /etc/openvpn/easy-rsa
cp -r /usr/share/doc/openvpn/examples/easy-rsa/2.0 /etc/openvpn/easy-rsa
(для 14.04 LTS) С лета 2013 года easy-rsa не входит в OpenVPN и команда указанная выше не сработает(не найдет easy-rsa), тогда делаем следующее:
apt-get install easy-rsa
mkdir /etc/openvpn/easy-rsa
cp -r /usr/share/easy-rsa /etc/openvpn/easy-rsa/2.0
Переходим в созданную директорию, где и займёмся генерацией ключей и сертификатов
cd /etc/openvpn/easy-rsa/2.0
Редактируем файл переменных
nano vars
Здесь можно заполнить например так:
# Почти в самом низу файла, заполняем информацию о сертификатах по умолчанию (ваши значения).
export KEY_COUNTRY="RU"
export KEY_PROVINCE="Amur Region"
export KEY_CITY="Blagoveschensk"
export KEY_ORG="Organization"
export KEY_EMAIL="vash@email.tut"
export KEY_OU="MyOrganizationalUnit"
# PKCS11 я не использовал, поэтому оставил без изменений. Кто шарит нафига эта штука, допишите статью.
export PKCS11_MODULE_PATH=changeme
export PKCS11_PIN=1234
#Добавить
export KEY_ALTNAMES="VPNsRUS"
копируем конфиг openssl
cp openssl-1.0.0.cnf openssl.cnf
Загружаем переменные
source ./vars
Очищаем от старых сертификатов и ключей папку keys и создаем серийный и индексные файлы для новых ключей
./clean-all
Создаем сертификат. По умолчанию поля будут заполняться данными, введенными ранее в vars, поэтому можно ничего не менять.
./build-ca
Создаем ключ сервера
A challenge password []: Если вы решили ввести challenge password, то необходимо убедиться, что сохранили этот пароль в безопасном месте. Если вам понадобится когда-нибудь переустановить этот сертификат, то потребуется ввести этот пароль снова.
./build-key-server server
В конце соглашаемся с запросом на подпись и добавление сертификата в базу.
Можно сразу создать ключи для клиента, перейдя в соответствующую часть статьи. Я вынес в отдельный раздел, т.к. ключи клиента могут генерироваться не один раз, чтобы было понятнее с чего начать в том случае когда нужно добавить клиента
Создаем ключ Диффи-Хеллмана
./build-dh
Cоздаем ключ для tls-аутификации
openvpn --genkey --secret keys/ta.key
Перемещаем сертификаты
cp -r /etc/openvpn/easy-rsa/2.0/keys/ /etc/openvpn/
Создание файла конфигурации сервера
cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/
cd /etc/openvpn
gunzip -d /etc/openvpn/server.conf.gz
nano /etc/openvpn/server.conf
port 1194
# Протокол может быть UDP или TCP, я выбрал 1-й вариант.
proto udp
# Если вы выберите протокол TCP, здесь должно быть устройство tap. Однако, это вариант я не проверял, поэтому ищите информацию отдельно. FIXME
dev tun
# Указываем где искать ключи
ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/server.crt
key /etc/openvpn/keys/server.key # This file should be kept secret
dh /etc/openvpn/keys/dh2048.pem
# Для 12.04 dh1024.pem
# Задаем IP и маску виртуальной сети. Произвольно, но если не уверены лучше делайте как показано здесь
server 10.8.0.0 255.255.255.0
# Указыем, где хранятся файлы с настройками IP-адресов клиентов (создадим ниже)
client-config-dir ccd
# Запоминать динамически выданные адреса для VPN-клиентов и при последующих подключениях назначать те же значения.
ifconfig-pool-persist ipp.txt
# Указываем сети, в которые нужно идти через туннель (сеть-клиента).
route 192.168.0.0 255.255.255.0
# Включаем TLS
tls-server
tls-auth /etc/openvpn/keys/ta.key 0
tls-timeout 120
auth SHA1
cipher AES-256-CBC
# Если нужно, чтобы клиенты видели друг друга раскомментируйте
;client-to-client
keepalive 10 120
# Сжатие трафика
comp-lzo
# Максимум клиентов
max-clients 10
user nobody
group nogroup
# Не перечитывать ключи, не закрывать и переоткрывать TUN\TAP устройство, после получения SIGUSR1 или ping-restart
persist-key
persist-tun
status openvpn-status.log
log /var/log/openvpn.log
# Детальность логирования
verb 3
# Защита от повторов (максимум 20 одинаковых сообщений подряд)
mute 20
# Файл отозванных сертификатов. Разремить, когда такие сертификаты появятся.
;crl-verify /etc/openvpn/crl.pem
Создадим директорию для клиентских конфигов
mkdir /etc/openvpn/ccd
Можно запускать наш сервер OpenVPN
service openvpn restart
Смотрим список интерфейсов
ifconfig
Если среди прочих видим
tun0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
inet addr:10.8.0.1 P-t-P:10.8.0.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)
значит VPN-сервер завелся. Если нет, то смотрим лог
tail -f /var/log/openvpn.log
Настройка маршрутизации на стороне сервера
Если сервер имеет «белый» IP то никакой маршрутизации на стороне сервера настраивать не нужно. Если сервер находится в локальной сети за NAT роутера то необходимо настроить маршрутизацию.
Для того, чтобы клиенты могли достучаться до сервера нужно пробросить порты с роутера на сервер. В разных моделях это делается по разному. Суть в том, чтобы стучась на внешний порт, например 12345 1 ), клиенты попадали на порт OpenVPN-сервера 1194 (или другой, который мы задали для нашего сервера). Кроме того устройствам в локальной сети нужно сообщить, что для доступа к сети за OpenVPN-сервером нужно обращаться к нему. Но проще задать этот маршрут на роутере, который обслуживает локалку.
Создаем файл в каталоге ccd с тем же именем, что и ключ для клиента, т.е. /etc/openvpn/ccd/client
# Маршрут в сеть клиента. Требуется для доступа к сетевым устройствам в сети клиента. Если не требуется - не прописывайте.
iroute 192.168.0.0 255.255.255.0
# Задаем маршрут для клиента, чтобы он видел сеть за OpenVPN-сервером.
push "route 192.168.1.0 255.255.255.0"
Включаем ipv4_forwarding
В /etc/sysctl.conf расскомментируем #net.ipv4.ip_forward=1 после чего
sysctl -p
Создание клиента
Создание ключей и сертификатов
Ключи клиента создаются на сервере
Переходим в созданную директорию, где и замёмся генерацией ключей и сертификатов
cd /etc/openvpn/easy-rsa/2.0
Загружаем переменные
source vars
Создаем ключ клиента
В данном случае название ключа - client. Каждый ключ должен быть со своим именем.
./build-key client
Если хотим защитить ключ паролем, то генерируем его другой командой
./build-key-pass client
В этом случае при запуске соединения нужно будет каждый раз вводить пароль на ключ.
Теперь нужно не забыть скопировать ключи (ca.crt, client.crt, client.key, ta.key) на клиента OpenVPN в /etc/openvpn/keys/
Создание файла конфигурации клиента
/etc/openvpn/client.conf
client
dev tun
proto udp
# Внеший IP, на или за которым находится ваш сервер OpenVPN и порт (на сервере или роутере, за которым стоит сервер)
remote 111.222.333.444 1194
# необходимо для DynDNS
resolv-retry infinite
ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/client.crt
key /etc/openvpn/keys/client.key
tls-client
tls-auth /etc/openvpn/keys/ta.key 1
auth SHA1
cipher AES-256-CBC
remote-cert-tls server
comp-lzo
persist-key
persist-tun
status openvpn-status.log
log /var/log/openvpn.log
verb 3
mute 20
Можно запускать наш клиент OpenVPN
service openvpn restart
Настройка маршрутизации на стороне клиента
Машина с openvpn уже готова работать с сервером в чём можно убедится
ping -c 2 10.8.0.1
ping -c 2 192.168.1.100
Но для того, чтобы пользоваться туннелем в другой офис могли другие устройства в локальной сети нужно указать им, чтобы доступ в подсеть 192.168.1.0/24 осуществляется через 192.168.0.100. Или, что часто проще и быстрее прописать это правило маршрутизации на роутере, который является шлюзом для устройств в сети.
Включаем ipv4_forwarding
Также как в случае с сервером.
Настройка выхода в интернет с IP сервера
Если ваши цели были - только организовать VPN сеть или соединится с изолированной сетью (например из дома с локальной сетью на работе), то эта часть статьи вам не нужна.
Настройки сервера
Если же вы хотите организовать доступ из VPN сети в интернет с IP адреса сервера, то вам нужно настроить на сервере NAT. Сделать это можно следующей командой (на сервере):
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
Здесь мы указали, что сеть 10.8.0.0/24 будет выходить наружу через интерфейс eth0.
Для того что бы настройки iptables сохранились после перезагрузки нужно их дополнительно сохранить:
iptables-save > /etc/iptables.up.rules
echo "pre-up iptables-restore < /etc/iptables.up.rules" >> /etc/network/interfaces
Настройки клиента
К конфиге клиента client.conf нужно добавить строчку
redirect-gateway def1
Отзыв сертификата
cd /etc/openvpn/easy-rsa/2.0
. ./vars
./revoke-full client2
Если все прошло штатно вы должны увидеть следующий вывод, сообщающий о том, что сертификат отозван:
error 23 at 0 depth lookup:certificate revoked
Скрипт revoke-full создаст CRL-файл (certificate revocation list, список отозванных сертификатов) с именем crl.pem в подкаталоге keys. Файл должен быть скопирован в каталог, в котором сервер OpenVPN может получить к нему доступ. Ранее в конфиге мы прописали, что этот файл должен находится в /etc/openvpn, туда и копируем.
Отключение автозапуска OpenVPN
Это бывает полезно, например для клиента с ключем защищенным паролем, т.к. всё равно при старте системы такое соединение не поднимется в виду отсутствия пароля для ключа. Да и в том случае, если вы сделали ключ с паролем, значит, скорее всего, вам не нужно постоянное соединение.
nano /etc/default/openvpn
Раскомментируем строчку
AUTOSTART="none"
Тест производительности OpenVPN
Условия теста:
- VPN-сервер на ВМ Virtualbox (1 ядро i5-4670)
- Сеть гигабит (без шифрования последовательная скорость передачи 120 МБ/с). Скорость буду указывать в мегабайтах, НЕ в мегабитах!
- Форвардинг на хоста
- Клиент Windows 7, OpenVPN 2.3 64, FX-6300
Результаты:
- Скорость всегда упиралась в ВМ, где процессор бы полностью занят. ЦП клиента был загружен не более 10% - 40% на 1/6 ядер.
- С конфигом выше - 14 МБ/с
- Отключаем сжатие ;comp-lzo - прибавка не более 1 МБ/с - до 15 МБ/с
- Отключаем аутентификацию auth none +2 МБ/с - до 17 МБ/с
- Отключаем шифрование cipher none +2 МБ/с - до 19 МБ/с
- Сжатие comp-lzo сжимает хорошо сжимаемые файлы в 2 раза хуже, чем zlib, зато почти не влияет не загрузку ЦП (в десятки раз быстрее). Проверял на копировании установленного в Windows Libreoffice 5. Сжатие в zip с помощью архиватора 7z дало результат около 35%, сжатие comp-lzo по статистике сетевого интерфейса - около 70%.
Максимальный прирост при отключении сжатия, шифрования и аутентификации составил около 35%. Не думаю, что это стоит того, чтобы отключать механизмы защиты, но ситуации бывают разные.
Может кому-то как мне будет интересно влияние опций на производительность и не придется тратить время на проведение замеров, хотя я бы с удовольствием ознакомился с результами других людей. Изначально тестил для себя, поэтому точных замеров не проводил, потом решил поделиться результатами.
Источники
http://www.lissyara.su/articles/freebsd/security/openvpn_via_nat/
http://lithium.opennet.ru/articles/openvpn/openvpn-howto.html
http://firstwiki.ru/index.php/%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_OpenVPN
https://serverfault.com/questions/266232/what-is-a-challenge-password