Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/ru-crypto-anarchy/YggNS
DNS-proxy for clumsy but distributed NS-system for Yggdrasil network
https://github.com/ru-crypto-anarchy/YggNS
Last synced: about 2 months ago
JSON representation
DNS-proxy for clumsy but distributed NS-system for Yggdrasil network
- Host: GitHub
- URL: https://github.com/ru-crypto-anarchy/YggNS
- Owner: ru-crypto-anarchy
- Created: 2019-10-20T12:56:47.000Z (about 5 years ago)
- Default Branch: master
- Last Pushed: 2019-10-20T12:57:20.000Z (about 5 years ago)
- Last Synced: 2024-08-08T18:21:33.512Z (5 months ago)
- Language: Python
- Size: 15.6 KB
- Stars: 23
- Watchers: 6
- Forks: 2
- Open Issues: 1
-
Metadata Files:
- Readme: README-RU.md
Awesome Lists containing this project
- awesome-starred - ru-crypto-anarchy/YggNS - DNS-proxy for clumsy but distributed NS-system for Yggdrasil network (others)
README
### YggNS
DNS-прокси для топорной и распреденной NS-системы для сети Yggdrasil.
## Идея
На мой взгляд, в DNS всегда есть компромисс между распределением и централизацией с точки зрения именования доменов. Если доменное имя случайно генерируется из адреса узла в сети и неразрывно с ним связано, то можно относительно легко распределить его по сети. Примерами являются сети TOR и I2P. Когда вы хотите красивое и короткое доменное имя, вы должны зарегистрировать его и связать его с некоторой идентичностью в иерархических системах, таких как DNS.
Для Yggdrasil я хочу попробовать некую гибридную систему. Старый добрый DNS распределенный по сети Yggdrasil.
Каждый узел в сети Yggdrasil имеет IPv6-адрес, который связан с узлом криптографически и никогда не изменяется, независимо от того, в какой точке сети рассматриваемый узел находится. Таким образом, если этот IPv6-адрес является статическим, то возможно функционально и неразрывно сопоставить его со статическим доменным именем.
Если адрес узла например такой `0201:9d54:3c57:d6d2:e8d7:a8ce:841f:eb89`, то возможно сопоставить ему функционально доменное имя `02019d543c57d6d2e8d7a8ce841feb89.ygg.`. То есть просто IPv6 адрес в расрытом написании поставить без символа `:` в домен второго уровня. Какие же могут быть методы разрешения доменного имени?
Самое очевидное - просто выполнить обратное преобразование. Взять домен второго уровня и сделать из него IPv6-адрес. Очень просто, но у такого подхода есть недостаток - таким образом у владельца узла отнимается свобода управления записями своего доменного имени, гибкое управления им. В таком случае можно применить несколько другой подход.
Итак, если мы хотим разрешить доменное имя `02019d543c57d6d2e8d7a8ce841feb89.ygg.`, то мы можем взять из него IPv6-часть `02019d543c57d6d2e8d7a8ce841feb89` и преобразовать её обратно в IPv6-адрес `0201:9d54:3c57:d6d2:e8d7:a8ce:841f:eb89`, и далее отправить обычный DNS-запрос на DNS-сервер на узле с этим адресом. На узле при этом должен быть установлен обычный DNS-сервер, который разрешит этот адрес и отправит ответ. Таким образом мы осталяем за владельцем узла гибкость управления своим доменом. Например, доменное имя `02019d543c57d6d2e8d7a8ce841feb89.ygg.` можно вообще не разрешать (отправить NXDOMAIN), разрешать только определенные типы запросов, или же разрешить имена, например `example.02019d543c57d6d2e8d7a8ce841feb89.ygg.` вообще на другой IPv6-адрес другого узла, скажем `0202:12a9:00e5:4474:d473:82be:16ac:9381`, и далее перейти к сервису этого доменного имени на другой узел, подконтрольный администратору.
В целом выходит так, что в сети каждый узел - сам-себе-DNS-сервер. К узлу привязан лишь DNS-сервер доменного имени, а не сам домен. Своим доменом и под-доменами администратор может управлять по своему желанию.
Для чего это требуется в сети Yggdrasil?
Есть несколько причин:
1) Поддержка в сети Yggdrasil сервисов, которые изначально ориентированы на наличие DNS. Конечно, ко мноним их них (веб-сайты) можно подключиться по IP-адресу, но функционал будет ограничен. Пример - виртуальные хосты веб-сервера. Некоторые сервисы без DNS работать не могут в целом.
2) При этом, когда доменные имена все же необходимы, основная возможность их использовать внутри сети Yggdrasil на данный момент - это использование DNS в сети Интернет. То есть при наличии домена можно сделать, предположим, AAAA-запись, адресующую на IPv6-адрес внутри сети Yggdrasil. Пример - y.netwhood.online разрешается в адрес `202:12a9:e5:4474:d473:82be:16ac:9381`. В таком случае желающий использовать DNS __внутри сети__ обязан регистрировать (часто за деньги) доменное имя __в сети Интернет__, чтобы использовать функционал сервисов, связанный с DNS. Данное решение предалагает рапределенный DNS по сети Yggdrasil, независимых от любых централизованных серверов, даже внутри сети Yggdrasil.
## Принцип работы и форматы имен
Принцип работы был описан выше, но раскроем детальнее. Во-первых необходимо определиться с форматами имен. Все доменные имена должны быть в зоне TLD `.ygg`. Далее решение предлагает 3 формата:
1) STRAIGHT. 32-символьный фиксированный формат. Получается из полностью раскрытого (со __всеми__ нулями) IPv6-адреса узла убираем двоеточий `:`. Например адрес `202:12a9:e5:4474:d473:82be:16ac:9381` раскрывается в полный `0202:12a9:00e5:4474:d473:82be:16ac:9381` и убираются двоеточия и добавляется TLD - получается `020212a900e54474d47382be16ac9381.ygg.`
2) BASE32. 25-символьный фиксированный формат. Из полностью расрытого IPv6 адреса убирается самый старший неизменяющийся hex-символ `0`, второй самый старший hex-символ (может быть только 2 или 3) остается на месте, оставшееся часть (120 бит) преобразуются по base32 в 25 символов. Пример - `202:12a9:e5:4474:d473:82be:16ac:9381` преобразуется в `2aijksahfir2ni44cxylkze4b.ygg.`.
3) DASHED. Формат с меняющейся длиной, в зависимости от IPv6-адреса. Получается из сокращенного IPv6-адреса заменой `:` на `-`. Пример - `202:12a9:e5:4474:d473:82be:16ac:9381` преобразуется в `202-12a9-e5-4474-d473-82be-16ac-9381.ygg.`.
Когда из доменного имени берется IPv6-адрес (и проверяется на валидность и принадлежность к подсети 0200::/7), в любом из форматов, __оригинальный запрос без преобразований перенаправляется__ на DNS-сервер по этому IPv6-адресу. DNS-сервер на узле может быть совершенно любой - dnsmasq, unbound, bind и прочие. Выбор может быть в зависимости от требований администратора к функционалу или простоте настройки. Итак, этот DNS-сервер разрешает запрос и отправляет ответ клиенту. Клиент получает разрешенный запрос и идет на IPv6-адрес из ответа.
### Как этим пользоваться
Вам понадобится python3 и установленные библиотеки dnspython и IPy.
```
pip3 install dnspython
pip3 install IPy
```Далее нужно запустить скрипт `yggns.py`. По умолчанию он будет слушать сокет [::1]:53535, на который нужно перенаправлять DNS-запросы зоны .ygg.
На Linux рекомендуется использование в связке локальными рекурсивными DNS-серверами с кешированием, например dnsmasq или dnscrypt. Разрешение зоны `.ygg` должно быть перенапрвлено на `[::1]:53535`. В dnsсrypt это настраивается в файле `forwarding-rules.txt` одной строкой:
```
ygg [::1]:53535
```При этом в настройках `dnscrypt-proxy.toml` должна быть установлена настройка форвардинга зон:
```
forwarding_rules = '/etc/dnscrypt-proxy/forwarding-rules.txt'
```В __dnsmasq__ это настраивается следующим образом:
```
server=/ygg/::1#53535
```Запустить в фоне `yggns.py` можно следующим образом:
```
nohup yggns.py 2>/dev/null &
```Если __нет возможности воспользоваться резолвером__, можно запустить YggNS с байпасс-сервером. Запросы, которые не предназначены для YggNS, будут разрешаться с помощью байпасс-сервера. Возможно, Вам необходимо будет запустить скрипт из-под root, чтобы он мог прослушивать 53ий порт.
```
nohup yggns.py -p 53 -b 8.8.8.8 2>/dev/null &
```
Так же необходимо в настройках ОС установить сервер DNS `::1`.__Для генерации доменых имен__ следует пользоваться скриптом __yggns-tool.py__. При вводе IPv6-адреса будет вывод доменного имени. По умолчанию в формате STRAIGHT. Задать формат можно с помощью опции -f и буквы формата: (S)TRAIGHT, (B)ASE32 или (D)ASHED.
При вводе же доменного имени в любом формате будет ввывод IPv6-адресаю.
Повторюсь, что в роли DNS-сервера сгодится любой. Нужно чтобы он прослушивал IPv6-адрес туннельного интерфейса Yggdrasil.
Пример настройки для __dnsmasq__:
```
listen-address=201:9d54:3c57:d6d2:e8d7:a8ce:841f:eb89
host-record=02019d543c57d6d2e8d7a8ce841feb89.ygg,201:9d54:3c57:d6d2:e8d7:a8ce:841f:eb89
host-record=netwhood.02019d543c57d6d2e8d7a8ce841feb89.ygg,202:12a9:e5:4474:d473:82be:16ac:9381
host-record=2agovipcx23jorv5iz2cb724j.ygg,201:9d54:3c57:d6d2:e8d7:a8ce:841f:eb89
host-record=netwhood.2agovipcx23jorv5iz2cb724j.ygg,202:12a9:e5:4474:d473:82be:16ac:9381
host-record=201-9d54-3c57-d6d2-e8d7-a8ce-841f-eb89.ygg,201:9d54:3c57:d6d2:e8d7:a8ce:841f:eb89
host-record=netwhood.201-9d54-3c57-d6d2-e8d7-a8ce-841f-eb89.ygg,202:12a9:e5:4474:d473:82be:16ac:9381```
Пример настройки для __unbound__:
```
local-zone: "02019d543c57d6d2e8d7a8ce841feb89.ygg" redirect
local-data: "02019d543c57d6d2e8d7a8ce841feb89.ygg. AAAA 201:9d54:3c57:d6d2:e8d7:a8ce:841f:eb89"
local-data-ptr: "201:9d54:3c57:d6d2:e8d7:a8ce:841f:eb89 02019d543c57d6d2e8d7a8ce841feb89.ygg"
```### Что опробовать
Тестовые сайты:
http://02019d543c57d6d2e8d7a8ce841feb89.ygg/
http://2agovipcx23jorv5iz2cb724j.ygg/
http://201-9d54-3c57-d6d2-e8d7-a8ce-841f-eb89.ygg/
Зеркала netwhood.online:
http://netwhood.02019d543c57d6d2e8d7a8ce841feb89.ygg/
http://netwhood.2agovipcx23jorv5iz2cb724j.ygg/
http://netwhood.201-9d54-3c57-d6d2-e8d7-a8ce-841f-eb89.ygg/