Установка и настройка OpenVPN на Ubuntu/CentOS

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

vpn openvpn linux windowsVPN (Virtual Private Network) - Виртуальная частная сеть, технология позволяющая создавать виртуальные сети поверх сети интернет. Поскольку к сети подключаются только доверенные пользователи, такая сеть называется частной.

В наше время VPN активно используется не только для защиты трафика, но и для обхода блокировок и цензуры в сети интернет.

Объединяя клиентов в локальную сеть, VPN-сервер не только связывает пользователей друг с другом, но и играет роль шлюза для выхода во внешнюю сеть. Обращение к сетевым узлам происходит c ip-адреса VPN-сервера. Возвращение ответного трафика происходит в обратном порядке, сначала VPN-сервер, потом конечный клиент.

Установка OpenVPN

Для работы OpenVPN требуется поддержка TUN/TAP. Поэтому для OpenVPN подходят не все типы виртуализации VPS/VDS. Hапример, подходит KVM и не подходит OpenVZ. Хотя в OpenVZ и существует возможность включения TUN/TAP устройств, но не все хостинг-провайдеры ее предоставляют. Это лучше уточнить заранее, перед оформлением услуги.

Поддержку TUN проверяют командой ls -l /dev/net/tun, вывод будет примерно такой.

ls -l /dev/net/tun
crw-rw-rw- 1 root root 10, 200 Sep 27 03:31 /dev/net/tun

В Ubuntu

Устанавливаем OpenVPN вместе с центром сертификации easy-rsa.

apt-get install -y openvpn easy-rsa

Копируем каталог easy-rsa в домашний каталог пользователя.

make-cadir ~/openvpn-ca

В CentOS

Для установки OpenVPN нужно добавить EPEL - репозиторий.

yum install -y epel-release

Устанавливаем OpenVPN вместе с центром сертификации easy-rsa.

yum install -y openvpn easy-rsa

Копируем каталог easy-rsa в домашний каталог пользователя.

cp -r /usr/share/easy-rsa/2.0 ~/openvpn-ca

Удостоверяющий центр, сертификаты и ключи

Переходим в каталог openvpn-ca.

cd ~/openvpn-ca

Сначала я редактирую файл vars, подставляя свои переменные. Я делаю это для того, чтобы при создании ключей и сертификатов не заполнять значения вручную.

 nano vars

Нужно изменить эти несколько строк.

# These are the default values for fields
# which will be placed in the certificate.
# Don't leave any of these fields blank.
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"

Для своего чешского сервера, я заполнил примерно так.

# These are the default values for fields
# which will be placed in the certificate.
# Don't leave any of these fields blank.
export KEY_COUNTRY="CZ"
export KEY_PROVINCE="CZ"
export KEY_CITY="Ktis"
export KEY_ORG="aruba"
export KEY_EMAIL="vpn@techlist.top"
export KEY_OU="aruba"

# X509 Subject Field
export KEY_NAME="server_aruba"

Инициализируем переменные.

source ./vars

Во время выполнения будет выдано напоминание, что если следом будет выполнена команда ./clean-all, то каталог keys будет очищен.

NOTE: If you run ./clean-all, I will be doing a rm -rf on /root/openvpn-ca/keys

Команда ./clean-all выполняется для очищения каталога keys от старых сертификатов и ключей, а также создания серийного и индексного файлов для новых.

./clean-all

Центр сертификации CA

Создадим сертификат и ключ центра сертификации CA. Если переменные были заданы заранее, то прописывать значения не нужно, во всех строках просто нажимаем Enter.

