DNS over I2P — настоящая приватность DNS-запросов / Блог компании ITSOFT / Хабр

Сегодня сложно кого-то удивить терминами DoH (DNS over HTTPS), DoT (DNS over TLS) и прочими крипто-примочками для DNS. Если кто-то запрыгнул в поезд только что и не понимает о чем речь, DNS (Domain Name System) — это система доменных имен, которую каждый из нас использует сотни и тысячи раз в течение дня. Все человекочитаемые имена вроде habr.com, cia.gov и прочие ведут на определенный IP-адрес, который компьютер может узнать, обратившись на специальные серверы.

Свой DNS сервер всегда есть на крупных предприятиях, у домашних интернет-провайдеров, а также у любого желающего, потому что DNS-сервер весьма прост в своем устройстве. Помимо прочих соображений, свои серверы разворачивают из соображений дополнительной приватности, потому что администратор чужого сервера, к которому мы обратимся, увидит наш адрес и будет знать какой веб-ресурс мы решили посетить.

Протокол DNS стар, как мир (~1987), поэтому не предусматривает никакого шифрования. Все запросы и ответы DNS идут по сети в открытом виде, поэтому в изначальной вариации шпионить за пользователем может не только администратор DNS-сервера, но и операторы всех промежуточных узлов, через которые проходит трафик. Современные решения вроде DNSCrypt, DNS over HTTPS и подобные им решают проблему перехвата информации по пути ее следования, так как шифруют DNS-запросы от пользователя до сервера и в обратном направлении. Но! Протоколы, которые шифруют трафик, не решают один важный вопрос — анализ всех запросов на стороне самого сервера, который всё еще видит как сам запрос, так и IP-адрес, с которого он пришел. У проекта DNSCrypt есть дополнительная примочка для этого, но меня это наслоение на трехэтажный пирог не впечатлило. Возможно, потому что у меня свой пирог… Адекватной критике буду рад, но надеюсь, не возникнет глупых комментариев о том, что каждому человеку на планете для сохранения приватности нужно иметь свой персональный DNS-сервер.

DNS через анонимную сеть I2P — это концепция, в которой DNS-запросы идут в зашифрованном виде, но кроме того: во-первых, администратор сервера не имеет представления о реальном IP-адресе пользователя; во-вторых, пользователь не знает месторасположение сервера, к которому обращается (тоже хорошо, дабы избежать возможное давление на администратора). DNS over I2P, или DoI2P (или вовсе DoI) — это весьма занимательная вариация использования скрытых сетей, подробным рассмотрением которой сейчас и займемся.

Теория

Стандарт предусматривает работу сервера DNS на 53 порте (веб-сайты, например, работают на стандартных портах 80 и 443), но в данном случае интереснее другое: какой транспортный протокол использует DNS. Эта информация необходима для создания подходящих туннелей через сеть I2P.

I2P-роутер, обеспечивающий выход в сеть I2P, предоставляет на локальном адресе прокси типов SOCKS и HTTP. В большинстве случаев для работы с сетью используется именно прокси, но для более тонкой настройки соединения через скрытую сеть в специальном конфигурационном файле создаются отдельные туннели. Туннели бывают серверными и клиентскими. Их суть заключается в приеме соединений из скрытой сети на назначенный локальный порт какой-либо службы, например, веб-сервера, либо в передаче клиентских подключений с локального адреса туннеля в скрытую сеть. Туннели делятся на два основных типа: TCP и UDP.

Основным рабочим протоколом DNS является UDP, однако стандарт предусматривает передачу некоторой информации и по протоколу TCP. Это означает, что необходимо создать два серверных и два клиентских туннеля: первый — для соединений по UDP, второй — для TCP.

Сервер

В примере используется крайне простой в установке и настройке сервер dnsmasq, но вы можете использовать любой другой на ваш вкус. Самый простой вариант конфигурации данного сервера выглядит так:

port=53
listen-address=256.257.258.259
domain-needed
bogus-priv
server=8.8.8.8

Такая конфигурация означает, что абсолютно все запросы будут переданы на адрес 8.8.8.8. Большого смысла такой сервер не имеет, но как прослойка анонимности и просто пример для статья — самое то. Сервер принимает обращения на IP-адрес 256.257.258.259, порт 53. Вымышленный IP-адрес выступает исключительно в роли примера, как бы изображая уже существующий сервер DNS, доступный из обычного интернета. По факту вы можете использовать локальный адрес 127.0.0.1 и любой порт на свое усмотрение, если будете обслуживать пользователей исключительно через скрытую сеть.

Чтобы сделать сервер DNS доступным из I2P, необходимо создать серверные туннели. Я использую i2pd на Debian 10. Конфигурационный файл туннелей по умолчанию лежит по пути /etc/i2pd/tunnels.conf. Ниже приведена минимальная конфигурация, необходимая для работы.

[DNS-TCP]
type = server
host = 256.257.258.259
port = 53
keys = hidden-dns.dat

[DNS-UDP]
type = udpserver
host = 256.257.258.259
address = 256.257.258.259
port = 53
keys = hidden-dns.dat

Обратите внимание на строку address в секции UDP-туннеля. Это необходимый параметр для нелокального адреса, который сообщает i2pd с какого адреса будут исходить поступающие обращения из скрытой сети. Этот параметр необходим для UDP-туннелей. Его можно опустить, если используется адрес 127.0.0.1.

