Linux: DNS mit Dnsmasq, DNSCrypt-Proxy 2 & Tor

Vorbemerkung

Zu den Methoden, das Nutzungsverhalten von Internetnutzern zu überwachen oder deren Zugriff auf Inhalte im Internet zu zensieren, was von Befürwortern als „Internet-Sperre“ bezeichnit wird, zählen Manipulationen der Namensauflösung und des Domain Name System (DNS). Bekannt sind Manipulationen in Ländern wie China. In Deutschland und Europa wurden in der Vergangenheit ähnliche Eingriffe vorgenommen oder Versuche zur Entwicklung und Durchsetzung von Zensur-Infrastrukturen gestartet. Auch Geheimdienste haben ein reges Interesse am Blockieren, Abfangen und Auswerten von Anfragen zur Namensauflösung wie das QUANTUMTHEORY/QUANTUMDNS System der 5-Eyes Geheimdienste aufgezeigt hat.

Zu den Methoden zur Abwehr der eigenen Überwachung und der Eingriffe in die Rezipientenfreiheit über die oben genannten Manipulationen gehört die Änderung der Konfiguration der Namensauflösung und Nutzung des DNS, um Zensur-Infrastrukturen und manipulierte Nameserver zu umgehen.

Tor

Nach der Installation von Tor wird in die Tor Konfigurationsdatei /etc/tor/torrc eingefügt:

DNSPort 127.0.0.1:1053

DNSCrypt-Proxy 2

DNSCrypt-Proxy 2 ist ein DNS Proxy, der das DNSCrypt Protokoll in Version 1 und 2, das keine offizielle Spezifikation der IETF ist und das DNS Queries over HTTPS (DoH) Protokoll nach IETF RFC8484 implementiert. Mit beiden Protokollen werden Anfragen und Antworten zur Namensauflösung verschlüsselt zwischen dem Proxy und DNS-Resolvern ausgetauscht, die DNSCrypt und/oder DoH ebenfalls unterstützen.

Zusätzlich hat DNSCrypt-Proxy u. a. weitere Funktionen:

  • HTTP/SOCKS Proxy-Schnittstelle (ab 2.0.15)
  • Filtern und Manipulieren von ausgehenden DNS-Anfragen
  • Weiterleiten von Anfragen zu spezifischen DNS-Resolvern
  • lokales Zwischenspeichern von DNS-Antworten
  • automatische Aktualisierung der Liste der DNSCrypt-Resolver, die DNSCrypt/DoH unterstützen
  • kompatibel mit DNSSEC

Installation

sudo aptitude install git golang

Sofern DNSCrypt-Proxy 2 (noch) nicht in einem Repository enthalten ist oder man DNSCrypt-Proxy 2 selbst installieren möchte:

mkdir dcp
cd dcp
git clone https://github.com/jedisct1/dnscrypt-proxy src
export GOPATH=$PWD
cd src/dnscrypt-proxy/
go clean
go build -ldflags="-s -w" -o $GOPATH/linux-amd64/dnscrypt-proxy
sudo mkdir /etc/dnscryptproxy
sudo chown :nogroup /etc/dnscryptproxy
sudo chmod 2750 /etc/dnscryptproxy
sudo cp ./example-dnscrypt-proxy.toml /etc/dnscryptproxy/dnscrypt-proxy.toml
sudo cp -f ../../linux-amd64/dnscrypt-proxy /usr/local/sbin/
sudo chmod 755 /usr/local/sbin/dnscrypt-proxy
rm -Rf /pfad/dcp/linux-amd64

Aktualisierung:

cd /pfad/dcp/src
git pull origin master

Anschließend die dnscryptproxy.service Unit-Datei herunterladen und in das entsprechende Verzeichnis kopieren:

dnscryptproxy.service
[Unit]
Description=DNSCrypt-Proxy
After=network.target network-online.target
Wants=network-online.target
Before=dnsmasq.service
 
