LINUX.ORG.RU

Включаем шифрование для DNS-запросов

 , , ,

Включаем шифрование для DNS-запросов

4

2

Рассмотренные ниже приемы будут полезны для пользователей прокси-серверов/VPN и позволяют скрывать запрашиваемые по DNS имена доменов.
Время на чтение: ~5 минут.
Сложность: Middle AnyKey Developer (нужно уметь запустить терминал).

Введение

Когда создавался интернет, то никаких доменов не существовало, были только ip-адреса отправителя и получателя.

Ясное дело, что все эти цифры, разделенные точками, сложно держать в голове, и в 1983 году была предложена система доменных имен DNS aka Domain Name System (а не магазин), которая стала стандартом в далеком 1986 году. DNS представляет собой систему доверенных корневых серверов, которые обмениваются данными между собой. В этой базе хранятся ip-адреса доменов (A и AAAA записи, последняя для ipv6), а так же дополнительная информация (TXT, CNAME, MX, NS, SOA, PTR и SRV-записи).

Когда вы переходите по ссылке или вбиваете адрес в поле для ввода, то браузер извлекает из него имя домена и делает DNS-запрос чтобы узнать ip-адрес конечного сервера. На этом этапе мы палим имя домена, к которому обращаемся, так как UDP-трафик не шифруется. В этом нет особого смысла при обычном использовании, так как СОРМ и аналогичные системы слежки и так видят ip-адрес, к которому вы в дальнейшем обращаетесь, а значит знают куда вы лазаете.

у UDP проблемы с использованием TLS, из двух существующих решений: QUIC и DTLS, только QUIC предложен в качестве стандарта DNS over QUIC (DoQ). Тут он не рассматиривается

Рассмотренные ниже приемы будут полезны для пользователей прокси-серверов/VPN. Они универсальны в отличии от настроек для отдельных приложений, например, браузера типа настройки Use proxy to perform DNS queries (SOCKS v5 only) в Mozilla FireFox.

Общее у всех решений: мы запускаем локальный DNS-сервер (прокси), который приходящие к нему UDP-запросы перенаправляет на реальный DNS-сервер с использованием шифрования.

Подготовка

Обязательно запрещаем Network Manager перезаписывать /etc/resolv.conf:

$ sudo -e /etc/NetworkManager/conf.d/dns.conf
[main]
dns=none

Перезапускаем для немедленного применения:

$ sudo systemctl restart NetworkManager

Если у вас нет systemd пропускаем

systemd-resolved представляет собой локальный DNS-сервер. Его нужно запустить, если он еще не запущен:

sudo systemctl enable --now systemd-resolved.service

DNS Over TLS (DoT) / DNSSec

Этот способ хорош тем, что ничего дополнительно ставить не нужно. Systemd-resolved давно поддерживает DNSSEC, а значит, будет работать и в умеренно старых дистрибутивах на базе systemd. Как выше уже писалось в UDP с поддержкой TLS существует неопределенность, а поэтому для обращения к конечным DNS серверам вместо UDP используется TCP. Схема: клиент обращается по UDP к локальному DNS, а тот делает DNS-запросы с использованием TLS поверх TCP.

# Ищем секцию [Resolve] и прописываем настройки
$ sudo -e /etc/systemd/resolved.conf
...
[Resolve]
...
DNS=1.1.1.1
FallbackDNS=1.0.0.1
DNSSEC=yes
DNSOverTLS=yes

# Содержимое всего файла должно быть таким
$ sudo -e /etc/resolv.conf
nameserver 127.0.0.53

# Перезапускаем сервис для применения настроек
$ systemctl restart systemd-resolved.service

# Проверяем
$ resolvectl
Global
           Protocols: +LLMNR +mDNS +DNSOverTLS DNSSEC=yes/supported
    resolv.conf mode: foreign
  Current DNS Server: 1.1.1.1
         DNS Servers: 1.1.1.1
Fallback DNS Servers: 1.0.0.1

# Делаем тестовый запрос
$ dig example.com

; <<>> DiG 9.18.24 <<>> example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 58280
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;example.com.                   IN      A

;; ANSWER SECTION:
example.com.            6439    IN      A       93.184.216.34

;; Query time: 0 msec
;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
;; WHEN: Sun Mar 03 13:17:55 MSK 2024
;; MSG SIZE  rcvd: 56

SERVER: 127.0.0.53#53(127.0.0.53) (UDP)

Означает что запросы к DNS осуществляются через защищенное соединение.

Вместо DNS=1.1.1.1 (Cloudflare) можно указать гугловый DNS 8.8.8.8 и фолбечный 8.8.4.4 к нему

