Создание сервера OpenVPN в Linux
Пример создания сервера OpenVPN в Linux с полным заворотом трафика пользователя на сервер.
Настройка серверной части проводилась на CentOS 5.3, но инструкции и конфигурационные файлы подойдут для любого дистрибутива.
Серверная часть.
Установка
Для быстрой передачи данных OpenVPN использует сжатие трафика посредством библиотеки lzo.
Еще до сборки openvpn необходимо скачать и устанавить библиотеку lzo:
wget http://www.oberhumer.com/opensource/lzo/download/lzo-2.03.tar.gz
tar zxvf lzo-2.03.tar.gz
cd lzo-2.03/
./configure
make
make install
Переходим к установке OpenVPN.
Скачиваем и устанавливаем последнюю стабильную версию из исходников:
wget http://openvpn.net/release/openvpn-2.0.9.tar.gz
tar zxvf openvpn-2.0.9.tar.gz
cd openvpn-2.0.9/
./configure
make
make install
Для простой генерации ключей и сертификатов в пакете с исходниками openvpn-2.0.9.tar.gz находится каталог со скриптами easy-rsa.
Копируем его:
mkdir -p /usr/share/doc/openvpn
cp -R easy-rsa /usr/share/doc/openvpn/
Генерируем ключи и сертификаты:
cd /usr/share/doc/openvpn/easy-rsa
открываем файл с переменными vars:
vi vars
Добавляем к export KEY_DIR=$D/keys еще и каталог server (в него будут складывается ключи и сертификаты)
Должно получится так:
export KEY_DIR=$D/keys/server
Если кто-то параноик, то можно увеличить длину ключа. По умолчанию стоит длина 1024 и этого вполне достаточно.
Длина ключа определяется в export KEY_SIZE=1024, соответственно по желанию можно поставить 2048 (на скорости работы практически не отражается.)
Создаем каталог key и в нем каталог server:
mkdir -p keys/server
. ./vars
Создаем сертификат.
chmod +x build-ca
./build-ca
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) [KG]:RU
State or Province Name (full name) [NA]:Samara
Locality Name (eg, city) [BISHKEK]:Samara
Organization Name (eg, company) [OpenVPN-TEST]:server
Organizational Unit Name (eg, section) []:server
Common Name (eg, your name or your server's hostname) []:server
Email Address [me@myhost.mydomain]:root@localhost
Жирным шрифтом выделены те данные, которые я вводил.
Создаем файлы index.txt и serial:
touch /usr/share/doc/openvpn/easy-rsa/keys/server/index.txt
echo "00" > /usr/share/doc/openvpn/easy-rsa/keys/server/serial
Затем создаем сертификат и ключ для сервера:
chmod +x build-key-server
./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) [KG]:RU
State or Province Name (full name) [NA]:Samara
Locality Name (eg, city) [BISHKEK]:Samara
Organization Name (eg, company) [OpenVPN-TEST]:server
Organizational Unit Name (eg, section) []:server
Common Name (eg, your name or your server's hostname) []:server
Email Address [me@myhost.mydomain]:root@localhost
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:mypassword
An optional company name []:server
Using configuration from /usr/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:'Samara'
localityName :PRINTABLE:'Samara'
organizationName :PRINTABLE:'server'
organizationalUnitName :PRINTABLE:'server'
commonName :PRINTABLE:'server'
emailAddress :IA5STRING:'root@localhost'
Certificate is to be certified until Apr 8 09:19:02 2019 GMT (3650 days)
Sign the certificate? [y/n]:y
В конце будет предложено согласится с созданием сертификата. Жмем y.
Создаем ключ для клиента:
chmod +x build-key
./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) [KG]:RU
State or Province Name (full name) [NA]:Samara
Locality Name (eg, city) [BISHKEK]:Samara
Organization Name (eg, company) [OpenVPN-TEST]:server
Organizational Unit Name (eg, section) []:client
Common Name (eg, your name or your server's hostname) []:client
Email Address [me@myhost.mydomain]:root@localhost
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:mypassword
An optional company name []:client
Using configuration from /usr/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:'Samara'
localityName :PRINTABLE:'Samara'
organizationName :PRINTABLE:'server'
organizationalUnitName :PRINTABLE:'client'
commonName :PRINTABLE:'client'
emailAddress :IA5STRING:'root@localhost'
Certificate is to be certified until Apr 8 09:47:58 2019 GMT (3650 days)
Sign the certificate? [y/n]:y
Создаем ключ Диффи-Хелмана (необходим для безопасной авторизации двух сторон):
chmod +x build-dh
./build-dh
Generating DH parameters, 1024 bit long safe prime, generator 2
This is going to take a long time
.............+...........................................+...........
......................................................+..........+.
...+....+...+...................................................
....................................................................+.
........+.............................................................
.................................+....................................
.....................+....+...........+.................+........
.+..................................+.................................
...................++*++*++*
Создаем ключ для tls-аутентификации:
/usr/local/sbin/openvpn --genkey --secret keys/server/ta.key
Создаем каталог /etc/openvpn
mkdir /etc/openvpn
Затем создаем каталог keys в /etc/openvpn
mkdir /etc/openvpn/keys
В каталоге keys будут храниться сертификаты и ключи сервера.
Копируем необходимые ключи и сертификаты, которые мы сгенерировали ранее.
Для сервера это будут ca.crt, dh1024.pem, server.crt, server.key, ta.key:
cd /etc/openvpn/keys
cp /usr/share/doc/openvpn/easy-rsa/keys/server/ca.crt .
cp /usr/share/doc/openvpn/easy-rsa/keys/server/dh1024.pem .
cp /usr/share/doc/openvpn/easy-rsa/keys/server/server.crt .
cp /usr/share/doc/openvpn/easy-rsa/keys/server/server.key .
cp /usr/share/doc/openvpn/easy-rsa/keys/server/ta.key .
Создаем конфигурационный файл сервера:
touch /etc/openvpn/server.conf
vi /etc/openvpn/server.conf
А теперь по порядку:
# порт
port 2000
# протокол (как показывает практика, tcp работает медленнее udp, я соответственно делаю выбор за последним)
proto udp
# тип виртуального устройства и его номер
dev tun0
# указываем где лежат ключи и сертификаты сервера
ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/server.crt
key /etc/openvpn/keys/server.key
dh /etc/openvpn/keys/dh2048.pem
# задаем адрес виртуальной внутренней сети между сервером и клиентом
server 10.10.0.0 255.255.255.0
# заворачиваем весь трафик на сервер
push "redirect-gateway def1"
# вместо 111.111.111.111 указаваем адрес DNS сервера, который будет передаваться клиенту
push "dhcp-option DNS 111.111.111.111"
mode server
client-config-dir ccd
# включаем TLS аутентификацию
tls-server
# указываем tls-ключ, параметр 0 для сервера и 1 для клиента
tls-auth keys/ta.key 0
# таймаут до реконекта
tls-timeout 120
# алгоритм хэширования. MD5 устарел и для него уже сейчас за небольшой промежуток времени находят коллизии. Пора переходить на новый алгоритм SHA512, для которого коллизии наверняка не скоро появятся.
auth SHA512
# используем один из самых быстрых в программной реализации симметричных шифров - BlowFish
cipher BF-CBC
# указывем, что каждые 10 секунд пинговать удаленный хост и в случае если в течении 120 секунд не будет ответа, то разрывать соединение
keepalive 10 120
# включаем сжатие трафика
comp-lzo
# максимум клиентов
max-clients 10
# я считаю себя параноиком, поэтому к аутентификации по сертификатам я добавил еще и аутентификацию по паролю. Если вы не хотите использовать аутентикацию по паролю, то просто удалите данную строку и в клиентском конфиге аналогичную строку
plugin /usr/local/lib/openvpn-auth-pam.so login
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 3
Как я указывал выше, помимо сертификатов я еще использую и аутентификацию по паролю. Для этих целей я создаю пользователя в системе с шеллом /sbin/nologin, на случай если кто-то узнает пароль от пользователя, чтобы никто не смог войти под SSH.
Создадим пользователя vpn:
useradd -s /sbin/nologin -m -d /home/vpn -p PASSWORD vpn
Для аутентификации по паролю нам необходим модуль openvpn-auth-pam.so, для его сборки заходим в наш каталог с исходниками:
cd /home/fulltux/openvpn-2.0.9/plugin/auth-pam
для сборки необходим пакет pam-devel
yum install pam-devel
Собираем плагин openvpn-auth-pam.so:
make
Копируем собранный плагин в директорию с библиотеками:
cp /home/fulltux/openvpn-2.0.9/plugin/auth-pam/openvpn-auth-pam.so /usr/local/lib/
Криптоанализ после выбранных нами алгоритмов хеширования и шифрования практически невозможен, по крайней мере в наше время.
Добавление init-файла и добавление openvpn в автозагрузку.
Копируем из каталога с исходниками openvpn-2.0.9 файлик openvpn.init в каталог со всеми init-скриптами:
cp /home/fulltux/openvpn-2.0.9/sample-scripts/openvpn.init /etc/rc.d/init.d/openvpn
добавляем openvpn в автозагрузку:
chkconfig --add openvpn
Загружаем модуль tun:
modprobe tun
Пробуем запустить:
service openvpn start
Если по какой-то причине openvpn не запустился - смотрим в /var/log/messages.
Включаем форвардинг пакетов
В файле /etc/sysctl.conf
находим
net.ipv4.ip_forward = 0
и заменяем на
net.ipv4.ip_forward = 1
Переменные из /etc/sysctl.conf читаются при запуске системы. Для того, чтобы изменения вступили в силу до перезагрузки:
echo "1" > /proc/sys/net/ipv4/ip_forward
В фаервол iptables необходимо добавить правило для трансляции адресов NAT из виртуальной сети:
/sbin/iptables -t nat -A POSTROUTING -s 10.10.0.0/24 -j SNAT --to-source внешний_ip_сервера
О настройке iptables можно почитать тут.
На этом настройка серверной части закончена.
Настройка клиентской части
С сервера необходимо скопировать созданные ранее сертификаты, но не все, а только необходимые пользователю, а именно: ca.crt, client.crt, client.key, dh1024.pem, ta.key.
На клиентской системе создаем каталог, назовем его ovpn, а в нем каталог keys, где будут лежать файлы ca.crt, client.crt, client.key, dh1024.pem, ta.key.
mkdir ovpn
cd ovpn
mkdir keys
затем создадим конфигурационный файл client.ovpn
vi client.ovpn
следующего содержания:
dev tun
proto udp
remote 33.33.33.33 #(вместо 33.33.33.33 необходимо указать внешний IP вашего сервера)
port 2000 #(порт, к которому устанавливается соединение)
client
resolv-retry infinite
ca keys/ca.crt
cert keys/client.crt
key keys/client.key
tls-client
tls-auth keys/ta.key 1
auth SHA512
auth-user-pass # команда, указывающая клиенту использовать авторизацию по паролю
cipher BF-CBC
ns-cert-type server
comp-lzo
persist-key
persist-tun
Сохраняем и выходим.
С клиентской стороны подключаться к серверу так:
openvpn client.ovpn
будет передложенно ввести имя пользователя и пароль. Если вы выполнили в точности все пункты в статье и ничего не пропустили, то должно быть создано VPN подключение с полным заворотом трафика через удаленный сервер.
В статье я привел использование алгоритма хэширования SHA512 и симметричный шифр Blowfish, которые обладают более чем достаточной криптостойкостью.
Возможно вам пригодится статья Настройка сервера OpenVPN в FreeBSD
Если возникли какие-то сложности, пишите в нашем форуме.

