Настройка IP-over-IP туннеля между DD-WRT и Ubuntu Linux

Опубликовано admin в Втр, 24/05/2011 - 08:46

Встала задача – пробросить туннель между двумя SOHO-сетями с минимальными затратами.

  1. Сеть A: функцию маршрутизатора выполняет компьютер на Linux Ubuntu 8.10, интернет через PPPoE;
  2. Сеть B: маршрутизатор D-Link DIR-300 rev. B1, интернет приходит по Ethernet-у.

В обоих сетях от провайдера получен белый IP. Кол-во компьютеров в каждой сетки более одного.

Сети должны быть связаны, но при этом максимально автономны (у каждой свой DNS и DHCP-сервер).

Алгоритм решения у меня был следующий:

  1. Установить на D-Link DIR-300 rev. B1 прошивку DD-WRT v24-sp2;
  2. Настроить туннель IP-over-IP между DD-WRT и Linux;
  3. Настроить маршрутизацию между подсетями через тунель.

Важный момент: трафик в туннеле передается в открытом виде. Каким образом его можно зашифровать я не разбирался.

Теперь по каждому пункту подробнее…

Установка DD-WRT на D-Link DIR-300 rev. B1

Существует как минимум две разновидности DIR-300: rev A и rev B. Судя по всему, они между собой внутри имеют мало общего.

На DIR-300 rev B прошивка DD-WRT устанавливается через штатный WEB-интерфейс без каких-либо проблем.

Надо отметить, что доступная под DIR-300 прошивка не имеет встроенной поддержки OpenVPN. Так же на маршрутизатор не получится поставить дополнительные пакеты – нет карты памяти и USB-порта.

Воспользоваться Firmware Modification Kit (http://www.bitsum.com/firmware_mod_kit.htm) для установки OpenVPN внутрь прошивки, у меня так же не получилось (утилитка отказалась распаковывать прошивку, сославшись на неизвестный формат образа). Таким образом от использования OpenVPN пришлось отказаться.

Настройка туннеля между DD-WRT и Linux

Для начала, нужно четко понимать, что туннели бывают разные. В процессе разбирательства я столкнулся со следующими:

  1. OpenVPN – самый идеологически правильный вариант, но от него пришлось отказаться из-за нежелания самому собирать прошивку из исходников. Обладает следующими особенностями:
    1. Качественное шифрование трафика;
    2. В качестве транспорта используется TCP или UDP. Оба протокола корректно обрабатываются NAT-ами;
    3. Клиент-серверная архитектура. Клиент может быть с серым IP-адресом.
  2. EoIP (Ethernet Over IP, протокол etherip – 97) – загадочный зверь, поддерживаемый DD-WRT из коробки.
    Теоретически позволяет настроить мост между двумя DD-WRT с минимальными усилиями, но я не нашел по нему никакой документации касательно Linux. Модуль для поддержки этого протокола etherip.ko в моем ядре так же отсутсвовал.
  3. IPIP (IP Over IP, ipencap – 4) – протокол для инкапсуляции IP-пакетов в IP-пакеты.
    Собственно его я и использовал. Для работы использует модуль ядра ipip.ko. Этот протокол был как в Linux, так и в DD-WRT.
  4. GRE (Generic Routing Encapsulation, gre – 47) – протокол для инкапсуляции всего и всея в IP-пакеты.
    В теории, туннель в GRE должен настраиваться точно так же, как и в IP-over-IP, но я не пробовал.

Во всех случаях, кроме OpenVPN, туннель существует отдельно от шифрования.

Адреса сети

Все дальнейшие примеры будут исходить из того, что будут использоваться следующие адреса:

Сеть A (Linux Ubuntu):

  1. Внутренняя сеть: 192.168.1.0/24
  2. Адрес сервера внутри туннеля: 192.168.0.1
  3. Внешний адрес сервера: 89.123.1.234

Сеть B (DD-WRT):

  1. Внутренняя сеть: 192.168.2.0/24
  2. Адрес сервера внутри туннеля: 192.168.0.2
  3. Внешний адрес сервера: 89.123.2.234

Предполагается, что обе сети по отдельности функционируют и имеют доступ в интернет с белым IP.

Настройка туннеля в Linux Ubuntu

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

auto tun1
iface tun1 inet static
    # Адрес машины внутри туннелся. Соединения точка-точка, по этому маска из одних единиц
    address 192.168.0.1
    netmask 255.255.255.255
    # Адрес внутренний адрес машины, с которой установлен тунель
    pointopoint 192.168.0.2
    # Размер MTU
    mtu 1480
    # Перед поднятием интерфейса нужно создать тунель, что мы тут и делаем
    pre-up iptunnel add tun1 mode ipip local 89.123.1.234 remote 89.123.2.234 ttl 255
    up ifconfig tun1 multicast
    # Весь трафик в соседнюю сеть надо завернуть в тунель
    up route add -net 192.168.2.0/24 gw 192.168.0.2 dev tun1
    # Удаляем туннель после удаления интерфейса
    post-down iptunnel del tun1

В примере используется имя интерфейса tun1, но, в принципе, его можно назвать как угодно.

Размер MTU может быть различным. Для его вычисления надо взять минимальный MTU от интерфейсов, смотрящих в интернет (это можно сделать командой ifconfig), и вычесть из него заголовок пакета ipip, которые равен 20 байтам.

Основная борьба под Linux начитается с фаерволом. У меня она свелась к добавлению следующих правил в файл /var/lib/ufw/user.rules (но это сильно зависит от конкретного случая):

-A ufw-user-input   -p ipencap -i ppp0 -j ACCEPT
-A ufw-user-input   -i tun1 -j ACCEPT
-A ufw-user-forward -i tun1 -j ACCEPT

Для того, чтобы предыдущие изменения вступили в силу, необходимо выполнить команды:

sudo ifup tun1
sudo /etc/init.d/ufw restart

Для диагностики могу посоветовать следующий порядок действий:

  1. Проверить наличие туннеля:
    ~$ ip tunnel show
    tunl0: ip/ip  remote any  local any  ttl inherit  nopmtudisc
    tun1: ip/ip  remote 83.123.1.234  local 83.123.2.234  ttl 255
  2. Проверить, поднялся ли интерфейс:
    ~$ ifconfig tun1
    tun1      Link encap:IPIP Tunnel  HWaddr
     inet addr:192.168.0.1  P-t-P:192.168.0.2  Mask:255.255.255.255
     UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1480  Metric:1
     RX packets:0 errors:0 dropped:0 overruns:0 frame:0
     TX packets:81 errors:0 dropped:0 overruns:0 carrier:0
     collisions:0 txqueuelen:0
     RX bytes:0 (0.0 B)  TX bytes:6478 (6.4 KB)

    Здесь надо отметить, что кол-во RX-пакетов должно расти при пинговании той стороны даже в том случае, если маршрутизатор на той стороне выключен.
    То есть если идет попытка пинговать адрес 192.168.0.2 или 192.168.2.100, то RX должен увеличиваться. В противном случае надо искать проблему в фаерволе.

  3. Проверить, проходят ли пакеты через нужные правила iptables.
    Для этого можно воспользоваться ключем -v. Он показывает сколько пакетов и байт прошло через указанное правило.
  4. Проверить, уходят ли пакеты во внешний интерфейс:
    sudo ~$ tcpdump -i ppp0 -n proto ipencap

Настройка туннеля в DD-WRT

Алгоритм настройки тот же, что и в Linux, только без /etc/network/interfaces.

Сначала надо обкатать эти команды через SSH, и только потом заносить в Administration > Commands.

Для поднятия интерфейса нужно выполнить следующие команды (их позже надо будет внести в Administration > Commands > Startup):

/sbin/insmod ipip
/usr/sbin/ip tunnel add tun1 mode ipip remote 89.123.1.234 local 89.123.2.234 ttl 255
ifconfig tun1 192.168.0.2 pointopoint 192.168.0.1 mtu 1480 up
route add -net 192.168.1.0/24 gw 192.168.0.1

Для пропускания пакетов через фаервол нужно выполнить команды (их позже надо будет внести в Administration > Commands > Firewall):

iptables -I INPUT 2 -p ipencap -s 89.123.1.234 -j ACCEPT
iptables -I INPUT 3 -i tun1 -j ACCEPT
iptables -I FORWARD 1 -o tun1 -j ACCEPT
iptables -I FORWARD 2 -i tun1 -j ACCEPT

Если все прошло успешно, то подсети 192.168.1.0/24 и 192.168.2/24 должны прозрачно общаться друг с другом.

Для диагностики справедливы те же принципы, что и для Linux.

После того, как ping-и ходят в обе стороны имеет смысл проверить размер MTU (при неправильном MTU может не работать передача больших IP-пакетов):
Для проверки вычисления размера MTU проще всего выполнить ping с крупным размером пакета, например:

ping -s 1500 -M do -c 10 192.168.2.1




Оригинал : http://www.bozaro.ru/2010/05/25/ipip-ddwrt-linux/

( categories: )