./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) [CZ]:
State or Province Name (full name) [CZ]:
Locality Name (eg, city) [Ktis]:
Organization Name (eg, company) [aruba]:
Organizational Unit Name (eg, section) [aruba]:
Common Name (eg, your name or your server's hostname) [aruba CA]:
Name [server_aruba]:
Email Address [vpn@techlist.top]:

В каталоге keys появятся файлы ca.crt и ca.key.

  • ca.crt - сертификат удостоверяющего центра CA. Должен быть и на сервере, и у клиента.
  • ca.key - приватный ключ CA. Должен храниться только на сервере, секретный.

Сертификат и ключ сервера

Создадим сертификат и закрытый ключ сервера.

./build-key-server server

Во время выполнения нужно подписать и заверить сертификат - ввести "y" и нажать Enter. Challenge password задавать не нужно, просто нажимаем Enter.

Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y

В каталоге keys появятся файлы server.crt и server.key.

  • server.crt - сертификат сервера, находится на сервере.
  • server.key - ключ сервера, находится на сервере, секретный.

Ключ Diffie Hellman

Создадим ключ Diffie Hellman'а.

./build-dh

По завершению генерации ключа в каталоге keys появится файл dh2048.pem. Если в команде не задана длина шифрования, то по умолчанию будет создан 2048-битный файл.

  • dh2048.pem - файл параметров Diffie Hellman'а, храниться только на сервере.

Ключ HMAC

Создадим ключ HMAC, для дополнительной TLS-аутентификации и защиты от DoS-атак и флуда.

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

В каталоге keys появится файл ta.key.

  • ta.key - ключ несущий в себе код аутентификации для проверки подлинности сообщений. Должен быть и на сервере и на клиенте. При использовании ключа в конфигурации сервера указывается вместе со значением 0, в клиентской конфигурации указывается со значением 1.

Сертификаты и ключи клиентов

Создадим сертификат и ключ клиента. Каждому клиенту нужно создавать отдельную пару (сертификат + ключ). Вместо username подставить имя пользователя.

./build-key username

Для примера создадим пару (сертификат + ключ) с именем client.

./build-key client

Подписываем и заверяем сертификат - y + Enter. Challenge password не задаем, просто нажимаем Enter.

Certificate is to be certified until Oct  8 14:03:17 2027 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 появятся файлы client.crt и client.key.

  • client.crt - сертификат клиента, находится у клиента.
  • client.key - ключ клиента, находится у клиента, секретный.

Если спустя какое-то время нужно будет создать дополнительные клиентские сертификаты, то выполняем без очистки каталога keys.

source ./vars
./build-key username_1
./build-key username_2
./build-key username_3
... и так сколько нужно.

Для конфигураций сервера и клиента нужны следующие файлы:

  • server.crt - сертификат сервера, только сервер.
  • server.key - ключ сервера, только сервер.
  • dh2048.pem - ключ DH, только сервер.
  • ca.crt - корневой CA-сертификат, сервер + клиент.
  • ta.key - HMAC ключ, сервер + клиент.
  • client.crt - сертификат клиента, только клиент.
  • client.key - ключ клиента, только клиент.

Пять верхних файлов должны быть на сервере, четыре нижних должны быть переданы клиенту.

Создадим каталог server-keys в /etc/openvpn.

mkdir /etc/openvpn/server-keys

Перейдем в каталог keys и скопируем из него нужные файлы.

cd ~/openvpn-ca/keys
cp server.crt server.key dh2048.pem ca.crt ta.key /etc/openvpn/server-keys

Настройка сервера

Теперь необходимо создать конфигурационный файл server.conf. Образец файла можно просмотреть в следующих каталогах:

  • /usr/share/doc/openvpn-2.4.3/sample/sample-config-files/server.conf - в CentOS
  • /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz - в Ubuntu
nano /etc/openvpn/server.conf

Для примера приведу минимальную конфигурацию OpenVPN сервера, которая может использоваться для повседневной работы в сети.

port  443
proto udp
dev   tun

ca       /etc/openvpn/server-keys/ca.crt
dh       /etc/openvpn/server-keys/dh2048.pem
key      /etc/openvpn/server-keys/server.key
cert     /etc/openvpn/server-keys/server.crt
tls-auth /etc/openvpn/server-keys/ta.key 0

server 172.16.150.0 255.255.255.0
push "redirect-gateway def1 bypass-dhcp"

keepalive 10 120

compress lz4-v2
push "compress lz4-v2"

#comp-lzo
mssfix 0

persist-key
persist-tun

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

Некоторые строки закомментированы, поэтому предлагаю сначала разобрать написанное, а не бездумно копировать и удивляться что ничего не работает.

Ключи и сертификаты

Указываем расположение файлов ключей и сертификатов, которые перед этим были скопированы в каталог /etc/openvpn/server-keys.

ca       /etc/openvpn/server-keys/ca.crt
dh       /etc/openvpn/server-keys/dh2048.pem
key      /etc/openvpn/server-keys/server.key
cert     /etc/openvpn/server-keys/server.crt
tls-auth /etc/openvpn/server-keys/ta.key 0

После ta.key, на сервере добавляем 0, на клиентах добавляем 1.

Порт сервера

Указываем значение порта на котором будет работать сервер. По умолчанию OpenVPN использует 1194 порт, но его можно изменить на любой другой. Я рекомендую использовать 443, хотя бы потому, что его использование не может быть заблокировано.

port 443

Если Openvpn установлен на чистый VPS/VDS, то 443 порт не будет занят. Но при установке на машину уже использующуюся, данный порт может быть занят web-сервером.

Узнать какие порты и какой программой используются на текущий момент, можно с помощью утилиты netstat. Вот так выглядит отчет на чистой системе, кроме ssh ничего нет.

netstat -tunlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:23532           0.0.0.0:*               LISTEN      1012/sshd           
tcp6       0      0 :::23532                :::*                    LISTEN      1012/sshd

Протокол TCP/UDP

Указываем протокол передачи пакетов, по умолчанию udp.

proto udp

Про различия UDP и TCP можно прочитать на Википедии. Здесь будет достаточно сказать что UDP работает быстрее чем TCP, а TCP надежнее чем UDP. Поскольку в VPN-сетях прежде всего важна скорость передачи данных, то выбор UDP в качестве протокола по умолчанию, очевиден.

TUN/TAP интерфейсы

Зададим тип сетевого интерфейса, TUN или TAP, который будет создаваться при запуске openvpn и использоваться для передачи данных. Про отличия TUN/TAP читаем Википедию, а использовать будем TUN, как задано по умолчанию.

dev tun

Рабочая подсеть

Зададим подсеть сервера, диапазон которой будет использоваться для выдачи адресов клиентам. По умолчанию в настройках OpenVPN используется подсеть 10.8.0.0/24, которая может быть изменена на любую из частных подсетей.

  • 10.0.0.0
  • 172.16.0.0
  • 192.168.0.0

Подсети могут использоваться с масками /8, /16, /24 или 255.0.0.0, 255.255.0.0, 255.255.255.0, соответственно. Подробнее про частные подсети можно прочитать тут.

С используемыми подсетями не все просто, иногда появляются конфликты адресов.

Представьте что вы используете подсеть с адресом 192.168.0.0/24, в таком случае ваш шлюз будет иметь адрес 192.168.0.1. А теперь представьте что вы находитесь в каком-нибудь месте с публичным Wi-Fi, и пытаетесь подключиться к своей VPN-сети через него. Если Wi-Fi сеть будет использовать такой же диапазон адресов, что и ваша, то возникнет конфликт в маршрутизации. Ваше устройство просто не будет знать кто есть кто, точнее к кому относится шлюз, к Wi-Fi сети или к вашему VPN-серверу.

Этого можно избежать назначив рабочей подсетью сервера что-нибудь более оригинальное чем распространенное 192.168.0.0/24. Например можно использовать 172.16.150.0/24.

server 172.16.150.0 255.255.255.0

Указываем клиентам что в качестве шлюза по умолчанию нужно использовать шлюз VPN-сервера. Если этого не сделать то весь трафик будет ходить во внешнюю сеть с вашего адреса, даже при активном VPN-соединении.

push "redirect-gateway def1 bypass-dhcp"

Сжатие трафика

Если канал связи не слишком большой, то следует использовать сжатие трафика для экономии полосы пропускания. На толстых каналах трафик можно не сжимать, разницы не видно.

В версии OpenVPN ниже чем 2.4.+ (устанавливается в Ubuntu), следует использовать comp-lzo. Опция должна быть указана и на сервере, и на клиенте.

comp-lzo

При использовании OpenVPN выше чем 2.4.+ (устанавливается в CentOS), в конфигурации на стороне сервера следует использовать:

compress lz4-v2
push "compress lz4-v2"

А на стороне клиента указывают comp-lzo.

comp-lzo

Если сжатие активировано, то следует добавить опцию mssfix, чтобы скрыть VPN fingerprint, но об этом немного позже. Пока просто добавим mssfix и укажем дефолтное значение равное 0.

mssfix 0

Ведение логов

Чтобы вести логи сервера создадим каталог openvpn в /var/log.

mkdir /var/log/openvpn

В конфигурацию сервера добавим следующие строки.

log    /var/log/openvpn/openvpn.log
status /var/log/openvpn/openvpn-status.log

В первом файле ведется учет клиентских подключений к серверу. Те самые логи "отсутствием" которых заманивают пользователей VPN-сервисы. Что впрочем не мешает им выдавать логи клиентов по первому обращению из соответствующих структур. Во втором файле отмечается статус сервера.

Чтобы регулировать подробность логов добавляют опцию verb, значения могут варьироваться от 0 до 9, чем больше значение, тем подробнее запись. По умолчанию достаточно значения 3.

verb 3

Также можно указать значение mute, которое будет приглушать повтор записи одинаковых сообщений в логи, по умолчанию 20.

mute 20

Остальные настройки

При перезапуске OpenVPN не изменять tun/tap устройства и не перепроверять файлы ключей.

persist-key
persist-tun

Опция keepalive отвечает за пинг клиентов и перезапуск туннеля. Например, каждые 10 секунд пинговать клиента, если в течении 120 секунд ответа от клиента не будет, то перезапускать туннель.

keepalive 10 120

На этом минимальную настройку можно считать законченной. Как я уже писал выше подобной конфигурации вполне хватает для безопасной работы в сети.

Запускаем OpenVPN сервер и добавляем его в автозагрузку.

systemctl start openvpn@server
systemctl enable openvpn@server

После запуска сервера должен появиться tun интерфейс.

ifconfig tun0
tun0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1500
        inet 172.16.150.1  netmask 255.255.255.255  destination 172.16.150.2
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 100  (UNSPEC)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 11  bytes 440 (440.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Настройка Файрвола

Осталось включить форвардинг пакетов и настроить iptables. Сначала включим пересылку трафика между интерфейсами.

Добавляем строку net.ipv4.ip_forward = 1 в файл sysctl.conf
echo net.ipv4.ip_forward = 1 >> /etc/sysctl.conf

Применяем изменения
sysctl -p

Для OpenVPN нужно настроить фаервол: разрешить входящие подключения к 443 порту, разрешить прохождение транзитных пакетов, настроить преобразование адресов SNAT.

Разрешаем подключения на 443-ем порту.

# eth0 заменить на имя своего основного интерфейса
iptables -A INPUT -i eth0 -p udp --dport 443 -j ACCEPT

Разрешаем прохождение транзитных пакетов из подсети OpenVPN.

# Разрешаем транзит трафика из подсети OpenVPN
iptables -A FORWARD -s 172.16.150.0/24 -j ACCEPT
# Разрешаем установленные соединения для транзита
iptables -A FORWARD -p all -m state --state ESTABLISHED,RELATED -j ACCEPT

Настраиваем SNAT. Локальный ip-адрес пакетов выходящих из подсети OpenVPN будет заменен на внешний ip-адрес вашего сервера.

# При необходимости заменить имя интерфейса XX.XX.XX.XX - заменить на свой IP сервера
iptables --table nat --append POSTROUTING --out-interface eth0 -j SNAT --to XX.XX.XX.XX

Естественно это не все правила iptables, а только необходимые для работы OpenVPN. Подробнее про настройку netfilter/iptables можно прочитать здесь.

Про настройку клиента под Windows читаем здесь. Настройка клиента для Linux Mint здесь.

Ответить:

Please enter your comment!
Please enter your name here