Настройка GRE туннеля через IPv6: практическое руководство

Владислав Павлович

Владислав Павлович

22 ноября 2025 • 13 мин чтения • 192

Проксирование трафика с сохранением исходного IP-адреса — задача, которая часто встречается при построении распределённой инфраструктуры. GRE туннели позволяют элегантно решить эту проблему, создавая виртуальный канал между серверами. В отличие от традиционных методов с использованием DNAT, подход с чистой маршрутизацией обеспечивает большую гибкость и производительность.

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

GRE (Generic Routing Encapsulation) — это протокол туннелирования, который позволяет инкапсулировать практически любой сетевой протокол внутри IP-пакетов, создавая виртуальные point-to-point соединения.

1. Архитектура решения

Схема работы

Наша схема состоит из двух серверов:

  • VPS (источник) — принимает входящий трафик на PROXY_IP
  • Dedicated (назначение) — обрабатывает трафик и возвращает ответы

Трафик проходит следующий путь:

  1. Клиент подключается к PROXY_IP на VPS
  2. VPS инкапсулирует пакеты в GRE туннель
  3. Туннель проходит по IPv6 между серверами
  4. Dedicated-сервер декапсулирует пакеты и обрабатывает их
  5. Ответы возвращаются тем же путём

Преимущества подхода

  • Сохранение источника трафика — конечный сервер видит реальный IP клиента
  • Использование IPv6 — экономия IPv4-адресов и обход некоторых сетевых ограничений
  • Чистая маршрутизация — отсутствие NAT упрощает отладку и повышает производительность
  • Гибкость — легко масштабируется на несколько серверов

Важно!
GRE туннели не шифруют трафик. Если требуется конфиденциальность, используйте IPsec поверх GRE или альтернативные решения типа WireGuard.

2. Подготовка к настройке

Проверка требований

Перед началом настройки убедитесь в выполнении следующих условий:

  • Ядро Linux версии 3.7 или новее (для поддержки ip6_gre)
  • Наличие IPv6-адресов на обоих серверах
  • Доступность серверов друг для друга по IPv6
  • Свободный IPv4-адрес для проксирования
bash
# Проверка версии ядра
uname -r

# Проверка наличия модуля ip6_gre
modprobe ip6_gre && echo "Модуль доступен" || echo "Модуль отсутствует"

# Проверка IPv6 связности
ping6 -c 3 <ipv6-адрес-удалённого-сервера>

# Проверка загруженных туннельных модулей
lsmod | grep gre

Определение переменных окружения

Для удобства работы определим все необходимые параметры как переменные. Это упростит копирование команд и снизит вероятность ошибок.

bash
# Адреса внутри туннеля (частная сеть)
SRC_TNL_IP=10.10.10.1    # IP туннеля на VPS
DST_TNL_IP=10.10.10.2    # IP туннеля на дедике

# IPv4-адрес для проксирования
PROXY_IP=203.0.113.50    # Замените на ваш адрес

# IPv6-адреса серверов (для транспорта туннеля)
SRC_IP6=2001:db8::1      # IPv6 VPS
DST_IP6=2001:db8::2      # IPv6 дедика

Совет
Сохраните эти переменные в файл /root/gre-config.sh для быстрого повторного использования:

bash
export SRC_TNL_IP=10.10.10.1
export DST_TNL_IP=10.10.10.2
export PROXY_IP=203.0.113.50
export SRC_IP6=2001:db8::1
export DST_IP6=2001:db8::2

Загрузите переменные:

bash
source /root/gre-config.sh

3. Настройка VPS (входной точки)

VPS принимает входящий трафик и направляет его через туннель на dedicated-сервер.

Включение IP-форвардинга

Первым делом необходимо разрешить серверу пересылать пакеты между интерфейсами:

bash
# Включение немедленно
sysctl -w net.ipv4.ip_forward=1

# Постоянное включение после перезагрузки
sed -i 's/.*net\.ipv4\.ip_forward.*/net.ipv4.ip_forward=1/' /etc/sysctl.d/99-sysctl.conf

# Если файл не существует, создаём
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.d/99-sysctl.conf

Настройка сетевого интерфейса

Добавьте следующий блок в конец файла /etc/network/interfaces:

text
auto gre1
iface gre1 inet static
    address $SRC_TNL_IP
    netmask 255.255.255.0
    # Создание туннеля при поднятии интерфейса
    pre-up ip -6 tunnel add gre1 mode ip6gre local $SRC_IP6 remote $DST_IP6 ttl 255
    post-down ip tunnel del gre1

    # Удаление PROXY_IP с физического интерфейса
    up ip a del $PROXY_IP/24 dev ens3

    # ARP-прокси для перехвата трафика
    up arp -sD $PROXY_IP ens3 pub

    # Создание таблицы маршрутизации для туннеля
    up ip route add default via $DST_TNL_IP dev gre1 table 100
    up ip rule add from all to $PROXY_IP/32 lookup 100

    # Исправление MSS для предотвращения фрагментации
    up iptables -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

    # Очистка при выключении интерфейса
    post-down arp -d $PROXY_IP dev ens3
    post-down ip route del default via $DST_TNL_IP dev gre1 table 100
    post-down ip rule del from all to $PROXY_IP/32 lookup 100
    post-down iptables -D FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

Понимание конфигурации

Разберём ключевые элементы:

  • ip -6 tunnel add — создаёт GRE туннель поверх IPv6
  • arp -sD … pub — публикует ARP-запись, перехватывая трафик для PROXY_IP
  • table 100 — отдельная таблица маршрутизации для изоляции правил туннеля
  • ip rule — политика маршрутизации (policy routing) для направления трафика в туннель
  • TCPMSS --clamp-mss-to-pmtu — автоматическая корректировка MSS во избежание фрагментации пакетов

Активация в runtime (без перезагрузки)

Если требуется поднять туннель немедленно:

bash
# Создание туннельного интерфейса
ip -6 tunnel add gre1 mode ip6gre local $SRC_IP6 remote $DST_IP6 ttl 255

# Присвоение IP-адреса
ip addr add $SRC_TNL_IP/24 dev gre1

# Активация интерфейса
ip link set gre1 up

# Удаление PROXY_IP с основного интерфейса (замените ens3 на ваш)
ip addr del $PROXY_IP/24 dev ens3

# Публикация ARP
arp -sD $PROXY_IP ens3 pub

# Настройка маршрутизации
ip route add default via $DST_TNL_IP dev gre1 table 100
ip rule add from all to $PROXY_IP/32 lookup 100

# Исправление MSS
iptables -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

Проверка конфигурации VPS

bash
# Проверка состояния интерфейса
ip addr show gre1

# Проверка таблицы маршрутизации
ip route show table 100

# Проверка правил маршрутизации
ip rule list

# Проверка ARP-записей
arp -n | grep $PROXY_IP

# Проверка правил iptables
iptables -L FORWARD -v -n

4. Настройка Dedicated-сервера (конечной точки)

Включение IP-форвардинга

Аналогично VPS, включаем пересылку пакетов:

bash
# Немедленное включение
sysctl -w net.ipv4.ip_forward=1

# Постоянная настройка
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.d/99-sysctl.conf
# Или раскомментируйте в /etc/sysctl.conf для старых дистрибутивов

Настройка туннельного интерфейса

Добавьте следующий блок в конец файла /etc/network/interfaces:

text
auto gre1
iface gre1 inet static
    address $DST_TNL_IP
    netmask 255.255.255.0
    # Загрузка модуля ядра
    pre-up modprobe ip6_gre
    # Создание туннеля (обратите внимание на порядок local/remote)
    pre-up ip -6 tunnel add gre1 mode ip6gre local $DST_IP6 remote $SRC_IP6 ttl 255
    post-down ip tunnel del gre1

    # Добавление PROXY_IP на loopback
    up ip addr add $PROXY_IP/32 dev lo

    # Маршрутизация ответов через туннель
    up ip route add default via $SRC_TNL_IP dev gre1 table 100
    up ip rule add from $PROXY_IP/32 lookup 100

    # Исправление MSS
    up iptables -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

    # Очистка при выключении
    post-down ip addr del $PROXY_IP/32 dev lo
    post-down ip route del default via $SRC_TNL_IP dev gre1 table 100
    post-down ip rule del from $PROXY_IP/32 lookup 100
    post-down iptables -D FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

Активация в runtime

bash
# Создание туннеля (обратите внимание: local и remote поменялись местами)
ip -6 tunnel add gre1 mode ip6gre local $DST_IP6 remote $SRC_IP6 ttl 255

# Присвоение IP
ip addr add $DST_TNL_IP/24 dev gre1

# Активация
ip link set gre1 up

# Добавление PROXY_IP на loopback для приёма трафика
ip addr add $PROXY_IP/32 dev lo

# Маршрутизация исходящего трафика от PROXY_IP через туннель
ip route add default via $SRC_TNL_IP dev gre1 table 100
ip rule add from $PROXY_IP/32 lookup 100

# Исправление MSS
iptables -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

Проверка конфигурации Dedicated

bash
# Состояние туннеля
ip addr show gre1
ip link show gre1

# Проверка PROXY_IP на loopback
ip addr show lo | grep $PROXY_IP

# Таблица маршрутизации
ip route show table 100

