linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Уроки
  • How it works
  • Симулятор
  • База знаний
  • Собеседование
Index
Categories
All entries
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
home/linux/kb/Сеть: L2 / L3/gre-tunnel

kb/network-l2-l3 ── Сеть: L2 / L3 ── intermediate

GRE-туннели и IPIP - point-to-point поверх IP

GRE - инкапсуляция любого L3 в IP (proto 47), 24 байта header. IPIP - тоньше, только IP-в-IP. mGRE - один интерфейс к multiple endpoint'ам. Без шифрования - обёртывают в IPsec. Используется в site-to-site VPN, BGP-полу-мешах.

view as markdownaka: gre, gre-tunnel, ipip, ip-in-ip, mgre

Зачем GRE и IPIP

Иногда нужен point-to-point туннель между двумя точками через обычный интернет: site-to-site VPN, точка-в-точку BGP-сессия, multicast-через-unicast (IGMP внутри туннеля). [[vxlan-overlay|VXLAN]] для этого слишком тяжёлый (ему нужен L2-сегмент); IPsec - готовая VPN но сложная.

GRE (Generic Routing Encapsulation, RFC 2784) - простейший universal туннель. Берёт IP-пакет (или Ethernet, IPv6, MPLS - что угодно), оборачивает в IP-пакет с GRE-header'ом, шлёт на другую сторону. Там распаковывается.

IPIP - частный случай: только IPv4-в-IPv4, без GRE-header'а. Overhead на пакет: IPIP добавляет только 20-байтный outer IP; GRE - 20 (IP) + 4 (минимальный GRE-header) = 24 байта.

Структура GRE-пакета

┌──────────────────────────────────────┐
│  outer IPv4 header (20 байт)         │ proto = 47 (GRE)
├──────────────────────────────────────┤
│  GRE header (4-16 байт)              │ optional checksum, key, sequence
├──────────────────────────────────────┤
│  payload protocol (что обернули)     │ IPv4 / IPv6 / Ethernet / MPLS
├──────────────────────────────────────┤
│  payload data                        │
└──────────────────────────────────────┘

