OpenVPN: установка сервера на CentOS

Автор: | 07/02/2014
 

openvpn-logoУстановка и настройка OpenVPN сервера

Хотя по размеру статьи может показаться что это процесс долгий и сложный — на самом деле всё очень просто и не займёт много времени.

Проверяем наличие устройства tun:

# file /dev/net/tun
/dev/net/tun: character special

Ищем пакет:

# yum search openvpn
...
NetworkManager-openvpn.i686 : NetworkManager VPN plugin for OpenVPN
openvpn-auth-ldap.i686 : OpenVPN plugin for LDAP authentication
eurephia.i686 : An advanced and flexible OpenVPN user authentication plug-in
stonevpn.noarch : Easy OpenVPN certificate and configuration management
openvpn.i686 : Robust and highly flexible VPN daemon

Или так:

# yum list openvpn
...
openvpn.i686 2.3.2-2.el6                           epel

Тут важно обратить внимание на репозиторий — в base его почему-то нет, поэтому нужно подключить Epel (или RPMForge — в нём тоже должен быть).

Установка и настройка выполняются на:

# cat /etc/redhat-release
CentOS release 6.5 (Final)

Устанавливаем:

# yum -y install openvpn easy-rsa
...
Installed:
openvpn.i686 0:2.3.2-2.el6

easy-rsa.noarch 0:2.2.2-1.el6

Dependency Installed:
pkcs11-helper.i686 0:1.08-1.el6.rf

Complete!

Создаём файл конфигурации:

# cp /usr/share/doc/openvpn-2.3.2/sample/sample-config-files/server.conf /etc/openvpn/

Редактируем его:

# vim /etc/openvpn/server.conf

Указываем на каком IP будет работать OpenVPN сервер (тут 192.168.1.105 — внешний IP сервера):

# Which local IP address should OpenVPN
# listen on? (optional)
local 192.168.1.105

Задаём OpenVPN сеть:

# Configure server mode and supply a VPN subnet
# for OpenVPN to draw client addresses from.
# The server will take 10.8.0.1 for itself,
# the rest will be made available to clients.
# Each client will be able to reach the server
# on 10.8.0.1. Comment this line out if you are
# ethernet bridging. See the man page for more info.
server 10.0.0.0 255.255.255.0

Передаём параметр клиентам, благодаря которому весь их трафик будет перенаправляться через OpenVPN:

# If enabled, this directive will configure
# all clients to redirect their default
# network gateway through the VPN, causing
# all IP traffic such as web browsing and
# and DNS lookups to go through the VPN
# (The OpenVPN server machine may need to NAT
# or bridge the TUN/TAP interface to the internet
# in order for this to work properly).
push "redirect-gateway def1 bypass-dhcp"

Далее зададим DNS-сервера для клиентов:

# Certain Windows-specific network settings
# can be pushed to clients, such as DNS
# or WINS server addresses. CAVEAT:
# http://openvpn.net/faq.html#dhcpcaveats
# The addresses below refer to the public
# DNS servers provided by opendns.com.
push "dhcp-option DNS 10.0.0.1"
push "dhcp-option DNS 8.8.8.8"

Меняем пользователя, под которым будет работать OpenVPN демон:

# It's a good idea to reduce the OpenVPN
# daemon's privileges after initialization.
#
# You can uncomment this out on
# non-Windows systems.
user nobody
group nobody

Меняем настройки логгирования:

# Output a short status file showing
# current connections, truncated
# and rewritten every minute.
status /var/log/openvpn-status.log

и:

# By default, log messages will go to the syslog (or
# on Windows, if running as a service, they will go to
# the "Program FilesOpenVPNlog" directory).
# Use log or log-append to override this default.
# "log" will truncate the log file on OpenVPN startup,
# while "log-append" will append to it. Use one
# or the other (but not both).
;log openvpn.log
log-append /var/log/openvpn.log

Готово, сохраняем и выходим.

Создание сертификатов для OpenVPN сервера

Создаём директорию для сертификатов:

# mkdir -p /etc/openvpn/easy-rsa/keys

Копируем необходимые файлы:

# cp -r /usr/share/easy-rsa/2.0/* /etc/openvpn/easy-rsa/

При желании можно отредактировать такие параметры, что бы не вводить потом руками во время генерации сертификатов:

export KEY_COUNTRY="US"
export KEY_PROVINCE="CA"
export KEY_CITY="SanFrancisco"
export KEY_ORG="Fort-Funston"
export KEY_EMAIL="me@myhost.mydomain"
export KEY_OU="MyOrganizationalUnit"

# X509 Subject Field
export KEY_NAME="EasyRSA"

в файле /etc/openvpn/easy-rsa/vars.

Генерируем сертификаты.

# cd /etc/openvpn/easy-rsa

Перечитаем файл vars:

# source ./vars
NOTE: If you run ./clean-all, I will be doing a rm -rf on /etc/openvpn/easy-rsa/keys

Удаляем старые ключи:

# ./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]:
Locality Name (eg, city) [SanFrancisco]:Kiev
Organization Name (eg, company) [Fort-Funston]:Home
Organizational Unit Name (eg, section) [MyOrganizationalUnit]:
Common Name (eg, your name or your server's hostname) [Fort-Funston CA]:main-home
Name [EasyRSA]:
Email Address [me@myhost.mydomain]:

После этого шага в катлоге /etc/openvpn/easy-rsa/keys появляются новые CA (Central Authority) сертификаты:

-rw-r--r-- 1 root root 1850 Dec 17 13:53 ca.crt
-rw------- 1 root root 1704 Dec 17 13:53 ca.key

Есть упоминание о том, что OpenVPN может не распознать версию OpenSSL на CentOS — в данном случае обошлось.

Если всё же появилась проблема — попробуйте скопировать файл конфигурации OpenSSL:

# cp /etc/openvpn/easy-rsa/openssl-1.0.0.cnf /etc/openvpn/easy-rsa/openssl.cnf

Далее создаём корневой сертификат для самого сервера:

# ./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]:
Locality Name (eg, city) [SanFrancisco]:Kiev
Organization Name (eg, company) [Fort-Funston]:Home
Organizational Unit Name (eg, section) [MyOrganizationalUnit]:
Common Name (eg, your name or your server's hostname) [server]:main-home
Name [EasyRSA]:
Email Address [me@myhost.mydomain]:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []: // тут ничего не вводим, просто Enter
An optional company name []:  // тут ничего не вводим, просто Enter
Using configuration from /etc/openvpn/easy-rsa/openssl-1.0.0.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName :PRINTABLE:'UA'
stateOrProvinceName :PRINTABLE:'CA'
localityName :PRINTABLE:'Kiev'
organizationName :PRINTABLE:'Home'
organizationalUnitName:PRINTABLE:'MyOrganizationalUnit'
commonName :PRINTABLE:'main-home'
name :PRINTABLE:'EasyRSA'
emailAddress :IA5STRING:'me@myhost.mydomain'
Certificate is to be certified until Jun 28 08:24:07 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

Генерируем ключ Диффи-Хелмана (Diffie Hellman). Алгоритм Диффи-Хелмана позволяет получить двум сторонам общий секретный ключ, использующийся для дальнейшего симметричного шифрования данных:

# ./build-dh
Generating DH parameters, 2048 bit long safe prime, generator 2
This is going to take a long time

Процесс довольно долгий, у меня занял около 5 минут.

И последний шаг, создание клиентских сертификатов — повторяем отдельно для каждого клиента:

# ./build-key client
Generating a 2048 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) [US]:
State or Province Name (full name) [CA]:
Locality Name (eg, city) [SanFrancisco]:
Organization Name (eg, company) [Fort-Funston]:
Organizational Unit Name (eg, section) [MyOrganizationalUnit]:
Common Name (eg, your name or your server's hostname) [client]:
Name [EasyRSA]:
Email Address [me@myhost.mydomain]:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []: // тут уже лучше задать пароль, т.к. ключ будет храниться у человеков
An optional company name []: // тут уже лучше задать пароль, т.к. ключ будет храниться у человеков
Using configuration from /etc/openvpn/easy-rsa/openssl-1.0.0.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName :PRINTABLE:'US'
stateOrProvinceName :PRINTABLE:'CA'
localityName :PRINTABLE:'SanFrancisco'
organizationName :PRINTABLE:'Fort-Funston'
organizationalUnitName:PRINTABLE:'MyOrganizationalUnit'
commonName :PRINTABLE:'client'
name :PRINTABLE:'EasyRSA'
emailAddress :IA5STRING:'me@myhost.mydomain'
Certificate is to be certified until Jun 28 08:28:14 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

Копируем ключи:

# ls -l /etc/openvpn/easy-rsa/keys
total 84
-rw-r--r-- 1 root root 5492 Jul 1 11:24 01.pem
-rw-r--r-- 1 root root 5404 Jul 1 11:28 02.pem
-rw-r--r-- 1 root root 1728 Jul 1 11:21 ca.crt
-rw------- 1 root root 1708 Jul 1 11:21 ca.key
-rw-r--r-- 1 root root 5404 Jul 1 11:28 client.crt
-rw-r--r-- 1 root root 1155 Jul 1 11:28 client.csr
-rw------- 1 root root 1708 Jul 1 11:28 client.key
-rw-r--r-- 1 root root 424 Jul 1 11:27 dh2048.pem
-rw-r--r-- 1 root root 285 Jul 1 11:28 index.txt
-rw-r--r-- 1 root root 21 Jul 1 11:28 index.txt.attr
-rw-r--r-- 1 root root 21 Jul 1 11:24 index.txt.attr.old
-rw-r--r-- 1 root root 136 Jul 1 11:24 index.txt.old
-rw-r--r-- 1 root root 3 Jul 1 11:28 serial
-rw-r--r-- 1 root root 3 Jul 1 11:24 serial.old
-rw-r--r-- 1 root root 5492 Jul 1 11:24 server.crt
-rw-r--r-- 1 root root 1082 Jul 1 11:24 server.csr
-rw------- 1 root root 1704 Jul 1 11:24 server.key
# cd keys/
# cp dh2048.pem ca.crt server.crt server.key /etc/openvpn

Настройка роутинга и запуск OpenVPN сервера

Проверяем статус IPTABLES:

# service iptables status
Table: filter
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
2 ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0
3 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
4 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
5 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited

Chain FORWARD (policy ACCEPT)
num target prot opt source destination
1 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited

Chain OUTPUT (policy ACCEPT)
num target prot opt source destination

Создаём резервную копию файла:

# cp -pv /etc/sysconfig/iptables /etc/sysconfig/iptables.bak.$(date +%Y%m%d%H%M%S)
`/etc/sysconfig/iptables' -> `/etc/sysconfig/iptables.bak.20140701141627'

Перезапускаем IPTABLES:

# service iptables restart

Далее предполагается что внешний интерфейс — это eth1 с IP 192.168.1.105., а сеть для клиентов OpenVPN10.0.0.0/24.

Добавляем правила:

# iptables -I INPUT 1 -p udp --dport 1194 -j ACCEPT
# iptables -I FORWARD -i eth1 -o tun0 -j ACCEPT
# iptables -I FORWARD -i tun0 -o eth1 -j ACCEPT
# iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth1 -j SNAT --to-source 192.168.1.105E

Так же — в основных мануалах предлагается использовать MASQUERADE вместо SNAT. Если что-то не получается — попробуйте вместо последней команды выполнить:

# iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth1 -j MASQUERADE

Сохраним их в отдельный файл, на «всякий случай», что бы потом не писать их заново:

# iptables-save > /etc/sysconfig/iptables-vpn

Сохраняем в основной файл:

# service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables:[ OK ]

Ещё раз смотрим правила:

# service iptables status
Table: filter
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 ACCEPT udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:1194
2 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
3 ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0
4 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
5 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
6 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited

Chain FORWARD (policy ACCEPT)
num target prot opt source destination
1 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
2 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
3 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited

Chain OUTPUT (policy ACCEPT)
num target prot opt source destination

Table: nat
Chain PREROUTING (policy ACCEPT)
num target prot opt source destination

Chain POSTROUTING (policy ACCEPT)
num target prot opt source destination
1 MASQUERADE all -- 0.0.0.0/0 0.0.0.0/0
2 SNAT all -- 10.0.0.0/24 0.0.0.0/0 to:192.168.1.105

Chain OUTPUT (policy ACCEPT)
num target prot opt source destination

Если что-то пошло не так — восстановить настройки можно так:

# iptables-restore < /etc/sysconfig/iptables.bak.20140701141157

После чего перезаписать их в основной файл командой:

# service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables:[ OK ]

Добавляем IP Forwarding  в ядро:

# vim /etc/sysctl.conf

Меняем:

# Controls IP packet forwarding
net.ipv4.ip_forward = 0

на:

net.ipv4.ip_forward = 1

Загружаем настройки:

# sysctl -p
net.ipv4.ip_forward = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
kernel.sysrq = 0
kernel.core_uses_pid = 1
net.ipv4.tcp_syncookies = 1
error: "net.bridge.bridge-nf-call-ip6tables" is an unknown key
error: "net.bridge.bridge-nf-call-iptables" is an unknown key
error: "net.bridge.bridge-nf-call-arptables" is an unknown key
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 4294967295
kernel.shmall = 268435456

Запускаем OpenVPN сервер:

# service openvpn start
Starting openvpn: [FAILED]

Упс 🙂

Смотрим лог (т.к. попытка старта неудачная — то лог /var/log/messages ):

Jul  1 11:45:55 main-home openvpn[7366]: Options error: --dh fails with 'dh1024.pem': No such file or directory

Тогда как у нас сертификат:

# ls -l /etc/openvpn/ | grep dh
-rw-r--r-- 1 root root 424 Jul 1 11:51 dh2048.pem

Возвращаемся к файлу конфигурации /etc/openvpn/server.conf, и меняем:

# Diffie hellman parameters.
# Generate your own with:
# openssl dhparam -out dh1024.pem 1024
# Substitute 2048 for 1024 if you are using
# 2048 bit keys.
dh dh1024.pem

на:

dh dh2048.pem

Ещё раз запускаем:

# service openvpn start
Starting openvpn: [ OK ]

Проверяем лог:

# tail /var/log/openvpn.log
Tue Jul 1 12:00:35 2014 /sbin/ip addr add dev tun0 local 10.0.0.1 peer 10.0.0.2
Tue Jul 1 12:00:35 2014 /sbin/ip route add 10.0.0.0/24 via 10.0.0.2
Tue Jul 1 12:00:35 2014 GID set to nobody
Tue Jul 1 12:00:35 2014 UID set to nobody
Tue Jul 1 12:00:35 2014 UDPv4 link local (bound): [undef]
Tue Jul 1 12:00:35 2014 UDPv4 link remote: [undef]
Tue Jul 1 12:00:35 2014 MULTI: multi_init called, r=256 v=256
Tue Jul 1 12:00:35 2014 IFCONFIG POOL: base=10.0.0.4 size=62, ipv6=0
Tue Jul 1 12:00:35 2014 IFCONFIG POOL LIST
Tue Jul 1 12:00:35 2014 Initialization Sequence Completed
# ifconfig tun0
tun0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
inet addr:10.0.0.1 P-t-P:10.0.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)
# netstat -tupln | grep openvpn
udp 0 0 192.168.1.105:1194 0.0.0.0:* 7713/openvpn

И добавляем OpenVPN в автозапуск:

# chkconfig openvpn on

Готово.

Продолжение — в статье CentOS: установка и настройка OpenVPN клиента

Ссылки по теме:

https://www.digitalocean.com

http://vds-admin.ru

http://fedoraproject.org