nix-git/modules/dns.nix

242 lines
8.5 KiB
Nix

{ config, pkgs, ... }:
{
assertions = [{
assertion = config.networking.networkmanager.enable;
message = ''This module is only tested with NetworkManager'';
} {
assertion = ! config.services.resolved.enable;
message = ''This module is incompatible with resolved as resolved does not listen to IPv6 loopback'';
} {
assertion = config.networking.enableIPv6;
message = ''This module assumes that IPv6 networking is available'';
}];
# Encrypted, anonymized DNS queries.
#
# NixOS networking options:
# https://nixos.wiki/wiki/Encrypted_DNS#Setting_nameservers
# Exmaple dnscrypt-proxy config:
# https://github.com/DNSCrypt/dnscrypt-proxy/blob/master/dnscrypt-proxy/example-dnscrypt-proxy.toml
# NixOS config examples:
# https://nixos.wiki/wiki/Encrypted_DNS#dnscrypt-proxy2
# https://github.com/LudovicoPiero/dotfiles/blob/338b0585d195e6644df9bf8b63fd574af7c18e26/cells/workstations/nixosProfiles/dnscrypt2/default.nix
#
# Check if service is running
# systemctl status dnscrypt-proxy2.service
#
# Check if it is working
# https://wiki.archlinux.org/title/Dnscrypt-proxy#Check_if_dnscrypt-proxy_is_working
#
# View generated config file:
# cat "$(systemctl show -P FragmentPath dnscrypt-proxy2.service)" | grep 'ExecStart='
# cat ....toml
# Example: Running c in a container and routhing dnscrypt-proxy queries through it
# https://github.com/AtaraxiaSjel/nixos-config/blob/3510d178bafeb5d742806d25d5c6c34570c498e8/profiles/workspace/proxy.nix
# TODO
# create new config option
# encrypted-dns
# If enabled
# use dnscrypt
# don't use adguard and ffmuc DNS servers
# Firefox use system DNS
networking.nameservers = [
# IPv4
"127.0.0.1"
# IPv6
"::1"
];
#networking.nameservers = [
# # https://www.kuketz-blog.de/empfehlungsecke/#dns
# # unfiltered.adguard-dns.com (supports DNSSEC)
# "94.140.14.140" "94.140.14.141"
# # https://www.kuketz-blog.de/empfehlungsecke/#dns
# # dot.ffmuc.net (supports DNSSEC)
# "5.1.66.255" "185.150.99.255"
#];
# If using dhcpcd.
networking.dhcpcd.extraConfig = "nohook resolv.conf";
# If using NetworkManager.
networking.networkmanager.dns = "none";
systemd.services.dnscrypt-proxy2.serviceConfig = {
StateDirectory = "dnscrypt-proxy";
};
services.dnscrypt-proxy2 = {
enable = true;
settings = {
#listen_addresses = ['127.0.0.1:53'];
# Enable a DNS cache to reduce latency and outgoing traffic
cache = true;
# DNSCrypt: Create a new, unique key for every single DNS query.
# This may improve privacy but can also have a significant impact on CPU usage.
# Only enable if you don't have a lot of network load.
#dnscrypt_ephemeral_keys = false
# The cipher suite can't be changed for TLS 1.3 connections, see
# https://github.com/dnscrypt/dnscrypt-proxy/wiki/Performance#cipher-suites-doh
# https://github.com/DNSCrypt/dnscrypt-proxy/issues/2359#issuecomment-1488501839
#tls_cipher_suite = ...
bootstrap_resolvers = [
#
# Local DNS servers
#
# DNS server of Fritz!Box guest WiFi
"192.168.179.1:53"
#
# Public DNS servers
#
# https://www.kuketz-blog.de/empfehlungsecke/#dns
# dot.ffmuc.net (supports DNSSEC)
"5.1.66.255:53" "185.150.99.255:53"
# https://www.kuketz-blog.de/empfehlungsecke/#dns
# unfiltered.adguard-dns.com (supports DNSSEC)
"94.140.14.140:853" "94.140.14.141:853"
"9.9.9.11:53" # Quad9
"1.1.1.1:53" # Cloudflare
"8.8.8.8:53" # Google
];
# Use servers reachable over IPv4.
ipv4_servers = true;
# Use servers reachable over IPv6.
# Do not enable if you don't have IPv6 connectivity.
ipv6_servers = true;
block_ipv6 = false;
# Use servers implementing the DNSCrypt protocol.
dnscrypt_servers = true;
# Use servers implementing the DNS-over-HTTPS protocol.
doh_servers = false;
# Use servers implementing the Oblivious DoH protocol
odoh_servers = false;
# Server must support DNS security extensions (DNSSEC).
require_dnssec = true;
# Server must not log user queries (declarative).
require_nolog = true;
# Server must not enforce its own blacklist (for parental control, ads blocking...).
require_nofilter = true;
# Fetch list of dnscrypt server names.
# These server names are used below in the `server_names` and `via` options.
sources = {
public-resolvers = {
urls = [
"https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v3/public-resolvers.md"
];
cache_file = "/var/lib/dnscrypt-proxy2/public-resolvers.md";
minisign_key = "RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3";
};
relays = {
urls = [
"https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v3/relays.md"
];
cache_file = "/var/lib/dnscrypt-proxy2/relays.md";
minisign_key = "RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3";
};
};
# Names of servers to be used for DNS queries.
# These are not contacted directly.
# Instead, the queries are forwarded by relay servers.
server_names = [
# Operated by https://cryptostorm.is/
"cs-berlin"
"cs-de"
"cs-dus1"
"cs-dus2"
"cs-dus3"
"cs-dus4"
# Other operators.
"dns.digitale-gesellschaft.ch"
"dns.digitale-gesellschaft.ch-ipv6"
"dct-de"
"dct-nl"
"dns.digitalsize.net"
"dns.digitalsize.net-ipv6"
"ibksturm" # Switzerland
"doh-ibksturm" # Switzerland
"faelix-ch-ipv4" # Switzerland
# Already used as relay server.
#"dnswarden-uncensor-dc-swiss" # Switzerland
# DNS servers that filter some requests.
#"switch" # Filters requests
#"dnsforge.de" # Filters requests
#"brahma-world" # Filters requests
#"brahma-world-ipv6" # Filters requests
#"libredns" # No DNSSEC
];
anonymized_dns = {
routes = [
{
# All DNS servers given in `server_names`.
server_name = "*";
# Relay servers.
# These forward requests to the chosen DNS servers.
via = [
"anon-digitalprivacy.diy-ipv4" # Germany, by https://digitalprivacy.diy
"anon-serbica" # Netherlands, by https://litepay.ch
"anon-kama" # France, by Frank Denis (@jedisct1)
"anon-scaleway" # France, by Frank Denis (@jedisct1)
"anon-scaleway2" # France, by Frank Denis (@jedisct1)
"anon-fluffycat-fr-01" # France
"anon-dnswarden-swiss"
# Already used as DNS server.
#"anon-cs-berlin"
#"anon-cs-de"
#"anon-cs-dus1" # Germany
#"anon-cs-dus2" # Germany
#"anon-cs-dus3" # Germany
#"anon-cs-dus4" # Germany
#"anon-cs-fr"
#"anon-cs-dk"
#"anon-cs-belgium"
#"anon-cs-nl"
#"anon-cs-nl2"
#"anon-cs-poland"
#"anon-cs-czech"
#"anon-cs-austria"
];
}
];
# Skip resolvers incompatible with anonymization instead of using them directly.
skip_incompatible = true;
};
# As this dict is converted to JSON, we can't use `proxy = lib.mkIf (...) "socks5://127.0.0.1:9050"` inside it - it won't be evaluated.
# Instead, we merge it with another dict below:
} // (
# On some networks dnscrypt-proxy can't resove DNS queries.
#
# Example: Fritz!Box Guest WiFi
# https://docs.pi-hole.net/routers/fritzbox/
# The Fritz!Box always sets its own IP as DNS server for the guest network.
#
# Solution: Proxy dnscrypt-proxy through Tor
# - Currently, we have this enabled.
# - The latency of DNS queries is higher than without Tor - at about 130ms.
if config.services.tor.torsocks.enable
then {
# Route all TCP connections to a local Tor node.
# As Tor doesn't support UDP, `force_tcp` has to be set to `true`.
proxy = "socks5://127.0.0.1:9050";
# This can be useful if you need to route everything through Tor.
# Otherwise, leave this to `false`.
force_tcp = true;
} else {}
);
};
}