Туннель ipv6 over ipv4 на FreeBSD и Juniper SRX NDP-proxy.

Наши большие домашние провы всё еще считают что ipv6 обычным людям нафиг не нужен, ибо кто тогда будет по 150р. статические айпишники покупать? Захотелось мне более менее прямой Ipv6 дома – что делать? 6to4 конечно есть и работает, но это скучно. Туннель до харикейнов всяких очень уж медленно. Есть вариант кинуть туннель до своей площадки и использовать немного прямых v6 адресов другого провайдера. Тем более скорость по v4 туда очень хорошая. Дома на роутере freebsd, на площадке есть циска и джунипер. Подстава в том что ipv6 там с префиксом /64 и отдельного маршрутизируемого большого куска тупо нет. Поэтому придется что-то придумывать с NDP-proxy. Циска, как я понял, NDP-proxy не умеет (по крайней мере рабочий вариантов я не нашел). Поэтому буду связывать туннелем juniper c freebsd.
Итак дано:
Dual stack на juniper srx – на один интерфейс приходит и ipv4 и ipv6 от провайдера, Ipv6 с префиксом /64. С другой стороны роутер на freebsd, за роутером домашняя сетка, в сетке венда. Задача – получить на венде “белый” v6 адрес с юнипера со всеми промежуточными туннелями и маршрутизацией. (картинку бы еще нарисовать)

Начнем с freebsd как с самого простого. Для туннелирования ip over ip во фре служит gif (4) — generic tunnel interface.
С помощью него будем делать туннель для ipv6 поверх ipv4.

Исходные данные:
$bsd_v4 – внешний реальный ipv4 адрес роутера на bsd
$srx_v4 – внешний реальный ipv4 адрес juniper
$bsd_v6 – ipv6 адрес на туннельном интерфейсе freebsd
$srx_v6 – ipv6 адрес на туннельном интерфейсе juniper
$v6net – ipv6 подсеть, которую я маршрутизирую через туннель

По идее $bsd_v6, $srx_v6 можно использовать хоть link-local хоть вообще левые. Но чисто для порядка я взял первые 2 адреса из $v6net

На BSD настройки элементарные:

MTU выставляю на 1472 т.к. 20 байт уходит на внешний ipv4 пакет и еще 8 байт оверхед на pppoe. С фрей пока все – переходим к юниперу.
Подразумевается что ipv6 к прову на юнипере уже давно настроен и работает, занимаюсь только туннелем. На юнипере все несколько сложнее. Проблема номер раз – ip4 адрес который будет терминировать туннель не настроен на самом интерфейсе srx’а, а маршрутизируется на него. Проблема номер два – ipv6 подсеть с префиксом /64 из которой надо будет отмаршрутизивать кусок наоборот висит на самом интерфейсе, поэтому вместо нормального рутинга придется использовать ndp-proxy. Т.е. юнипер должен с внешнего интерфейса отвечать провайдерскому рутеру на его neighbour solicitation запросы к v6 адресам которые на самом деле будет лежать за туннелем.

Для начала как-то так: Создаю туннельный интерфейс, назначаю внуренний v6 и внешние v4 адреса

Теперь с учетом того что $srx_v4 адреса на самом деле на srx нет, надо его навесить на лупбек интерфейс, чтобы приходящие пакеты на этот адрес не пытались маршрутизироваться дальше а терминировались на туннельном интерфейсе.

Updated: Последний штрих – для туннельных пакетов можно выключить flow-фильтрацию, т.к. этот трафик все равно транзитный и полисить его нет смысла.
Туннельный трафик передается в Ip-пакетах c меткой протокола 41. Для этого можно воспользоваться пакетным фильтром который будет задавать пакетный режим для протокола 41.

Главное не забыть закрывающий term который пропускает остальные пакета, иначе можно зарубить весь трафик на интерфейсе кроме туннельного.
Навешиваем фильтр на внешний интерфейс:

Туннель готов – с бсд можно попингать туннельный адрес юнипера, а с юнипера бсдшный. Пинги должны бегать.

