Апр 022014
 

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

 uname -a
FreeBSD slik.loc 9.2-RELEASE FreeBSD 9.2-RELEASE #1: Tue Feb 18 12:08:12 EET 2014     slik@slik.loc:/usr/obj/usr/src/sys/SLIK  i386

Приступаем к установке openvpn

cd /usr/ports/security/openvpn/ && make install clean

После установки OpenVPN приступаем к конфигурации.

cd /usr/local/share/doc/openvpn/easy-rsa/2.0/

Для начала сделаем правку в файле vars, приводим его к такому состоянию.

# Меняем export KEY_DIR="$EASY_RSA/keys" на
export KEY_DIR="$EASY_RSA/keys/server"
# меняем export KEY_SIZE=1024 на 2048
# (увеличим размер ключей с 1024 бит до 2048 бит)
export KEY_SIZE=2048

Немного поправим права на скрипты.

chmod 544 *

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

mkdir -p keys/server

Запускаем shell

#sh
#. ./vars

Нам сказали что необходимо все почистить в папке server, что мы и делаем.
Один очень важный момент, команда ./clean-all удаляет все ранее созданные ключи и сертификаты, будьте осторожны!

./clean-all

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

# ./build-ca
Generating a 2048 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) [US]:UA
State or Province Name (full name) [CA]:Kyiv
Locality Name (eg, city) [SanFrancisco]:Kyiv
Organization Name (eg, company) [Fort-Funston]:server
Organizational Unit Name (eg, section) [changeme]:server
Common Name (eg, your name or your server's hostname) [changeme]:server
Name [changeme]:
Email Address [mail@host.domain]:admin@slik45.kiev.ua
#


Далее создаем для сервера сертификат X.509
Заполняем все аналогично сертификату, но для большей безопастности еще можно указать пароль, об этом чуть ниже напишу.

# ./build-key-server server
Generating a 2048 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) [US]:UA
State or Province Name (full name) [CA]:Kyiv
Locality Name (eg, city) [SanFrancisco]:Kyiv
Organization Name (eg, company) [Fort-Funston]:server
Organizational Unit Name (eg, section) [changeme]:server
Common Name (eg, your name or your server's hostname) [server]:server
Name [changeme]:
Email Address [mail@host.domain]:admin@slik45.kiev.ua

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:server
Using configuration from /usr/local/share/doc/openvpn/easy-rsa/openssl-0.9.8.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName            PRINTABLE:'UA'
stateOrProvinceName    PRINTABLE:'Kyiv'
localityName           PRINTABLE:'Kyiv'
organizationName       PRINTABLE:'server'
organizationalUnitName PRINTABLE:'server'
commonName             PRINTABLE:'server'
name                   PRINTABLE:'changeme'
emailAddress           IA5STRING:'admin@slik45.kiev.ua'
Certificate is to be certified until Mar 30 10:14:47 2024 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

Создаем ключ для клиента.

# ./build-key slik
Generating a 2048 bit RSA private key
...................+++
....+++
writing new private key to 'slik.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) [US]:UA
State or Province Name (full name) [CA]:Kyiv
Locality Name (eg, city) [SanFrancisco]:Kyiv
Organization Name (eg, company) [Fort-Funston]:server
Organizational Unit Name (eg, section) [changeme]:server
Common Name (eg, your name or your server's hostname) [slik]:slik
Name [changeme]:
Email Address [mail@host.domain]:admin@slik45.kiev.ua

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:slik
Using configuration from /usr/local/share/doc/openvpn/easy-rsa/openssl-0.9.8.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName            PRINTABLE:'UA'
stateOrProvinceName    PRINTABLE:'Kyiv'
localityName           PRINTABLE:'Kyiv'
organizationName       PRINTABLE:'server'
organizationalUnitName PRINTABLE:'server'
commonName             PRINTABLE:'slik'
name                   PRINTABLE:'changeme'
emailAddress           IA5STRING:'admin@slik45.kiev.ua'
Certificate is to be certified until Mar 30 10:32:55 2024 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

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

Далее создаем ключ Диффи Хельман, на слабых серверах процесс создания ключа занимает прилично времени 🙂

# ./build-dh

Вот мой вывод top в момент создания ключа.

last pid: 94759;  load averages:  0.38,  0.11,  0.08                                                                                                                                                 up 3+23:38:08  13:38:37
193 processes: 4 running, 170 sleeping, 19 waiting
CPU: 51.6% user,  0.0% nice,  4.1% system,  1.4% interrupt, 42.9% idle
Mem: 663M Active, 2244M Inact, 202M Wired, 47M Cache, 89M Buf, 221M Free
Swap: 8075M Total, 2944K Used, 8072M Free

  PID USERNAME      THR PRI NICE   SIZE    RES STATE   C   TIME   WCPU COMMAND
   11 root            2 171 ki31     0K    16K RUN     1 181.2H 103.76% idle
94757 root            1 115    0 11108K  3168K CPU1    1   0:23 87.26% openssl

После создания ключа Диффи Хельман выходим из sh написав команду exit
В завершении создаем ключ для tls-аутификации

openvpn --genkey --secret keys/server/ta.key

После того как закончили создавать ключи и сертификаты, в папке keys/server у нас получилось много файлов.

ca.crt - Главный CA сертификат, этот файл нужен и клиенту и серверу
dh1024.pem - ключ Диффи Хельман, этот файл нужен только серверу
server.crt - Сертификат сервера, нужен только серверу
server.key - Ключ сервера, нужен только серверу (СЕКРЕТНЫЙ файл)
slik.crt - Сертификат клиента, нужен только клиенту
slik.key - Ключ клиента, нужен только клиенту (СЕКРЕТНЫЙ файл)
ta.key - TLS-ключ, нужен и клиенту и серверу

Серверу достаются файлы следующие файлы

ca.crt
dh1024.pem
server.crt
server.key
ta.key

Клиенту

ca.crt
dh1024.pem
slik.crt
slik.key
ta.key

Большую часть работы мы уже сделали 🙂
Приступаем к настройке сервера и клиента.

Создаем директории на сервере для наших ключей

mkdir /usr/local/etc/openvpn
mkdir /usr/local/etc/openvpn/keys
mkdir /usr/local/etc/openvpn/ccd

Для удобства копируем ключи сервера в папку keys на сервере

ca.crt
dh1024.pem
server.crt
server.key
ta.key

Клиенту достаются файлы следующие файлы, копируем их так же в папку keys

ca.crt
dh1024.pem
slik.crt
slik.key
ta.key

Создаем конфигурационный файл server.conf


#порт на котором работает сервер
port 8080
# протокол - советую udp
proto udp
# - используемый тип устройства и номер 
dev tun0
#указываем файл CA
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
#задаем IP-адрес сервера и маску подсети
# (виртуальной сети) - можно произвольную, (я выбрал такую)
server 172.16.0.0 255.255.255.0
#задаем МАРШРУТ который передаём клиентту
# и маску подсети для того чтобы он "видел"
# сеть за опенвпн сервером (сеть 192.168.0.0/24)
push "route 192.168.0.0 255.255.255.0"
# указываем где хранятся файлы с
# настройками IP-адресов клиентов
client-config-dir ccd
# добавляем маршрут сервер-клиент
route 172.16.0.0 255.255.255.252
# этой строкой описываем маршруты к сетям к которым ходить
# через тунель!!!!!(в данном случае к сети в филиале)
route 192.168.1.0 255.255.255.0
# включаем TLS аутификацию
tls-server
# указываем tls-ключ, и указываем 0 для сервера, а 1 для клиента
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
# Не перечитывать ключи после получения
# SIGUSR1 или ping-restart
persist-key
# Не закрывать и переоткрывать TUN\TAP
# устройство, после получения
# SIGUSR1 или ping-restart
persist-tun
# логирование (не забудьте создать эту дирректорию /var/log/openvpn/)
status /var/log/openvpn/openvpn-status.log
log /var/log/openvpn/openvpn.log
# Уровень информации для отладки
verb 4

В папке /usr/local/etc/openvpn/ccd на сервере создаем файл slik (имя файла — имя которому выдан сертификат) следующего содержания

ifconfig-push 172.16.0.2 172.16.0.1
iroute 192.168.0.0  255.255.255.0

Мы выдали клиенту с сертификатом slik.crt виртуальный ип 172.16.0.2, шлюз 172.16.0.1 и указали маршрут через туннель к сети за клиентом.
Сервер готов!
Правим rc.conf для автостарта до такого состояния

openvpn_enable="YES"
openvpn_if="tun"
openvpn_configfile="/usr/local/etc/openvpn/server.conf"
openvpn_dir="/usr/local/etc/openvpn"

После всех манипуляций, запускаем сервер и проверяем его работу.

# /usr/local/etc/rc.d/openvpn start
Starting openvpn.

# ps aux|grep open
nobody     95892   0.0  0.1  11232   3540 ??  Ss    2:34PM     0:00.00 /usr/local/sbin/openvpn --cd /usr/local/etc/openvpn --daemon openvpn --config /usr/local/etc/openvpn/server.conf --writepid /var/run/openvpn.pid
root       95928   0.0  0.0   9632   1496  3  S+    2:35PM     0:00.00 grep open

Теперь переходим на клиента, и создаем файл конфигурации клиента.
На клиенте у меня тоже Freebsd

 uname -a
FreeBSD gw.slik.local 9.2-RELEASE-p1 FreeBSD 9.2-RELEASE-p1 #0 r258341: Wed Nov 20 10:15:57 EET 2013     slik@gw.slik.local:/usr/obj/usr/src/sys/GW  amd64

Вот что у меня получилось в файле client.conf

 cat client.conf
dev tun
proto udp
remote 10.10.10.10 # реальный айпи вашего сервера
port 8080 #порт к которому устанавливать соединение
client
resolv-retry infinite
ca keys/ca.crt
cert keys/slik.crt
key keys/slik.key
tls-client
tls-auth keys/ta.key 1
auth MD5
cipher BF-CBC
ns-cert-type server
comp-lzo
persist-key
persist-tun

#proxy 192.168.0.1:3128
#Добавьте эту строку если добрый провайдер фильтрует
# прямое соединение, благо Openvpn умеет работать
#через прокси, где 192.168.0.1:3128 - адрес и порт прокси-сервера
# логирование (не забудьте создать эту директорию /var/log/openvpn/)

status /var/log/openvpn/openvpn-status.log
log /var/log/openvpn/openvpn.log
verb 4

После чего на клиенте запускаем OpenVPN

# /usr/local/etc/rc.d/openvpn start
Starting openvpn.
# ps aux|grep open
root 49523   0,0  0,2  18276  3980 ??  Ss   14:35        0:00,00 /usr/local/sbin/openvpn --cd /usr/local/etc/openvpn --daemon openvpn --config /usr/local/etc/openvpn/client.conf --writepid /var/run/op
root 49525   0,0  0,1  16288  1764  1  S+   14:35        0:00,00 grep open

На этом установка OpenVPN завершена.
Проверим пинги между клиентом и сервером

ping 172.16.0.1
PING 172.16.0.1 (172.16.0.1): 56 data bytes
64 bytes from 172.16.0.1: icmp_seq=0 ttl=64 time=1.783 ms
64 bytes from 172.16.0.1: icmp_seq=1 ttl=64 time=1.917 ms
64 bytes from 172.16.0.1: icmp_seq=2 ttl=64 time=1.860 ms
64 bytes from 172.16.0.1: icmp_seq=3 ttl=64 time=1.553 ms
64 bytes from 172.16.0.1: icmp_seq=4 ttl=64 time=1.917 ms
^C

и с сервера на клиента

 ping 172.16.0.6
PING 172.16.0.6 (172.16.0.6): 56 data bytes
64 bytes from 172.16.0.6: icmp_seq=0 ttl=64 time=1.654 ms
64 bytes from 172.16.0.6: icmp_seq=1 ttl=64 time=2.016 ms
64 bytes from 172.16.0.6: icmp_seq=2 ttl=64 time=1.635 ms
64 bytes from 172.16.0.6: icmp_seq=3 ttl=64 time=2.816 ms
64 bytes from 172.16.0.6: icmp_seq=4 ttl=64 time=1.731 ms
^C
--- 172.16.0.6 ping statistics ---
5 packets transmitted, 5 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 1.635/1.970/2.816/0.444 ms

Как видим, у нас все работает отлично.
На этом все 🙂