[Service]
Type=simple
DynamicUser=yes
User=dnscrypt-proxy
Group=nogroup
RuntimeDirectory=dnscryptproxy
RuntimeDirectoryMode=750
CacheDirectory=dnscryptproxy
CacheDirectoryMode=750
LogsDirectory=dnscryptproxy
LogsDirectoryMode=750
ConfigurationDirectory=dnscryptproxy
ConfigurationDirectoryMode=2750
PIDFile=/run/dnscryptproxy/proxy.pid
ExecStart=/usr/local/sbin/dnscrypt-proxy -config /etc/dnscryptproxy/dnscrypt-proxy.toml -pidfile /run/dnscryptproxy/proxy.pid
ExecStop=/bin/kill -TERM $MAINPID
TimeoutStartSec=180
Restart=on-failure
RestartSec=10s
UMask=0027
RestrictAddressFamilies=AF_INET
RestrictRealtime=true
RestrictNamespaces=true
PrivateDevices=true
PrivateUsers=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectControlGroups=true
ProtectSystem=strict
InaccessiblePaths=/boot /root /home
ReadWritePaths=/run/dnscryptproxy /var/cache/private/dnscryptproxy /var/log/private/dnscryptproxy
MemoryDenyWriteExecute=true
NoNewPrivileges=true
CapabilityBoundingSet=CAP_MKNOD CAP_NET_BIND_SERVICE
SystemCallArchitectures=x86-64
SystemCallFilter=~@clock @cpu-emulation @debug @keyring @ipc @module @mount @obsolete @raw-io @privileged @reboot @resources @setuid @swap
 
[Install]
WantedBy=multi-user.target
sudo cp dnscryptproxy.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable dnscryptproxy.service

Konfiguration

sudo vi /etc/dnscryptproxy/dnscrypt-proxy.toml

server_names = ['name1', 'name2', 'nameN'] oder
# server_names

require_dnssec = true
require_nolog = true
require_nofilter = true

Es wird nur die Auswahl der benannten DNSCrypt-Resolver verwendet oder – wenn auskommentiert – alle der Liste der DNSCrypt-Resolver. Wählt man die zweite Option, sollte man die require_* Optionen aktivieren, um nur die Resolver zu nutzen, die DNSSEC Prüfungen selbst ausführen oder auswerten und erklärt haben, keine Anfragen zu protokollieren, sie nicht zu filtern oder zu blockieren (aus welchen Gründen auch immer).

listen_addresses = ['127.0.0.1:port']

Der DNSCrypt-Proxy lauscht nur lokal an IP-Adresse 127.0.0.1 am angegebenen Port (z. B. 1153) auf Anfragen.

ipv4_servers = [true|false]
ipv6_servers = [true|false]

Einstellung, ob man nur DNS-Resolver ansprechen will, die über IPv4 oder IPv6 erreichbar sind.

dnscrypt_servers = true

DNS-Resolver, die das DNSCrypt Protokoll unterstützen, werden verwendet.

doh_servers = [true|false]

DNS-Resolver, die das DNS Queries over HTTPS (DoH) Protokoll unterstützen, werden verwendet oder nicht.

Ist die Option aktiviert, werden u. a. automatisch die DNS-Resolver von Cloudflare und Google (plus der DNS-Resolver, die wiederum an beide weiterleiten) immer mitverwendet, da sie nur DoH unterstützen. Da sie zumeist die kürzesten Antwortzeiten bieten, ist die Wahrscheinlichkeit groß, dass sie überwiegend vom DNSCrypt-Proxy angefragt werden und ein Großteil der Anfragen nur über diese Anbieter erfolgt. Da DNSCrypt-Proxy mit der server_names Option nur die Auswahl zwischen allen oder bestimmten Resolvern lässt, aber keine Blacklist für Resolvernamen anbietet, muss man die Option deaktivieren oder entsprechende Regeln für Paketfilter einrichten, wenn man beide Anbieter nicht nutzen will.

force_tcp = true
proxy = "socks5://127.0.0.1:9050"

Wenn der Datenverkehr mit den DNS-Resolvern über Tor anonymisiert werden soll, aktiviert man die Option mit true, da Tor noch keinen UDP -Transport unterstützt und die Option zur Verwendung von Tor als SOCKS-Proxy.

lb_strategy = 'methode'

Mit random als Methode werden Anfragen zufällig auf alle Resolver verteilt, unabhängig von ihren Antwortzeiten. Mit p2 oder ph statt random werden Anfragen zufällig auf die zwei Resolver mit den kürzesten Antwortzeiten oder die Hälfte aller Resolver mit kürzesten Antwortzeiten verteilt. Die p2/ph Listen werden dynamisch bei Veränderungen der Antwortzeiten neu gebildet. Die p2 oder ph Methode kann den Effekt haben, dass für alle Anfragen z. B. immer Cloudflare Nameserver verwendet werden, weil Cloudflare die kürzesten Antwortzeiten bietet.

