{ config, lib, ... }: with lib; let cfg = config.modules.services.blocky; in { options.modules.services.blocky = { enable = mkEnableOption ""; }; config = mkIf cfg.enable { services.blocky = { enable = true; settings = { ports = { # Safety: NixOS firewall should block public access to 53. # Only machines connected to the tailscale is able to reach the service. dns = 53; http = "127.0.0.1:4000"; }; upstream.default = [ "https://dns.quad9.net/dns-query" "https://one.one.one.one/dns-query" ]; upstreamTimeout = "10s"; # For initially solving DoH/DoT Requests when no system Resolver is available bootstrapDns = { upstream = "https://dns.quad9.net/dns-query"; ips = [ "9.9.9.9" "149.112.112.112" ]; }; customDNS.mapping = { "metrics.internal" = "100.93.1.1"; # kanata }; caching = { minTime = "0m"; maxTime = "12h"; cacheTimeNegative = "1m"; prefetching = true; }; prometheus.enable = true; queryLog.type = "console"; conditional = { fallbackUpstream = true; }; blocking = { blackLists = { ads = [ "https://raw.githubusercontent.com/blocklistproject/Lists/master/ads.txt" "https://raw.githubusercontent.com/blocklistproject/Lists/master/phishing.txt" "https://raw.githubusercontent.com/blocklistproject/Lists/master/tracking.txt" ]; }; clientGroupsBlock = { default = [ "ads" ]; }; }; }; }; services.prometheus = { enable = true; listenAddress = "127.0.0.1"; port = 9000; globalConfig.scrape_interval = "15s"; globalConfig.evaluation_interval = "15s"; scrapeConfigs = [{ job_name = "blocky"; static_configs = [{ targets = [ "127.0.0.1:4000" ]; }]; }]; }; services.grafana = { enable = true; settings = { analytics.reporting_enabled = false; server = { domain = "127.0.0.1:3000"; http_addr = "127.0.0.1"; enable_gzip = true; }; # Required for blocky panel panels.disable_sanitize_html = true; }; provision = { enable = true; datasources.settings = { datasources = [{ name = "Prometheus"; type = "prometheus"; access = "proxy"; orgId = 1; uid = "5Z0Y8D3GXAMDODSF"; url = "http://127.0.0.1:9000"; 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"; }]; }; }; }; services.nginx.virtualHosts."metrics.internal" = { locations."/" = { proxyPass = "http://localhost:3000"; proxyWebsockets = true; extraConfig = '' proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; ''; }; }; environment.etc."grafana-dashboards/blocky_rev3.json" = { source = ./grafana_blocky_rev3.json; group = "grafana"; user = "grafana"; }; }; }