We'll try to set up blocky on The Wobserver instead of pi-hole on fontkeming:
NEXT describe how my DNS all works w/ magicdns etc
non-qualified host names are resolved via MagicDNS by the Tailscale local daemon on each host first
when you're on TS you have adblocked DNS
when you're on home wifi you have adblocked DNS as my router tells clients to use the Wobserver's LAN IP.
when you're on TS traffic to The Wobserver will go direct instead of to the edge node
Upstreams
We'll mix our DNS traffic between a bunch of different providers and protocols; Blocky by default will pick two at random for each query, and return the first result. I would like to add more public-interest providers, it was nice to learn that Wikimedia operates public DNS infrastructure:
| 9.9.9.9 | quad9 |
| 1.1.1.1 | clownflare |
| 8.8.8.8 | |
| 84.200.69.80 | dns.watch |
| 208.67.222.222 | opendns |
| https://wikimedia-dns.org/dns-query | wikimedia |
| https://mozilla.cloudflare-dns.com/dns-query | clownflare w/ mozilla privacy policy |
local lines = {}
for _, row in ipairs(tbl) do
table.insert(lines, string.format('"%s" # %s', row[1], row[2]))
end
return table.concat(lines, "\n")Custom DNS entries
With this only being served to internal traffic on MagicDNS, and my LAN, we can direct some traffic that would go to the edge SSL terminator over tailscale just to be =proxy_pass='d back over the clearnet as HTTPS to me to instead go over tailscale to the Wobserver directly.
I need to move this behavior behind a client group so that LAN devices which aren't on Tailscale but which get DNS from blocky querying the LAN IP instead of MagicDNS will continue to resolve the Wobserver's domains to the public IPs. but that might not be possible like it is to use different blocklists per-client...
| printer | 192.168.69.50 |
| whatthefuck.computer | 100.123.74.28 |
| rix.si | 100.123.74.28 |
| fontkeming.fail | 100.123.74.28 |
| dns.fontkeming.fail | 209.251.245.117 |
| library.lol | 193.218.118.42 |
| download.library.lol | 176.119.25.72 |
| local.fosterparentcollege.com | 127.0.0.1 |
local lines = {}
for _, row in ipairs(tbl) do
table.insert(lines, string.format('"%s" = "%s";', row[1], row[2]))
end
return table.concat(lines, "\n")NEXT table for denylists
Configuration
This is all pretty straightforward, I think, consult upstream docs. Prometheus is enabled for Wobservability; query logging is enabled, you should disable this or modify the columns if you're serving for other people.
Two denylists are included here, StevenBlack's primary hosts lists, and one that only has astroturf and other misinformation domains in it. Now if I want to check that my ad-blocking is working I can try to browse to some of the funnier domain names in that fakenews list and watch them not load.
{ pkgs, config, ... }:
{
services.blocky.enable = true;
services.blocky.settings = {
# have to specify these or it'll conflict with lennartd-resolved
# ports.dns = ["192.168.69.69:53" "127.0.0.1:53" "100.123.74.28:53" ];
# when an upgrade breaks, it's because this key was renamed in 0.24!
blocking.blackLists = {
ads = [
"https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts"
];
fakenews = [
"https://raw.githubusercontent.com/StevenBlack/hosts/master/alternates/fakenews-only/hosts"
];
};
blocking.clientGroupsBlock = {
# could partition this up later on... local rules for restricted devices...
default = [ "ads" "fakenews" ];
};
upstreams.groups.default = [
<<upstreams()>>
];
customDNS.mapping = {
<<custom-dns()>>
};
conditional.mapping = {
"lan" = "192.168.69.1";
};
prometheus.enable = true;
# picked at "random"
ports.http = 4678;
queryLog = {
type = "csv";
target = "/var/lib/blocky/log";
};
bootstrapDns = [
{ upstream = "https://wikimedia-dns.org/dns-query";
ips = [ "185.71.138.138" ]; }
];
hostsFile.sources = [ "/etc/hosts" ];
};
networking.extraHosts = ''
100.116.176.133 virtuous-cassette
100.89.170.115 fontkeming
100.68.36.86 homeass
100.124.188.69 morning-run
100.77.133.94 octopi
100.82.104.74 windows
'';
networking.firewall.allowedUDPPorts = [ 53 ];
systemd.tmpfiles.rules = [
"d /srv/blocky 1777 blocky blocky -"
];
services.grafana.settings.panels.disable_sanitize_html = true;
services.prometheus.scrapeConfigs = [
{
job_name= "blocky";
static_configs = [
{ targets = ["localhost:4678"]; }
];
}
];
}NEXT install the dashboard
Don't forget to add the Wobservability dashboard following the docs, which needs the disable_sanitize_html option we've enabled here. Without this there is an HTTP API to enable/disable you have to curl, there is no built-in graphical metrics interface.
would be nice to declare the dashboard exist on the system...
NEXT install local helpers to enable/disable blocky
cli or at least an emacs command