DN42 — большая BGP-песочница

—

от автора

DN42 — это сеть из VPN-туннелей с маршрутизацией по протоколу BGP. Участники устанавливают между собой соединения, используя различные туннельные технологии (Wireguard, OpenVPN, GRE, Tinc, ZeroTier и другие).

DN42 использует адреса в диапазоне 172.20.0.0/14 (для IPv4), fd00::/8 (для IPv6), а также номера автономных систем (AS) из приватного диапазона 4242420000-4242429999.

В настоящий момент (сентябрь 2023го) для аллокации свободно 314 IPv4-блоков (15% диапазона), ~72058 миллиардов /64-сетей (0.00006% диапазона), 1404 ASN (65% диапазона). ASN можно получить в диапазоне 4242420000-AS4242423999 (остальные блоки пока закрыты для регистрации).

В отличие от Интернет, в DN42 минимальный маршрутизируемый блок — это /29 (IPv4) и /64 (IPv6). Что позволяет делать dual-stack системы.

Для сравнения, в Интернет минимальный маршрутизируемый IPv4-блок — это /24, который стоит ~11000 EUR (покупка), ~200 EUR/месяц (аренда).

Зачем оно нужно?

  • Можно поэкспериментировать и изучить технологии маршрутизации.

    Основная польза от DN42 — это возможность получить опыт настройки туннелей и BGP-соединений. Именно так работает маршрутизация в Интернет.

  • Можно узнать как устроен Интернет и почувствовать себя провайдером.

    В DN42 есть регистр (registry), который очень схож с той же RIPE Database, набор внутренних сервисов и свой корневой домен .dn42 и корневые DNS-сервера.

Что для этого нужно?

  1. Иметь какое-нибудь устройство с доступом в Интернет. Любая Linux/BSD VM может быть DN42-роутером.

    В идеале, VM/Компьютер/Роутер должен быть подключен к сети 24/7 и иметь статические адреса.

  2. Разместить это устройство в сегменте, где разрешено делать сетевые туннели (Wireguard, GRE и так далее).

    Я использую дешевую VPS (2.50 евро в месяц) в Суоми.

  3. Иметь хотя бы начальные знания о сетях и маршрутизации.

Ключи и начальная настройка

Эти шаги можно делать как на вашем личном компьютере (что безопаснее), так и на VPS (если под рукой нет Linux/BSD машины). Кстати, использовать Windows-PC не получится, так как при создании объектов inet6num и route6 в названии файла используется :, а в Windows это не разрешено.

SSH

Скорее всего у Вас уже есть SSH ключи, но если нет, то генерируем их командой ssh-keygen:

ssh-keygen -t ecdsa -b 521

Она создаст пару ключей ~/.ssh/id_ecdsa (закрытый ключ) и /home/asm/.ssh/id_ecdsa.pub (публичный ключ).

PGP

PGP-ключи для настройки DN42 не обязательны, но желательны. Вот хорошая инструкция от GitHub.

Git

Также нам нужно будет установить git. DN42 Registry — это git-репозиторий.

Создание объектов в DN42 Registry

Настройка учётной записи и добавление ключей в Gitea

  • Первым делом идём в Registry и регистрируемся.

  • Затем идём в профиль и добавляем ключи.

В KeyName указать название ключа, в Content — содержимое файла ~/.ssh/id_ecdsa.pub

  • Также добавим и PGP-ключ

  • Если адрес электропочты PGP-ключа не совпадает с тем, что использовался при регистрации в Registry, то желательно подтвердить и его. Это можно сделать в настройках учетки

Создание объектов

Наконец-то приступаем к созданию объектов.

  • Для этого идём в Registry и жмём кнопку Fork.
    Это создаст форк проекта, который будет доступен по адресу

  • Клонируем наш форк

