Skip to content

Instantly share code, notes, and snippets.

@dhess
Last active November 22, 2017 10:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dhess/f6fd0eb648f5a0483832382bbbd11a80 to your computer and use it in GitHub Desktop.
Save dhess/f6fd0eb648f5a0483832382bbbd11a80 to your computer and use it in GitHub Desktop.
# An unbound instance that uses blocklists and forwards requests to
# Google DNS.
#
# Works by assigning a virtual IP to lo (10.8.8.8).
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.services.unbound-adblock;
# Note -- the parent directory must match the definition in Nixpkgs
# unbound.nix!
stateDir = "/var/lib/unbound";
blockListDir = "${stateDir}/blocklists";
shcFile = "${blockListDir}/blocklist-someonewhocares.conf";
ipt4tcp = concatMapStringsSep "\n" (x: "iptables -A nixos-fw -p tcp -s ${x} --dport 53 -j nixos-fw-accept") cfg.allowedAccessIpv4;
ipt4udp = concatMapStringsSep "\n" (x: "iptables -A nixos-fw -p udp -s ${x} --dport 53 -j nixos-fw-accept") cfg.allowedAccessIpv4;
ipt6tcp = concatMapStringsSep "\n" (x: "ip6tables -A nixos-fw -p tcp -s ${x} --dport 53 -j nixos-fw-accept") cfg.allowedAccessIpv6;
ipt6udp = concatMapStringsSep "\n" (x: "ip6tables -A nixos-fw -p udp -s ${x} --dport 53 -j nixos-fw-accept") cfg.allowedAccessIpv6;
in {
options.services.unbound-adblock = {
allowedAccessIpv4 = mkOption {
default = [ "127/8" ];
type = types.listOf types.str;
description = "IPv4 networks that can use the server as a resolver.";
};
allowedAccessIpv6 = mkOption {
default = [ "::1/128" ];
type = types.listOf types.str;
description = "IPv6 networks that can use the server as a resolver.";
};
};
config = {
# Note: I would prefer to assign an alias to lo, but I can't get
# that to work. c.f.,
# https://github.com/NixOS/nixpkgs/issues/10909
# https://github.com/NixOS/nixpkgs/issues/7227
boot.kernelModules = [ "dummy" ];
networking.interfaces.dummy0.ip4 = [
{ address = "10.8.8.8"; prefixLength = 32; }
];
services.unbound = {
enable = true;
allowedAccess = cfg.allowedAccessIpv4 ++ cfg.allowedAccessIpv6;
interfaces = [ "10.8.8.8" ];
forwardAddresses = [ "8.8.8.8" "8.8.4.4" "2001:4860:4860::8888" "2001:4860:4860::8844" ];
# Don't want DNSSEC, have had issues with it in the past where
# failed DNSSEC causes very odd and hard-to-debug issues.
enableRootTrustAnchor = false;
extraConfig = ''
unwanted-reply-threshold: 10000000
verbosity: 3
prefetch: yes
prefetch-key: yes
hide-version: yes
hide-identity: yes
private-address: 10.0.0.0/8
private-address: 172.16.0.0/12
private-address: 192.168.0.0/16
private-address: 169.254.0.0/16
private-address: fd00::/8
private-address: fe80::/10
include: "${shcFile}"
'';
};
systemd.services.update-unbound-block-hosts = {
description = "Update Unbound's block list";
after = [ "network-online.target" ];
wants = [ "network-online.target" ];
before = [ "unbound.service" ];
requiredBy = [ "unbound.service" ];
preStart = ''
mkdir -m 0755 ${blockListDir} > /dev/null 2>&1 || true
chown -R unbound ${blockListDir}
'';
script = ''
until ${pkgs.unbound-block-hosts}/bin/unbound-block-hosts \
--file ${shcFile}.latest
do
sleep 10
done
[ -e ${shcFile} ] && \
cp ${shcFile} ${shcFile}.last
cp ${shcFile}.latest ${shcFile}
# Not yet working, need to run unbound-control-setup.
# ${pkgs.unbound}/bin/unbound-control -c ${stateDir}/unbound.conf reload
'';
restartIfChanged = true;
restartTriggers = [ pkgs.unbound-block-hosts ];
serviceConfig = {
PermissionsStartOnly = true;
User = "unbound";
Type = "oneshot";
RemainAfterExit = true;
};
};
systemd.timers.update-unbound-block-hosts = {
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = "daily";
Persistent = "yes";
};
};
networking.firewall.extraCommands = ''
${ipt4tcp}
${ipt4udp}
${ipt6tcp}
${ipt6udp}
'';
meta = {
maintainers = [ "Drew Hess <src@drewhess.com>" ];
};
};
}
{ stdenv, fetchFromGitHub, makeWrapper, pkgs, perl, perlPackages }:
let
in
stdenv.mkDerivation rec {
name = "unbound-block-hosts-${version}";
version = "20151112";
src = fetchFromGitHub {
owner = "jodrell";
repo = "unbound-block-hosts";
rev = "87966ee571cdeb78b89d16aac48d8fa2935ad6b2";
sha256 = "1mc2snciqwcqxpkf9qbcv7xd4287vkd5hdrpmhbi91i44y5q962n";
};
buildInputs = [
makeWrapper
perl
perlPackages.GetoptLong
perlPackages.HTTPDate
perlPackages.LWP
];
installPhase = let path = stdenv.lib.makeBinPath []; in ''
mkdir -p $out/bin
cp unbound-block-hosts $out/bin
wrapProgram $out/bin/unbound-block-hosts --set PERL5LIB $PERL5LIB --prefix PATH : "${path}"
'';
meta = {
description = "Convert Dan Pollock's ad blocking host file into Unbound local-data";
maintainers = [ "Drew Hess <src@drewhess.com>" ];
license = pkgs.lib.licenses.gpl3;
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment