DNS много не бывает или установка DNSCrypt-proxy в контейнере Docker

Преамбула: долгое время у меня был развернут dnsmasq в виде отдельного контейнера, который занимался вырезанием рекламы и использовался как основной DNS в моей сети. Но шило в з всегда хочется чего-то нового, лучшего и секурного. Для секурного раньше использовали связку dnsmasq c каким-либо вышестоящим сервером, например на том же dnscrypt-proxy. Но несколько версий назад в Dnscrypt-proxy появилась возможность самостоятельно резать рекламу и я решил переехать на него. А с учетом того, что он еще работает и как кеширующий сервер – так вообще замечательно.

В двух словах, что такое DNSCrypt и для чего он нужен.

DNSCrypt – это open-source протокол, который позволяет шифровать и рекурсивно обрабатывать DNS запросы. Таким образом, если ваш компьютер/телефон/телевизор/холодильник настроены на использовании вашего локального сервера DNSCrypt, то ни один DNS запрос не выйдет за пределы вашей квартиры в открытом (незашифрованном) виде, не будет известен вашему провайдеру и не будет доступен для перехвата и подмены.

DNSCrypt is a protocol that encrypts, authenticates and optionally anonymizes communications between a DNS client and a DNS resolver. It prevents DNS spoofing. It uses cryptographic signatures to verify that responses originate from the chosen DNS resolver and haven’t been tampered with.

It is an open specification, with free and open source reference implementations, and it is not affiliated with any company nor organization.

Free, DNSCrypt-enabled resolvers are available all over the world.

https://dnscrypt.info

Итак, на первом месте там стоит реализация под именем DNSCrypt-proxy поддерживающая все что нужно и даже немного сверху, поэтому была выбрана именно она.

Выбор сделан, а значит дальше лезем на https://github.com/DNSCrypt/dnscrypt-proxy и смотрим, какие варианты установки есть. Угу, бинарники и source, но готового контейнера под докер не предлагается. Ок, лезем на hub.docker.com, вбиваем в поиск dnscrypt-proxy и смотрим, что уже надокерил народ до нас.

А народ надокерил по полной, вариантов куча, придется изучать их все и смотреть, чем они отличаются друг от друга. И после относительно недолгого изучения я остановился на контейнере mattbodholdt/dnscrypt-proxy который благополучно несколько модифицировал под себя. Но большинство правок пришлось откатить, поскольку мой контейнер запущен в Synology и я не могу создать пользователя и группу с нужными мне SID и GID (автор, кстати, судя по ним, использует этот контейнер на Raspberry Pi).

Но вот такой вот Dockerfile получился у меня в итоге:

FROM golang:alpine

RUN apk add --update bind-tools curl jq && \
	rm -rf /var/cache/apk/*

ADD dnscrypt-proxy.toml /etc/dnscrypt-proxy/dnscrypt-proxy.toml
ADD test.sh /etc/dnscrypt-proxy/tests/test.sh

RUN case $(uname -m) in \
	armv7l) \
		ARCH=arm \
	;; \
	arm64|aarch64) \
		ARCH=arm64 \
	;; \
	amd64|x86_64) \
		ARCH=x86_64 \
	;; \
	*) \
		echo "Unhandled arch $(uname -m)!  Please report!" \
		ARCH=unknown \
	;; \
	esac; \
	echo "Fetching dnscrypt-proxy-latest for ${ARCH}" && \
	VER=$(curl -sL https://api.github.com/repos/jedisct1/dnscrypt-proxy/releases/latest | jq -j .tag_name) && \
	curl -s -L https://github.com/jedisct1/dnscrypt-proxy/releases/download/${VER}/dnscrypt-proxy-linux_${ARCH}-${VER}.tar.gz > dnscrypt-proxy-linux_${ARCH}.tar.gz && \
	tar -xzf dnscrypt-proxy-linux_${ARCH}.tar.gz && \
	mv linux-${ARCH}/dnscrypt-proxy $GOPATH/bin/dnscrypt-proxy && \
	rm -rf dnscrypt-proxy-linux_${ARCH}.tar.gz linux-${ARCH}

RUN addgroup -g 1000 proxy && \
	adduser -u 1000 -G proxy -H proxy -S && \
    mkdir /etc/dnscrypt-proxy/run && \
	touch /etc/dnscrypt-proxy/run/dnscryptProxy.pid && \
	chown -R proxy:proxy /etc/dnscrypt-proxy

EXPOSE 53/tcp
EXPOSE 53/udp

ENTRYPOINT ["/go/bin/dnscrypt-proxy", "-config", "/etc/dnscrypt-proxy/dnscrypt-proxy.toml", "-pidfile", "/etc/dnscrypt-proxy/run/dnscryptProxy.pid"]

HEALTHCHECK --interval=15s --timeout=3s --retries=3 CMD dig one.one.one.one || exit 1

Как видите, в контейнере сразу уже присутствует конфигурация и сервер может быть запущен с ней. Но это не очень удобный вариант, поэтому файл конфигурации положен локально и примаплен в контейнер вместо уже существующего. Так же я маплю с хоста папку conf в которой находятся мои локальные хосты и настройки фильтрации рекламы.

В конфигурации еще я поменял список серверов на которые отправляются запросы, потому что автор использовал всего 1 – cloudflare, я предпочел использовать загрузку списка серверов и выбор нескольких самых быстрых из них сервером автоматически. Для этого в конфигурации надо закомментировать строку server_names = [‘cloudflare’]. Добавил локальный резолвер: cloaking_rules = ‘conf/cloaking-rules.txt’ (для этого и нужна папка conf) и настроил фильтрацию рекламы.

Сам контейнер повешен на сеть хост и в настройках указаны два интерфейса для бинда – 127.0.0.1 и интерфейс Synology. Это нужно для того, что бы другие контейнеры как с host так и с bridge могли успешно обращаться к dns серверу.

На этом сервер стал полностью функционален, первый запрос к новому имени обрабатывается от 80мс до 140мс, что в принципе вполне приемлемо, особенно учитывая, что запросы кешируются и в дальнейшем ответ приходит в пределах 8мс-12мс. Для сравнения, после подключения фильтров рекламы в dnsmasq на Synology, ответы даже из кеша я мог ожидать до 200мс. Это не значит что dnsmasq плохой, это значит, что он почему то плохо работает именно в моем случае, на той же raspberry он работал куда шустрее.

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

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