git clone git@git.dn42.dev:username/registry.git
cd registry
  1. Первым создаём объект person.

    Здесь и далее USERNAME, Username, username используются в качестве примера. Замените их на Ваши значения.

    vim data/person/USERNAME-DN42
    person:             username e-mail:             me@domain.tld nic-hdl:            USERNAME-DN42 mnt-by:             USERNAME-MNT source:             DN42

    person — ваше имя пользователя (aka ник),
    email — адрес электропочты (желательно, тот который указан в PGP‑ключе),
    nic‑hdl — должно совпадать с названием файла,
    mnt‑by — ссылка на объект mntner (его мы сделаем следующим),
    source — DN42.

  2. Создаём объект mntner.

    vim data/mntner/USERNAME-MNT
    mntner:             USERNAME-MNT admin-c:            USERNAME-DN42 tech-c:             USERNAME-DN42 mnt-by:             USERNAME-MNT source:             DN42 auth:               ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAAEVWYzitbGM5wyH07zY3iieXH28drL24rYpglGMlnH8QK4Tz+sCCg5LI/XpGd7At+liXWa90zQjAoYjk3q4Vi1+QFseJUC... auth:               pgp-fingerprint 88361AC....

    mntner — название объекта (должно совпадать с названием файла).
    admin-c — административный контакт. Ссылка на объект person.
    tech-c — технический контакт. Также ссылка на объект person.
    mnt-by — то же самое, что и поле mntner.
    source — DN42.
    auth — содержимое файла ~/.ssh/id_ecdsa.pub.
    auth — fingerprint pgp-ключа (если создавали).

  3. Для следующих объектов нам нужно выбрать номер автономной системы (ASN), IPv4 и IPv6 префиксы (сети).

    Чтобы найти свободные ASN и префиксы идём в FreeExplorer и выбираем.

    Обычно люди выбирают одну ASN, /27 IPv4-сеть (32-адреса) и /48 IPv6-сеть. Если у Вас маленькая сеть, то советую взять /28-ую сеть (16-адресов). Если наоборот, то /26 — её дадут без дополнительных вопросов. Всё что больше /26 (для IPv4) и /48 (для IPv6) потребует объяснения зачем Вам нужна такая большая сеть.

    Итак, выбираем. Опять же я взял случайные значения из FreeExplorer и их надо заменять на выбранные Вами.

    AS4242422076 172.23.109.240/28 fd46:b10:16::/48
  4. Возвращаемся в склонированный репозиторий и создаём объект для нашей ASN

    vim data/aut-num/AS4242422076
    aut-num:            AS4242422076 as-name:            EXAMPLE-AS descr:              My Username Personal AS or another useful desciption admin-c:            USERNAME-DN42 tech-c:             USERNAME-DN42 remarks:            Peer with me at me@domain.tld or another human-oriented message mnt-by:             USERNAME-MNT source:             DN42 

    as-name — название нашей автономной системы;
    descr — описание (для людей);
    admin-c, tech-c и mnt-by — ссылки на mntner-объект;
    remarks — необязательное поле для заметок (Обычно там указывается информации о способах peering);
    source — как и везде DN42.

  5. Дальше описываем блоки

    vim data/inetnum/172.23.109.240_28
    inetnum:            172.23.109.240 - 172.23.109.255 cidr:               172.23.109.240/28 netname:            EXAMPLE-NETWORK descr:              My Personal IPv4 Network remarks:            Peer with me at me@domain.tld country:            FI admin-c:            USERNAME-DN42 tech-c:             USERNAME-DN42 mnt-by:             USERNAME-MNT status:             ASSIGNED source:             DN42 

    Название файла должно содержать нашу подсеть и маску (/ заменяется на _).

    inetnum — указывается диапазон возможных адресов (можно посчитать с помощью IP calculator);
    cird — подсеть в CIRD-нотации;
    netname — название сети;
    descr — описание для людей;
    remarks — то же самое что и для автономной системы (можно писать, а можно и нет).
    country — тоже необязательное поле;
    admin-c, tech-c и mnt-by — ссылки на mntner-объект;
    status — ASSIGNED (там есть и другие, но вроде нужно указывать именно ASSIGNED);
    source — как обычно, DN42.

  6. IPv6-блок практически тоже самое

    vim data/inet6num/fd46:b10:16::_48
    inet6num:           fd46:0b10:0016:0000:0000:0000:0000:0000 - fd46:0b10:0016:ffff:ffff:ffff:ffff:ffff cidr:               fd46:b10:16::/48 netname:            EXAMPLE-NETWORK descr:              My Personal IPv6 Network remarks:            peer with me at me@domain.tld country:            FI admin-c:            USERNAME-DN42 tech-c:             USERNAME-DN42 mnt-by:             USERNAME-MNT status:             ASSIGNED source:             DN42
  7. Объекты для блоков мы создали, теперь самое время связать блоки с нашей автономной системой. Для этого есть объекты route и route6.

    vim data/route/172.23.109.240_28
    route:              172.23.109.240/28 origin:             AS4242422076 mnt-by:             USERNAME-MNT source:             DN42

    Тут тоже всё понятно. Единственное, в официальной инструкции сказано, что ещё нужен атрибут max-length, который должен быть равен маске сети. Этот атрибут говорит другим роутерам, что максимально возможный блок будет именно /28, а если мы попробуем анонсировать /29, то этот анонс не пройдёт валидацию.

    Я не советую его указывать, ибо если появится желание анонсировать свою сеть частями, то этот атрибут придётся убрать. Как показала практика — это совсем не просто, так как основные пользователи против роста маршрутной таблицы.

    vim data/route6/fd46:b10:16::_48
    route6:             fd46:b10:16::/48 origin:             AS4242422076 mnt-by:             USERNAME-MNT source:             DN42
  8. Ещё есть объекты dns (для своего домена в .dn42-зоне) и organisation (для организации), но они необязательны и о них я напишу в другом посте.

