Привет, Хабр! Меня зовут Олег, я архитектор клиентских решений в Selectel. Недавно мы столкнулись с интересным клиентским кейсом при создании Full-Mesh сети. Расскажу, как пришлось тестировать VPN-сервисы, чтобы найти оптимальное решение.
Все результаты собрал в сводной таблице, чтобы наглядно показать разницу и аргументировать выбор.
К нам обратился клиент с задачей по переносу данных с арендованных выделенных серверов одного популярного в России поставщика услуг из Германии. На то было две причины:
- Невозможность простой и быстрой оплаты услуг, поскольку привязанная карта российского банка перестала работать.
- Защита от возможной эскалации санкционного давления (то есть полный запрет работы).
Если в первом случае мы помогли временно решить проблему, то во втором никаких гарантий дать не могли. Поэтому клиент принял решение мигрировать в Selectel, воспользовавшись специальным предложением.
C чем мы столкнулись
Компания арендовала в Германии такую инфраструктуру:
- два сервера-гипервизора на базе Qemu/KVM с управлением через libvirtd,
- два сервера c Docker-контейнерами для разработчиков и их заказной CRM/ERP-системой,
- несколько виртуальных машин на Linux и Windows Server 2019.
Со схемой можно ознакомиться ниже:
Сначала мы изучили текущее клиентское решение и предложили на его основе свою схему миграции, которая бережно относилась к текущей IT-инфраструктуре и при этом не теряла в отказоустойчивости.
Далее мы занялись обеспечением сетевой связности на втором уровне стека протоколов TCP/IP. Так мы смогли обеспечить клиенту «бесшовный» перенос виртуальных машин и сохранить IP-адреса. Чтобы оптимизировать бюджет, клиент выбрал серверы линейки Chipcore, в которых отсутствует «приватная сеть».
На этапе миграции остановились на следующей организации сетевой топологии. Так мы обеспечили единую L2-связность между дата-центром Selectel и зарубежным ЦОД:
Потенциальные кандидаты
Дело осталось за малым — подобрать VPN, который прост в настройке, поддерживает L2, полносвязную топологию и использует быстрые, криптостойкие алгоритмы шифрования.
Вариант с Wireguard был отброшен сразу: он не работает по L2, только по L3, хотя продукт достойный.
OpenVPN — в данном случае не лучший выбор, так как имеет клиент-серверную архитектуру. В случае возникновения проблем или при регламентном обслуживании сервера связность на L2 потеряется. Нам не хотелось создавать точку отказа.
Во время миграции можно было бы использовать OpenVPN, но хотелось сразу подготовить решение, которое не нужно дорабатывать.
Рассматривались следующие варианты:
- fastd,
- VpnCloud,
- Tinc.
Стоит отметить, что у разработчика VpnCloud удобный сайт. Есть подробные описания, проведены синтетические тесты и сравнены результаты, много «теории» и т.д. Есть даже таблица сравнения возможностей ПО:
К сожалению, там нет даже упоминания fastd, который использовался в проекте.
Выбирать, основываясь на субъективном мнении пользователей и разработчиков, не хотелось, поэтому решили провести лабораторное тестирование VPN-систем и составить свое предвзятое мнение ????.
Критерии, по которым оценивались кандидаты:
- скорость передачи данных через туннель,
- стабильность работы,
- простота и удобство настройки,
- кроссплатформенность, наличие готовых пакетов под различные дистрибутивы Linux,
- документация.
Важное лирическое отступление по MTU
При использовании VPN мы имеем дело с инкапсуляцией пакетов, поэтому важно правильно выставить значение MTU. Новый туннель добавляет дополнительные заголовки к пакету и снижает возможное количество передаваемых полезных данных (payload). Накладные расходы зависят как от типа туннельного интерфейса, так и от используемых алгоритмов шифрования данных.
Например, для нашего проекта получаем:
- Базовый MTU — 1 500 байт (стандарт для IEEE 802.3 Ethernet).
- TAP-интерфейс — дополнительно 28+14=42 байта.
- IPv4 дополнительных байт не добавляет. Если бы использовался IPv6, то общий MTU уменьшился еще на 20 байт.
- Шифрование — еще 24 байта.
Итого: 1500-42-24 = 1 434 байта
Что это означает на практике:
- При создании сетевого моста Linux или программного коммутатора (если вы захотите использовать Open vSwitch), в который предполагается добавить VPN-интерфейс, то MTU моста/свитча, как и MTU всех подключенных к нему Ethernet и виртуальных интерфейсов должен быть одинаковый, но при этом меньше или равен 1 434 байтам.
- Нужно убедиться, что в ОС на виртуальной машине на сетевом адаптере также выставлен правильный MTU, например, для ВМ с ОС Windows:
- Во избежании проблем с path mtu discovery blackhole на хостах Qemu/KVM нужно создать правило netfilter. Например, при использовании iptables:
sudo iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
С дополнительной информацией по решению проблемы можно ознакомиться здесь и здесь.
Тестирование
План тестирования:
- На нашей облачной платформе создаются три виртуальные машины в разных зонах доступности (и регионах). При этом используются разные дистрибутивы Linux (rpm-based и deb-based).
- Один раз запускаем iperf для измерения скорости передачи данных между машинами без VPN, фиксируем результат.
- Средствами пакетного менеджера из репозиториев устанавливаем тестируемый VPN на все серверы и настраиваем его для взаимодействия с другими пирами. Также настраиваем автоматический старт при перезагрузке машины. Если позволяет ПО, выставляем либо самый быстрый, либо рекомендуемый разработчиком алгоритм шифрования трафика. Важно: VpnCloud не позволяет задать алгоритм шифрования вручную — только автоматически после запуска внутреннего бенчмарка.
- Запускаем iperf на 30 минут, фиксируем скорость передачи данных, задержки, затем заносим данные в таблицу.
- Последовательно осуществляем остановку и запуск VPN-сервиса на всех виртуальных машинах и фиксируем прохождение трафика между остальными включенными пирами (убеждаемся, что VPN действительно полносвязный).
- После теста пакет с машины удаляется.
- Оцениваем VPN-сервисы по объявленным выше критериям, выставляя места от 1 до 3.
Виртуальные машины создаются с образами AlmaLinux 8 64-bit, CentOS 7 Minimal 64-bit и Ubuntu 22.04 LTS 64-bit. Так мы достигли следующей сетевой топологии:
Переходим к тестированию.
fastd
По установке все тривиально. Для RHEL-based дистрибутивов собранный пакет присутствует в EPEL, для Ubuntu — в universe.
Для AlmaLinux и CentOS убеждаемся, что EPEL задействован и ставим пакет:
sudo yum -y install epel-release && (yum repolist | grep -i epel)
sudo yum -y install fastd
Для Ubuntu устанавливаем штатно:
sudo apt-get --yes install fastd
Конфигурирование идентично для всех дистрибутивов в тесте. Смотрим на unit, поставляемый с пакетом:
sudo systemctl cat fastd@.service
[Unit]
Description=Fast and Secure Tunnelling Daemon (connection %I)
After=network.target
[Service]
Type=notify
ExecStart=/usr/bin/fastd --syslog-level info --syslog-ident fastd@%I -c /etc/fastd/%I/fastd.conf
ExecReload=/bin/kill -HUP $MAINPID
[Install]
WantedBy=multi-user.target
Создаем каталог и конфигурационный файл в нем:
sudo mkdir /etc/fastd/vpntest/ && sudo touch /etc/fastd/vpntest/fastd.conf
Генерируем публичный и приватный ключ для каждой машины:
fastd --generate-key
Вывод будет иметь следующий вид (ключи в production-конфигурациях не используются):
2022-03-03 11:35:15 +0300 --- Info: Reading 32 bytes from /dev/random...
Secret: f0a31725e3750e40c7664599359ef80dc209431c865ed3b56f94346c2009d96c
Public: 71fdf3236cd5e26a528449b5a9a7ab8c1d78382fa7c740685d4e717a67d21f2d
Содержимое раздела с пирами уникально на каждой виртуальной машине. У каждого будет свой secret и скрипты on up/down, а также закомментирован peer, в котором фигурирует непосредственно хост. Для примера здесь приведена конфигурация fastd на peer-01:
sudo cat /etc/fastd/vpntest/fastd.conf
Что получилось
# Log warnings and errors to stderr
log level warn;
# Log informational messages to syslog
log to syslog level info;
# Hides IP addresses in log output
hide ip addresses no;
# Hides MAC addresses in log output
hide mac addresses no;
# Sets the mode of the interface; the default is TAP mode.
# In TAP mode, a single interface will be created for all peers
# in multi-TAP and TUN mode, each peer gets its own interface.
# mode multitap;
mode tap;
# Use the L2TP kernel implementation for the “null@l2tp” method.
# Enabling offloading allows for significantly higher throughput,
# as data packets don’t need to be copied between kernel and userspace.
# We do not use methods without encryption so setting this option to
# "yes" does not make any sense
offload l2tp no;
# Set the interface name
interface "mesh-vpn";
# If set to no, fastd will create peer-specific interfaces
# only as long as there’s an active session with the peer.
# Does not have an effect in TUN mode.
#persist interface no;
persist interface yes;
# Set the interface MTU for TAP mode with xsalsa20/aes128 over IPv4 with a base MTU of 1492 (PPPoE)
# (see MTU selection documentation)
# The basic overhead of a fastd packet in TUN mode over IPv4 is 28 bytes plus method-specific overhead
# Method “null” uses 1 additional header byte, “null@l2tp” 8 bytes, and all other methods 24 bytes
# TAP mode needs 14 bytes more than TUN mode
# Tunneling over IPv6 needs 20 bytes more than IPv4
# If your base MTU is 1500 and you want to use TUN mode over IPv4 with any crypto method
# Choose 1500 - 28 - 24 = 1448 bytes.
mtu 1434;
# Enables or disabled forwarding packets between peers.
forward yes;
# Support salsa2012+umac #and null methods, prefer salsa2012+umac
method "salsa2012+umac";
# Bind to a fixed port, IPv4 only
bind 0.0.0.0:10000;
# Sets the user to run fastd as.
user "nobody";
# Sets the group to run fastd as.
# Use group "nogroup" in Debian/Ubuntu and "nobody" on RHEL-based distros.
group "nobody";
#group "nogroup";
# By default, fastd switches to the configured user
# and/or drops its POSIX capabilities after the on-up command has been run
drop capabilities yes;
# Configures a shell command that is run after the interface is created,
# before the interface is destroyed, when a handshake is sent to make
# a new connection, when a new peer connection has been established,
# or after a peer connection has been lost
#on pre-up [ sync | async ] "<command>";
#on up [ sync | async ] "<command>";
#on down [ sync | async ] "<command>";
#on post-down [ sync | async ] "<command>";
#on connect [ sync | async ] "<command>";
#on establish [ sync | async ] "<command>";
#on disestablish [ sync | async ] "<command>";
#on up sync "/usr/local/bin/peer-fastd up virtsrvbr0";
on up "ip addr add 172.16.0.11/24 dev mesh-vpn";
# Secret key generated by `fastd --generate-key`
secret "f0a31725e3750e40c7664599359ef80dc209431c865ed3b56f94346c2009d96c";
# An inline peer configuration.
# peer "peer-01" { remote 198.51.100.11:10000; key "71fdf3236cd5e26a528449b5a9a7ab8c1d78382fa7c740685d4e717a67d21f2d"; }
peer "peer-02" { remote 192.0.2.12:10000; key "b5b9a0187324e9581c332f9701411ee32da2d0d8c875f2bc0e6d1a72b4241ee2"; }
peer "peer-03" { remote 203.0.113.13:10000; key "c7eeafa25a59b910f85dd570dc27dd6889cf3acdf3f1561200f754b377b9d693"; }
# Include peers from the directory 'peers'
#include peers from "peers";
Запускаем демон и задействуем его при включении сервера:
sudo systemctl enable --now fastd@vpntest
Проверяем:
sudo systemctl status fastd@vpntest
fastd@vpntest.service - Fast and Secure Tunnelling Daemon (connection vpntest)
Loaded: loaded (/usr/lib/systemd/system/fastd@.service; enabled; vendor preset: disabled)
Active: active (running) since Thu 2022-03-03 11:45:52 MSK;
Main PID: 8021 (fastd)
Tasks: 1 (limit: 203248)
Memory: 948.0K
CGroup: /system.slice/system-fastd.slice/fastd@vpntest.service
└─8021 /usr/bin/fastd --syslog-level info --syslog-ident fastd@vpntest -c /etc/fastd/vpntest/fastd.conf
После подключения всех пиров в логах будут следующие строки:
sudo journalctl -u fastd@vpntest.service --no-pager --no-hostname | grep "connection with"
мар 05 11:47:36 fastd@vpntest[8021]: connection with <peer-02> established.
мар 05 11:47:39 fastd@vpntest[8021]: connection with <peer-03> established.
Устанавливаем iperf. Для RHEL-based дистрибутивов:
sudo yum -y install iperf
Для Debian соответственно:
sudo apt-get --yes install iperf
Запускаем утилиту в режиме сервера на одном из пиров, на втором — в режиме клиента и замеряем скорость соединения без использования туннеля:
peer-01>iperf -c 192.0.2.12 -e
peer-02>iperf -s
Результат
------------------------------------------------------------
Client connecting to 192.0.2.12, TCP port 5001 with pid 13242
Write buffer size: 128 KByte
TCP window size: 85.0 KByte (default)
------------------------------------------------------------
[ 3] local 198.51.100.11 port 38160 connected with 192.0.2.12 port 5001
[ ID] Interval Transfer Bandwidth Write/Err Rtry Cwnd/RTT
[ 3] 0.00-1800.00 sec 197.40 GBytes 942 Mbits/sec /0 3 462K/2543 us
ICMP-пинги:
peer-02>ping -c 120 -s -A 198.51.100.11
……
198.51.100.11 xmt/rcv/%loss = 120/120/0%, min/avg/max = 0.38/0.44/0.80
1 targets
1 alive
0 unreachable
0 unknown addresses
0 timeouts (waiting for response)
120 ICMP Echos sent
120 ICMP Echo Replies received
0 other ICMP received
0.38 ms (min round trip time)
0.44 ms (avg round trip time)
0.80 ms (max round trip time)
120.000 sec (elapsed real time)
Далее повторяем измерения, но уже через VPN-туннель:
peer-01>iperf -c 172.16.0.12 -e -t 1800 -i 60 -o iperf_fastd_btest.txt
peer-02>iperf -s
Результат (только полезные данные)
peer-01>cat iperf_fastd_btest.txt
------------------------------------------------------------
Client connecting to 172.16.0.12, TCP port 5001 with pid 15233 (1 flows)
Write buffer size: 131072 Byte
TOS set to 0x0 (Nagle on)
TCP window size: 45.0 KByte (default)
------------------------------------------------------------
[ 1] local 172.16.0.12%mesh-vpn port 42552 connected with 172.16.0.11 port 5001 (MSS=1382) (sock=3) (irtt/icwnd=475/13) (ct=0.55 ms) on 2022-03-03 07:04:56 (MSK)
[ ID] Interval Transfer Bandwidth Write/Err Rtry Cwnd/RTT(var) NetPwr
……………
[ 1] 0.00-1800.03 sec 187 GBytes 894 Mbits/sec 1534056/0 68845 149K/1278(59) us 87406
peer-02>ping -c 120 -s -A 172.16.0.11
……
172.16.0.11 xmt/rcv/%loss = 120/120/0%, min/avg/max = 0.38/0.44/0.80
1 targets
1 alive
0 unreachable
0 unknown addresses
0 timeouts (waiting for response)
120 ICMP Echos sent
120 ICMP Echo Replies received
0 other ICMP received
0.38 ms (min round trip time)
0.44 ms (avg round trip time)
0.80 ms (max round trip time)
120.000 sec (elapsed real time)
VpnCloud
Разработчик предоставляет готовые пакеты, которые доступны для скачивания и установки в разделе releases на GitHub. Для Debian/Ubuntu также можно воспользоваться репозиторием.
Для установки последней стабильной версии в AlmaLinux и CentOS выполняем:
sudo yum -y install
Для Ubuntu подключаем репозиторий и устанавливаем:
echo "deb https://repo.ddswd.de/deb stable main" | sudo tee /etc/apt/sources.list.d/vpncloud.list
wget https://repo.ddswd.de/deb/public.key -qO- | sudo apt-key add
sudo apt-get update && sudo apt-get --yes install vpncloud
Далее для конфигурирования можно воспользоваться мастером, который предоставляет TUI, работающий в трех режимах: базовом, продвинутом и экспертном. Запускается мастер следующим образом:
sudo vpncloud config
Вводим запрашиваемые данные и после его успешного выполнения по пути
/etc/vpncloud/${your_network_name}.net
создастся YAML-файл с настройками. Я мастером пользоваться не стал, изучил man vpncloud, пример из /etc/vpncloud/example.net.disabled
и сделал конфигурацию самостоятельно, предварительно сгенерировав ключи. На каждом из peer запускаем:vpncloud genkey
Private key: gLtF7RuP4Jbew55N1wGDr81TXgD10OeipRTjPtL28Hr
Public key: J1UYpeLbR9Jq51jbsfPKfyfPCKPcgoTpEsecxgSgDIW
Attention: Keep the private key secret and use only the public key on other nodes to establish trust.
Приведенные ключи в production-конфигурациях не используются.
Вносим ключи в конфигурацию на каждой виртуальной машине, не забываем добавить публичную часть ключа в доверенные на других серверах.
Пример файла конфигурации на peer-02
sudo cat /etc/vpncloud/vpntest.net
---
device:
type: tap
name: mesh-vpn-%d
ip: 172.16.0.12/24
crypto:
private-key: gLtF7RuP4Jbew55N1wGDr81TXgD10OeipRTjPtL28Hr
public-key: J1UYpeLbR9Jq51jbsfPKfyfPCKPcgoTpEsecxgSgDIW
trusted-keys:
- cG5BMfIyDBZghrNlopOE8QT06aUXYoaXHFJAwZxM84j
- BQK0a8clKrfiQGsPLDaByiT4ULyRZWbTnQcUYYJVXhZ
listen: 3210
peers:
- 198.51.100.11:3210
- 203.0.113.13:3210
peer-timeout: 600
mode: switch
switch-timeout: 600
# claims:
# - 172.16.0.0/24
port-forwarding: false
user: nobody
group: nogroup
Как и для предыдущего участника теста, изучаем Unit systemd пакета:
sudo systemctl cat vpncloud@.service
Что получилось
[Unit]
Description=VpnCloud network '%I'
After=network-online.target
Wants=network-online.target
PartOf=vpncloud.target
Documentation=man:vpncloud(1)
[Service]
Type=forking
ExecStart=/usr/bin/vpncloud --config /etc/vpncloud/%i.net --log-file /var/log/vpncloud-%i.log --stats-file /var/log/vpncloud-%i.stats --daemon --daemon --pid-file /run/vpncloud-%i.pid
PIDFile=/run/vpncloud-%i.pid
WorkingDirectory=/etc/vpncloud
RestartSec=5s
Restart=on-failure
TasksMax=10
MemoryMax=50M
PrivateTmp=yes
ProtectHome=yes
ProtectSystem=strict
ReadWritePaths=/var/log /run
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_SETGID CAP_SETUID CAP_SYS_CHROOT
DeviceAllow=/dev/null rw
DeviceAllow=/dev/net/tun rw
[Install]
WantedBy=multi-user.target
Запускаем его и задействуем старт при включении сервера:
sudo systemctl enable --now vpncloud@vpntest.service
Проверяем журнал:
sudo journalctl -u vpncloud@vpntest.service --no-pager | tail -3
мар 03 15:48:36 vpncloud[21820]: INFO - Crypto speeds: AES_128_GCM: 3495.9 MiB/s, AES_256_GCM: 3128.9 MiB/s, CHACHA20_POLY1305: 2011.0 MiB/s
мар 03 15:48:36 vpncloud[21820]: INFO - Running process as daemon
мар 03 15:48:36 systemd[1]: Started VpnCloud network 'vpntest'.
Теперь все готово для замера скорости в iperf.
peer-01>iperf -c 172.16.0.12 -e -t 1800 -i 60 -o iperf_vpncloud_btest.txt
peer-02>iperf -s
Результат (представлены только полезные данные):
cat iperf_vpncloud_btest.txt
>------------------------------------------------------------
Client connecting to 172.16.0.12, TCP port 5001 with pid 153600 (1 flows)
Write buffer size: 131072 Byte
TOS set to 0x0 (Nagle on)
TCP window size: 45.0 KByte (default)
------------------------------------------------------------
[ 1] local 172.16.0.11%mesh-vpn-0 port 42620 connected with 172.16.0.12 port 5001 (MSS=1361) (sock=3) (irtt/icwnd=400/13) (ct=0.42 ms) on 2022-03-03 16:04:08 (MSK)
[ ID] Interval Transfer Bandwidth Write/Err Rtry Cwnd/RTT(var) NetPwr
[ 1] 0.00-60.00 sec 6.23 GBytes 892 Mbits/sec 51056/0 300 1133K/10113(61) us 11029
[ 1] 60.00-120.00 sec 6.25 GBytes 894 Mbits/sec 51162/0 252 1031K/9197(102) us 12152
[ 1] 0.00-120.04 sec 12.5 GBytes 893 Mbits/sec 102219/0 552 1034K/10616(2769) us 10514
Результат идентичен показателям fastd в пределах погрешности.
Tinc
Tinc — весьма популярный проект. Готовые бинарные пакеты присутствуют, пожалуй, во всех дистрибутивах Linux и BSD. Для RHEL-based дистрибутивов собранный пакет присутствует в EPEL, для Ubuntu — в universe.
Для AlmaLinux и CentOS убеждаемся, что EPEL задействован и ставим пакет:
sudo yum -y install epel-release && (yum repolist | grep -i epel)
sudo yum -y install tinc
Для Ubuntu/Debian устанавливаем с помощью пакетного менеджера APT:
sudo apt-get --yes install tinc
Посмотрим, какой systemd-юнит нам предлагает мейнтейнер пакета:
sudo systemctl cat tinc@.service
[Unit]
Description=Tinc net %i
Documentation=info:tinc
Documentation=man:tinc(8) man:tinc.conf(5)
Documentation=http://tinc-vpn.org/docs/
PartOf=tinc.service
ReloadPropagatedFrom=tinc.service
[Service]
Type=simple
WorkingDirectory=/etc/tinc/%i
EnvironmentFile=/etc/default/tinc
ExecStart=/usr/sbin/tincd -n %i -D $EXTRA
ExecReload=/usr/sbin/tincd -n %i -kHUP
KillMode=mixed
Restart=on-failure
RestartSec=5
TimeoutStopSec=5
[Install]
WantedBy=tinc.service
Создаем каталог и конфигурационный файл в нем:
sudo mkdir -p /etc/tinc/vpntest/hosts && sudo touch /etc/tinc/vpntest/tinc.conf
Генерируем ключи:
sudo tincd -n vpntest -K
Generating 2048 bits keys:
.........+++++ p
.............................................................................+++++ q
Done.
Please enter a file to save private RSA key to [/etc/tinc/vpntest/rsa_key.priv]:
Please enter a file to save public RSA key to [/etc/tinc/vpntest/rsa_key.pub]:
Создадим конфигурацию. Для примера здесь приведена конфигурация Tinc на peer-01:
sudo cat /etc/tinc/vpntest/tinc.conf
Mode = switch
Name = peer01
Interface = mesh-vpn
AddressFamily = ipv4
Cipher = aes-256-cbc
PMTUDiscovery = yes
ConnectTo = peer02
ConnectTo = peer03
Затем в папке /etc/tinc/vpntest/hosts нужно создать конфигурационные файлы для других участников mesh-сети с сгенерированными публичными ключами (даны для примера, в production не используются и не должны использоваться).
Пример для peer-01
sudo cat /etc/tinc/vpntest/hosts/peer02
Address = 192.0.2.12
Subnet = 172.16.0.0/24
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAwrGjie2YhqFp+iEe57IHPMeUCILEeQbogbamQVV+0fQeaiqLFjcu
zKEu8FRAQL+e+bxBTZXH0oC0b6FzjYQYv46ag4PyMJUVZyOmonAhBavH74IC5hL1
mOadCS4GCJQiyKqPF9T+oXvUIUwmzUpzMYsSgetEYQYVzl1DH0b6L06Pc2OTuHEb
3LLF0cv1OuZFKDo7rgUxylySxd5WmS3Y1lr+8jOxyMNfJOuy7BgLwADakK6Xem46
J0NbniLBza+B2e/3A7XqVgwb5bbN1QLPubvzkHyNXYEAv17GoDCAwJGJNDUREv+P
WHc/6K+QhdAxRjzY2KA34EAFSujaVP6aKQIDAQAB
-----END RSA PUBLIC KEY-----
sudo cat /etc/tinc/vpntest/hosts/peer03
Address = 203.0.113.13
Subnet = 172.16.0.0/24
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAuT1Ddm3zDeGJVDorTnIJ0WoldNaLB318cje8fPb8Gsyu5IcEqQSr
lZJyGhci1aGXbeXox3Pz+VKxCG1LXf7lwhH1I4TdvWbncTT5JpR+3HzWN9Km9pJ4
Sjeco2GMx8urNpfgeKcJJ1/bZpo2oZUVRkeWa6pBtxQXpInzsIYIhxywtDz922nV
4NldkrjLMy0M14ZHQiT3LyWpbUlYz/Y514Rx5T/tRvWFPF9iXcwcaYkmmHMGMO7Z
kdJ4JixLfQGSVccNzT+MyHb3VN7y5mKWyhwfF7GHycmVyXJ4iPJs/RP9PPMdL28f
bpKyGCam9gWF07F05vHkdzV5liWtAjy+OQIDAQAB
-----END RSA PUBLIC KEY-----
Создаем скрипт, который будет выполняться при запуске tincd:
sudo touch /etc/tinc/vpntest/tinc-up && sudo chmod +x /etc/tinc/vpntest/tinc-up
со следующим содержимым (пример: опять же, для peer-01, для peer-02 и peer-03 вносятся соответствующие сетевой схеме адреса):
cat /etc/tinc/vpntest/tinc-up
#!/bin/sh
ip link set dev $INTERFACE up
ip addr add 172.16.0.11/24 dev $INTERFACE
Запускаем сервис и проверяем:
sudo systemctl enable --now tinc@vpntest.service
sudo journalctl -u tinc@vpntest.service --no-hostname --no-pager | tail -4
мар 03 18:21:29 systemd[1]: Started Tinc net vpntest.
мар 03 18:21:29 tincd[1539909]: tincd 1.0.36 starting, debug level 0
мар 03 18:21:29 tincd[1539909]: /dev/net/tun is a Linux tun/tap device (tap mode)
мар 03 18:21:29 tincd[1539909]: Ready
Тестируем задержки и скорость передачи данных через туннель:
peer-01>iperf -c 172.16.0.12 -e -t 1800 -i 60 -o iperf_tinc_btest.txt
peer-02>iperf -s
Получившийся результат
peer-01>cat iperf_tinc_btest.txt
------------------------------------------------------------
Client connecting to 172.16.0.12, TCP port 5001 with pid 15407 (1 flows)
Write buffer size: 131072 Byte
TOS set to 0x0 (Nagle on)
TCP window size: 45.0 KByte (default)
------------------------------------------------------------
[ 1] local 172.16.0.11%mesh-vpn port 42670 connected with 172.16.0.12 port 5001 (MSS=1385) (sock=3) (irtt/icwnd=474/13) (ct=0.61 ms) on 2022-03-03 18:42:45 (MSK)
[ ID] Interval Transfer Bandwidth Write/Err Rtry Cwnd/RTT(var) NetPwr
[ 1] 0.00-60.00 sec 5.42 GBytes 776 Mbits/sec 44390/0 3209 489K/5152(68) us 18822
[ 1] 60.00-120.00 sec 5.45 GBytes 780 Mbits/sec 44641/0 2692 403K/3807(116) us 25616
[ 1] 0.00-120.05 sec 10.9 GBytes 778 Mbits/sec 89032/0 5901 409K/4249(132) us 22878
Скорость у Tinc заметно «просела», а задержки оказались выше.
Результаты
Скорость передачи данных. Первое место между собой поделили VpnCloud и fastd, Tinc — на втором месте.
Стабильность работы. Все программы работали стабильно: ошибок, аварийных завершений и утечек памяти во время тестирования не наблюдалось. Все участники теста разделили первое (или последнее третье, если угодно) место.
Простота, удобство настройки. Этот пункт для оценки достаточно субъективный. Мне показалось, что fastd гибче в настройке, так как позволяет создать как монолитную конфигурацию, так и «разнести» по отдельным файлам.
Также для fastd был создан Ansible Playbook для его массового развертывания и настройки. Если эта тема интересна — могу написать отдельную статью или добавить ссылку в GitHub gists без подробного разбора.
Из плюсов — VpnCloud поддерживает beaconing. Это позволяет облегчить конфигурирование, но я его не использовал ни в тестировании, ни в production, так как ни в одном из случаев не было большого количества узлов.
Кроссплатформенность, наличие готовых пакетов. Как уже было упомянуто, пакеты собраны для всех распространенных дистрибутивов Linux. Но что касается других платформ (Windows, MacOS X, BSD), то тут Tinc — безусловный лидер. На втором месте — fastd (без поддержки Windows), а на третьем — VpnCloud, который на данный момент поддерживает только Linux.
Документация. Выскажу субъективное мнение. Считаю, что документация fastd лучше структурирована, используется Read the Docs со всеми вытекающими. Безусловно, стоит отметить VpnCloud. Документация Tinc хороша, если рассматривать ее с точки зрения принципа KISS: вся нужная информация в одном man-файле. Отдаю приз fastd, а второе место делят VpnCloud и Tinc.
Место | ПО | Версия | ЯП | Поддержка ОС Linux/Windows/BSD | Транспортные протоколы | Выбор алгоритма шифрования данных | Алгоритм(-ы) шифрования передаваемых данных |
---|---|---|---|---|---|---|---|
1 | fastd | v22 | C | да/нет/да | UDP | вручную | AES-256, AES-128, ChaCha20 |
2 | VpnCloud | 2.3.0 | Rust | да/нет/нет | UDP | авто | AES-128-CTR, Salsa20, Salsa2012 |
3 | Tinc | 1.0.36 | C | да/да/да | UDP+TCP | вручную | AES-256 (все поддерживаемые OpenSSL) |
Что в итоге
По результатам тестирования был выбран fastd, который и был использован в проекте.
Демоны fastd были сконфигурированы на всех серверах и при старте добавлялись в уже работающие мосты с предварительно настроенным MTU 1 400 байт, которые использует libvirtd, настроена сеть на серверах с Docker. После чего была осуществлена миграция виртуальных машин и persistent-данных для контейнеров. В эксплуатации новая информационная система находится с апреля текущего года и проблем с сетью и стабильностью работы мы не наблюдаем. Стоит отметить, что такое решение можно при необходимости использовать и в Proxmox VE.
Нам удалось предоставить клиенту кастомное решение, которое полностью закрывало его потребности во время миграции. Для этого пришлось проделать исследование и провести ряд тестов, что положительно сказалось на результате и комфорте эксплуатации проекта.
Комментарии (7)
Harliff
22.11.2022 20:27Подскажите, а vxlan/geneve поверх L3 - не рассматривали?
Kot1gruN Автор
23.11.2022 12:48Конечно, рассматривали VxLAN и NVGRE. Мы любим VxLAN.
Планировали воспользоваться этим и этим гайдами.
Administrative effort для клиента показался выше). Им хотелось что-то простого и монолитного, поставил, добавил в бридж и забыл.
А тут надо было перейти на OVS + Strongswan, и получается по интерфейсу на каждый туннель.
Но мы готовы протестировать и сравнить OpenvSwitch, если это будет интересно.
juffinhalli
23.11.2022 11:26+1Имхо нужны очень веские причины чтобы растягивать L2 на два датацентра. Проблемы с каналом связи между ними могут сильно аффектить работу сетевых приложений не рассчитанных на высокий latency (mongodb например).
Adjuster2004
По 1 и 2 варианту не стали тестировать по TCP?
В части стран просто блокируется UDP.
Kot1gruN Автор
Протестировать TCP можно было бы только у tinc, у него есть опция - TCPonly (и если один из пиров за NAT еще поможет IndirectData). fastd и vpncloud используют только UDP, увы.