Отлично. Туннель работает, теперь нужно отмаршрутизировать небольшой блок v6 адресов через этот туннель и настроить ndp-proxy. Я решил что раз заполучить что-то короче /64 все равно не получится, то мне вполне хватит префикса /120, т.е. 256 ipv6 адресов (смех да и только).

И для проверки на bsd на lo0 интерфейсе подниму один адресок из моей новой подсеточки.

Собственно всё, маршрутизация должна работать. Для проверки я попингал “снаружи” этот адрес из маршрутизируемого ipv6 сегмента, поглядывая на tcpdump на gif интерфейсе… Однако ответа я не получил, равно как и входящих icmp запросов. Фаерволом трафик резаться не дожен, да и пинги на адреса туннельных интерфейсов ходили нормально! А с подсеточкой какая-то мистика – джунипер тупо резал входящие пакеты не пуская их в туннель. Разбор полётов допросы с пристрастиямы выявили вот такое безобразие:

Не понял!? Мой префикс появился в таблице маршрутизации с правильным шлюзом, но в довесок srx добавил его же как discard и с преференсом 1. “Да что за нах?!” – спросил я себя и полез в гугл. Нагугленное меня просто выбесило! Очередные индусы “накодили” в джунос свое очередное “правильное” видение того как всё дожно быть. Оказывается с версии JunOS 11.2 на адреса из proxy-arp и proxy-ndp навешивается принудительный маршрут в null, мол “для безопасности” (KB24709)!!! Т.е. вот так вот на мегафаерволе проблемы доступа к менеджменту железки теперь решаются втыканием костылевых маршрутов в нулл. Аргументация уникальная, мол проксиарп адреса надо натить, и тогда всё будет ОК. А если натить тебе не надо, то ты всё равно настрой левую трансляцию в какие-нибудь несуществующие адреса. Ну так чисто подоткни еще костыликов, не ломай нам концепцию безопасности… А то что от этого появляются маршруты в таблице которых там никто не ожидал это пофиг… и преференс выставили сразу единичку, ну раз уж если прибивать гвоздями то так что бы никто и не помышлял о самовольностях. С какого вообще proxy-arp связан с натом? Зарекался уже связываться с юниперами и с их костылестроением. Решение каждой задачи в JunOS превращаяется в хождение по KBшкам и выяснению очередных порций костылей. Причем в конце туннеля света не видать, костыли надежно уходят в продакшен, приматываются синей изолентой и объявляются фичами. Потом пишутся трактаты как правильно обходить “фичи” с помощью других костылей.
Обидно и досадно… но отступать было поздно, я уже итак кучу времени потратил пока раскопал эти грабли.
Вобщем следуя рекоммендованой джунипером идеологии “костылеориентированного конфигурирования” я придумал маршрутизировать в туннель префикс на 1 бит длиннее чем настроено в ndp-proxy. По идее тогда в таблицу маршрутизации попадет более точный префикс по которому и будут уходить пакеты в туннель. Ну попробуем…

Ну надо же! Заработало!

Браво джунипер! Ты воспитываешь настоящих суровых сетевиков! В результате мне достанется всего 128 адресов, ну да и ладно… если что всегда можно отроутить еще несколько кусочков если “припрет”.
Однако долго петь диферамбы не пришлось – ndp-proxy толком так и не заработал. Я промучался еще пару часов но так ничего и не добился. Опуская детали всей возни с поисками проблем скажу только что ndp-proxy то работал то нет. В какие-то моменты мне удавалось увидеть что трафик проходит. Т.е. ndp-proxy срабатывал, на соседнем хосте под линуксом в списке соседей (ip -6 ne sh) появлялся ipv6 адрес подсети из-за туннеля с маком юнипера, но потом спустя короткое время после протуханя записи о соседе второй раз ndp-proxy уже не срабатывал. Ответов на neighbour solicitaion juniper больше не давал и ничего не работало.
Устав бороться с этим глюкавым порождением индусов я решил забить на juniper и поднять туннель на каком-нибудь серваке с BSD/Linux.
Об этом в следующий раз.

http://chimera.labs.oreilly.com/books/1234000001633/ch09.html#static_nat_examples

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">