Проверка, коммит, подпись и запрос на слияние (Pull Request)

На данный момент все необходимые объекты созданы и теперь нужно проверить, закоммитить и создать Pull Request.

  • Первым делом, отформатируем наши объекты

./fmt-my-stuff USERNAME-MNT
  • Затем проверим их на правильность и соответствие схеме

./check-my-stuff USERNAME-MNT
вывод команды check-my-stuff

[NOTE] ## Scan Started at 2023-09-12 15:36:45
CHECK data/mntner/USERNAME-MNT PASS MNTNERS: USERNAME-MNT
[NOTE] ## Scan Completed at 2023-09-12 15:36:46
[NOTE] ## Scan Started at 2023-09-12 15:36:46
CHECK data/aut-num/AS4242422076 PASS MNTNERS: USERNAME-MNT
[INFO] fd46:b10:16::/48
CHECK data/inet6num/fd46:b10:16::_48 PASS MNTNERS: USERNAME-MNT
CHECK data/inetnum/172.23.109.240_28 PASS MNTNERS: USERNAME-MNT
CHECK data/mntner/USERNAME-MNT PASS MNTNERS: USERNAME-MNT
CHECK data/person/USERNAME-DN42 PASS MNTNERS: USERNAME-MNT
CHECK data/route/172.23.109.240_28 PASS MNTNERS: USERNAME-MNT
CHECK data/route6/fd46:b10:16::_48 PASS MNTNERS: USERNAME-MNT
[NOTE] ## Scan Completed at 2023-09-12 15:36:47

  • Всё хорошо — можно коммитить

git add -A && git commit -am "Join DN42"
  • Теперь надо этот коммит подписать

./sign-my-commit --ssh --key ~/.ssh/id_ecdsa USERNAME-MNT
вывод команды sign-my-commit

Fetching dn42registry master
From git.dn42.dev:dn42/registry
branch master -> FETCH_HEAD
1 local commits found, no squash is required
Signing using SSH key
Detected git version >= 2.34, using git SSH signature
Using: 2048 SHA256:KJrAwld+1JfuT6zTN3t/fGVsNnIJq+Ltz9LkGdUj6kw /home/username/.ssh/id_ecdsa.pub (ECDSA)
[master d6b44bb97] Join DN42
Date: Tue Sep 12 17:38:42 2023 +0300
7 files changed, 49 insertions(+)
create mode 100644 data/aut-num/AS4242422076
create mode 100644 data/inet6num/fd46:b10:16::_48
create mode 100644 data/inetnum/172.23.109.240_28
create mode 100644 data/mntner/USERNAME-MNT
create mode 100644 data/person/USERNAME-DN42
create mode 100644 data/route/172.23.109.240_28
create mode 100644 data/route6/fd46:b10:16::_48
Verifying SSH signature in git
Good «git» signature for USERNAME-MNT with key SHA256:….
SSH signature verified ok