В параметре keys указываются ключи, которые образуют внутрисетевой адрес. По умолчанию они лежат в директории /var/lib/i2pd. Если файл не обнаружен, создается новый.

Перезапустите i2pd, чтобы изменения вступили в силу. I2P-адрес туннеля можно увидеть в веб-консоли, во вкладке «I2P Tunnels». В моем случае это dnsgzxkak4zlrrs5tfh42ob57iley4xrp7srrltn2j2yl2ynbiaq.b32.i2p.

Клиент

В моем случае на клиентской машине также используется i2pd и операционная система Debian, файл туннелей располагается в том же месте, что и на сервере — /etc/i2pd/tunnels.conf. Клиентская конфигурация может выглядить так:

[DNS-CLIENT-TCP]
type = client
address = 127.0.0.1
port = 35353
inbound.length = 2
outbound.length = 2
destination = dnsgzxkak4zlrrs5tfh42ob57iley4xrp7srrltn2j2yl2ynbiaq.b32.i2p
keys = transient-dns

[DNS-CLIENT-UDP]
type = udpclient
address = 127.0.0.1
port = 35353
destination = dnsgzxkak4zlrrs5tfh42ob57iley4xrp7srrltn2j2yl2ynbiaq.b32.i2p
keys = transient-dns

Параметры inbound.length и outbound.length отвечают за длину входящих и исходящих туннелей. По умолчанию они составляют три транзитных узла, но я сократил эти значения до двух, чтобы немного минимизировать задержку. Аналогичные параметры применимы в том числе и для серверных туннелей. Дополнительные параметры указаны только в первой секции, так как в самом первом блоке определяются параметры, которые применяются для всех туннелей, использующих тот же ключ (в моем случае это transient-dns). Ключи, начинающиеся со слова transient являются временными — после каждого рестарта i2pd, клиент будет обращаться к серверу с нового внутрисетевого адреса.

Чтобы новые туннели были созданы, нужно перезапустить i2pd. На этом может показаться, что дело сделано. Но нет, остался еще один нюанс.

Файл, отвечающий за настройку DNS в моей операционной системе (Debian 10), не поддерживает указание порта. Можно указать только IP-адрес сервера. Все запросы будут отправлены на порт 53, но наш туннель висит на порте 35353. Если указать в клиентских туннелях порт 53, случится ошибка и туннели созданы не будут, потому что все порты ниже 1024 являются привелегированными — зарезервированными для специальных нужд. Запустить службу на таком порте может только суперпользователь (root), а i2pd, как и другие прикладные программы, работает без прав суперпользователя. Прежде, чем запускать i2pd (или какое-то другое стороннее ПО) с правами root, глубого выдохните, а затем читайте статью дальше.

Удаляем из /etc/resolv.conf прежние DNS, чтобы все запросы шли исключительно через I2P, и добавляем единственный сервер — локальный: nameserver 127.0.0.1. Это сообщит операционной системе, что за разрешением имен в адреса нужно обращаться на адрес 127.0.0.1:53. Осталось попросить ядро системы перенаправлять запросы с порта 53 на 35353, где висят наши TCP/UDP туннели, а затем отдавать ответы в обратном направлении. Самое время для магии iptables (простите, что не новомодный netfilter, я маг старой школы).

iptables -t nat -A PREROUTING -i lo -p udp --dport 53 -j REDIRECT --to-port 35353
iptables -t nat -I OUTPUT -p udp -d 127.0.0.1 --dport 53 -j REDIRECT --to-port 35353

iptables -t nat -A PREROUTING -i lo -p tcp --dport 53 -j REDIRECT --to-port 35353
iptables -t nat -I OUTPUT -p tcp -d 127.0.0.1 --dport 53 -j REDIRECT --to-port 35353

Слышите? Прислушайтесь, это звучат фанфары! Проверьте резолвинг любым удобным способом, я воспользуюсь утилитой nslookup:

acetone@adeb:~$ nslookup habr.com
Server:		127.0.0.1
Address:	127.0.0.1#53

Non-authoritative answer:
Name:	habr.com
Address: 178.248.237.68

Послесловие

В ходе настройки я обратил внимание, что dnsmasq в режиме ожидания занимает только UDP-сокет, однако решил оставить и TCP-туннель согласно стандарту DNS, который предусматривает передачу некоторой информации по TCP. Как бы там ни было, функциональность описанного отлично наблюдается даже при отсутствии TCP-туннелей.

У приведенной конфигурации уходит в среднем 1-2 секунды на запрос и ответ до DNS-сервера. Если ваш результат покажется вам слишком медленным, вы можете сократить длину серверных и клиентских туннелей до 2. Возможны варианты с туннелями в один транзитный узел, но это применимо только для устройств, за компрометацию которых вы не переживаете: например, если ваш DNS не является секретным, длина туннелей может быть равно единице или даже нулю! В таком случае вы даете возможность пользователю выстроить более длинный анонимизирующий туннель с его стороны. Главное, делать всё с умом и не лениться знакомиться с документацией, а также советоваться со знающими людьми.

В качестве демонстрации (а может быть и для постоянного использования), можете воспользоваться сервером DNS, пользовательские конфиги для которого приведены выше.

Source link

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

Ваш адрес email не будет опубликован.