Приветствую сообщество.
В этой заметке я хотел бы поделиться своим велосипедом по настройке ipv6 в локациях где невозможно это сделать нормальным способом (провайдер не умеет/может/хочет ipv6).
На входе у нас есть локация где есть ipv4 интернет (дача, регион, офис), oracle VM instance и роутер на базе openwrt обслуживающий сеть в нашей локации.
На выходе мы хотим получить нормально (насколько это возможно в рамках наших ограничений) работающий ipv6 там, где не удалось настроить правильным/ровным способом через провайдера.
Мы будем решать 2 задачи, а именно:
1) Все устройства в нашей локальной сети должны иметь доступ к ipv6 ресурсам в интернете
2) Из интернета мы хотим иметь возможность достучаться до устройств внутри нашей локальной сети по прямому ipv6 адресу.
Это удобно когда, например, на даче у нас есть камеры/хабы/NAS/итд и мы хотим обращаться к ним напрямую по ipv6 адресу.
Теория
Для того чтобы реализовать задачу №1 нам нужен хотя бы один роутер у которого есть ipv6 адрес и который умеет выходить в мир. Все остальные устройства мы спрячем за NAT'ом. Да-да, вы не ослышались, технология которая была придумана чтобы избавить мир от этого ужасного зла, сама будет его использовать :(
Увы, таковы ограничения oracle free tier instances.
Технически это будет выглядеть так.
У нас есть oracle compute instance (далее просто VM) на котором мы настроим global ipv6 address. На этой машине поднимем wireguard vpn, подключим к ней все наши локации и сделаем ip6tables masquerade. Таким образом все наши устройства внутри конкретной локации смогут достучаться до любых ipv6 ресурсов.
Криво ? Да ! Костыльно ? Снова, да ! Есть идеи получше ? Пишите в комментариях.
Для решения задачи №2 нам снова понадобятся костыли но уже иного рода.
Чтобы какое-то устройство было видно из интернета ему нужен global ipv6 address.
А где ж его взять когда его нет ? Ответ: ip6tables DNAT.
Мы настроим на нашей VM еще пачку global ipv6 адресов и будем пробрасывать их на устройства внутри локаций через ip6tables DNAT.
Криво ? Да ! Костыльно ? Снова, да ! Есть идеи получше ? Пишите в комментариях.
Внимательный читатель спросит: а почему бы просто не нарезать и зароутить ipv6 /64 подсеть через wireguard vpn в нужную локацию ?
Увы, oracle free tier не маршрутизирует выделенную подсеть /64 на нашу VM.
Адреса из подсети /64 нужно назначать ручками (ohh, shit) и поштучно (ohh, shit !) c лимитом не более 32 адресов (ohhh, shit ?!) на одну VM :(
Вот такие пироги... С практической точки зрения это означает что мы сможем достучаться не более чем до 32 устройств во всех наших локациях.
Практика
В практической части настройку мы будем делать в трех местах:
роутер на базе прошивки openwrt
oracle cloud interface
внутри oracle VM
В этой заметке предполагается что читатель уже обзавелся oracle cloud free tier account ом (как его получить можно почитать например тут) и уже поднял/настроил wireguard vpn на oracle VM.
Пошаговая инструкция
Шаг 1: Настройка ipv6 на oracle VM
Сначала включаем/настраиваем ipv6 на VM, подробный гайд на эту тему можно почитать тут.
Теперь добавим нашей VM global unique ipv6 адрес.
Это нужно для того чтобы решить задачу №1, именно под этим адресом все устройства из наших локаций будут ходить на ipv6 ресурсы в интернете.
Для этого в интерфейсе oracle cloud:
-
Идем в Compute → Instances → <выбираем нашу VM> → Attached VNICs → <выбираем Primary VNIC> → IPv6 Addresses → Assign IPv6 Address
-
В открывшемся блоке Subnet IPv6 Prefix выбираем ранее созданный subnet → Manually assign IPv6 addresses from prefix → <задаем ipv6 адрес> → Assign.
Во всех примерах далее будет использоваться адрес 2603:a:b:c::100 Теперь заходим на нашу VM по ssh и добавляем этот адрес на внешний интерфейс
ip a a 2603:a:b:c::100 dev enp0s3 |
Проверяем
enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 9000 |
Видим что все в порядке, теперь попробуем попинговать его из интернета (не забываем включить соответствующее правило в файерволе если вы его не отключили в oracle cloud interface). Сделать это можно например так.
Если пинг прошел успешно можно вас поздравить и переходить к следующему шагу ?
Шаг 2: Настройка ipv6 в локальной сети нужной локации
Для нормально функционирующего ipv6 на роутере нам необходимо поднять /64 подсеть. Учитывая то, что link-local адреса не маршрутизируются, а global адресов у нас нету мы поднимем ULA подсеть. Эти адреса не глобальные но они маршрутизируются, и этого достаточно для решений обеих задач.
ULA адреса берутся из специально выделенного диапазона fc00::/7.
Мы для удобства будет использовать fd01::/16 для первой локации, fd02::/16 для второй, fd03::/16 для третьей, итд.
На роутере с openwrt это делается очень просто
Идем в Network → Interfaces → Global network options и задаем там желаемую подсеть
Идем в Network → Interfaces и в интерфейсе который обслуживает наш LAN, проверяем что Delegate IPv6 prefixes (checked) и IPv6 assignment length 64 (вкладка Advanced Settings)
После вышеописанных манипуляций убеждаемся что подсеть поднялась на интерфейсе обслуживающем локальную сеть.
Настраиваем DHCPv6 на роутере так, чтобы устройства в нашей сети начали получать адреса вида fd01::/64 (нам понадобятся дальше статические ipv6 адреса когда мы будем настраивать доступ к конкретным устройствам из интернета).
Для этого идем в Network → Interfaces и в интерфейсе который обслуживает наш LAN
-
Проверяем что устройства внутри нашей локальной сети начали получать адреса вида fd01::a:b:c:d/128
Шаг 3: Настройка wireguard server/client
Тут нет никаких особых премудростей, подойдет любая инструкция.
Ниже я опишу только самые важные моменты.
На сервере (oracle VM) в конфиге wireguard не забываем добавить подсети вида fd01::/64, fd02::/64 итд в AllowedIPs соответствующих секций и перезапустить server
[Peer] |
-
На клиенте (openwrt router) не забываем в настройки peer в AllowedIPs добавить подсеть → ::/0 и перезапустить интерфейс
На клиенте заворачиваем весь ipv6 трафик на wireguard интерфейс
ip -6 r a default dev wgoracle |
Проверяем пингуется ли ipv6 global адрес из шага 1 с любого устройства из локальной сети.
ping -c 4 2603:a:b:c::100 |
Ну что ж отлично, полпути уже проделано.
На сервере включаем ipv6 forwarding
sysctl -w net.ipv6.conf.all.forwarding=1 |
Ну а теперь самый важный шаг: на сервере настраиваем ipv6 маскарад
ip6tables -t nat -A POSTROUTING -o enp0s3 -s fd01::1/64 -j MASQUERADE |
Это правило говорит о том, что весь трафик из локальной сети fd01::1/64 будет NAT ится в oracle VM global ip из шага 1 (в нашем примере это 2603:a:b:c::100)
С любого устройства из локальной сети пробуем пингануть какой-нибудь внешний ipv6 ресурс
ping6 -c 4 ipv6.ya.ru |
Ура ! Работает ! :) На этом шаге задача №1 успешно решена.
Любые ipv6 ресурсы нам теперь доступны через самопальный ipv6-in-ipv4 туннель :)
Шаг 4: Настраиваем доступ к конкретным устройства внутри LAN из интернета.
Предположим что у нас внутри LAN есть устройства к которым мы хотим достучаться (камера, smart home hub, NAS). И у этих устройств уже есть статические ULA ipv6 адреса которые они получают через dhcpv6 которые мы настроили на шаге 2.
Ниже мы настроим прямой доступ из интернета к устройству fd01::10.
Для всех остальных устройств шаги аналогичные. Приступаем:
На сервере (oracle VM) убеждаемся что устройство доступно по ULA адресу
-
Далее заходим в oracle cloud interface (как мы делали это на шаге 1) и добавляем адрес 2603:a:b:c::1:10.
Тут хочу замечу что такая нотация удобна лично мне, вы можете выбрать любую другую.
Внешний адрес 2603:a:b:c::1:10 будет мапиться на внутренний fd01::10.
Другой внешний адрес, например, 2603:a:b:c::2:15 будет мапиться в fd02::15.
И так далее.
Самый важный шаг: на сервере настраиваем IPv6 DNAT (по сути маппинг внешнего адреса во внутренний)
ip6tables -t nat -A PREROUTING -d 2603:a:b:c::1:10 -j DNAT --to-destination fd01::10 |
Проверяем через пинг (не забываем настроить правило в файерволе локальной сети) с какого-нибудь внешнего ресурса.
ping -c 4 2603:a:b:c::1:10 |
Ура ! Заработало ! Трафик действительно дошел до нашего устройства :)
Заключение
Ну что ж, обе задачи нами успешно решены через набор подпорок и костылей.
Автор полностью осознает ущербность, неправильность и костыльность предложенных решений и посыпает голову пеплом.
Но, увы, других (более “ровных”) вариантов пока отыскать не удалось.
В комментариях предлагаю забросать автора помидорами и указать правильные способы решения вышеупомянутых задач :)
Успехов !
Комментарии (22)
olegtsss
11.05.2024 15:05Но, увы, других (более “ровных”) вариантов пока отыскать не удалось - относительно недавно достаточно подробно рассматривал вашу проблему через интеграцию с ipv6 брокером: https://habr.com/ru/companies/ruvds/articles/760338/
sirj Автор
11.05.2024 15:05Годное решение.
Когда я пробовал играться с туннелями от hurrican electric меня смущало то, что они периодически отваливались если через них не шел трафик (просто моя догадка, на самом деле не знаю в чем проблема) и приходилось прикручивать костыли чтобы их периодически перезапускать.
Если эти болячки уже починились то выглядит как более "ровный" способ если не смущает лишний hop в цепочке маршрутов (lan -> vps -> broker -> internet)
AlexHighTower
11.05.2024 15:05а это способ случаем не подразумевает обязательное наличие публичного ipv4 адреса на который будут лететь пакеты? т.е. если провайдер не даёт тебе публичный адрес, то ой...
DaemonGloom
11.05.2024 15:05+4Один из простых и разумных вариантов - тоннель от hurricane electric (https://tunnelbroker.net).
sirj Автор
11.05.2024 15:05Я когда-то пробовал это решение.
Да, там все просто и оно даже работает, но нужен внешний белый IPv4 (либо я что-то недопонял).
С моим велосипедом этого не требуется.
haga777
11.05.2024 15:05а если у меня есть ipv6 на микроте? как подсесть /64 кинут через впн на другой микрок с который за нат?
Chupaka
11.05.2024 15:05+1Инструкция по получению Oracle Cloud уже не первый год неактуальна для значительной аудитории Хабра? Я уж понадеялся, что что-то новое открыли...
sirj Автор
11.05.2024 15:05Статья про возможность поднять ipv6 там где его не выдает провайдер.
У меня под рукой был oracle cloud поэтому решение основано на нем.
Теоретически можно все это повторить на любом другом клауде, надо только понять какие там ограничение по ipv6 адресам/подсетям
ciuafm
11.05.2024 15:05Не вижу препятствий. Для ораклового аккаунта нужно: карточка банка в разрешённой стране (возможно даже виртуальная), телефонная карточка в той же разрешённой стране, 30 минут времени человека который находиться в этой стране и может этими карточками воспользоваться.
Неужели у вас нет знакомых за границей?
osj
11.05.2024 15:05Вы удивитесь, но не все так просто. Большинство дебетовок пластиковых откидывается. We accept credit cards and debit cards that function like credit cards. We do not accept debit cards with a PIN or virtual, single-use, or prepaid cards.
CCNPengineer
11.05.2024 15:05а зачем IPv6 ? можно же на IPv4 адрес Оракл и на далее NAT с разных портов на разные устройства.
sirj Автор
11.05.2024 15:05Это да, но port mapping это тот еще геморрой, яркий пример это NATить наружу FTP.
Когда у нас устройство доступно по IP адресу, проблем гораздо меньше (сугубо имхо).CCNPengineer
11.05.2024 15:05разве кто то использует сейчас нешифрованый FTP ? и открывает динамические порты? сейчас думаю все используют SCP шифрованый протокол передачи файлов поверх SSH на порту TCP 22
sirj Автор
11.05.2024 15:05Если у вас нет проблем с NAT и пробросом портов и вы умеете управлять всем этим "зоопарком" вам этот велосипед не нужен :)
Hinedes
11.05.2024 15:05Статья прикольная так-то, просто я не знаю зачем использовать Ipv6..
sirj Автор
11.05.2024 15:05Основное преимущество для меня это возможность напрямую работать с устройствами внутри сети (у каждого устройства свой "белый" IP).
Никакого геморроя с пробросом портом и сопуствующими проблемами.enamchuk
11.05.2024 15:05Если нужна "внутрисеть", то советую присмотреться к ZeroTier, Tailscale, Netbird.
При желании можно и пробросы портов сделать, или использовать как VPN, выходя в сеть через любой (заранее настроенный) узел сети.
Внутри сети используются IPv4, IPv6, а связь между узлами, зачастую идёт напрямую, минуя релеи.
litos
Сейчас дистрибутивы Linux начинают переходить с iptables на nftables, хорошо бы было попробовать использовать его
sirj Автор
В принципе можно, принципиально ничего не поменяется, только команды DNAT/MASQUERADE будут другими.
Думаю что через различного рода "конвертеры" iptables <-> nftables можно легко их себе нагенерить.