—

Remember to push your changes using: git push —force

—

  • Отправляем изменения в гит

git push --force
вывод команды git push

Enumerating objects: 364, done.
Counting objects: 100% (364/364), done.
Delta compression using up to 12 threads
Compressing objects: 100% (142/142), done.
Writing objects: 100% (333/333), 45.11 KiB | 45.11 MiB/s, done.
Total 333 (delta 230), reused 286 (delta 191), pack-reused 0
remote: Resolving deltas: 100% (230/230), completed with 28 local objects.
remote:
remote: Create a new pull request for ‘username:master’:
remote: https://git.dn42.dev/dn42/registry/compare/master…username:master
remote:
remote: . Processing 1 references
remote: Processed 1 references in total
To git.dn42.dev:username/registry.git

9c55ad3be…d6b44bb97 master -> master (forced update)

  • Идём по ссылке в сообщении, проверяем изменения, а также что коммит подписан и делаем New Pull Request

  • Дальше Ваш коммит проверят с помощью автоматической проверки.

    Если всё хорошо, то остаётся ждать когда Ваш PR сольют с основной веткой. Этот процесс может занять 1-2 дня. На практике проверено, что слияния происходят утром (в 9-10 EEST) и вечером (17-20 EEST)

    Если что-то пошло не так

    • Если валидатор указал на ошибку, то нужно её исправить и отправить изменения.

    vim data/path/to/file

    исправляем ошибку

    • Дальше коммитим

    git add -A && git commit -am "Join DN42"
    • Теперь у нас 2 коммита и их надо слить в один. Для этого выполняем:

./squash-my-commits
вывод команды squash-my-commits

Fetching dn42registry master
From git.dn42.dev:dn42/registry
branch master -> FETCH_HEAD
Rebasing local changes against the registry master
Current branch master is up to date.
Squashing 2 commits…
[master ac847fda0] squashed commit:
7 files changed, 49 insertions(+)
create mode 100644 data/aut-num/AS4242422076
create mode 100644 data/inet6num/fd46:b10:16::_48
create mode 100644 data/inetnum/172.23.109.240_28
create mode 100644 data/mntner/USERNAME-MNT
create mode 100644 data/person/USERNAME-DN42
create mode 100644 data/route/172.23.109.240_28
create mode 100644 data/route6/fd46:b10:16::_48

Remember to sign your commit: ./sign-my-commit FOO-MNT
and then push your changes using: git push —force

  • Как и до этого, коммит надо подписать и отправить.

./sign-my-commit --ssh --key ~/.ssh/id_ecdsa USERNAME-MNT
git push --force
вывод команды git push

Enumerating objects: 26, done.
Counting objects: 100% (26/26), done.
Delta compression using up to 12 threads
Compressing objects: 100% (17/17), done.
Writing objects: 100% (17/17), 2.88 KiB | 2.88 MiB/s, done.
Total 17 (delta 10), reused 0 (delta 0), pack-reused 0
remote:
remote: Visit the existing pull request:
remote: https://git.dn42.dev/dn42/registry/pulls/1234
remote:
remote: . Processing 1 references
remote: Processed 1 references in total
To git.dn42.dev:username/registry.git

d6b44bb97…82037bd0e master -> master (forced update)

Как видно из сообщения, новый PR создавать не надо и изменения уже отправлены в существующий запрос.

На этот раз обе проверки прошли успешно и остаётся только ждать

Подготовка сервера

Первое правило Бойцовского клуба dn42: всегда отключайте rp_filter.

Вообще-то, rp_filter штука полезная и блокирует пакет, если маршрут возврата пакета использует другой интерфейс, чем тот, с которого он прибыл.

Но как и в Интернет, так и в DN42 маршрутизация асимметричная, то пакеты могут идти по разным маршрутам. Вот почему rp_filter необходимо отключить.

