Строим сеть Openvpn

Зачем нужен vpn-туннель? Ясное дело - связать две приватные подсети друг с другом через интернет. А если подсетей, допустим не две, а пять? Что делать в этом случае? Как можно, как лучше? Мои размышления на эту тему с конкретным примером реализации.

Предисловие

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

Не буду скрывать, да это и очевидно - всё, что будет описано в данной записи - 100% материала - придумано всё это не мной, как сказал один мой знакомый - всё украдено до нас. Моя задача смотреть, анализировать, собирать информацию и доводить проект до конечной реализации сперва на бумаге, а потом в продакшене.

Выбор топологии

Итак, несколько подсетей. Для начала нужно проверить, что они не перекрываются. При всей очевидности проверить все-таки надо. Вот скажите сходу перекрываются ли сети?

192.168.0.0/20
192.168.17.0/24

А сети?

192.168.0.0/20
192.168.15.0/24

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

Полносвязное соединение

455

Все элементы равнозначны.

Плюсы:

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

Минусы:

  • При большом количестве сетей избыточная, громоздкая структура;
  • Добавление новой сети требует настройки еще стольких новых туннелей, сколько подсетей уже имеется;
  • Если одна сеть (филиал организации) переезжает по новому адресу, то это требует полной перенастройки всех связанных с ней туннелей.
Звезда

Строим сеть Openvpn

Ядро системы настраивается как VPN сервер, остальные элементы как VPN клиенты.

Плюсы:

  • VPN клиент находится за NAT. IP адрес он может получать по DHCP. Это делает такого клиента непривязанным к конкретной сети провайдера. Включаем его на новом месте, он подсоединяется к серверу и работает. Всё что нужно сделать, это кинуть на него маршрут;
  • Простота добавления нового клиента - минимальная настройка на сервере, а сам клиент настраивается из типового шаблона;
  • Если клиент реализован на виртуальной машине, то это бесплатно. Вычислительная мощность такого клиента настраивается за минуту в любую сторону;
  • Неочевидный плюс безопасности: маршрут на клиент, выступающий в роли шлюза в туннель, можно прописать как для всей локальной сети, так и для отдельных узлов;
  • Второй неочевидный плюс безопасности: анонимность - остальные подсети видятся только по своим приватным адресам, а если вдобавок на vpn-сервере выключен лог, то даже получив доступ к нему невозможно собрать информацию кто и откуда подключался;
  • Третий неочевидный плюс безопасности: если локальная подсеть клиента маленькая, либо же малое число клиентов в сети использует туннель, то в этом случае клиент можно реализовать на микрокомпьютере Raspberry Pi. При необходимости такой микрокомпьютер можно здорово запрятать, а при настройке соединения через Wi-Fi и вовсе его не найдешь;
  • Четвертый неочевидный плюс безопасности: всю структуру можно выключить, выключив VPN сервер. Если при этом VPN сервер реализован как VPS в интернете, то сделать это можно, находясь где угодно, одним нажатием на смартфоне. Если хостер разумно-жадный, что в данном случае хорошо и не делает бесплатных бекапов, то и полностью удалить VPN сервер без всяких следов можно также легко.

Минусы:

  • Единая точка отказа, если VPN сервер недоступен по каким-либо причинам, то вся сеть лежит;
  • Для каждого клиента нужны либо виртуальная машина, либо машина физическая;
  • Размещенный в интернете VPN сервер требует ежемесячной оплаты;
  • VPN сервер должен обладать необходимой вычислительной мощностью чтобы покрывать обсчет трафика от клиентов. Теоретически при достаточно большом количестве клиентов и больших подсетях за клиентами этой мощности может не хватить. На практике такого никогда не случится.
Реализация