А как быть тем, кому религиозные убеждения не позволяют использовать systemd? - Для таких есть подгончик от меня.

ОБЯЗАТЕЛЬНО! Для начала заходим на гитхаб моего репозитория и ставим звезду.

Качаем репозиторий и переходим в каталог:

$ git clone https://github.com/s3rgeym/dot-proxy
$ cd dot-proxy

Редактируем .env чтобы сменить DNS.

Запускаем DoT-прокси:

docker-compose up -d

Меняем /etc/resolv.conf:

nameserver 127.0.0.52

Проверяем:

$ dig www.linux.org.ru | grep -i server
;; SERVER: 127.0.0.52#53(127.0.0.52) (UDP)

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

DNS Over HTTPS (DoH)

Этот способ использовался ранее, но все еще актуален. Локальный сервер принимает UDP-запросы и пересылает их на серваки Гугла, Клауда, которые поддерживают DNS Over HTTPS: GET и POST запросы с параметром name и JSON-лапшой в виде ответа. См. RFC 8484.

# Ставим пакет
$ yay -S dns-over-https

# В качестве nameserver указываем 127.0.0.1
$ sudo -e /etc/resolv.conf
nameserver 127.0.0.1

# Тут можно dns-сервер выбрать
$ sudo -e /etc/dns-over-https/doh-client.conf

$ sudo systemctl enable --now doh-client.service

# Проверяем
$ dig www.google.com | grep -i server
;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP)

Инструкция с Arch Wiki:

Сама утилита:

Прочее:

Более старое решение:

Пример DNS-запроса через HTTPs чисто в академических целях:

$ curl -s 'https://dns.google/resolve?name=example.com&type=A' | jq
{
  "Status": 0,
  "TC": false,
  "RD": true,
  "RA": true,
  "AD": true,
  "CD": false,
  "Question": [
    {
      "name": "example.com.",
      "type": 1
    }
  ],
  "Answer": [
    {
      "name": "example.com.",
      "type": 1,
      "TTL": 371,
      "data": "93.184.215.14"
    }
  ]
}


Проверено: hobbit ()
Последнее исправление: rtxtxtrx (всего исправлений: 25)

Ответ на: комментарий от hobbit

да, мозилла. я только введение написал, остальное и так у меня в заметках валялось. в debian 11 точно работать должно

rtxtxtrx
() автор топика

Спасибо за гайд!!!

Я только после теста осознал, что недоделал свой конфиг до конца.

Теперь, после применения твоей инструкции - работает!

Set440
()
Ответ на: комментарий от teod0r

Хз Nginx настроить и где-то прописать локальный DNS. 98% сидят на systemd - это в принципе повод задуматься о переходе на темную сторону. Пока я не словлю шизу и не задумыюсь о выпиле systemd такой инструкции не будет

rtxtxtrx
() автор топика
Ответ на: комментарий от rtxtxtrx

98% сидят на systemd - это в принципе повод задуматься о переходе на темную сторону

нет. 10000000000 мух не убедят меня что говно вкусно.

teod0r ★★★★★
()
Ответ на: комментарий от teod0r

ну пиши свой прокси-сервер - там буквально 100 строк.

  • прочитать парашу что по UDP приходит
  • открыть TCP соединение и переслать ее по TCP
  • отдать ответ в неизменном виде

Парсить ничего не надо - самый примитивный прокси-сервер.

rtxtxtrx
() автор топика

Обязательно запрещаем Network Manager перезаписывать /etc/resolv.conf:

Содержимое /etc/resolv.conf nameserver 127.0.0.53

Достаточно (и правильно, на мой взгляд) будет переделать /etc/resolv.conf на символическую ссылку на /run/systemd/resolve/stub-resolv.conf

MagicMirror
()
Ответ на: комментарий от teod0r

а без сисьтемдэ и нетворкмэнэджэр как?

dnsmask + dnscrypt-proxy2. Но там настроек минимум, так что на статью не потянет.

mord0d ★★★★★
()
Ответ на: комментарий от rtxtxtrx

98% сидят на systemd

 $ uname -srm
FreeBSD 14.0-RELEASE-p6 amd64

А остальные ≈1.8% — пользователи Windows и macOS? Ты сильно переоцениваешь долю Linux. ☺

mord0d ★★★★★
()
Ответ на: комментарий от rtxtxtrx

Это сDOH.

Нужно использовать это:

Неможно, в портах такого нет. ☺ Зато есть unbound, который в DoT вроде как умеет, причём уже довольно давно.

mord0d ★★★★★
()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.