vim /etc/sysctl.conf

Также включаем форвардинг между интерфейсами:

vim /etc/sysctl.conf
net.ipv4.ip_forward = 1 net.ipv6.conf.all.forwarding = 1 net.ipv6.conf.default.forwarding = 1

Применяем налету

sysctl -p

Проверяем

sysctl -a | grep rp_filter
sysctl -a | grep forwarding

Находим пиринг-партнера

После того как наши изменения оказались в основной ветке (master), можно искать пиринг-партнера или сразу нескольких пиринг-партнеров.

Но я советую всё же подождать пару-тройку часов. Как и в Интернет, в DN42 есть механизм защиты и верификации маршрутов ROA (Route Origin Authorization).

ROA — это файл конфигурации вида

route 172.23.67.0/25 max 29 as 4242420022; route 172.20.175.96/27 max 29 as 4242421508; ...

Он сообщает BGP-демону, что ASN 4242420022 может анонсировать префикс 172.23.67.0/25 или её подсети вплоть до /29. Данный файл генерируется dn42regsrv ROA Generator-ом и доступен для скачивания отсюда.

Большинство (IMHO) пиров скачивает этот файл по cronjob (или systemd timer) раз в 15-20 минут и подождать надо именно с целью того, чтобы информация о ваших объектах разошлась по сети.

Чтобы найти пиринг-партнера можно использовать сервис DN42 PeerFinder.

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

Вот список сетей, которые предоставляют автоматический пиринг.

Лично мне больше всего понравился сервис сети Lutoma. Он предоставляет дружелюбный интерфейс и looking glass, который позволяет посмотреть состояние сессии со стороны Lutoma.

Автоматический пиринг

Процесс пиринга состоит из 3 шагов:

  • Верификация того, что Вы владеете AS, которую используете для пиринга

  • Создание туннеля

  • Создание BGP-сессии

Покажем как это выглядит на практике (на примере Lutoma и нашего сервера на ArchLinux).

Регистрация и Верификация AS

  • Открываем Peering Portal и жмём жёлтую кнопку «Sign up»

  • Вводим свой maintainer object USERNAME-MNTи получаем на электропочту ссылку для верификации.

Настройка туннеля Wireguard

Для автоматического пиринга Lutoma использует Wireguard-туннели (это самый популярный туннельный тип в DN42), поэтому нужно установить wireguard-tools

pacman -Sy wireguard-tools

Дальше нам надо сгенерировать ключи для шифрования в туннеле.

cd /etc/wireguard
wg genkey | (umask 0077 && tee 64719.pri) | wg pubkey > 64719.pub

Тут и далее я использую номер автономной сети пиринг-партнера в названии файлов конфигурации.

После успешной верификации и создания учётки можно, наконец, создавать туннель и настраивать BGP-cессию.

Для этого:

  • жмём Create Peering

  • выбираем подходящий Router и вводим название соединения. Что-то вроде myuserame (потом оно пригодится при отладке)

  • VPN Type — уже выбран.

  • В Wireguard endpoint — нужно вставить IP вашего роутера (это внешний IP, по которому роутер доступен в Интернете) и порт, на котором будет работать наш Wireguard. Также есть возможность ввести доменное имя, что по идее, позволяет устанавливать соединение с динамическим IP (DynDNS), но я такое не пробовал.

  • Далее Lutome нужен Ваш публичный ключ. Копируем его и вставляем в поле Wireguard public key.

cat 64719.pub

Заполняем секцию BGP:

  • вводим номер автономной системы 4242422076

  • В поле Internal IPv4 address нужно ввести один из IP из нашей DN42 подсети, например,172.23.109.249. У меня сделано таким образом: я разделил свою /28-ую сеть на две /29-ые. Первая часть (172.23.109.240/29) используется для LAN, вторая (172.23.109.248/29) — для пиринга.

  • В Link-local IPv6 address вводим любой адрес из диапазона fe80::/64 (например, fe80::4719).

  • Оставляем галочку на Multi-protocol BGP over IPv6 (Bird2 такое умеет).

  • В Link bandwidth выбираем пропускную способность своего Интернет соединения.

