Настройка IP-over-IP туннеля между DD-WRT и Ubuntu Linux
by Bozaro on Май.25, 2010, under Сети
Встала задача – пробросить туннель между двумя SOHO-сетями с минимальными затратами.
- Сеть A: функцию маршрутизатора выполняет компьютер на Linux Ubuntu 8.10, интернет через PPPoE;
- Сеть B: маршрутизатор D-Link DIR-300 rev. B1, интернет приходит по Ethernet-у.
В обоих сетях от провайдера получен белый IP. Кол-во компьютеров в каждой сетки более одного.
Сети должны быть связаны, но при этом максимально автономны (у каждой свой DNS и DHCP-сервер).
Алгоритм решения у меня был следующий:
- Установить на D-Link DIR-300 rev. B1 прошивку DD-WRT v24-sp2;
- Настроить туннель IP-over-IP между DD-WRT и Linux;
- Настроить маршрутизацию между подсетями через тунель.
Важный момент: трафик в туннеле передается в открытом виде. Каким образом его можно зашифровать я не разбирался.
Теперь по каждому пункту подробнее…
Установка 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 для установки OpenVPN внутрь прошивки, у меня так же не получилось (утилитка отказалась распаковывать прошивку, сославшись на неизвестный формат образа). Таким образом от использования OpenVPN пришлось отказаться.
Настройка туннеля между DD-WRT и Linux
Для начала, нужно четко понимать, что туннели бывают разные. В процессе разбирательства я столкнулся со следующими:
- OpenVPN – самый идеологически правильный вариант, но от него пришлось отказаться из-за нежелания самому собирать прошивку из исходников. Обладает следующими особенностями:
- Качественное шифрование трафика;
- В качестве транспорта используется TCP или UDP. Оба протокола корректно обрабатываются NAT-ами;
- Клиент-серверная архитектура. Клиент может быть с серым IP-адресом.
- EoIP (Ethernet Over IP, протокол etherip – 97) – загадочный зверь, поддерживаемый DD-WRT из коробки.
Теоретически позволяет настроить мост между двумя DD-WRT с минимальными усилиями, но я не нашел по нему никакой документации касательно Linux. Модуль для поддержки этого протокола etherip.ko в моем ядре так же отсутсвовал. - IPIP (IP Over IP, ipencap – 4) – протокол для инкапсуляции IP-пакетов в IP-пакеты.
Собственно его я и использовал. Для работы использует модуль ядра ipip.ko. Этот протокол был как в Linux, так и в DD-WRT. - GRE (Generic Routing Encapsulation, gre – 47) – протокол для инкапсуляции всего и всея в IP-пакеты.
В теории, туннель в GRE должен настраиваться точно так же, как и в IP-over-IP, но я не пробовал.
Во всех случаях, кроме OpenVPN, туннель существует отдельно от шифрования.
Адреса сети
Все дальнейшие примеры будут исходить из того, что будут использоваться следующие адреса:
Сеть A (Linux Ubuntu):
- Внутренняя сеть: 192.168.1.0/24
- Адрес сервера внутри туннеля: 192.168.0.1
- Внешний адрес сервера: 89.123.1.234
Сеть B (DD-WRT):
- Внутренняя сеть: 192.168.2.0/24
- Адрес сервера внутри туннеля: 192.168.0.2
- Внешний адрес сервера: 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
Для диагностики могу посоветовать следующий порядок действий:
- Проверить наличие туннеля:
~$ 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
- Проверить, поднялся ли интерфейс:
~$ 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 должен увеличиваться. В противном случае надо искать проблему в фаерволе. - Проверить, проходят ли пакеты через нужные правила iptables.
Для этого можно воспользоваться ключем -v. Он показывает сколько пакетов и байт прошло через указанное правило. - Проверить, уходят ли пакеты во внешний интерфейс:
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
Апрель 14th, 2011 on 09:49
Добрый день.
Не затруднит скинуть вашу прошивку, а то у моей прошивки нет модуля «ipip»
На сайте доступна для скачивания прошивка V24 preSP2beta Build 14896
Май 23rd, 2011 on 07:12
В данный момент использую прошивки (в обоих есть модуль ipip):
Самый простой способ получить список всех модулей:
ls -R /lib/modules/Январь 5th, 2012 on 18:26
Пробовал на дир-825, ни в какой из версии нету модуля ipip, уже пробовал и с дистрибутивов линукса снимать и с других роутеров – нифига не заводится(((