Linux поддерживает множество видов туннелей. Это запутывает новичков, которым бывает сложно разобраться в различиях технологий, и понять то, каким туннелем лучше воспользоваться в конкретной ситуации. В материале, перевод которого мы сегодня публикуем, будет дан краткий обзор часто используемых туннельных интерфейсов ядра Linux. Сильно углубляться в эту тему мы не будем, рассмотрев лишь общие особенности туннелей и варианты их использования в Linux.

IPIP

Туннель IPIP, как можно понять из его названия — это туннель, работающий в режиме «IP over IP» (RFC 2003). Заголовок пакета туннеля IPIP выглядит так, как показано ниже.

Заголовок пакета туннеля IPIP

Такие туннели обычно используются для соединения двух внутренних IPv4-подсетей через общедоступную IPv4-сеть (интернет). Применение IPIP создаёт минимальную дополнительную нагрузку на систему, но по такому туннелю можно выполнять только однонаправленную передачу данных (unicast). То есть, построив подобный туннель, нельзя будет использовать его для групповой передачи данных (multicast).

IPIP-туннели поддерживают режимы «IP over IP» и «MPLS over IP».

Обратите внимание на то, что когда загружен модуль ipip, или когда впервые создано IPIP-устройство, ядро Linux создаст в каждом пространстве имён устройство по умолчанию tunl0 с атрибутами local=any и remote=any. Получая IPIP-пакеты, ядро, в определённых случаях, будет перенаправлять их на tunl0 как на устройство, используемое по умолчанию. Это происходит тогда, когда ядро не может найти другого устройства, атрибуты local/remote которого более точно соответствуют адресам источника и приёмника пакетов.

Вот как создать IPIP-туннель:

На сервере A:

ip link add name ipip0 type ipip local LOCAL_IPv4_ADDR remote REMOTE_IPv4_ADDR
ip link set ipip0 up
ip addr add INTERNAL_IPV4_ADDR/24 dev ipip0
Add a remote internal subnet route if the endpoints don’t belong to the same subnet
ip route add REMOTE_INTERNAL_SUBNET/24 dev ipip0

На сервере B:
ip link add name ipip0 type ipip local LOCAL_IPv4_ADDR remote REMOTE_IPv4_ADDR
ip link set ipip0 up
ip addr add INTERNAL_IPV4_ADDR/24 dev ipip0
ip route add REMOTE_INTERNAL_SUBNET/24 dev ipip0

Обратите внимание на то, что при использовании этой конфигурации её нужно привести в соответствие с реальными данными. В частности, LOCAL_IPv4_ADDRREMOTE_IPv4_ADDRINTERNAL_IPV4_ADDR и REMOTE_INTERNAL_SUBNET нужно заменить на адреса, используемые в вашем окружении. То же самое справедливо и для других примеров конфигураций, которые мы будем рассматривать далее.

SIT

SIT (Simple Internet Transition) — это технология создания туннелей, главной целью существования которой является соединение изолированных IPv6-сетей через интернет с использованием протокола IPv4.

Изначально технология SIT могла работать лишь в режиме туннелирования «IPv6 over IPv4». Однако за годы развития она приобрела поддержку ещё нескольких режимов. В частности, это ipip (то же самое было с IPIP-туннелем), ip6ipmplsip и any.

Режим any используется для работы с IP- и IPv6-трафиком, что может оказаться полезным в некоторых ситуациях. SIT-туннели также поддерживают ISATAP. Вот пример использования этой технологии.

Заголовок SIT-пакета выглядит так, как показано ниже.

Заголовок пакета туннеля SIT

Когда загружается модуль sit, ядро Linux создаёт устройство по умолчанию sit0.

Вот как создать SIT-туннель (эти действия надо выполнить на серверах A и B):

ip link add name sit1 type sit local LOCAL_IPv4_ADDR remote REMOTE_IPv4_ADDR mode any
ip link set sit1 up
ip addr add INTERNAL_IPV4_ADDR/24 dev sit1

Ip6tnl

Интерфейс ip6tnl работает в режиме «IPv4/IPv6 over IPv6». Он похож на IPv6-версию туннеля SIT. Вот как выглядит заголовок пакета ip6tnl.

Заголовок пакета туннеля ip6tnl

Туннели ip6tnl поддерживают режимы ip6ip6ipip6 и any. Режим ipip6 представлен схемой «IPv4 over IPv6», режим ip6ip6 — это «IPv6 over IPv6». Режим any поддерживает обе схемы.

Когда загружается модуль ip6tnl, ядро Linux создаёт устройство по умолчанию с именем ip6tnl0.

Вот как создать туннель ip6tnl:

ip link add name ipip6 type ip6tnl local LOCAL_IPv6_ADDR remote REMOTE_IPv6_ADDR mode any

VTI и VTI6

Интерфейс VTI (Virtual Tunnel Interface) в Linux похож на интерфейс VTI Cisco и на Juniper-реализацию защищённого туннеля (st.xx).