Cоздаём пиринг

Возвращаемся на сервер и настраиваем туннель.

vim /etc/wireguard/wg64719.conf
/etc/wireguard/wg64719.conf
[Interface] PrivateKey = <Private_key_from_64719.pri> ListenPort = 64719 Table = off  PostUp = /sbin/ip addr add dev %i 172.23.109.241/32 peer 172.22.119.1/32 PostUp = /sbin/ip addr add dev %i fe80::4719/128 peer fe80::acab/128 PostUp = sysctl -w net.ipv4.conf.%i.rp_filter=0 PostUp = sysctl -w net.ipv4.conf.%i.forwarding=1 PostUp = sysctl -w net.ipv6.conf.%i.autoconf=0 PostUp = sysctl -w net.ipv6.conf.%i.accept_ra=0 PostUp = sysctl -w net.ipv6.conf.%i.forwarding=1  [Peer] Endpoint = de-fra.dn42.lutoma.org:43229 PublicKey = <Lutoma_Public_Key> AllowedIPs = 172.20.0.0/14, fd00::/8, fe80::/64 PersistentKeepalive = 20

В PrivateKey вставляем наш приватный ключ из файла 64719.pri.

В Endpoint-e нужно вставить хост и порт из Вашей конфигурации.

Lutoma_Public_Key также берём из конфигурации.

Запускаем туннель

systemctl enable --now wg-quick@wg64719

После этого можно проверить соединение.

ping 172.22.119.1
ping fe80::acab%wg64719

Если оба адреса пингуются, то можно переходить к настройке BGP, если нет, то смотрим состояние с помощью команды

wg

Настройка BGP-сессии

В качестве BGP-демона в Linux/BSD можно использовать Bird/Quagga/FRRouting и другие. Я использую Bird2, если Вы планируете использовать другой демон, но у DN42, скорее всего, будет инструкция по его настройке.

Установка Bird2

pacman -S bird

Создаём структуру директорий

mkdir -p /etc/bird/{roa,peers}

ROA

Как я уже писал ранее ROA позволяет проверять соответствие ASN-prefix, это позволяет защититься от BGP hi-jacking.

Это можно и не делать, но я советую использовать ROA-проверку, тем более это несложно.

Для синхронизации ROA-конфигурации я использую curl, который запускается каждые 15 минут Systemd Timer-ом.

vim /etc/systemd/system/roa.service
/etc/systemd/system/roa.service
[Unit] Description=Update DN42 ROA  [Service] Type=oneshot ExecStart=curl -sfSLR -o /etc/bird/roa/roa_v4.conf -z /etc/bird/roa/roa_v4.conf https://dn42.burble.com/roa/dn42_roa_bird2_4.conf ExecStart=curl -sfSLR -o /etc/bird/roa/roa_v6.conf -z /etc/bird/roa/roa_v6.conf https://dn42.burble.com/roa/dn42_roa_bird2_6.conf ExecStart=birdc configure

vim /etc/systemd/system/roa.timer
/etc/systemd/system/roa.timer

[Unit]
Description=Update DN42 ROA periodically

[Timer]
OnBootSec=2m
OnUnitActiveSec=15m
AccuracySec=1m

[Install]
WantedBy=timers.target

systemctl enable --now roa.timer

В итоге у нас должны появится два новых файла /etc/bird/roa/roa_v4.conf и /etc/bird/roa/roa_v6.conf

Bird2

Переходим к настройке Bird. Для начала я взял конфигурацию из документации.

В данной конфигурации мы получаем все маршруты, отфильтровываем те, которые не прошли ROA-проверку, остальные устанавливаем в таблицу маршрутов ядра.

Экспортируем (сообщаем пиринг-партнеру) все маршруты, которые имеем, но предварительно отсеиваем не DN42-cети.

