239 lines
6.8 KiB
Nix
239 lines
6.8 KiB
Nix
{ config, lib, pkgs, ... }:
|
|
let
|
|
inherit (import ../hardware/networks.nix) interfaces;
|
|
wg = interfaces.wireguard0;
|
|
wgIfname = wg.ifname;
|
|
brIfname = interfaces.main'.bridgeName;
|
|
tailscaleIfname = config.services.tailscale.interfaceName;
|
|
in {
|
|
networking.extraHosts = ''
|
|
192.0.46.9 www.internic.net
|
|
'';
|
|
# For debugging purposes
|
|
environment.systemPackages = with pkgs; [ tcpdump dnsutils ];
|
|
services.resolved.extraConfig = ''
|
|
DNSStubListener=off
|
|
'';
|
|
systemd.network.networks."20-${brIfname}".networkConfig.DNS = lib.mkForce "127.0.0.1";
|
|
systemd.network.networks."90-${wgIfname}".networkConfig.DNS = lib.mkForce "127.0.0.1";
|
|
|
|
networking.firewall.interfaces = let
|
|
ports = {
|
|
allowedTCPPorts = [
|
|
config.services.blocky.settings.ports.dns
|
|
# config.services.grafana.settings.server.http_port
|
|
];
|
|
allowedUDPPorts = [
|
|
config.services.blocky.settings.ports.dns
|
|
];
|
|
};
|
|
in {
|
|
${wgIfname} = ports;
|
|
${tailscaleIfname} = ports;
|
|
};
|
|
|
|
# TODO: DoH (https://unbound.docs.nlnetlabs.nl/en/latest/topics/privacy/dns-over-https.html)
|
|
services.unbound = {
|
|
enable = true;
|
|
package = pkgs.unbound-full;
|
|
settings = {
|
|
server = {
|
|
root-hints = "${config.services.unbound.stateDir}/root.hints";
|
|
port = "553";
|
|
interface = [
|
|
"127.0.0.1"
|
|
"::1"
|
|
];
|
|
access-control = [
|
|
"0.0.0.0/0 refuse"
|
|
"127.0.0.0/8 allow"
|
|
"::0/0 refuse"
|
|
"::1 allow"
|
|
];
|
|
private-address = [
|
|
"127.0.0.0/8"
|
|
"::1"
|
|
];
|
|
hide-version = "yes";
|
|
aggressive-nsec = "yes";
|
|
cache-max-ttl = "86400";
|
|
cache-min-ttl = "600";
|
|
deny-any = "yes";
|
|
do-ip4 = "yes";
|
|
do-ip6 = "yes";
|
|
do-tcp = "yes";
|
|
do-udp = "yes";
|
|
harden-algo-downgrade = "yes";
|
|
harden-dnssec-stripped = "yes";
|
|
harden-glue = "yes";
|
|
harden-large-queries = "yes";
|
|
harden-referral-path = "yes";
|
|
harden-short-bufsize = "yes";
|
|
hide-identity = "yes";
|
|
minimal-responses = "yes";
|
|
msg-cache-size = "128m";
|
|
neg-cache-size = "4m";
|
|
prefer-ip6 = "no";
|
|
prefetch = "yes";
|
|
prefetch-key = "yes";
|
|
qname-minimisation = "yes";
|
|
rrset-cache-size = "256m";
|
|
rrset-roundrobin = "yes";
|
|
serve-expired = "yes";
|
|
so-rcvbuf = "4m";
|
|
so-reuseport = "yes";
|
|
so-sndbuf = "4m";
|
|
unwanted-reply-threshold = "100000";
|
|
use-caps-for-id = "yes";
|
|
};
|
|
cachedb = {
|
|
backend = "redis";
|
|
redis-server-host = "127.0.0.1";
|
|
redis-server-port = toString config.services.redis.servers.unbound.port;
|
|
redis-timeout = "300";
|
|
redis-expire-records = "no";
|
|
};
|
|
};
|
|
};
|
|
services.redis.vmOverCommit = true;
|
|
services.redis.servers.unbound = {
|
|
enable = true;
|
|
port = 7379;
|
|
databases = 1;
|
|
save = [ [ 3600 1 ] [ 1800 10 ] [ 600 100 ] ];
|
|
settings = {
|
|
maxmemory = "16mb";
|
|
protected-mode = true;
|
|
rdbchecksum = false;
|
|
stop-writes-on-bgsave-error = false;
|
|
tcp-keepalive = 300;
|
|
timeout = 0;
|
|
};
|
|
};
|
|
# TODO: maybe set internic ip address to hosts?
|
|
systemd.services.root-hints = {
|
|
script = ''
|
|
${pkgs.wget}/bin/wget -O ${config.services.unbound.stateDir}/root.hints https://www.internic.net/domain/named.root
|
|
'';
|
|
serviceConfig.Type = "oneshot";
|
|
startAt = "weekly";
|
|
};
|
|
# systemd.services.unbound = {
|
|
# after = [ "root-hints.service" ];
|
|
# };
|
|
# Blocky + prometheus + grafana
|
|
services.blocky = {
|
|
enable = true;
|
|
settings = {
|
|
upstream.default = [ "127.0.0.1:553" "[::1]:553" ];
|
|
upstreamTimeout = "10s";
|
|
bootstrapDns = [{
|
|
upstream = "https://dns.quad9.net/dns-query";
|
|
ips = [ "9.9.9.9" "149.112.112.112" ];
|
|
}];
|
|
blocking = {
|
|
blackLists = {
|
|
ads = [
|
|
"https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts"
|
|
"https://github.com/RPiList/specials/raw/master/Blocklisten/malware"
|
|
];
|
|
telemetry = [
|
|
"https://raw.githubusercontent.com/crazy-max/WindowsSpyBlocker/master/data/hosts/spy.txt"
|
|
"https://github.com/RPiList/specials/raw/master/Blocklisten/MS-Office-Telemetry"
|
|
"https://github.com/RPiList/specials/raw/master/Blocklisten/Win10Telemetry"
|
|
../../../misc/telemetry.hosts
|
|
];
|
|
};
|
|
clientGroupsBlock.default = [ "ads" "telemetry" ];
|
|
};
|
|
# disable caching (use unbound)
|
|
caching = {
|
|
minTime = -1;
|
|
maxTime = -1;
|
|
cacheTimeNegative = -1;
|
|
prefetching = false;
|
|
};
|
|
ports = {
|
|
dns = 53;
|
|
http = "127.0.0.1:4000";
|
|
};
|
|
prometheus.enable = true;
|
|
queryLog = {
|
|
type = "console";
|
|
};
|
|
};
|
|
};
|
|
# services.prometheus = {
|
|
# enable = true;
|
|
# listenAddress = "127.0.0.1";
|
|
# globalConfig.scrape_interval = "15s";
|
|
# globalConfig.evaluation_interval = "15s";
|
|
# scrapeConfigs = [{
|
|
# job_name = "blocky";
|
|
# static_configs = [{
|
|
# targets = [ config.services.blocky.settings.ports.http ];
|
|
# }];
|
|
# }];
|
|
# };
|
|
# services.grafana = {
|
|
# enable = true;
|
|
# settings = {
|
|
# analytics.reporting_enabled = false;
|
|
# server = {
|
|
# enable_gzip = true;
|
|
# domain = "localhost";
|
|
# http_addr = "0.0.0.0";
|
|
# http_port = 3000;
|
|
# };
|
|
# # Grafana can be accessed only through wireguard, so it's secure enough
|
|
# security = {
|
|
# admin_user = "admin";
|
|
# admin_password = "admin";
|
|
# };
|
|
# panels.disable_sanitize_html = true;
|
|
# };
|
|
# provision = {
|
|
# enable = true;
|
|
# datasources.settings = {
|
|
# datasources = [{
|
|
# name = "Prometheus";
|
|
# type = "prometheus";
|
|
# access = "proxy";
|
|
# orgId = 1;
|
|
# uid = "Y4SSG429DWCGDQ3R";
|
|
# url = "http://127.0.0.1:${toString config.services.prometheus.port}";
|
|
# isDefault = true;
|
|
# jsonData = {
|
|
# graphiteVersion = "1.1";
|
|
# tlsAuth = false;
|
|
# tlsAuthWithCACert = false;
|
|
# };
|
|
# version = 1;
|
|
# editable = true;
|
|
# }];
|
|
# };
|
|
# dashboards = {
|
|
# settings = {
|
|
# providers = [{
|
|
# name = "My Dashboards";
|
|
# options.path = "/etc/grafana-dashboards";
|
|
# }];
|
|
# };
|
|
# };
|
|
# };
|
|
# };
|
|
# environment.etc = {
|
|
# "grafana-dashboards/blocky_rev3.json" = {
|
|
# source = ../../../misc/grafana_blocky_rev3.json;
|
|
# group = "grafana";
|
|
# user = "grafana";
|
|
# };
|
|
# };
|
|
|
|
persist.state.directories = [
|
|
"/var/lib/grafana"
|
|
"/var/lib/prometheus2"
|
|
"/var/lib/redis-unbound"
|
|
"/var/lib/unbound"
|
|
];
|
|
} |