Безграничный DNS
Преамбула
Ввиду государственных/корпоративных поползновений на остатки свободы ходить взрослым людям по просторам интернетов куда заблагорассудится, встаёт вопрос, каким образом от оных препон хоть «на минималках» отгородиться.
Что ж, попробуем.
Амбула
Понадобятся пакеты:
- tor — для преобразования «луковых» имён в IP'ы;
- dnscrypt-proxy — то же самое, но для плебса: без препонов, чинимых хоть вышестоящим провайдером, хоть надзорными органами;
- dnsmasq (на уровне организации/квартиры) или unbound (в масштабе провайдера) — для кэширования запросов к обоим вышеозначенным «шифрующимся» (эрго, довольно неспешным) резолверам.
The Onion Router («луковый» маршрутизатор)
Настроим так, чтобы он и в ДНС умел, и к ресурсам пропускал. Добавим в его конфиг /etc/tor/torrc
:
VirtualAddrNetwork 172.16.0.0/12 # «Серая» сеть, не используемая на предприятии…
AutomapHostsOnResolve 1 # …адрес из которой прикреплять к IPv6-адресу каждого онион-сайта.
DNSPort 853 # Порт на петлевом интерфейсе для резолвинга .onion-имён…
TransPort 9040 # …а этот — для перенаправления в тор-сеть запросов к таким сайтам.
SocksPort 10.0.1.187:9040 # Собственный адрес:порт машины в обслуживаемой локалке, если надо проксировать запросы к недоступным напрямую ресурсам (см. примеры ниже к фильмам, книгам и т.п.).
Адреса и порты выбирайте уместные для своих реалий.
«Шифрующийся» ДНС-прокси
Умолчально слушает запросы на 127.0.2.1:53 (как системд велит), мой примитивный конфиг /etc/dnscrypt-proxy.toml
выглядит так:
# Empty listen_addresses to use systemd socket activation
listen_addresses = []
server_names = ['cisco', 'cisco-ipv6']
dnscrypt_servers = true
doh_servers = true
use_syslog = true
[sources]
[sources.'public-resolvers']
url = 'https://download.dnscrypt.info/resolvers-list/v2/public-resolvers.md'
cache_file = 'public-resolvers.md'
minisign_key = 'RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3'
refresh_delay = 72
prefix = ''
Кэширующий ДНС
UnBound
/etc/unbound/unbound.conf
(где искать настройки):
include-toplevel: "/etc/unbound/*.conf"
/etc/unbound/server.conf
(основные параметры — адрес в локалке ставить свой!):
server:
do-not-query-localhost: no
interface: 127.0.0.1
interface: 10.0.1.187
domain-insecure: "onion"
private-domain: "onion"
local-zone: "onion." nodefault
/etc/unbound/forwards.conf
(куда стучаться по зонам "onion" — тор, и "." — всем прочим):
Адреса и порты выбирайте уместные для своих реалий.
forward-zone:
name: "onion"
forward-addr: 127.0.0.1@853
forward-zone:
name: "."
forward-addr: 127.0.2.1
DNSmasq
В /etc/dnsmasq.conf
раскомментировать строчку:
conf-dir=/etc/dnsmasq.d/,*.conf
И создать парочку файлов.
/etc/dnsmasq.d/main.conf
:
bind-interfaces
expand-hosts
localise-queries
log-queries
# имя интерфейса локалки ставьте своё!
interface=lan
/etc/dnsmasq.d/dns.conf
(onion-имена запрашивать у тора, все остальные — у днс-криптопрокси):
server=/onion/127.0.0.1#853
server=127.0.2.1
Работают оба — проверено в одном и том же контейнере поочерёдно.
Просто в «к<онто|варти>ре» unbound
избыточен без выделенного контейнера под него, а dnsmasq
зачастую и выступает главным дхцпшником/днс-кэшером, которому остаётся всего-то конфиг подкорректировать вышеприведёнными опциями.
Переадресация запросов к .onion-сайтам
Ну, онион-имена через торовский ДНС-порт теперь резолвятся. Но чтобы до них достучаться, эти стуки следует тоже пропустить через тор. Например, посредством нф-таблиц (примеры к ип-таблицам можете нагуглить самостоятельно — их тьмы и тьмы).
Запросы машин из локалки к адресам из VirtualAddrNetwork следует перекидывать на транспортный тор-порт, добавив в файл настроек /etc/nftables.conf
(в моём случае):
table ip nat {
chain prerouting {
type nat hook prerouting priority filter
iif "lan" ip daddr 172.16.0.0/12 tcp flags & (syn | ack) == syn redirect to 9040
}
}
А чтоб клиентам можно было ходить не только на .onion-сайты, но и прочие блокируемые ресурсы (ну, и по ссх к нашему серверу подключаться), добавим ещё и это:
table inet filter {
chain input {
type filter hook input priority filter
ct state new tcp dport {ssh,9040} tcp flags & (syn|ack) == syn accept
}
}
Для пропуска же клиентских запросов наружу не обойтись без включения маршрутизации — в файл /etc/sysctl.d/router.conf
добавить строчку net.ipv4.ip_forward = 1
и примененить без перезагрузки командой:
# sysctl -w net.ipv4.ip_forward=1
Проверка работоспособности
С нашего днс/тор-прокси
Запустим всё добро
# systemctl enable --now nftables tor dnscrypt-proxy dnsmasq (или unbound)
Глянем, кто слушает ДНС-запросы
root@dnsproxy:~# lsof -ni :53
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
systemd 1 root 22u IPv4 2398895732 0t0 TCP 127.0.2.1:domain (LISTEN)
systemd 1 root 24u IPv4 2398895733 0t0 UDP 127.0.2.1:domain
systemd-r 1542 systemd-resolve 17u IPv4 2498608608 0t0 UDP 127.0.0.53:domain
systemd-r 1542 systemd-resolve 18u IPv4 2498608609 0t0 TCP 127.0.0.53:domain (LISTEN)
unbound 3247 unbound 3u IPv4 2532507011 0t0 UDP 127.0.0.1:domain
unbound 3247 unbound 4u IPv4 2532507012 0t0 TCP 127.0.0.1:domain (LISTEN)
unbound 3247 unbound 5u IPv4 2532507013 0t0 UDP 10.0.1.187:domain
unbound 3247 unbound 6u IPv4 2532507014 0t0 TCP 10.0.1.187:domain (LISTEN)
dnscrypt- 3512 _dnscrypt-proxy 9u IPv4 2398895732 0t0 TCP 127.0.2.1:domain (LISTEN)
dnscrypt- 3512 _dnscrypt-proxy 10u IPv4 2398895733 0t0 UDP 127.0.2.1:domain
root@dnsproxy:~# lsof -ni :853
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
tor 1964 _tor 7u IPv4 2508094076 0t0 UDP 127.0.0.1:domain-s
Поопрашиваем наш кэш
admin@dnsproxy:~$ host ya.ru localhost
Using domain server:
Name: localhost
Address: ::1#53
Aliases:
ya.ru has address 87.250.250.242
ya.ru has IPv6 address 2a02:6b8::2:242
ya.ru mail is handled by 10 mx.yandex.ru.
admin@dnsproxy:~$ host google.ru 10.0.1.187
Using domain server:
Name: 100.0.1.187
Address: 10.0.1.187#53
Aliases:
google.ru has address 173.194.73.94
google.ru has IPv6 address 2a00:1450:4010:c0d::5e
google.ru mail is handled by 0 smtp.google.com.
admin@dnsproxy:~$ host rutorzzmfflzllk5.onion
rutorzzmfflzllk5.onion has address 172.30.0.165
rutorzzmfflzllk5.onion has IPv6 address feb7:c904:733c:691f:d722:3a78:be39:6ba5
Host rutorzzmfflzllk5.onion not found: 4(NOTIMP)
С рабочей станции
Cтатический маршрут к VirtualAddrNetwork
Если таковой не отдаётся дхцп-опцией/домен-политикой для заворота через нашу тор-машинку, можно прибить по месту врукопашную:
# ip r a 172.16.0.0/12 via 10.0.1.187
Для виндоклиента:
route add -p 172.16.0.0/12 10.0.1.187
Опрашиваем кэш
[admin@it-1 ~]$ host mail.ru 10.0.1.187
Using domain server:
Name: 10.0.1.187
Address: 10.0.1.187#53
Aliases:
mail.ru has address 217.69.139.202
mail.ru has address 94.100.180.200
mail.ru has address 94.100.180.201
mail.ru has address 217.69.139.200
mail.ru has IPv6 address 2a00:1148:db00:0:b0b0::1
mail.ru mail is handled by 10 mxs.mail.ru.
[admin@it-1 .ssh]$ host ghwqllapkfpnufc4rjlcay2y4ycgngpgdjhl6qblasz3q4s33wsx5uyd.onion 10.0.1.187
Using domain server:
Name: 10.0.1.187
Address: 10.0.1.187#53
Aliases:
ghwqllapkfpnufc4rjlcay2y4ycgngpgdjhl6qblasz3q4s33wsx5uyd.onion has address 172.24.99.80
ghwqllapkfpnufc4rjlcay2y4ycgngpgdjhl6qblasz3q4s33wsx5uyd.onion has IPv6 address fea2:9235:5ab8:aaa3:b6cf:c537:69f4:b09a
Host ghwqllapkfpnufc4rjlcay2y4ycgngpgdjhl6qblasz3q4s33wsx5uyd.onion not found: 2(SERVFAIL)
Сходим браузером
Постамбула
К блокируемым ресурсам не обязательно ломиться через браузерный прокси-плагин с каждой машинки, коль скоро есть вариант с ява-скриптовым автопрокси на всю контору — например:
- На нашем свежезапущенном тор-днс-прокси поднять простецкий веб-сервис типа
lighttpd
. - В корень веб-сервиса положить файлик
wpad.dat
приблизительно следующего содержания:function FindProxyForURL(url,host){ if (shExpMatch(url,"*baza-knig.ru/*") || shExpMatch(url,"*bookzip.ru/*") || shExpMatch(url,"*fantasy-worlds.org/*") || shExpMatch(url,"*flibusta.net/*") || shExpMatch(url,"*loveread.ec/*") || shExpMatch(url,"*nnmclub.to/*") || shExpMatch(url,"*rg-mechanics.games/*") || shExpMatch(url,"*rgmechanics.info/*") || shExpMatch(url,"*rutor*/*") || shExpMatch(url,"*seasonvar.ru/*") || shExpMatch(url,"*torlock.cc/*") || shExpMatch(url,"*torrent*/*") || shExpMatch(url,"*tracker.*/*") || shExpMatch(url,"*weebly.com/*") || shExpMatch(url,"*xatab-repack.net/*") || shExpMatch(url,"*.onion/*")) return "SOCKS5 10.0.1.187:9040; SOCKS 10.0.1.187:9040"; else return "DIRECT"; }
- в дальнейшем по необходимости пополняя его другими блокируемыми сайтами;
- Для клиентов из локалки присвоить серверу имя/псевдоним вида
wpad.наш.внутренний.домен
- В принципе, если настроить браузер на автоопределение прокси-сервера, он уже на этом шаге должен подтягивать приведённый сценарий по ДНС, но лучше всё же...
- Указать
252-й опцией DHCP
адресhttp://wpad.наш.внутренний.домен/wpad.dat
, дабы дать знать клиентам локалки, кто решает, что куда проксировать;- Проверить действенность списка можно, прямо задав браузеру указанный адрес в пути к сценарию автонастройки;