bird.conf
################################################ #               Variable header                # ################################################  define OWNAS =  4242422076; define OWNIP =  172.23.109.241; define OWNIPv6 = fd46:b10:16::1; define OWNNET = 172.23.109.240/28; define OWNNETv6 = fd46:b10:16::/48; define OWNNETSET = [172.23.109.240/28+]; define OWNNETSETv6 = [fd46:b10:16::/48+];  ################################################ #                 Header end                   # ################################################  router id OWNIP;  protocol device {     scan time 10; }  /*  *  Utility functions  */  function is_self_net() {   return net ~ OWNNETSET; }  function is_self_net_v6() {   return net ~ OWNNETSETv6; }  function is_valid_network() {   return net ~ [     172.20.0.0/14{21,29}, # dn42     172.20.0.0/24{28,32}, # dn42 Anycast     172.21.0.0/24{28,32}, # dn42 Anycast     172.22.0.0/24{28,32}, # dn42 Anycast     172.23.0.0/24{28,32}, # dn42 Anycast     172.31.0.0/16+,       # ChaosVPN     10.100.0.0/14+,       # ChaosVPN     10.127.0.0/16{16,32}, # neonetwork     10.0.0.0/8{15,24}     # Freifunk.net   ]; }  roa4 table dn42_roa; roa6 table dn42_roa_v6;  protocol static {     roa4 { table dn42_roa; };     include "/etc/bird/roa_dn42.conf"; };  protocol static {     roa6 { table dn42_roa_v6; };     include "/etc/bird/roa_dn42_v6.conf"; };  function is_valid_network_v6() {   return net ~ [     fd00::/8{44,64} # ULA address space as per RFC 4193   ]; }  protocol kernel {     scan time 20;      ipv6 {         import none;         export filter {             if source = RTS_STATIC then reject;             krt_prefsrc = OWNIPv6;             accept;         };     }; };  protocol kernel {     scan time 20;      ipv4 {         import none;         export filter {             if source = RTS_STATIC then reject;             krt_prefsrc = OWNIP;             accept;         };     }; }  protocol static {     route OWNNET reject;      ipv4 {         import all;         export none;     }; }  protocol static {     route OWNNETv6 reject;      ipv6 {         import all;         export none;     }; }  template bgp dnpeers {     local as OWNAS;     path metric 1;      ipv4 {         import filter {           if is_valid_network() && !is_self_net() then {             if (roa_check(dn42_roa, net, bgp_path.last) != ROA_VALID) then {               print "[dn42] ROA check failed for ", net, " ASN ", bgp_path.last;               reject;             } else accept;           } else reject;         };          export filter { if is_valid_network() && source ~ [RTS_STATIC, RTS_BGP] then accept; else reject; };         import limit 1000 action block;     };      ipv6 {         import filter {           if is_valid_network_v6() && !is_self_net_v6() then {             if (roa_check(dn42_roa_v6, net, bgp_path.last) != ROA_VALID) then {               print "[dn42] ROA check failed for ", net, " ASN ", bgp_path.last;               reject;             } else accept;           } else reject;         };         export filter { if is_valid_network_v6() && source ~ [RTS_STATIC, RTS_BGP] then accept; else reject; };         import limit 1000 action block;     }; }  include "/etc/bird/peers/*.conf";

По факту, нужно только подставить в Header свои значения:

  • С OWNAS всё понятно — это номер автономной системы

  • В OWNIP указываем адрес роутер (я использую адрес LAN-адаптера).

  • С OWNIPv6 — то же самое, что и с OWNIP

  • В OWNNET и OWNNETv6 — указываем нашу IPv4-подсеть (и в IPv6-подсеть соответственно).

  • В OWNNETSET/OWNNETSETv6 — то же самое.

Добавим конфигурацию для нашего пиринг-партнера.

vim /etc/bird/peers/lutoma.conf
/etc/bird/peers/lutoma.conf

protocol bgp lutoma from dnpeers {
neighbor fe80::acab % ‘wg64719’ as 64719;
description «https://dn42.lutoma.org / hello@lutoma.org«;
};

Взлетаем Запускаемся!

systemctl enable --now bird

Проверка состояния

Ждём 2-3 минуты и проверяем, что маршруты пришли:

ip route && ip -6 route

