Gre tunnel def gw miniHowto

Аватар пользователя ROMANEX

*Благодарности*
Инициатором статьи, а так же основным консультантом был Sergei LITVINENKO.

Введение.
Это моя первая статья aka mini HowTo. Предистория ее очень проста, стала задача соединить два офиса тунелем. Итак, время действие-наши дни, место-мой офис...
Поехали... Немного теории:
GRE это протокол тоннелирования, который был разработан фирмой Cisco. В ОС Linux поддерживаются 3 типа тоннелей. Это тоннелирование IP в IP, GRE тоннелирование и тоннели не-ядерного уровня. Для построения gre туннеля используется iproute2 при поддержки модуля ядра ip_gre. Подробнее можно прочитать тут: http://www.opennet.ru/base/net/iproute2_cebka.txt.html. И еще, туннелирование увеличивает нагрузку на систему и сеть, потому что добавляются дополнительные IP-заголовки. Обычно, это 20 байт на пакет. Таким образом, если обычный размер пакета TU) в сети равен 1500 байтам, то при пересылке по тоннелю, пакет может содержать только 1480 байт.

Задача: Имеем два офиса в разных концах города. Нужно с центрального офиса №1 (далее офис1) раздать интернет по локалке и удаленному офису №2 (далее офис2) который не имеет доступа в интернет а с офисом1 связан wavelanом. В обеих офисах стоит роутеры под AspLinux 10.0

Данные:
Роутер1 local (в офисе1) eth0 внешний 10.0.0.1 eth1 локалка 192.168.0.1
Роутер2 remote (в офисе2) eth0 внешний 10.0.1.1 eth1 локалка 192.168.2.1

Ход работы:
В папке /etc/sysconfig/network-scripts/ создаем (touch <имя_файла>) 3 файла со следующим содержанием:

ifup-gre

#! /bin/bash

modprobe ip_gre

cd /etc/sysconfig/network-scripts
. network-functions

CONFIG=$1

source_config