# Правила маршрутизации
ip rule list | grep -E "100|$PROXY_IP"

# Тестирование связности через туннель
ping -c 3 $SRC_TNL_IP

5. Тестирование и отладка

Проверка связности туннеля

С VPS:

bash
# Ping через туннель
ping -c 5 $DST_TNL_IP

# Трассировка маршрута
traceroute $DST_TNL_IP

# Проверка MTU
ping -c 1 -M do -s 1400 $DST_TNL_IP

С Dedicated:

bash
# Ping обратно
ping -c 5 $SRC_TNL_IP

# Проверка доступности PROXY_IP локально
ping -c 3 $PROXY_IP -I $PROXY_IP

Тестирование проксирования

С внешнего клиента:

bash
# HTTP-запрос (если на dedicated запущен веб-сервер)
curl -v http://$PROXY_IP

# Проверка исходного IP в логах сервера
# На dedicated проверьте логи, должен отображаться реальный IP клиента
tail -f /var/log/nginx/access.log
# или
tail -f /var/log/apache2/access.log

Мониторинг трафика в туннеле

bash
# Захват трафика на туннельном интерфейсе
tcpdump -i gre1 -n

# Подробный просмотр с дешифровкой
tcpdump -i gre1 -vvv -n

# Сохранение в файл для анализа в Wireshark
tcpdump -i gre1 -w /tmp/gre-capture.pcap

# Просмотр статистики интерфейса
ip -s link show gre1

# Мониторинг в реальном времени
watch -n 1 'ip -s link show gre1'

Проверка таблиц маршрутизации

bash
# Все таблицы маршрутизации
ip route show table all | grep gre1

# Конкретная таблица
ip route show table 100

# Проверка какой маршрут будет выбран для пакета
ip route get $PROXY_IP

# Из какого источника
ip route get $PROXY_IP from 8.8.8.8

6. Устранение типичных проблем

Проблема: туннель не поднимается

Симптомы: интерфейс gre1 отсутствует или в состоянии DOWN

Решение:

bash
# Проверка загрузки модуля
lsmod | grep ip6_gre

# Принудительная загрузка
modprobe ip6_gre

# Проверка доступности IPv6
ping6 -c 3 $DST_IP6  # (или $SRC_IP6 с другого конца)

# Проверка журнала ядра на ошибки
dmesg | grep -i gre
journalctl -k | grep -i tunnel

Проблема: трафик не проходит через туннель

Симптомы: ping работает, но HTTP/другой трафик не проходит

Решение:

bash
# Проверка, активна ли пересылка пакетов
sysctl net.ipv4.ip_forward

# Проверка firewall правил
iptables -L -v -n
iptables -L FORWARD -v -n

# Временное отключение firewall для теста
iptables -P FORWARD ACCEPT

# Проверка policy routing
ip rule list
ip route show table 100

# Трассировка пакетов
traceroute -n $PROXY_IP

Проблема: медленная скорость или потеря пакетов

Симптомы: высокий ping, потери пакетов, низкая пропускная способность

Причина: фрагментация пакетов из-за overhead GRE туннеля

Решение:

bash
# Убедитесь, что правило TCPMSS добавлено
iptables -L FORWARD -v -n | grep TCPMSS

# Если отсутствует, добавьте
iptables -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

# Проверка MTU на интерфейсах
ip link show gre1

# Ручная установка MTU (обычно 1476 для GRE over IPv6)
ip link set gre1 mtu 1476

# Тестирование разных размеров пакетов
ping -c 5 -M do -s 1400 $DST_TNL_IP
ping -c 5 -M do -s 1450 $DST_TNL_IP

Проблема: ARP не работает на VPS

Симптомы: трафик не приходит на VPS для PROXY_IP

Решение:

bash
# Проверка ARP-записи
arp -n | grep $PROXY_IP

# Удаление и повторное добавление
arp -d $PROXY_IP dev ens3
arp -sD $PROXY_IP ens3 pub

# Проверка, что IP удалён с физического интерфейса
ip addr show ens3 | grep $PROXY_IP

# Если присутствует, удалите
ip addr del $PROXY_IP/24 dev ens3

# Отправка тестового ARP-запроса
arping -I ens3 $PROXY_IP

Проблема: dedicated не отвечает на трафик

Симптомы: трафик приходит на dedicated, но ответы не возвращаются

Решение:

bash
# Проверка, что PROXY_IP добавлен на loopback
ip addr show lo | grep $PROXY_IP

# Проверка правила маршрутизации источника
ip rule list | grep $PROXY_IP

# Проверка маршрута для исходящего трафика
ip route get 8.8.8.8 from $PROXY_IP

# Должен показывать маршрут через gre1