Если сессия установилась, то Вы увидите ~565 IPv4 и ~740 IPv6-маршрутов.

Поздравляю! Вы подключены к DN42. Можно даже пингануть какой-нибудь IP (корневой DNS server DN42, например):

ping -c 2 172.20.0.53
ping 172.20.0.53

PING 172.20.0.53 (172.20.0.53) 56(84) bytes of data.
64 bytes from 172.20.0.53: icmp_seq=1 ttl=63 time=24.7 ms
64 bytes from 172.20.0.53: icmp_seq=2 ttl=63 time=25.1 ms

— 172.20.0.53 ping statistics —
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 24.726/24.937/25.149/0.211 ms

Отладка

Если не всё так радужно и в маршрутной таблице почти пусто, то идём к Lutoma, где myuserame — это название нашего соединения.

Также смотрим и со своей стороны:

birdc show protocols lutoma
birdc show route

Настройка DNS

Пинговать и трейсить IP-адреса — это хорошо, но быстро наскучит. В DN42 есть же куча сервисов, которые доступны только изнутри.

Так как зона .dn42 является внутренней и корневые DNS-сервера Интернета о ней не знают, то использовать тот же Cloudflare DNS или Google DNS не получится. Вместо это можно использовать локальный DNS-демон dnsmasq, который все запросы к dn42-доменам будет адресовать к корневому DN42-серверу, а остальное к Cloudflare/Google/Quad9.

Установка и конфигурация dnsmasq

pacman -S dnsmasq
vim /etc/dnsmasq.conf
/etc/dnsmasq.conf
# Listen on this standard DNS port port=53  # Never forward plain names (without a dot or domain part) domain-needed  # Don't read /etc/hosts file no-hosts  # Don't read /etc/resolv.conf or any other file. # Use only the configuration provided by this file. no-resolv  # Don't poll changes from external files (like /etc/resolv.conf) no-poll  # Upstream DNS servers server=2606:4700:4700::1111 server=2001:4860:4860::8844 server=1.1.1.1 server=8.8.8.8  # Force the upstream servers to be used in order strict-order  # Increase the cachesize cache-size=1500  # Don't store in cache the invalid resolutions no-negcache  # Forward DN42 rebind-domain-ok=dn42 server=/dn42/172.20.0.53  # Reverse Forwards for DN42 server=/10.in-addr.arpa/172.20.0.53 server=/20.172.in-addr.arpa/172.20.0.53 server=/21.172.in-addr.arpa/172.20.0.53 server=/23.172.in-addr.arpa/172.20.0.53

А ещё dnsmasq умеет блокировать рекламу, но это совсем другая история.

Остаётся запустить dnsmasq и прописать его в качестве DNS-сервера по умолчанию.

systemctl enable --now dnsmasq
vim /etc/resolv.conf
/etc/resolv.conf

nameserver ::1
nameserver 2606:4700:4700::1111

Проверяем.

ping -c 2 asm.dn42
ping asm.dn42

PING asm.dn42(asm.ax (fd21:3087::1)) 56 data bytes
64 bytes from asm.ax (fd21:3087::1): icmp_seq=1 ttl=63 time=11.7 ms
64 bytes from asm.ax (fd21:3087::1): icmp_seq=2 ttl=63 time=11.8 ms

— asm.dn42 ping statistics —
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 11.702/11.747/11.793/0.045 ms

На этом предлагаю остановиться. Неохваченными остались следующие темы:

  • Multi-homing (пиринг с несколькими пиринг-партнерами).

  • BGP communities

  • Создание своего домена в зоне .dn42

  • Создание организации

  • Различные типы пиринга: Peer, Upsteam, Client

  • Anycast

  • Другие типы VPN (OpenVPN/GRE/ZeroTier)

  • 2+ сервера в DN42 и внутренняя маршрутизация

  • IXP

  • Настройка всяких Mikrotik-ов.

Если кому-то это будет интересно и полезно, то могу написать статью-продолжение.

Ну и конечно, Пиринг со мной.

Полезные ссылки


ссылка на оригинал статьи https://habr.com/ru/articles/760866/


Комментарии

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

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