Сначала хотел сделать что-то, взяв готовые решения типа IpCop, но потом понял, что из этого ничего не получится. Заставить тестового Ubuntu-клиента приконнектиться к серверу не удалось. Несмотря на стандарт, реализация Openvpn видимо везде разная, например openvpn-сервер на роутере Mikrotik RB2011U почему-то использует TCP.. ( //voxlink.ru/kb/voip-devices-configuration/Conf_openVPN_windows_after_openVPN_Mikrotik/ ). Это видно из строки proto tcp-client. Роутер Mikrotik в режиме клиента непонятно что использует, но к готовой реализации проекта он также не подключился. Может что-то не разобрал, не спорю, тем не менее в конце-концов, ещё задолго до заказа VPS, пришел к выводу, что придется всё настраивать с нуля на одной ОС для всех машин туннеля.

По многим причинам выбрал вариант с выделенным VPS в интернете. Для начала нужно определиться где, в каком дата-центре разместить VPN сервер. Для этого нужно попросить в поддержке интересующего дата-центра тестовый IP, попинговать его и сделать трассировку из всех предполагаемых к соединению сетей, посмотреть число хопов. Полезная программа WinMTR:

Строим сеть Openvpn

Это занимает определенное время и вот наконец дата-центр выбран, VPS оплачен и готов к настройке.

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

Используем Ubuntu 16.04 LTS  как дружелюбную, хорошо отлаженную систему. Установить систему на VPS можно из предварительно настроенных образов хостера, либо же отписать в поддержку и попросить загрузить для установки свой дистрибутив - А у вас нет такого же, но с перламутровыми пуговицами?  Не стал заморачиваться и взял то, что дают. Установил, установка занимает пару минут: root включен, ssh доступ root включен, swap раздела нет. Последнее не очень хорошо, поэтому первое:

apt-get install swapspace
vi /etc/swapspace.conf

swappath="/var/lib/swapspace" - директория, где создаются swap-файлы

lower_freelimit=20 - нижний лимит незанятого пространства ОЗУ

upper_freelimit=60 - верхний лимит незанятого пространства ОЗУ

freetarget=30 - уровень до которого 
будет освобождено, должен находиться между двумя предыдущими 

min_swapsize=512m - минимальный размер swap-файла

max_swapsize=1g - максимальный размер swap-файла

cooldown=600 - какая-то задержка (сек.) max=10 min

Меняем hostname, когда сидишь через ssh сразу на нескольких машинах, то можно легко запутаться и набумбасить лишнего там, где не надо, потом будет обидно, а если отвалится связь с машиной, то очень обидно, поэтому:

vi /etc/hosts
вместо "hostname" - имя вашего компьютера

vi /etc/hostname

Своих клиентов обозвал по порядку V1, V2, V3 и так далее.

Убираем автообновление, вредная штука:

apt-get update
apt-get dist-upgrade

dpkg-reconfigure unattended-upgrades

Меняем root пароль:

passwd root

Также полезно пользоваться командой history для просмотра истории команд.

Настройка Openvpn и сертификатов
apt-get install openvpn easy-rsa

Копируем дефолтный конфиг Openvpn для правки:

gunzip -c /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz > /etc/openvpn/server.conf

Правим:

vi /etc/openvpn/server.conf
Конфиг
#################################################
# Sample OpenVPN 2.0 config file for #
# multi-client server. #
# #
# This file is for the server side #
# of a many-clients <-> one-server #
# OpenVPN configuration. #
# #
# OpenVPN also supports #
# single-machine <-> single-machine #
# configurations (See the Examples page #
# on the web site for more info). #
# #
# This config should work on Windows #
# or Linux/BSD systems. Remember on #
# Windows to quote pathnames and use #
# double backslashes, e.g.: #
# "C:\\Program Files\\OpenVPN\\config\\foo.key" #
# #
# Comments are preceded with '#' or ';' #
#################################################

# Which local IP address should OpenVPN
# listen on? (optional)
;local a.b.c.d

# Which TCP/UDP port should OpenVPN listen on?
# If you want to run multiple OpenVPN instances
# on the same machine, use a different port
# number for each one. You will need to
# open up this port on your firewall.
port 1194

# TCP or UDP server?
;proto tcp
proto udp

# "dev tun" will create a routed IP tunnel,
# "dev tap" will create an ethernet tunnel.
# Use "dev tap0" if you are ethernet bridging
# and have precreated a tap0 virtual interface
# and bridged it with your ethernet interface.
# If you want to control access policies
# over the VPN, you must create firewall
# rules for the the TUN/TAP interface.
# On non-Windows systems, you can give
# an explicit unit number, such as tun0.
# On Windows, use "dev-node" for this.
# On most systems, the VPN will not function
# unless you partially or fully disable
# the firewall for the TUN/TAP interface.
;dev tap
dev tun

# Windows needs the TAP-Win32 adapter name
# from the Network Connections panel if you
# have more than one. On XP SP2 or higher,
# you may need to selectively disable the
# Windows firewall for the TAP adapter.
# Non-Windows systems usually don't need this.
;dev-node MyTap

# SSL/TLS root certificate (ca), certificate
# (cert), and private key (key). Each client
# and the server must have their own cert and
# key file. The server and all clients will
# use the same ca file.
#
# See the "easy-rsa" directory for a series
# of scripts for generating RSA certificates
# and private keys. Remember to use
# a unique Common Name for the server
# and each of the client certificates.
#
# Any X509 key management system can be used.
# OpenVPN can also use a PKCS #12 formatted key file
# (see "pkcs12" directive in man page).
ca ca.crt
cert server.crt
key server.key # This file should be kept secret

# Diffie hellman parameters.
# Generate your own with:
# openssl dhparam -out dh2048.pem 2048
dh dh2048.pem

# Network topology
# Should be subnet (addressing via IP)
# unless Windows clients v2.0.9 and lower have to
# be supported (then net30, i.e. a /30 per client)
# Defaults to net30 (not recommended)
;topology subnet

# 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.8.0.0 255.255.255.0

# Maintain a record of client <-> virtual IP address
# associations in this file. If OpenVPN goes down or
# is restarted, reconnecting clients can be assigned
# the same virtual IP address from the pool that was
# previously assigned.
ifconfig-pool-persist ipp.txt

# Configure server mode for ethernet bridging.
# You must first use your OS's bridging capability
# to bridge the TAP interface with the ethernet
# NIC interface. Then you must manually set the
# IP/netmask on the bridge interface, here we
# assume 10.8.0.4/255.255.255.0. Finally we
# must set aside an IP range in this subnet
# (start=10.8.0.50 end=10.8.0.100) to allocate
# to connecting clients. Leave this line commented
# out unless you are ethernet bridging.
;server-bridge 10.8.0.4 255.255.255.0 10.8.0.50 10.8.0.100

# Configure server mode for ethernet bridging
# using a DHCP-proxy, where clients talk
# to the OpenVPN server-side DHCP server
# to receive their IP address allocation
# and DNS server addresses. You must first use
# your OS's bridging capability to bridge the TAP
# interface with the ethernet NIC interface.
# Note: this mode only works on clients (such as
# Windows), where the client-side TAP adapter is
# bound to a DHCP client.
;server-bridge

# Push routes to the client to allow it
# to reach other private subnets behind
# the server. Remember that these
# private subnets will also need
# to know to route the OpenVPN client
# address pool (10.8.0.0/255.255.255.0)
# back to the OpenVPN server.
;push "route 192.168.10.0 255.255.255.0"
;push "route 192.168.20.0 255.255.255.0"

# To assign specific IP addresses to specific
# clients or if a connecting client has a private
# subnet behind it that should also have VPN access,
# use the subdirectory "ccd" for client-specific
# configuration files (see man page for more info).

# EXAMPLE: Suppose the client
# having the certificate common name "Thelonious"
# also has a small subnet behind his connecting
# machine, such as 192.168.40.128/255.255.255.248.
# First, uncomment out these lines:
;client-config-dir ccd
;route 192.168.40.128 255.255.255.248

client-config-dir ccd 
ccd-exclusive  

route 192.168.190.0 255.255.255.0
route 192.168.192.0 255.255.255.0
route 192.168.0.0 255.255.240.0

# Then create a file ccd/Thelonious with this line:
# iroute 192.168.40.128 255.255.255.248
# This will allow Thelonious' private subnet to
# access the VPN. This example will only work
# if you are routing, not bridging, i.e. you are
# using "dev tun" and "server" directives.

# EXAMPLE: Suppose you want to give
# Thelonious a fixed VPN IP address of 10.9.0.1.
# First uncomment out these lines:
;client-config-dir ccd
;route 10.9.0.0 255.255.255.252

# Then add this line to ccd/Thelonious:
# ifconfig-push 10.9.0.1 10.9.0.2

# Suppose that you want to enable different
# firewall access policies for different groups
# of clients. There are two methods:
# (1) Run multiple OpenVPN daemons, one for each
# group, and firewall the TUN/TAP interface
# for each group/daemon appropriately.
# (2) (Advanced) Create a script to dynamically
# modify the firewall in response to access
# from different clients. See man
# page for more info on learn-address script.
;learn-address ./script

# 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"

# 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 208.67.222.222"
push "dhcp-option DNS 208.67.220.220"

# Uncomment this directive to allow different
# clients to be able to "see" each other.
# By default, clients will only see the server.
# To force clients to only see the server, you
# will also need to appropriately firewall the
# server's TUN/TAP interface.
client-to-client

# Uncomment this directive if multiple clients
# might connect with the same certificate/key
# files or common names. This is recommended
# only for testing purposes. For production use,
# each client should have its own certificate/key
# pair.
#
# IF YOU HAVE NOT GENERATED INDIVIDUAL
# CERTIFICATE/KEY PAIRS FOR EACH CLIENT,
# EACH HAVING ITS OWN UNIQUE "COMMON NAME",
# UNCOMMENT THIS LINE OUT.
;duplicate-cn

# The keepalive directive causes ping-like
# messages to be sent back and forth over
# the link so that each side knows when
# the other side has gone down.
# Ping every 10 seconds, assume that remote
# peer is down if no ping received during
# a 120 second time period.
keepalive 20 120

# For extra security beyond that provided
# by SSL/TLS, create an "HMAC firewall"
# to help block DoS attacks and UDP port flooding.
#
# Generate with:
# openvpn --genkey --secret ta.key
#
# The server and each client must have
# a copy of this key.
# The second parameter should be '0'
# on the server and '1' on the clients.
;tls-auth ta.key 0 # This file is secret

# Select a cryptographic cipher.
# This config item must be copied to
# the client config file as well.
;cipher BF-CBC # Blowfish (default)
cipher AES-128-CBC # AES
;cipher DES-EDE3-CBC # Triple-DES

# Enable compression on the VPN link.
# If you enable it here, you must also
# enable it in the client config file.
comp-lzo

# The maximum number of concurrently connected
# clients we want to allow.
;max-clients 100

# 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 nogroup

# The persist options will try to avoid
# accessing certain resources on restart
# that may no longer be accessible because
# of the privilege downgrade.
persist-key
persist-tun

# Output a short status file showing
# current connections, truncated
# and rewritten every minute.
;status 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 Files\OpenVPN\log" 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 openvpn.log

# Set the appropriate level of log
# file verbosity.
#
# 0 is silent, except for fatal errors
# 4 is reasonable for general usage
# 5 and 6 can help to debug connection problems
# 9 is extremely verbose
verb 0

# Silence repeating messages. At most 20
# sequential messages of the same message
# category will be output to the log.
;mute 20

Все понятно, наиболее важные параметры:

push "redirect-gateway def1 bypass-dhcp" - клиенты будут пихать весь траффик в туннель по умолчанию

client-to-client - разрешить пакеты из подсети одного клиента в подсеть другого

cipher AES-128-CBC - алгоритм шифрования, точно такой же должен быть прописан в конфиге клиента

comp-lzo - включить сжатие

user nobody
group nogroup - две команды запускать openvpn не от root'а

;log openvpn.log
;log-append openvpn.log
verb 0 - это чтобы сервер "не шумел" и ничего не писал в лог

Разрешаем форвардинг пакетов, полученных с других машин. Вот тут я долго не мог понять почему с клиента пакеты через туннель ходят, а пакеты отправленные с хостов на клиент лезут в интернет, вместо того чтобы лезть в туннель:

echo 1 > /proc/sys/net/ipv4/ip_forward
vi /etc/sysctl.conf

net.ipv4.ip_forward=1
Файрвол

Файрвол по умолчанию выключен. Настраиваем:

ufw allow ssh
ufw allow 1194/udp

vi /etc/default/ufw

DEFAULT_FORWARD_POLICY="ACCEPT"

vi /etc/ufw/before.rules

# rules.before
#
# Rules that should be run before the ufw command line added rules. Custom
# rules should be added to one of these chains:
# ufw-before-input
# ufw-before-output
# ufw-before-forward
# START OPENVPN RULES
# NAT table rules
*nat
:POSTROUTING ACCEPT [0:0] 
# Allow traffic from OpenVPN client to eth0
-A POSTROUTING -s 10.8.0.0/8 -o eth0 -j MASQUERADE
COMMIT
# END OPENVPN RULES

И включаем:

ufw enable
Генерация сертификатов сервера
cp -r /usr/share/easy-rsa/ /etc/openvpn
mkdir /etc/openvpn/easy-rsa/keys
vi /etc/openvpn/easy-rsa/vars
 
 export KEY_COUNTRY="US"
 export KEY_PROVINCE="TX"
 export KEY_CITY="Dallas"
 export KEY_ORG="My Company Name"
 export KEY_EMAIL="sammy@example.com"
 export KEY_OU="MYOrganizationalUnit"
- тут меняем данные на что-то близкое к реальности

 export KEY_NAME="server" - эта строчка важна, потому что серверный ключ должен называться server
Алгоритм Диффи-Хеллмана (DH) не является механизмом шифрования и обычно не используется для шифрования данных. Он позволяет обеспечивать безопасный обмен ключами, которые используются для шифрования данных. Алгоритмы DH позволяют двум сторонам установить общий секретный ключ, который используется алгоритмами шифрования и хеширования.

openssl dhparam -out /etc/openvpn/dh2048.pem 2048

Данное действо происходит довольно долго и зависит от мощности сервера.

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

cd /etc/openvpn/easy-rsa

. ./vars
./clean-all - это действо нужно производить аккуратно, очищает все старые ключи
./build-ca - на все вопросы жмем Enter, все параметры мы уже поправили выше и где вопрос [y/n] - там y.
./build-key-server server - тож самое

Будут сгенерированы сертификат удостоверяющего центра и сертификат и ключ сервера - ca.crt, server.crt, server.key, все их нужно скопировать в папку /etc/openvpn:

cp /etc/openvpn/easy-rsa/keys/ca.crt /etc/openvpn
cp /etc/openvpn/easy-rsa/keys/server.crt /etc/openvpn
cp /etc/openvpn/easy-rsa/keys/server.key /etc/openvpn

Проверим, что все на месте:

ls -la /etc/openvpn

Запускаем сервис и проверяем его статус:

service openvpn start
service openvpn status

Строим сеть Openvpn

Если само не возвращается в привилегированный режим, то жмем Ctrl-C.

Генерация сертификатов клиентов
./build-key client1
./build-key client2
...................
./build-key clientX - по количеству клиентов

Совет - генерируйте сразу на пару клиентских сертификатов больше, чем нужно, с запасом.

Для заливки/скачивания с машины файлов есть очень удобная программа WinSCP.exe

458

 

Копируем ключи с сервера с помощью WinSCP.exe на свою локальную машину. Для каждого клиента X должен быть наборчик - ca.crt, clientX.crt, clientX.key.

Параметры сервера для каждого клиента

В конфиге сервера есть строчки:

client-config-dir ccd 
ccd-exclusive 

Они говорят что дополнительные параметры клиентов хранятся в директории ccd и для каждого клиента доступны свои эксклюзивные параметры. Создаем указанную директорию и файлы параметров:

cd /etc/openvpn
mkdir ccd
cd ccd
touch client1
touch client2
.............
touch clientX

Редактируем каждый файл параметров:

vi client1

ifconfig-push 10.8.0.6 10.8.0.5
iroute 192.168.190.0 255.255.255.0

Первая строчка говорит, что шлюз туннеля на клиенте один получит адрес 10.8.0.6, вторая обратный маршрут - маршрут с VPN сервера в подсеть клиента один. После настройки всех файлов параметров:

service openvpn restart
service openvpn status
Немного о подсетях для туннеля

Каждый туннель это соединение point-to-point, в котором используется подсеть на 4 адреса. Такая подсесть имеет маску /30, то есть 255.255.255.252, а количество адресов вычисляется по формуле 2^n , где n = 32 - количество бит маски, поэтому адресов для маски /30:

2^(32-30) = 2^2 = 4

Но первый адрес - это адрес всей подсети, последний - широковещательный адрес этой подсети, поэтому для назначения узлам доступно только два адреса - второй и третий по счету. Формула  тут уже 2^n-2 и для наших подсетей это равно двум. Считать очень легко, группами по четыре ( 0,1,2,3 - 4,5,6,7 - 8,9,10,11 - 12,13,14,15 - 16,17,18,19 - ... - 252,253,254,255 ):

10.8.0.0 - 10.8.0.3 - первая подсесть (используется для vpn-сервера - из конфига: # The server will take 10.8.0.1 for itself.. ), доступные адреса узлов - 10.8.0.1 и 10.8.0.2 

10.8.0.4 - 10.8.0.7 - вторая подсесть (используется для клиента один), доступные адреса узлов - 10.8.0.5 и 10.8.0.6

10.8.0.8 - 10.8.0.11 - третья подсесть (используется для клиента два), доступные адреса узлов - 10.8.0.9 и 10.8.0.10

Легко можно посчитать, что максимум клиентов при такой конфигурации 256/4 - 1 = 63, то есть больше, чем когда-либо понадобится.

На этом, чтобы не усложнять, с сервером пока всё.

Настройка клиента

Для клиентов официальный дистрибутив Ubuntu-Server x64 со страницы проекта, в качестве носителя - виртуальная машина, получение настроек сети - по умолчанию (от DHCP). Виртуальная машина идеально подходит для экспериментов, создаем контрольную точку и по необходимости откатываемся на неё столько раз, сколько надо. Создание нового клиента также идеально на виртуальной машине - предварительно настроенная болванка машины выкладывается куда-нибудь на Яндекс Диск и люди с той стороны её забирают, включают на своем Hyper-V и всё работает.

После установки включаем root'а:

sudo passwd root

Включаем вход root по ssh:

sudo vi /etc/ssh/sshd_config 

PermitRootLogin yes

Переключаемся на root и убиваем текущего пользователя, созданного при установке:

userdel user11 - или какой там у вас

Далее кратенько, так как почти все уже делалось на сервере:

apt-get update
apt-get upgrade

sudo dpkg-reconfigure unattended-upgrades
apt-get install openvpn
echo 1 > /proc/sys/net/ipv4/ip_forward
vi /etc/sysctl.conf
 net.ipv4.ip_forward=1

Файрвол не включаем, клиент за NAT, нет необходимости.

cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf /etc/openvpn/server.conf
 
vi /etc/openvpn/server.conf
Конфиг
##############################################
# Sample client-side OpenVPN 2.0 config file #
# for connecting to multi-client server. #
# #
# This configuration can be used by multiple #
# clients, however each client should have #
# its own cert and key files. #
# #
# On Windows, you might want to rename this #
# file so it has a .ovpn extension #
##############################################

# Specify that we are a client and that we
# will be pulling certain config file directives
# from the server.
client

# Use the same setting as you are using on
# the server.
# On most systems, the VPN will not function
# unless you partially or fully disable
# the firewall for the TUN/TAP interface.
;dev tap
dev tun

# Windows needs the TAP-Win32 adapter name
# from the Network Connections panel
# if you have more than one. On XP SP2,
# you may need to disable the firewall
# for the TAP adapter.
;dev-node MyTap

# Are we connecting to a TCP or
# UDP server? Use the same setting as
# on the server.
;proto tcp
proto udp

# The hostname/IP and port of the server.
# You can have multiple remote entries
# to load balance between the servers.
remote X.X.X.X 1194
;remote my-server-2 1194

# Choose a random host from the remote
# list for load-balancing. Otherwise
# try hosts in the order specified.
;remote-random

# Keep trying indefinitely to resolve the
# host name of the OpenVPN server. Very useful
# on machines which are not permanently connected
# to the internet such as laptops.
resolv-retry infinite

# Most clients don't need to bind to
# a specific local port number.
nobind

# Downgrade privileges after initialization (non-Windows only)
user nobody
group nogroup

# Try to preserve some state across restarts.
persist-key
persist-tun

# If you are connecting through an
# HTTP proxy to reach the actual OpenVPN
# server, put the proxy server/IP and
# port number here. See the man page
# if your proxy server requires
# authentication.
;http-proxy-retry # retry on connection failures
;http-proxy [proxy server] [proxy port #]

# Wireless networks often produce a lot
# of duplicate packets. Set this flag
# to silence duplicate packet warnings.
;mute-replay-warnings

# SSL/TLS parms.
# See the server config file for more
# description. It's best to use
# a separate .crt/.key file pair
# for each client. A single ca
# file can be used for all clients.

ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/client1.crt
key /etc/openvpn/keys/client1.key

# Verify server certificate by checking that the
# certicate has the correct key usage set.
# This is an important precaution to protect against
# a potential attack discussed here:
# http://openvpn.net/howto.html#mitm
#
# To use this feature, you will need to generate
# your server certificates with the keyUsage set to
# digitalSignature, keyEncipherment
# and the extendedKeyUsage to
# serverAuth
# EasyRSA can do this for you.
remote-cert-tls server

# If a tls-auth key is used on the server
# then every client must also have the key.
;tls-auth ta.key 1

# Select a cryptographic cipher.
# If the cipher option is used on the server
# then you must also specify it here.
;cipher x
cipher AES-128-CBC 

# Enable compression on the VPN link.
# Don't enable this unless it is also
# enabled in the server config file.
comp-lzo

# Set log file verbosity.
verb 0

# Silence repeating messages
;mute 20

Тут важного:

cipher AES-128-CBC 
remote X.X.X.X 1194 - вместо X.X.X.X должен быть публичный ip-адрес vpn-сервера
Ключи
mkdir /etc/openvpn/keys
cd /etc/openvpn/keys

Копируем ключи, проверяем что все на месте, стартуем Openvpn, проверяем статус туннеля:

ifconfig tun0

Если все нормально, то будет так:

460

Доступность openvpn-сервера:

ping 10.8.0.1

На этом с основной настройкой всё.

Скрип авто-поднятия туннеля на клиентах

Дело в том, что если туннель на работающем клиенте по каким-то причинам упадёт, то сам он не поднимется до перезапуска сервиса или до перезагрузки клиента, поэтому лепим скрипт, делаем его исполняемым и ставим его в Cron:

cd /etc
mkdir scripts
vi /etc/scripts/openvpn.sh

# test openvpn-tun
if [ -z "`ifconfig tun0`" ]; then
 service openvpn restart
 echo "`date`" >> /etc/scripts/openvpn.bug
fi

Если туннель не найден среди активных интерфейсов, то время пишется в файл openvpn.bug.

chmod +x /etc/scripts/openvpn.sh
vi /etc/crontab

# restart openvpn-service if drop
*/3 * * * * root /etc/scripts/openvpn.sh

Проверка идет каждые 3 минуты, этого достаточно, так как перезапуск службы и подъём туннеля происходит мгновенно.

Синхронизация времени

Решил что будет правильным, если время синхронизировано. И на клиентах, и на сервере:

apt-get install ntpdate
apt-get install -y ntp
/etc/init.d/ntp stop
ntpdate pool.ntp.org
/etc/init.d/ntp start

Установить временную зону:

dpkg-reconfigure tzdata

Проверить время можно так:

date
Сервер
vi /etc/ntp.conf
# /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help

driftfile /var/lib/ntp/ntp.drift

# Enable this if you want statistics to be logged.
#statsdir /var/log/ntpstats/

statistics loopstats peerstats clockstats
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable

# Specify one or more NTP servers.

# Use servers from the NTP Pool Project. Approved by Ubuntu Technical Board
# on 2011-02-08 (LP: #104525). See http://www.pool.ntp.org/join.html for
# more information.
pool 0.ubuntu.pool.ntp.org iburst
pool 1.ubuntu.pool.ntp.org iburst
pool 2.ubuntu.pool.ntp.org iburst
pool 3.ubuntu.pool.ntp.org iburst

# Use Ubuntu's ntp server as a fallback.
pool ntp.ubuntu.com

# Access control configuration; see /usr/share/doc/ntp-doc/html/accopt.html for
# details. The web page <http://support.ntp.org/bin/view/Support/AccessRestrictions>
# might also be helpful.
#
# Note that "restrict" applies to both servers and clients, so a configuration
# that might be intended to block requests from certain clients could also end
# up blocking replies from your own upstream servers.

# By default, exchange time with everybody, but don't allow configuration.
restrict -4 default kod notrap nomodify nopeer noquery limited
restrict -6 default kod notrap nomodify nopeer noquery limited

# Local users may interrogate the ntp server more closely.
restrict 127.0.0.1
restrict ::1

# Needed for adding pool entries
restrict source notrap nomodify noquery

# Clients from this (example!) subnet have unlimited access, but only if
# cryptographically authenticated.
#restrict 10.8.0.0 mask 255.255.255.0 notrust

restrict 10.8.0.0 mask 255.255.255.0 nomodify notrap

# If you want to provide time to your local subnet, change the next line.
# (Again, the address is an example only.)
broadcast 10.8.0.1

# If you want to listen to time broadcasts on your local subnet, de-comment the
# next lines. Please do this only if you trust everybody on the network!
#disable auth
#broadcastclient

#Changes recquired to use pps synchonisation as explained in documentation:
#http://www.ntp.org/ntpfaq/NTP-s-config-adv.htm#AEN3918

#server 127.127.8.1 mode 135 prefer # Meinberg GPS167 with PPS
#fudge 127.127.8.1 time1 0.0042 # relative to PPS for my hardware

#server 127.127.22.1 # ATOM(PPS)
#fudge 127.127.22.1 flag3 1 # enable PPS API

Чтобы с NTP-сервером могли синхронизироваться машины из локальной сети:

restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap

Служба синхронизации времени использует порт 123 для соединения с сервером, поэтому необходимо разрешить доступ:

ufw allow from 10.8.0.0/24 to any port ntp

Окончательный вид файрвола сервера:

ufw status

461

Клиенты
# Use servers from the NTP Pool Project. Approved by Ubuntu Technical Board
# on 2011-02-08 (LP: #104525). See http://www.pool.ntp.org/join.html for
# more information.
server 10.8.0.1 iburst prefer
pool 0.ubuntu.pool.ntp.org 
pool 1.ubuntu.pool.ntp.org 
pool 2.ubuntu.pool.ntp.org 
pool 3.ubuntu.pool.ntp.org 

Узнаем насколько время на клиенте отстает от сервера:

ntpdate -q 10.8.0.1
Строим сеть Openvpn
Основные маршруты

Чтобы все машины подсети клиента, речь идёт о Windows машинах, могли ходить в туннель и видеть подсети за туннелем накидываем маршруты для этих подсететй на местный офисный роутер. Если же это нужно только для отдельных машин, то прописываем маршруты на каждой из них, пример для 1 маршрута и соответственно для 1 удалённой подсети:

route add -p 192.168.0.0 mask 255.255.240.0 192.168.190.162 - опция -p нужна чтобы маршрут остался после перезагрузки

Остальные машины данной подсети не смогут видеть другие подсети через туннель и сами будут недоступны из других подсетей - пакет-то они получат, но вот оправить обратно не смогут.

Как добавить постоянный маршрут на Ubuntu машину рассказано в отдельной записи.

Дополнительные маршруты

А что если на одном или нескольких клиентах есть больше чем одна подсеть? К примеру у меня в центральном офисе за напрямую подключенной к клиенту сетью 192.168.0.0/20, есть еще 10.50.0.0/20. Эта сеть находится за роутером и маршрута в эту сеть на клиенте центрального офиса нет, он ничего про неё не знает. Нужно прописать 4 маршрута - 3 прямых и 1 обратный. То есть сеть 10.50.0.0/20 прописывается:

  • На клиенте центрального офиса V3;
  • В файле sever.conf на vpn-сервере:
# EXAMPLE: Suppose the client
# having the certificate common name "Thelonious"
# also has a small subnet behind his connecting
# machine, such as 192.168.40.128/255.255.255.248.
# First, uncomment out these lines:
;client-config-dir ccd
;route 192.168.40.128 255.255.255.248

client-config-dir ccd 
ccd-exclusive  

route 192.168.190.0 255.255.255.0
route 192.168.192.0 255.255.255.0
route 192.168.0.0 255.255.240.0
route 10.50.0.0 255.255.240.0
  • В файле параметров клиента на vpn-сервере:
cd /etc/openvpn/ccd/
vi client3

ifconfig-push 10.8.0.14 10.8.0.13
iroute 192.168.0.0 255.255.240.0
iroute 10.50.0.0 255.255.240.0
  • И в подсети другого клиента, где сеть 10.50.0.0/24 должна быть доступна, на роутере или на хостах.
Клиент - физическая машина

Админов можно классифицировать по разным признакам, один из признаков - админы, как и коты, бывают ленивые и очень ленивые. Умные дядьки с хорошими зарплатами из центрального офиса сказали, что поднять Hyper-V сервер - это невозможная задача и времени надо как минимум до середины ноября, поэтому готовую виртуальную машину пришлось заливать на физическую и передавать уже в таком виде. Процесс описан в отдельной записи. Ещё надо не забыть включить в BIOS машины опцию Power On After Power Fail.

Клиент - Raspberry Pi 3

Начиная с третьей версии Малинка поддерживает Ubuntu. Два дистрибутива, что я нашел - не заработали. Дистрибутив с официальной страницы после обновления стал вываливаться в дамп. Второй дистрибутив с "raspberry2" в названии вообще не стартовал. Поставил Raspbian. Это моё первое знакомство с данной ОС. Логин/пароль по умолчанию pi/raspberry. Практически все команды работают, Debian он и есть.. - установить vim и команды задавать как vim ... Не нашел как отключить автоматическое обновление (а включено ли оно вообще?). Всё остальное также как и для других клиентов - включить root, убить пользователя pi и так далее. Рассмотрение настройки Малинки не входит в задачи этой статьи. Очень-очень кратко:

raspi-config

rm -rf /opt - удалим каталог с образцом видео 
df -h - проверяем свободное место

update-rc.d -f bluetooth remove
update-rc.d -f dhcpcd remove
vim /etc/network/interfaces - закомментировать всё, что не по делу
Добавление нового клиента

Через некоторое время потребуется добавить нового клиента. Генерим новые сертификаты на сервере:

. ./vars
./build-key client5

Другой хороший вариант - сгенерировать сразу клиентских сертификатов с запасом, штук десять.

Прописываем новую сеть в конфигурацию сервера server.conf, создаем файл параметров клиента в папке ccd. Берем болванку виртуальной машины и заливаем сертификаты, а старые удаляем. В начале этого процесса лучше изолировать машину от выхода в интернет, иначе она полезет к серверу и нарушит работу машины, с которой была снята эта болванка.

Подключение к клиентам

После прописывания основных маршрутов все клиенты доступны по SSH через туннель по своим адресам в туннеле - 10.8.0.X.

Заключение

Чего-то много опять получилось, реально статья - 5300+ слов. Наверное половину слов дают конфиги 🙂 А на написание и правку так вообще целый день ушел, больше даже, но написание подобных статей хорошо систематизирует знания. Openvpn сеть работает и чем дольше пользуюсь, тем больше мне нравится. Приятно, что открытое ПО стало уже таким зрелым и вкусным.

Строим сеть Openvpn: 8 комментариев

  1. /etc/default/ufw
    DEFAULT_FORWARD_POLICY="ACCEPT"
    слишком координально...
    лучше добавить правило, например:
    ufw route allow from 10.8.0.0/24 to 192.168.0.0/24
    хотя и это многовато.. 🙂

    1. Так, ещё раз всё проверил, что-то вы путаете. http://help.ubuntu.ru/wiki/руководство_по_ubuntu_server/безопасность/firewall
      Цитирую: 1. Во-первых, в ufw должно быть активировано перенаправление. Для этого нужно изменить конфигурацию двух файлов, в /etc/default/ufw измените DEFAULT_FORWARD_POLICY на “ACCEPT”
      И посмотрите в статье "Окончательный вид файрвола сервера:". Там мы видим, что разрешён трафик ssh отовсюду - он защищён паролем и сертификатом, разрешён трафик openvpn отовсюду - подключатся лишь клиенты с верным сертификатом и разрешен трафик NTP из внутренней сети. Никаких проблем в безопасности нет, DEFAULT_FORWARD_POLICY “ACCEPT” всего лишь правило по-умолчанию, без которого вообще никакой форвардинг пакетов через сервер невозможен.

      1. Возможно что то путаю, но у меня работает с DROP по умолчанию и правилом ufw route. Я это понимают так. Если openvpn сервер находится в локалке то да можно так
        /etc/default/ufw
        DEFAULT_FORWARD_POLICY="ACCEPT"
        Правило по умолчанию: Если не запрещено то куда угодно.
        В такой ситуации даже ufw disable не слишком опасно, но если на интернет шлюзе то лучше всетаки "DROP" и правило
        ufw route allow from 10.8.0.0/24 to 192.168.0.0/24
        (хотя и там лучше ограничить порты и протоколы до необходимых) - разрешает маршрутизацию только между подсетями 10.8.0 и 192.168.0
        На help.ubuntu.ru хорший мануал, но там эту проблему решают както непосредсвенно через iptable.. для меня слишком умно ))), а ufw route почемуто забыли.. см. man ufw
        Сама маршрутизация включается действительно в /etc/ufw/sysctl.conf :
        net/ipv4/ip_forward=1
        в Windows c помощью regedit кажется так:
        HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters для параметра IPEnableRouter на “1” и перезагрузить...

        1. Насколько понимаю в силу своего разумения - ufw закрывает не только трафик снаружи, но и внутри машины, а именно между сетевыми интерфейсами, если их несколько.
          DEFAULT_INPUT_POLICY="DROP"
          DEFAULT_OUTPUT_POLICY="ACCEPT"
          DEFAULT_FORWARD_POLICY="DROP"
          DEFAULT_APPLICATION_POLICY="SKIP"
          Вот чтобы интерфейсы имели возможность пересылать между собой трафик и нужно правило DEFAULT_FORWARD_POLICY="ACCEPT" и больше ни для чего, и больше ни на что оно не влияет. Можно его сделать DROP и точно указать с какого интерфейса на какой разрешено пересылать трафик? Да можно конечно. А зачем? Ведь это внутри машины всё. Зачем трафик внутри машины нагружать обсчётом? На это тратятся ресурсы. Считаю неоптимальным решением.

          1. Полнстью согласен. Оптимальное решение должно быть основано на конкретной ситуации и личных предпочтениях. Я только предложил еще один вариант конфигурации.

          2. Спасибо за комментарии, пришлось посидеть, поразбираться с устройством файрвола в Linux. Уже хорошо 🙂 Также чётче обозначилась необходимость закончить LPIC-1, потому что знаний курса Essentials, который пройдён на момент, явно недостаточно и довольно несложная вещь (как вопрос, который мы обсуждали) сначала превращается в гадание на кофейной гуще, а потом в высиживание интернета в поисках ответов - это про себя говорю. Надеюсь, вы тоже получили какую-то пользу от нашего обсуждения.

      2. Да точно в linux для включения маршрутизации нужно еще echo 1 > /proc/sys/net/ipv4/ip_forward

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *