VPN-туннель без шифрования трафика (GRE-тунель) в Ubuntu Linux


Давайте с вами рассмотрим довольно популярную ситуацию с объединением группы виртуальных или физических серверов на площадке хостинг провайдера предоставляющего дополнительно серую подсеть которая объединяет его физические и VPS сервера, такими провайдерами являются практически все облачные сервисы наподобие Amazon и несколько крупных провайдеров VPS и физических серверов наподобие Hetzner.

Настройка GRE-тунеля в Linux

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

Немного размышлений про GRE-туннель

Следовательно, вам в любом случае придется для объединения вашей виртуальной сети в некий кластер строить еще одну виртуальную сеть, но при этом уже вашу собственную и вот тут то мы и подходим к самому интересному вопросу как можно задействовать эту самую "серую сеть", для того чтобы снизить нагрузку на хост-сервера при построении VPN-сети. Для интересующихся вопросом достаточно ли велика доп-нагрузка при построении VPN я уже давно подготовил статью "Какую дополнительную нагрузку на процессор создает копирование данных по сети (защищенное и без криптозащиты)" и рекомендую ознакомиться с проведенными тестами.

Сразу скажу, что использовать VLAN-ы на управляющей сети у вас не получится (я пробовал на Amazon и был практически на 100% уверен, что ничего не получится и естественно, что не ошибся), OpenVPN создает большую нагрузку на процессор при интенсивном взаимодействии нод, а L2TP мне не подошел по той причине, что мне требовался виртуальный сетевой адаптер как при использовании OpenVPN. В результате ряда экспериментов я остановился на GRE-туннелях и в принципе меня в этом решении все устраивает (не шифрованный трафик в управляющей сети, сможет перехватывать только ваш хостинг провайдер, но не будьте параноиком ведь он может и дамп всей вашей машины при желании сделать и покопаться там).

Более подробно про GRE-тунели вы можете почитать на Википедии: https://en.wikipedia.org/wiki/Generic_Routing_Encapsulation

У GRE-туннелей довольно много недостатков связанных с тем, что он не шифрованный, неприспособлен для работы с NAT, GRE-трафик режется провайдерами и т.п., но если уж он работает, то работает. Настраивается gre-тунель не просто, а очень просто и я вам сейчас продемонстрирую это на примере. И еще раз повторюсь, пока меня тряпками не закидали, что GRE- это не VPN в полноценном его понимании, а протокол инкапсуляции информации о маршрутизации и передаваемой информации в IP-пакеты (в общем, лучше почитайте Википедию, а я на практике сосредоточусь).

Пример объединения двух KVM-хостов GRE-туннелем

Итак, мне требуется объединить для хоста KVM виртуализации с адресами 10.1.1.102 и 10.1.1.29 на каждой из них создан сетевой мост (master-bridge) в который включаются виртуальные машины:

auto master-bridge
iface master-bridge inet static
    address 10.212.11.1
    netmask 255.255.0.0
    bridge_ports none
    bridge_stp off
    bridge_fd 0
    bridge_maxwait 0
    post-up /etc/firewall/firewall.sh

На стороне каждого из LibVirt создана следующая виртуальная сеть (и про это я тоже писал в статье: Создание сети типа мост для платформы виртуализации KVM при помощи Libvirt ):

<network>
  <name>master-bridge</name>
  <forward mode="bridge"/>
  <bridge name="master-bridge"/>
</network>

Соответственно я хотел бы объединить эти два сетевых моста при помощи GRE-тунеля, чем мы сейчас и займемся, а первое что нам потребуется сделать, это подключить соответствующий модуль (как и в случае с настройкой VLAN-ов описанный в статье Работа с VLAN-интерфейсами в Ubuntu Linux) и установить его в автозагрузку при старте сервера:

# modprobe ip_gre
# echo "ip_gre" >> /etc/modules

Настраиваем GRE-туннель на первой ноде:

# ip link add gre-link type gretap local 10.1.1.102 remote 10.1.1.29 dev enp3s0

На второй ноде естественно меняем местами remote и local:

# ip link add gre-link type gretap local 10.1.1.29 remote 10.1.1.102 dev enp3s0

На обеих нодах поднимаем интерфейсы:

# ip link set gre-link up

Добавляем интерфейсы GRE в сетевой мост master-bridge:

# brctl addif master-bridge gre-link

Если вы на этом этапе получаете ошибку "can't add gre-link to bridge master-bridge: Invalid argument", то вероятнее всего вы используете режим просто gre (по умолчанию точка-точка), а не gretap (полноценный интерфейс) и как вы понимаете точка-точка в сетевой мост добавить не получится и вам придется использовать маршрутизацию вместо мостов.

Для удаления моста используйте команду:

# ip tunnel del gre-link

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

# ping 10.212.11.201

И наоборот:

# ping 10.212.11.1

Ну а куда дополнить эти параметры для автоподнятия соедиенения при старте сервера, тут как говориться на вкус и цвет и можно при помощи небольшого хака их вообще в /etc/network/interfaces добавить:

auto gre1
    iface gre1 inet static
    address 0.0.0.0
    netmask 0.0.0.0
    pre-up ip tunnel add gre1 mode gre remote 173.230.145.76 local 173.230.147.224
    post-down ip tunnel del gre1