use_syslog = false

Ausgaben des DNSCrypt-Proxy werden nicht in Systemlogs mitprotokolliert.

dnscrypt_ephemeral_keys = true
tls_disable_session_tickets = true
tls_cipher_suite = [nr1, nrN]

Für jede Anfrage werden neue Schlüssel erzeugt, statt nur einmalig beim Start, TLS Session-Tickets werden deaktiviert und dem Server, von dem die Liste der DNSCrypt-Resolver heruntergeladen wird wie auch den DoH-Servern werden die mit nr bezeichneten TLS Cipher-Suites vorgegeben. Achtung: Die in der Beispiel-Konfigurationsdatei angegebenen Beispiel Cipher-Suites tls_cipher_suite = [52392, 49199] unterstützt download.dnscrypt.info gerade nicht.

fallback_resolver = 'a.b.c.d:53'
ignore_system_dns = false/true

Angabe eines DNS-Resolvers, über den die herkömmliche bzw. unverschlüsselte Auflösung des Domainnamens erfolgen soll, von dem die Liste der DNSCrypt-Resolver heruntergeladen wird, wenn die Namensauflösung über den DNS-Resolver des Systems fehlschlägt (false) oder sie generell über den angegebenen Fallback DNS-Resolver erfolgen soll (true). Einen DNS-Resolver kann man z. B. in den DNS-Resolver/Server Listen aussuchen. Mit false kann man den Domainnamen auch via Dnsmasq über Tor anonymisiert auflösen lassen.

log_files_max_size = 1
log_files_max_age = 1
log_files_max_backups = 1

Die Logdateien in /var/log/dnscryptproxy/ werden von DNSCrypt-Proxy selbst rotiert. Mit den obigen Optionen erreichen sie eine maximale Größe von 1 MB und danach wird von jeder Logdatei ein Backup angelegt, das maximal einen Tag vorgehalten wird. Will man keine Logdateien anlegen, belässt man die Angaben zu Namen und Pfaden auskommentiert.

forwarding_rules = '/etc/dnscryptproxy/forwarding-rules.txt'

In der Regeldatei können ähnlich wie mit der fallback_resolver Option Anfragen zu weiteren Domainnamen unverschlüsselt an spezifische DNS-Resolver weitergeleitet werden.

Beispiel
domain.tld Resolver-IP-Adresse1[,Resolver-Ip-AdresseN]

cloaking_rules = '/etc/dnscryptproxy/cloaking-rules.txt'

In der Regeldatei können ähnlich wie in der /etc/hosts Datei Domainnamen (oder ihren Mustern) statische IP-Adressen zugeordnet werden. Statt IP-Adressen können auch andere Domainnamen eingesetzt werden, deren IP-Adressen nach Auflösung den ursprünglichen Domainnamen zugeordnet werden (siehe auch Cache Poisoning).

Beispiel
localhost   127.0.0.1
domain.tld  IP-Adresse
domain1.tld domain2.tld

Bestimmt die maximale Anzahl von n aufgelösten Domainnamen, die im RAM-Zwischenspeicher für erneute Abfragen vorgehalten werden. Standard sind 512 Einträge, aber n sollte <= n bei Dnsmasq sein.

[query_log]
   file = '/var/log/dnscryptproxy/query.log'
   format = 'tsv'
   ignored_qtypes = ['DNSKEY', 'NS']

Logdatei, in der die Anfragen im Tab-separated values Format mitprotokolliert werden können.

[nx_log]
   file = '/var/log/dnscryptproxy/nx.log'
   format = 'tsv'

Logdatei, in der Anfragen zu nicht extistierenden Zonen mitprotokolliert werden können.

[blacklist]
   blacklist_file = '/etc/dnscryptproxy/blacklist.txt'
   log_file = '/var/log/dnscryptproxy/blacklist.log'
   log_format = 'tsv'

[ip_blacklist]
   blacklist_file = '/etc/dnscryptproxy/ip-blacklist.txt'
   log_file = '/var/log/dnscryptproxy/blacklist.log'
   log_format = 'tsv'

[whitelist]
   whitelist_file = '/etc/dnscryptproxy/whitelist.txt'
   log_file = '/var/log/dnscryptproxy/whitelist.log'
   log_format = 'tsv'