if [ -n \\\\\\\"$BROADCAST\\\\\\\" ] ; then
    forceBROADCAST=\\\\\\\"yes\\\\\\\"
fi

expand_config

if [ -n $MULTICAST -a \\\\\\\"$MULTICAST\\\\\\\" = \\\\\\\"yes\\\\\\\" ] ; then
    mFEATURE=\\\\\\\"multicast on\\\\\\\"
fi

if [ -n \\\\\\\"$PEER\\\\\\\" ] ; then
    echo \\\\\\\"PEER=$PEER is used\\\\\\\"
    tFEATURE=\\\\\\\"peer $PEER\\\\\\\"
fi

if  [ -n \\\\\\\"$forceBROADCAST\\\\\\\" -a  \\\\\\\"$forceBROADCAST\\\\\\\" = \\\\\\\"yes\\\\\\\" ] ; then
    tFEATURE=\\\\\\\"broadcast $BROADCAST\\\\\\\"
    echo \\\\\\\"BROADCAST $BROADCAST is used\\\\\\\"
fi

if [ -n \\\\\\\"$MTU\\\\\\\" -a $MTU -gt 0 ] ; then
        mtuFEATURE=\\\\\\\"mtu $MTU\\\\\\\"
fi

ip tunnel add $DEVICE mode gre remote $REMOTE local $LOCAL ttl $TTL
ip link set up dev $DEVICE $mFEATURE $mtuFEATURE
ip addr add $IPADDR/$PREFIX $tFEATURE dev $DEVICE

if [ -n \\\\\\\"$REMNET\\\\\\\"  ] ; then
   ip route add $REMNET dev $DEVICE # Needed if you run BGP instead of OSPF
fi

# ip addr show $DEVICE

ifdown-gre

#! /bin/bash

cd /etc/sysconfig/network-scripts
. network-functions

CONFIG=$1
source_config

expand_config
ip addr flush $DEVICE
ip tunnel del $DEVICE
# rmmod ip_gre

Делаем их исполняемыми chmod 755 ifup-gre ifdown-gre.
Там же создаем конфигурационные файлы ifcfg-gre.

ifcfg-gre local

DEVICE=gre
BOOTPROTO=static
# --- local ipsec endpoint
LOCAL=10.0.0.1
# --- remote ipsec enpoint
REMOTE=10.0.1.1
TTL=100
NETWORK=192.168.1.0
# --- Uncomment PEER if tunnel type is point-to-point
#PEER=192.168.1.2
#----------------------------------------------------
IPADDR=192.168.1.1
PREFIX=24
#NETMASK=255.255.255.0
#BROADCAST=192.168.1.255
# --- Set MULTICAST=yes if tunnel is multicast
MULTICAST=yes
#
# ------------------------------------------------
# default mtu(ipsec) = 16260
# gre   MTU=mtu(ipsec)-header(gre) =16260-24=16236   
# ------------------------------------------------
# ipsec MTU=mtu(ether)-header(ipsec)=1500-84=1416 
# gre   MTU=mtu(ipsec)-header(gre)  =1416-24=1392
# ------------------------------------------------
MTU=1392
#
ONBOOT=yes
REMNET=\\\\\\\"192.168.2.0/24\\\\\\\"

И ifcfg-gre remote

DEVICE=gre
BOOTPROTO=static
# --- local ipsec endpoint
LOCAL=10.0.1.1
# --- remote ipsec enpoint
REMOTE=10.0.0.1
TTL=100
NETWORK=192.168.1.0
# --- Uncomment PEER if tunnel type is point-to-point
#PEER=192.168.1.2
#----------------------------------------------------
IPADDR=192.168.1.2
PREFIX=24
#NETMASK=255.255.255.0
#BROADCAST=192.168.1.255
# --- Set MULTICAST=yes if tunnel is multicast
MULTICAST=yes
#
# ------------------------------------------------
# default mtu(ipsec) = 16260
# gre   MTU=mtu(ipsec)-header(gre) =16260-24=16236
# ------------------------------------------------
# ipsec MTU=mtu(ether)-header(ipsec)=1500-84=1416
# gre   MTU=mtu(ipsec)-header(gre)  =1416-24=1392
# ------------------------------------------------
MTU=1392
#
ONBOOT=yes
REMNET=\\\\\\\"192.168.0.0/24\\\\\\\"

Теперь можно проверить правильно ли все было сконфигурировано.
Поднимаем на обоих роутерах интерфейс gre (ifup gre)
Если все сконфигурировано правильно то можем увидеть (ifconfig) следущее:

gre  Link encap:UNSPEC HWaddr 59-B9-02-6E-31-00-00-00-00-00-00-00-00-00-00-00  
          inet addr:192.168.1.1  P-t-P:192.168.1.1  Mask:255.255.255.0          
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1392  Metric:1            
          RX packets:47112 errors:0 dropped:0 overruns:0 frame:0                
          TX packets:50546 errors:0 dropped:0 overruns:0 carrier:0              
          collisions:0 txqueuelen:0                                             
          RX bytes:5541666 (5.2 Mb)  TX bytes:15088862 (14.3 Mb)

Далее пингуем выходы из туннеля:
local# ping 192.168.1.2
remote# ping 192.168.1.1
Должны получить от них ответ.

Поздравляю, полпути пройдено!

Переходим к настройки маршрутизации.
Маршрут между сетями устанавливается скриптом ifup-gre при наличии параметра REMNET в файле конфигурации, но нам нужно чтобы офис2 по умолчанию посылал пакеты через тунель, а вот тунель в свою очередь должен нас привести к внешнему интерфейсу роутера1 через eth0. Вот здесь может возникнуть небольшая проблемка. Сейчас шлюз по умолчанию позволяет нам найти путь к противоположному концу туннеля. Как только мы укажем шлюзом по умолчанию туннель на роутере2, то он сразу потеряется из поля зрения, т.к. не будет знать как пройти к роутеру1. Чтобы этого не произошло, на роутере2 нужно построить статический маршрут на роутер1 через публичную сеть.

Способов добавления статического маршрута много, пойду по пути наименьшего сопротивления...
На роутере2 создаем в /etc/sysconfig/ файл gateway со следующим содержанием:

#!/bin/bash
/sbin/route add 10.0.0.1 gw 10.0.1.10 (10.0.1.10 шлюз по умолчанию,выданный провайдером)
/sbin/route del default
/sbin/route add default dev gre

Добавляем строку /etc/sysconfig/gateway в /etc/rc.d/rc.local
Теперь все пакеты с офиса2 будут идти на офис1.

Скажу пару слов о настройке фаервола (iptables). Для полноценного функционирования туннеля необходимо:
1. Разрешить форвардинг пакетов между сетями офиса1 и офиса2, на роутере1

$IPTABLES -A FORWARD -s 192.168.2.0/24 -o gre -j ACCEPT
IPTABLES -A FORWARD -o gre -m state --state ESTABLISHED,RELATED -j ACCEPT

на роутере2

$IPTABLES -A FORWARD -s 192.168.0.0/24 -o gre -j ACCEPT
IPTABLES -A FORWARD -o gre -m state --state ESTABLISHED,RELATED -j ACCEPT

2. т.к. к пакету добавляются дополнительные IP-заголовки и увеличивается mtu,

Цитата:
Более коварная проблема - использование ICMP пакетов в проверках MTU. Все хорошие TCP реализации (включая Linux) используют проверки MTU, чтобы выяснить максимальный размер нефрагментированного пакета, который может принять адресат (фрагментация, снижает эффективность, особенно, когда при потере некоторых фрагментов). Проверка MTU существляется посылкой пакетов с установленным битом \\\\\\\"Don\\\\\\\'t Fragment\\\\\\\". Если в ответ на эти пакеты приходит ICMP-ответ \\\\\\\"Fragmentation needed but DF set\\\\\\\" -- то есть \\\\\\\"необходима фрагментация, но установлен флаг DF\\\\\\\". Это пакеты типа \\\\\\\"destination unreachable\\\\\\\', и если они не получены, локальный хост не будет уменьшать MTU, и эффективность будет крайне низкой или нулевой.

На роутере1 добавляем строки:

$IPTABLES -A FORWARD -o gre -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 576
$IPTABLES -A FORWARD -i gre -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 576

(на этом шаге универсальность статьи заканчивается, далее Вы можете продвигаться в направлении поставленной Вам задачи, я лишь завершу задачу, поставленную мне).

3. Для того, чтобы роутер1 пропускал пакеты в интернет, на роутере1 в фаерволе добавляем следующую строку:
$IPTABLES -t nat -A POSTROUTING -s 192.168.2.0/24 -j SNAT --to-source 10.0.0.1

Перезагружаем службы service network restart на обоих роутерах и смотрим что получилось.

Проверка работы:
Пробуем пропинговать из сети 192.168.0.0 адрес из сети 192.168.2.0 и наоборот.
Ну и наконец, пинг из сети 192.168.2.0 на какой-нибудь внешний адрес и для полного удовлетворения пускаем трассу traceroute

на внешний адрес.

Если все сделано верно то получаем работоспособную схему, но увы без шифрования...
Но об этом в другой статье...
Все вопросы, пожелания и исправления отправлять по адресу romanex@mail.ru
touch <имя_файла>

Your rating: Нет Average: 5.6 (5 votes)
RSS-материал