Этот драйвер туннелирования реализует IP-инкапсуляцию, что может быть использовано с xfrm для создания защищённых туннелей и для последующего использования поверх таких туннелей маршрутизации уровня ядра.

В целом, VTI-туннели работают почти так же как туннели IPIP или SIT. Исключением является то, что они задействуют fwmark и инкапсуляцию/декапсуляцию IPsec.

VTI6 — это IPv6-эквивалент VTI.

Вот как создать VTI-туннель:

ip link add name vti1 type vti key VTI_KEY local LOCAL_IPv4_ADDR remote REMOTE_IPv4_ADDR
ip link set vti1 up
ip addr add LOCAL_VIRTUAL_ADDR/24 dev vti1
ip xfrm state add src LOCAL_IPv4_ADDR dst REMOTE_IPv4_ADDR spi SPI PROTO ALGR mode tunnel
ip xfrm state add src REMOTE_IPv4_ADDR dst LOCAL_IPv4_ADDR spi SPI PROTO ALGR mode tunnel
ip xfrm policy add dir in tmpl src REMOTE_IPv4_ADDR dst LOCAL_IPv4_ADDR PROTO mode tunnel mark VTI_KEY
ip xfrm policy add dir out tmpl src LOCAL_IPv4_ADDR dst REMOTE_IPv4_ADDR PROTO mode tunnel mark VTI_KEY

Кроме того, конфигурировать IPsec можно с помощью libreswan или strongSwan.

GRE и GRETAP

Технология GRE (Generic Routing Encapsulation) описана в RFC 2784. При GRE-туннелировании между заголовками внутреннего и внешнего IP-пакета добавляется дополнительный заголовок GRE.

Теоретически, GRE может инкапсулировать пакеты любого протокола 3 уровня с допустимым Ethernet-типом. Это отличает технологию GRE от технологии IPIP, которая поддерживает лишь инкапсуляцию IP-пакетов. Вот как выглядит заголовок пакета при использовании технологии GRE.

Заголовок пакета туннеля GRE

Обратите внимание на то, что туннели GRE позволяют выполнять групповую передачу данных и поддерживают IPv6.

При загрузке модуля gre ядро Linux создаёт устройство по умолчанию gre0.

Вот как создать туннель GRE:

ip link add name gre1 type gre local LOCAL_IPv4_ADDR remote REMOTE_IPv4_ADDR [seq] key KEY

В то время как туннели GRE работают на 3 уровне модели OSI, туннели GRETAP работают на 2 уровне OSI. Это означает, что одними из внутренних заголовков соответствующих пакетов являются Ethernet-заголовки.

Заголовок пакета туннеля GRETAP

Вот как создать туннель GRETAP:

ip link add name gretap1 type gretap local LOCAL_IPv4_ADDR remote REMOTE_IPv4_ADDR

GRE6 и GRE6TAP

GRE6 — это IPv6-эквивалент GRE. Туннели GRE6 позволяют инкапсулировать любые протоколы 3 уровня в IPv6. Вот как выглядит заголовок пакета GRE6.

Заголовок пакета туннеля GRE6

В туннелях GRE6TAP, как и в туннелях GRETAP, среди внутренних заголовков пакета есть и Ethernet-заголовки.

Заголовок пакета туннеля GRE6TAP

Вот как создать туннель GRE:

ip link add name gre1 type gre6 local LOCAL_IPv6_ADDR remote REMOTE_IPv6_ADDR
ip link add name gretap1 type gretap6 local LOCAL_IPv6_ADDR remote REMOTE_IPv6_ADDR
[/simtrm]
FOU
Туннелирование может выполняться на разных уровнях сетевого стека. Туннели IPIP, SIT и GRE существуют на уровне IP. А туннели FOU (они устроены по схеме «foo over UDP») работают на уровне UDP.
В применении UDP-туннелирования есть некоторые преимущества перед IP-туннелированием. Дело в том, что протокол UDP работает с существующей аппаратной инфраструктурой.
Например, это RSS в сетевых картах, ECMP в коммутаторах, это технологии расчёта контрольных сумм без участия центрального процессора. Применение соответствующего FOU-патча для разработчиков показывает значительное увеличение производительности для протоколов SIT и IPIP.
В настоящее время FOU-туннели поддерживают инкапсуляцию протоколов на основе IPIP, SIT и GRE. Вот как может выглядеть заголовок FOU-пакета.
Заголовок пакета туннеля FOU
Вот как создать туннель FOU:
[simterm]
ip fou add port 5555 ipproto 4
ip link add name tun1 type ipip remote 192.168.1.1 local 192.168.1.2 ttl 225 encap fou encap-sport auto encap-dport 5555

Первая команда настраивает принимающий порт FOU для IPIP, привязанный к номеру 5555. Для использования GRE нужно использовать ipproto 47. Вторая команда настраивает новый виртуальный интерфейс IPIP (tun1), рассчитанный на FOU-инкапсуляцию, целевым портом которого является 5555.

Обратите внимание на то, что FOU-туннели не поддерживаются в Red Hat Enterprise Linux.

GUE

Ещё одна разновидность UDP-туннелирования представлена технологией GUE (Generic UDP Encapsulation). Разница между FOU и GUE заключается в том, что у GUE имеется собственный заголовок, который содержит сведения о протоколе и другие данные.

В настоящее время туннели GUE поддерживают внутреннюю инкапсуляцию IPIP, SIT и GRE. Вот как может выглядеть заголовок GUE-пакета.

Заголовок пакета туннеля GUE

Вот как создать GUE-туннель:

ip fou add port 5555 gue
ip link add name tun1 type ipip remote 192.168.1.1 local 192.168.1.2 ttl 225 encap gue encap-sport auto encap-dport 5555

Благодаря этим командам будет создан принимающий GUE-порт для IPIP, привязанный к номеру 5555, и IPIP-туннель, настроенный на GUE-инкапсуляцию.

GUE-туннели не поддерживаются в Red Hat Enterprise Linux.

GENEVE

Туннели GENEVE (Generic Network Virtualization Encapsulation) поддерживают все возможности XLAN, NVGRE и STT. Технология GENEVE спроектирована с учётом обхода выявленных ограничений этих трёх технологий. Многие считают, что данная технология способна, в перспективе, полностью заменить эти три более старых формата. Вот как выглядит заголовок пакета туннеля GENEVE.

Заголовок пакета туннеля GENEVE

Этот заголовок похож на заголовок VXLAN-пакета. Основное различие между ними заключается в том, что заголовок GENEVE является более гибким. Он позволяет очень легко реализовывать новые возможности путём расширения заголовков с помощью полей Type-Length-Value (TLV).

Подробности о GENEVE можно узнать здесь и здесь.

GENEVE используется в SDN-решении Open Virtual Network (OVN) как стандартное средство инкапсуляции. Вот как создать туннель GENEVE:

ip link add name geneve0 type geneve id VNI remote REMOTE_IPv4_ADDR

ERSPAN и IP6ERSPAN

Технология ERSPAN (Encapsulated Remote Switched Port Analyzer) использует GRE-инкапсуляцию для расширения базовых возможностей по зеркалированию портов со 2 уровня до 3 уровня. Это позволяет пересылать зеркалируемый трафик по маршрутизируемой IP-сети. Вот как выглядит заголовок пакета ERSPAN.

Заголовок пакета туннеля ERSPAN

Туннели ERSPAN позволяют Linux-хостам действовать в роли источника трафика ERSPAN и отправлять отзеркалированный ERSPAN-трафик либо на удалённый хост, либо в некий пункт назначения ERSPAN, который принимает и обрабатывает ERSPAN-пакеты, сгенерированные коммутаторами Cisco или другими устройствами, поддерживающими ERSPAN. Подобную систему можно использовать для анализа и диагностики сети, для выявления вредоносного трафика.

Linux в настоящее время поддерживает большинство возможностей двух версий ERSPAN — v1 (type II) и v2 (type III).

Вот как создавать ERSPAN-туннели:

ip link add dev erspan1 type erspan local LOCAL_IPv4_ADDR remote REMOTE_IPv4_ADDR seq key KEY erspan_ver 1 erspan IDX

Ещё можно поступить так:

ip link add dev erspan1 type erspan local LOCAL_IPv4_ADDR remote REMOTE_IPv4_ADDR seq key KEY erspan_ver 2 erspan_dir DIRECTION erspan_hwid HWID

Добавим tc-фильтр для мониторинга трафика:

tc qdisc add dev MONITOR_DEV handle ffff: ingress
tc filter add dev MONITOR_DEV parent ffff: matchall skip_hw action mirred egress mirror dev erspan1

Итоги

Мы рассмотрели здесь довольно много технологий создания туннелей в Linux. Вот сводная таблица по ним.

Тип туннеля / подключенияВнешний заголовокИнкапсулированный заголовокВнутренний заголовок
ipipIPv4NoneIPv4
sitIPv4NoneIPv4/IPv6
ip6tnlIPv4NoneIPv4/IPv6
vtiIPv4IPsecIPv4
vti6IPv6IPsecIPv6
greIPv4GREIPv4/IPv6
gretapIPv4GREEther + IPv4/IPv6
gre6IPv6GREIPv4/IPv6
gre6tapIPv6GREEther + IPv4/IPv6
fouIPv4/IPv6UDPIPv4/IPv6/GRE
gueIPv4/IPv6UDP + GUEIPv4/IPv6/GRE
geneveIPv4/IPv6UDP + GeneveEther + IPv4/IPv6
erspanIPv4GRE + ERSPANIPv4/IPv6
ip6erspanIPv6GRE + ERSPANIPv4/IPv6

Обратите внимание на то, что все туннели, примеры создания которых здесь показаны, существуют только до перезагрузки сервера. Если вы хотите создать туннель, восстанавливающийся и после перезагрузки, рассмотрите возможность использования демона для настройки сети, наподобие NetworkManager, или примените подходящий механизм из используемого вами дистрибутива Linux.

Источник