Mit der Muster-Blacklist für Domainnamen, der IP-Blacklist für IP-Adressen oder ihren Anteilen und der Muster-Whitelist für Domainnamen können ausgehende Anfragen gefiltert bzw. blockiert oder generell zugelassen werden.

[sources]
   cache_file = '/var/cache/private/dnscryptproxy/public-resolvers.md'

Absolute Pfadangabe zur Datei, in der die Liste der DNSCrypt-Resolver heruntergeladen wird.

Dnsmasq

Dnsmasq ist ein DNS-Resolver/Server, DNS-Cache und DHCP-Server. In der Anleitung wird Dnsmasq nur als DNS-Resolver eingesetzt, der lokale Adressen direkt auflöst und alle weiteren Anfragen an DNSCrypt-Proxy2 und/oder Tor weiterleitet.

Installation

sudo aptitude install dnsmasq

Konfiguration

sudo chown dnsmasq:root /etc/dnsmasq.conf
sudo chmod 440 /etc/dnsmasq.conf
sudo vi /etc/dnsmasq.conf

port=53
interface=lo
listen-address=127.0.0.1
except-interface=nic-name
no-dhcp-interface=lo
bind-interfaces

Dnsmasq lauscht nur lokal am Loopback-Interface (127.0.0.1) und Port 53 auf DNS-Anfragen zur Namenauflösung, DHCP wird nicht bedient.

no-resolv
no-poll

Die Adressen der Nameserver, an die Dnsmasq die Anfragen weiterleitet (DNSCrypt-Proxy2 und Tor), werden direkt in der Dnsmasq Konfiguration definiert und deshalb die Auswertung und Überwachung auf Änderungen der /etc/resolv.conf Datei deaktiviert.

domain-needed
bogus-priv
dns-loop-detect
stop-dns-rebind
rebind-localhost-ok
proxy-dnssec

  • Anfragen, die keine Domainnamen bzw. -anteile enthalten, werden nicht an Nameserver weitergeleitet
  • Anfragen zu Adressen aus dem privaten Adressraum werden nicht an Nameserver weitergeleitet
  • Nameserver, die Weiterleitungs-Loops auslösen, werden nicht weiter angefragt
  • Antworten der Nameserver, die Adressen aus dem privaten Adressraum enthalten, werden verworfen und protokolliert
  • Dnsmasq führt selbst keine DNSSEC Überprüfung durch, sondern cacht Prüfresultate der Nameserver und leitet sie an anfragende Clients weiter

cache-size=n

Bestimmt die maximale Anzahl von n aufgelösten Domainnamen, die im RAM-Zwischenspeicher für erneute Abfragen vorgehalten werden. Standard sind 150 Einträge, aber n sollte >= n bei DNSCrypt-Proxy2 sein.

local=/domainname1/
local=/domainnameN/

Angabe rein lokal existierender Domainnamen und FQDNs, die nur direkt über die Einträge in der /etc/hosts Datei aufgelöst werden bzw. hier die in der /etc/hosts vorhandenen Domainnamen einsetzen.

address=/host.domain.tld1/a.b.c.d
address=/host.domain.tldN/a.b.c.d

Die aufgeführten Domainnamen werden nicht durch Anfragen an Nameserver aufgelöst, sondern ihnen wird direkt eine statische IP-Adressen zugeordnet. Kann ergänzend zur /etc/hosts Datei oder alternativ zur Cloaking Regeldatei von DNCrypt-Proxy2 eingesetzt werden.

server=/.onion/127.0.0.1#1053
server=/.exit/127.0.0.1#1053
server=/.i2p/127.0.0.1#4444
server=/download.dnscrypt.info/127.0.0.1#1053
server=/raw.githubusercontent.com/127.0.0.1#1053
server=127.0.0.1#1153

  • Anfragen zur Auflösung von Domainnamen mit den .onion, .exit Tor TLDs werden an Tor bzw. zu Tors DNSPort weitergeleitet
  • Anfragen zur Auflösung von Domainnamen mit der .i2p I2P TLD werden an den lokalen I2P HTTP-Proxy weitergeleitet
  • Die download.dnscrypt.info und raw.githubusercontent.com Domains, von der die Liste der DNSCrypt-Resolver heruntergeladen wird, wird anonymisiert über Tor aufgelöst – wenn auskommentiert, über den Fallback DNS-Resolver, der in der Konfigurationsdatei von DNSCrypt-Proxy2 angegeben ist
  • Alle weiteren Anfragen zu anderen Domainnamen werden an DNSCrypt-Proxy2 weitergeleitet