GRE header базовый:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|C| |K|S| Reserved0       | Ver |         Protocol Type         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  • C - присутствует ли checksum
  • K - GRE Key (4 байта, после header'а если K=1)
  • S - sequence number
  • Protocol Type - что внутри (0x0800 = IPv4, 0x86DD = IPv6, 0x6558 = Ethernet)

Минимум - 4 байта. С checksum + key + sequence - до 16 байт.

IP outer header: protocol number = 47 (GRE) или 4 (IPIP).

GRE Key - multiplexing

Если между двумя хостами нужно несколько раздельных GRE-туннелей (один для prod-сети, другой для dev) - помогает GRE Key, 32-битный идентификатор туннеля. На приёме разбираешь по ключу.

Key - не для безопасности (передаётся в clear), просто способ логически разделить туннели в одной IP-паре.

Linux GRE

Создать GRE-туннель IPv4-в-IPv4:

ip tunnel add gre1 mode gre \
    local 203.0.113.1 \
    remote 198.51.100.1 \
    ttl 64 \
    key 1234
ip link set gre1 up
ip addr add 10.99.99.1/30 dev gre1
ip route add 192.168.20.0/24 dev gre1

IPIP:

ip tunnel add ipip1 mode ipip local 203.0.113.1 remote 198.51.100.1
ip link set ipip1 up
ip addr add 10.99.99.1/30 dev ipip1

Тип туннеля выбирается через mode:

ModeEncapsulationКогда
ipipIPv4 в IPv4минимум overhead, только v4
greIPv4 в IPv4 (с GRE)+ key, + multicast support
gretapEthernet в IP (через GRE)L2 туннель (как VXLAN, но GRE)
sitIPv6 в IPv4переход на IPv6 поверх IPv4-сети
ip6greIPv4/v6 в IPv6то же поверх IPv6
ip6tnlIPv6 в IPv6плотный v6-туннель

mGRE - multipoint GRE

Обычный GRE - точка-точка. Если у hub-and-spoke топологии 50 spoke'ов, на hub'е надо 50 туннелей. mGRE (multipoint GRE) решает: один интерфейс - множество удалённых endpoint'ов.

Cisco DMVPN использует mGRE + NHRP (Next Hop Resolution Protocol) для поиска remote IP. На Linux mGRE поддерживается через gre без remote параметра:

ip tunnel add mgre1 mode gre local 203.0.113.1 ttl 64 key 100

Но без NHRP нужно вручную добавлять neighbor:

ip neigh add 10.99.99.2 lladdr 198.51.100.2 dev mgre1
ip neigh add 10.99.99.3 lladdr 198.51.100.3 dev mgre1

GRE vs VXLAN vs IPsec

СвойствоGREVXLANIPsec
OSIL3 (или L2 в gretap)L2 over L3L3
Header overhead24 байта50 байт50-80 байт
Шифрованиенетнетда (AES-GCM)
Multitenantчерез GRE key (32 бит)VNI 24 битчерез SA
Multicast insideдада (через multicast/HER)сложно
Через NATплохо (нет L4-портов)хорошо (UDP)требует NAT-T
UnderlayIP unicastIP unicastIP unicast
Use casesite-to-site VPN, labDC overlay, k8s CNIsecure VPN

Главное: GRE не шифрует. Для безопасности обычно делают GRE-over-IPsec - сначала GRE-туннель (для multicast/L3-routing features), потом весь GRE-трафик в IPsec transport-mode для encryption.

NAT и GRE - почему не дружат

GRE - L3-протокол (proto 47), у него нет L4-портов. NAT-роутер делает NAPT по портам, GRE подменять не умеет.

Решения:

  • PPTP-style ALG в роутере (старо, often broken)
  • GRE через IPsec NAT-T (UDP encapsulation)
  • VXLAN вместо GRE - UDP-based, NAT-friendly out of the box

В современной инфраструктуре GRE стараются не пускать через NAT - либо public IP с обеих сторон, либо переходи на VXLAN.

MTU - неизбежная боль

Total overhead GRE поверх IPv4 = 20 (outer IP) + 4 (минимальный GRE-header) = 24 байта. С key - 28, с checksum+key+sequence - до 36. Если underlay MTU 1500 - tunnel MTU = 1476 (без опций).

ip link set gre1 mtu 1476

Если полезная нагрузка не лезет в 1476 - либо фрагментация (плохо), либо PMTUD (часто blackhole). См. [[mtu-and-pmtud|MTU и PMTUD]]. MSS clamping в iptables - стандартный фикс на gre0:

iptables -t mangle -A FORWARD -o gre1 -p tcp --tcp-flags SYN,RST SYN \
         -j TCPMSS --clamp-mss-to-pmtu

Где это применяется

  • Site-to-site VPN без шифрования (внутренние линки между офисами через MPLS-провайдера, который уже secure)
  • OSPF/BGP над интернетом - GRE-туннель + IGP внутри (multicast OSPF Hello требует подходящий link)
  • IPv6 поверх IPv4 интернета - sit туннели (исторически 6to4)
  • Cisco DMVPN - hub-and-spoke с mGRE + NHRP + IPsec
  • Calico CNI в IPIP-mode - когда underlay не BGP-friendly (см. [[cni-plugins|CNI plugins]])

Когда что-то пошло не так

  • Туннель не работает после старта - проверь IP-связность underlay (ping <remote>), потом firewall (proto 47 для GRE, proto 4 для IPIP). На AWS/GCP proto 47 часто блокирован - используй VXLAN.
  • Ассиметричный traffic - туннель up в одну сторону, down в другую. Проверь, что на обеих сторонах настроен match local/remote.
  • MTU blackhole - те же симптомы что у [[mtu-and-pmtud|VXLAN]]. ip link set gre1 mtu 1400 + MSS clamping.
  • ip tunnel show пустой, но ip link показывает туннель - intermixing старого ip tunnel API и нового через ip link. Используй один из них (ip link add ... type gre - современный).
  • GRE через NAT не работает - смотри секцию выше, GRE и NAT не дружат.
  • Multicast inside tunnel не идёт - убедись ttl поднят на обеих сторонах, IGMP snooping не режет.

Полезные настройки sysctl

  • net.ipv4.conf.all.rp_filter=0 для GRE-интерфейса (асимметричный routing нормален)
  • net.ipv4.ip_forward=1 - туннель почти всегда на роутере
  • net.ipv4.conf.gre1.accept_redirects=0 - параноидально

§ команды

bash
ip tunnel add gre1 mode gre local 203.0.113.1 remote 198.51.100.1

Создать GRE-туннель point-to-point между двумя public IP

bash
ip link add gre1 type gre local 203.0.113.1 remote 198.51.100.1 key 42

Современный способ через ip link, с GRE key для multiplexing

bash
ip link set gre1 mtu 1476 up

Установить MTU 1476 (1500 underlay - 24 GRE) и поднять интерфейс

bash
ip tunnel show

Список всех IP-туннелей в системе - GRE, IPIP, sit

bash
tcpdump -ni eth0 proto 47

Перехват GRE-трафика на underlay интерфейсе - debug

bash
ip route add 192.168.20.0/24 dev gre1

Маршрут в удалённую сеть через туннель

bash
iptables -t mangle -A FORWARD -o gre1 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

MSS clamping для туннеля - частая необходимость из-за PMTUD blackhole

bash
ip tunnel add sit1 mode sit local 203.0.113.1 remote 198.51.100.1

SIT-туннель: IPv6 поверх IPv4. Исторически использовался для 6to4

§ см. также

  • vxlan-overlayVXLAN - L2 overlay поверх L3-сетиVXLAN - L2-overlay через UDP/4789. 24-битный VNI = 16M сегментов (vs 4K у VLAN). VTEP делает encap/decap. BUM-трафик идёт через multicast или head-end replication. EVPN-VXLAN - control plane через BGP. Underlay MTU 1550 минимум.
  • mtu-and-pmtudMTU и Path MTU Discovery (PMTUD)MTU - максимум байт IP-пакета на интерфейсе. PMTUD ищет минимум на пути через ICMP "Fragmentation Needed". Если ICMP режут - blackhole больших пакетов. MSS clamping в iptables/nftables - стандартный фикс на туннелях VXLAN/IPsec.
  • ipsec-ikeIPsec и IKEv2 - стандарт корпоративных VPNIPsec - L3-VPN-стандарт. ESP инкапсулирует и шифрует, IKEv2 обменивается ключами. Tunnel-mode даёт новый IP-заголовок для site-to-site; transport-mode - host-to-host. На Linux это strongSwan.
  • routing-tableRouting tableТаблица маршрутизации - список «куда направлять пакеты с таким destination». Самая длинная (longest-prefix) подходящая запись выигрывает.
  • cmd-ipip - швейцарский нож сетевой настройки`ip` - фронт-энд iproute2, заменяет старые ifconfig/route/arp. Подкоманды: `ip addr` (адреса), `ip link` (интерфейсы), `ip route` (маршруты), `ip neigh` (ARP).
  • ipv6-basicsIPv6 - адресация и базовые концепцииIPv6 - 128-битные адреса в 8 группах по 16 бит. Link-local fe80::/10 для соседей, global для интернета. SLAAC выдаёт адрес автоматически через Router Advertisement. Neighbor Discovery (NDP) заменяет ARP.
Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки