Linux поддерживает множество видов туннелей. Это запутывает новичков, которым бывает сложно разобраться в различиях технологий, и понять то, каким туннелем лучше воспользоваться в конкретной ситуации. В материале, перевод которого мы сегодня публикуем, будет дан краткий обзор часто используемых туннельных интерфейсов ядра Linux. Сильно углубляться в эту тему мы не будем, рассмотрев лишь общие особенности туннелей и варианты их использования в Linux.
Автор этого материала полагает, что то, о чём пойдёт здесь речь, может быть интересно всем, кто имеет какое-то отношение к управлению компьютерными сетями. Список туннельных интерфейсов, а также справочные сведения о конкретной конфигурации можно получить с помощью iproute2-команды ip link help
.
Здесь будут рассмотрены следующие часто используемые интерфейсы: IPIP, SIT, ip6tnl, VTI и VTI6, GRE и GRETAP, GRE6 и GRE6TAP, FOU, GUE, GENEVE, ERSPAN и IP6ERSPAN.
Прочитав эту статью, вы узнаете об особенностях этих интерфейсов и выясните различия между ними. Вы научитесь их создавать и узнаете о ситуациях, в которых их лучше всего использовать.
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_ADDR
, REMOTE_IPv4_ADDR
, INTERNAL_IPV4_ADDR
и REMOTE_INTERNAL_SUBNET
нужно заменить на адреса, используемые в вашем окружении. То же самое справедливо и для других примеров конфигураций, которые мы будем рассматривать далее.
SIT
SIT (Simple Internet Transition) — это технология создания туннелей, главной целью существования которой является соединение изолированных IPv6-сетей через интернет с использованием протокола IPv4.
Изначально технология SIT могла работать лишь в режиме туннелирования «IPv6 over IPv4». Однако за годы развития она приобрела поддержку ещё нескольких режимов. В частности, это ipip
(то же самое было с IPIP-туннелем), ip6ip
, mplsip
и 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 поддерживают режимы ip6ip6
, ipip6
и 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
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:
# 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. Вот сводная таблица по ним.
Тип туннеля / подключения | Внешний заголовок | Инкапсулированный заголовок | Внутренний заголовок |
ipip | IPv4 | None | IPv4 |
sit | IPv4 | None | IPv4/IPv6 |
ip6tnl | IPv4 | None | IPv4/IPv6 |
vti | IPv4 | IPsec | IPv4 |
vti6 | IPv6 | IPsec | IPv6 |
gre | IPv4 | GRE | IPv4/IPv6 |
gretap | IPv4 | GRE | Ether + IPv4/IPv6 |
gre6 | IPv6 | GRE | IPv4/IPv6 |
gre6tap | IPv6 | GRE | Ether + IPv4/IPv6 |
fou | IPv4/IPv6 | UDP | IPv4/IPv6/GRE |
gue | IPv4/IPv6 | UDP + GUE | IPv4/IPv6/GRE |
geneve | IPv4/IPv6 | UDP + Geneve | Ether + IPv4/IPv6 |
erspan | IPv4 | GRE + ERSPAN | IPv4/IPv6 |
ip6erspan | IPv6 | GRE + ERSPAN | IPv4/IPv6 |
Обратите внимание на то, что все туннели, примеры создания которых здесь показаны, существуют только до перезагрузки сервера. Если вы хотите создать туннель, восстанавливающийся и после перезагрузки, рассмотрите возможность использования демона для настройки сети, наподобие NetworkManager, или примените подходящий механизм из используемого вами дистрибутива Linux.
Уважаемые читатели! Какими Linux-туннелями вы пользуетесь?
Автор: ru_vds