Man kann das Modell auch umkehren, wenn man nur spezifische Domainnamen über DNSCrypt-Proxy2 auflösen lassen will und für alle anderen Domainnamen die anonymisierte Namensauflösung über Tor bevorzugt:

Beispiel
server=/domain1/127.0.0.1#1153
server=/domainN/127.0.0.1#1153
server=/.i2p/127.0.0.1#4444
server=127.0.0.1#1053

log-facility=/var/log/dnsmasq/logfile
log-queries

Anfragen und Statusmeldungen von Dnsmasq werden in der angegebenen Logdatei mitprotokolliert.

Tracker- und Ad-Blocking

Die blacklist.txt Blacklist von DNSCrypt-Proxy kann man auch für die Blockierung der Namensauflösung der Domains von Tracker- und Werbe-Dienstleistern direkt in Dnsmasq als DNS Sinkhole verwenden, sofern in der DNSCrypt-Proxy Blacklist nur Domainnamen, aber keine Muster verwendet werden.

Vorgehensweise

Man speichert das folgende „dnsmasq_blocklist“ Skript in /usr/local/bin und ändert die Verzeichnisrechte für /etc/dnsmasq.d/. Das Skript liest die DNSCrypt-Proxy Blacklist aus (die man mit einem Editor um neue, zu blockierende Tracker-Domains ergänzt) und erstellt die Dnsmasq Blacklist mit address=„/tracker.domain/“ Einträgen für jede Domain, so dass eine Anfrage zu tracker.domain von Dnsmasq mit NXDOMAIN beantwortet wird:

dnsmasq_blocklist
#!/bin/sh
 
dcpblockfile="/etc/dnscryptproxy/blacklist.txt"
dmblockfile="/etc/dnsmasq.d/blacklist.txt"
 
if [ ! -f "$dmblockfile" ]; then
	touch "$dmblockfile"
else
	echo -n "" > "$dmblockfile"
fi
 
while read line; do
    domain="/${line}/"
    echo "address=\"${domain}\"" >> "$dmblockfile"
done < $dcpblockfile
 
exit 0
sudo chmod 2775 /etc/dnsmasq.d
$ dig @127.0.0.1 -p 53 -t A -4 kissmetrics.com
 
; <<>> DiG 9.11.3-1~bpo9+1-Debian <<>> @127.0.0.1 -p 53 -t A -4 kissmetrics.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 18196
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
 
;; QUESTION SECTION:
;kissmetrics.com.               IN      A

Die dnsmasq.service Systemd-Unitdatei wird abgeändert (bzw. mit der Änderung in /etc/systemd/system geführt), um das dnsmasq_blocklist Skript vor dem Start von Dnsmasq auszuführen:

dnsmasq.service
ExecStartPre=/usr/local/bin/dnsmasq_blocklist

Die dnsmasq.conf Dnsmasq-Konfigurationsdatei wird abgeändert, um die Dnsmasq Blacklist einzulesen:

dnsmasq.conf
conf-dir=/etc/dnsmasq.d/,*.txt

DNS-Resolver/Server Listen

Konfiguration Namensauflösung

Sofern noch nicht installiert, das resolvconf Paket nachinstallieren:

sudo aptitude install resolvconf

Danach ist dafür Sorge zu tragen, dass in der letztendlich genutzten resolv.conf Konfigurationsdatei nur auf localhost und damit Dnsmasq als DNS-Resolver zur Namensauflösung verwiesen wird:

nameserver 127.0.0.1

Bei dynamischer Konfiguration der Netzwerkkarte per DHCP wird die resolv.conf Datei überschreiben und die Adressen der Nameserver eingesetzt, die der DHCP Client vom DHCP Server erhält, so dass man dafür Sorge tragen muss, dass ein Überschreiben der resolv.conf Datei unterbleibt.

Unter Debian erreicht man das durch Entfernung von domain-name-servers in der request Zeile und Auskommentieren von prepend domain-name-servers 127.0.0.1; in /etc/dhcp/dhclient.conf:

request subnet-mask, (…) domain-name-servers
prepend domain-name-servers 127.0.0.1;

Sonstiges

Verweise auf aktuelle Seite