# Проверка, принимает ли приложение соединения на PROXY_IP
ss -tlnp | grep $PROXY_IP
netstat -tlnp | grep $PROXY_IP

# Настройка приложения для прослушивания на всех интерфейсах
# Например, для Nginx в /etc/nginx/sites-available/default:
# listen 80 default_server;
# вместо
# listen 127.0.0.1:80;

7. Оптимизация и best practices

Постоянство конфигурации

Убедитесь, что все настройки сохранятся после перезагрузки:

bash
# Проверка конфигурации в /etc/network/interfaces
cat /etc/network/interfaces | grep -A 20 "auto gre1"

# Проверка sysctl настроек
cat /etc/sysctl.d/99-sysctl.conf | grep ip_forward

# Сохранение правил iptables (для Debian/Ubuntu)
apt install iptables-persistent
iptables-save > /etc/iptables/rules.v4

# Для CentOS/RHEL
service iptables save

Мониторинг состояния туннеля

Создайте файл /usr/local/bin/check-gre-tunnel.sh со следующим содержимым:

bash
#!/bin/bash

REMOTE_IP="10.10.10.2"  # Удалённый конец туннеля

if ! ip link show gre1 &>/dev/null; then
    echo "ERROR: Interface gre1 does not exist"
    exit 1
fi

if ! ip link show gre1 | grep -q "state UP"; then
    echo "ERROR: Interface gre1 is DOWN"
    exit 1
fi

if ! ping -c 1 -W 2 $REMOTE_IP &>/dev/null; then
    echo "ERROR: Cannot reach remote end of tunnel"
    exit 1
fi

echo "OK: GRE tunnel is operational"
exit 0

Сделайте скрипт исполняемым и добавьте в cron для регулярной проверки:

bash
chmod +x /usr/local/bin/check-gre-tunnel.sh

# Проверка каждые 5 минут с автоматическим перезапуском туннеля при сбое
echo "*/5 * * * * /usr/local/bin/check-gre-tunnel.sh || /sbin/ifdown gre1 && /sbin/ifup gre1" | crontab -

Логирование проблем

bash
# Логирование отброшенных пакетов в FORWARD цепочке
iptables -I FORWARD -j LOG --log-prefix "GRE-FORWARD: " --log-level 4

# Просмотр логов
tail -f /var/log/kern.log | grep GRE-FORWARD

# Удаление правила после отладки
iptables -D FORWARD -j LOG --log-prefix "GRE-FORWARD: " --log-level 4

Безопасность

bash
# Ограничение доступа к туннелю по IPv6
ip6tables -A INPUT -s $DST_IP6 -p ipv6-icmp -j ACCEPT  # VPS
ip6tables -A INPUT -s $SRC_IP6 -p ipv6-icmp -j ACCEPT  # Dedicated
ip6tables -A INPUT -s $DST_IP6 -p 47 -j ACCEPT         # VPS, протокол GRE
ip6tables -A INPUT -s $SRC_IP6 -p 47 -j ACCEPT         # Dedicated

# Блокировка остального трафика (опционально)
ip6tables -P INPUT DROP
ip6tables -A INPUT -i lo -j ACCEPT
ip6tables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

Документирование конфигурации

Создайте файл /root/gre-tunnel-info.txt с описанием настройки:

text
GRE Tunnel Configuration
========================
Date configured: <текущая дата>
VPS IPv6: $SRC_IP6
Dedicated IPv6: $DST_IP6
Tunnel network: $SRC_TNL_IP - $DST_TNL_IP
Proxied IP: $PROXY_IP

Routing table ID: 100

To restart tunnel:
  ifdown gre1 && ifup gre1

To check status:
  /usr/local/bin/check-gre-tunnel.sh

To view traffic:
  tcpdump -i gre1 -n

8. Заключение

GRE туннели — мощный инструмент для построения сетевой инфраструктуры. Представленная конфигурация с использованием чистой маршрутизации обеспечивает:

  • Прозрачность — приложения видят реальные IP-адреса клиентов
  • Гибкость — легко добавить дополнительные туннели и IP-адреса
  • Производительность — минимальный overhead по сравнению с NAT
  • Простоту отладки — всё работает на уровне маршрутизации

Помните о ключевых моментах:

  1. GRE не обеспечивает шифрование — используйте IPsec при необходимости
  2. Правильная настройка MSS критична для производительности
  3. Policy routing (ip rule) позволяет гибко управлять трафиком
  4. Мониторинг состояния туннеля предотвращает простои

Успешной настройки! При возникновении проблем обращайтесь к разделу отладки и не забывайте проверять логи системы.


Дополнительные ресурсы

Комментарии (0)

Оставить комментарий

Комментариев пока нет. Будьте первым!