208 lines
5.5 KiB
Nix
208 lines
5.5 KiB
Nix
{ config, lib, pkgs, ... }:
|
|
|
|
with lib;
|
|
let
|
|
hostname = config.instance.hostname;
|
|
|
|
domain-name = config.fudo.hosts.${hostname}.domain;
|
|
site-name = config.fudo.hosts.${hostname}.site;
|
|
zone-name = config.fudo.domains.${domain-name}.zone;
|
|
|
|
site = config.fudo.sites.${site-name};
|
|
|
|
cfg = config.fudo.services.local-network;
|
|
|
|
resolverOpts = {
|
|
options = {
|
|
ip = mkOption {
|
|
type = str;
|
|
description = "IP address of the upstream recursive resolver.";
|
|
default = "1.1.1.1";
|
|
};
|
|
|
|
port = mkOption {
|
|
type = port;
|
|
description = "Port of DNS server on the recursive resolver.";
|
|
default = 53;
|
|
};
|
|
};
|
|
};
|
|
|
|
in {
|
|
options.fudo.services.local-network = with types; {
|
|
enable = mkEnableOption "Enable local network server.";
|
|
|
|
internal-interfaces = mkOption {
|
|
type = listOf str;
|
|
description = ''
|
|
Interfaces on which to:
|
|
|
|
* Accept NAT traffic
|
|
* Serve DNS
|
|
* Serve DHCP
|
|
'';
|
|
};
|
|
|
|
external-interface = mkOption {
|
|
type = str;
|
|
description = "Interface facing the larger internet.";
|
|
example = "extif0";
|
|
};
|
|
|
|
resolvers = mkOption {
|
|
type = listOf (submodule resolverOpts);
|
|
description = "List of upstream DNS servers.";
|
|
default = [
|
|
{ ip = "1.1.1.1"; }
|
|
{ ip = "1.0.0.1"; }
|
|
{ ip = "9.9.9.9"; }
|
|
{ ip = "149.112.112.112"; }
|
|
];
|
|
};
|
|
|
|
dns-filter-proxy = {
|
|
enable = mkEnableOption "Enable DNS filter.";
|
|
|
|
http-listen-port = mkOption {
|
|
type = port;
|
|
description = "Port on localhost on which to listen for HTTP requests.";
|
|
default = 4080;
|
|
};
|
|
|
|
http-host-alias = mkOption {
|
|
type = str;
|
|
description = "Host alias for the DNS filter server.";
|
|
default = "dns-filter";
|
|
};
|
|
|
|
dns-listen-port = mkOption {
|
|
type = port;
|
|
description = "Port on localhost on which to listen for DNS requests.";
|
|
default = 4053;
|
|
};
|
|
|
|
upstream-dns = mkOption {
|
|
type = listOf str;
|
|
description = "List of upstream DNS-over-HTTPS endpoints.";
|
|
default = [
|
|
"https://1.1.1.1/dns-query"
|
|
"https://1.0.0.1/dns-query"
|
|
# These 11 addrs send the network, so the response can prefer closer answers
|
|
"https://9.9.9.11/dns-query"
|
|
"https://149.112.112.11/dns-query"
|
|
"https://2620:fe::11/dns-query"
|
|
"https://2620:fe::fe:11/dns-query"
|
|
];
|
|
};
|
|
};
|
|
};
|
|
|
|
config = mkIf (site.local-gateway != null) (let
|
|
host-ipv4 = pkgs.lib.network.host-ipv4 config;
|
|
gateway-host = site.local-gateway;
|
|
nameserver-host = gateway-host;
|
|
gateway-ip = host-ipv4 gateway-host;
|
|
nameserver-ip = host-ipv4 gateway-host;
|
|
is-gateway = hostname == gateway-host;
|
|
agp = cfg.dns-filter-proxy;
|
|
fqdn = hostname: "${hostname}.${domain-name}.";
|
|
in {
|
|
networking = {
|
|
nat = mkIf is-gateway {
|
|
enable = true;
|
|
externalInterface = cfg.external-interface;
|
|
internalInterfaces = cfg.internal-interfaces;
|
|
};
|
|
|
|
nameservers = [ nameserver-ip ];
|
|
|
|
firewall = if is-gateway then {
|
|
enable = true;
|
|
trustedInterfaces = cfg.internal-interfaces;
|
|
} else {
|
|
enable = false;
|
|
};
|
|
};
|
|
|
|
fudo = {
|
|
adguard-dns-proxy = mkIf agp.enable {
|
|
enable = true;
|
|
http = {
|
|
listen-ip = "127.0.0.1";
|
|
listen-port = agp.http-listen-port;
|
|
};
|
|
dns = {
|
|
listen-ips = [ "127.0.0.1" ];
|
|
listen-port = agp.dns-listen-port;
|
|
reverse-dns = [ (host-ipv4 gateway-host) ];
|
|
};
|
|
local-domain-name = domain-name;
|
|
};
|
|
|
|
zones."${zone-name}" = {
|
|
aliases = {
|
|
"${agp.http-host-alias}" = mkIf (agp.enable) (fqdn gateway-host);
|
|
ns = (fqdn nameserver-host);
|
|
gw = (fqdn gateway-host);
|
|
};
|
|
|
|
hosts = {
|
|
gateway.ipv4-address = gateway-ip;
|
|
nameserver.ipv4-address = nameserver-ip;
|
|
};
|
|
|
|
nameservers = [ "nameserver" ];
|
|
|
|
srv-records = {
|
|
tcp.domain = [{
|
|
host = "nameserver.${domain-name}";
|
|
port = 53;
|
|
}];
|
|
udp.domain = [{
|
|
host = "nameserver.${domain-name}";
|
|
port = 53;
|
|
}];
|
|
};
|
|
};
|
|
|
|
local-network = {
|
|
enable = is-gateway;
|
|
domain = domain-name;
|
|
dns-servers = [ nameserver-ip ];
|
|
gateway = gateway-ip;
|
|
dhcp-interfaces = cfg.internal-interfaces;
|
|
dns-listen-ips =
|
|
optionals is-gateway [ nameserver-ip "127.0.0.1" "127.0.1.1" ];
|
|
dns-listen-ipv6s =
|
|
optionals (is-gateway && config.networking.enableIPv6) [ "::1" ];
|
|
recursive-resolver = if agp.enable then {
|
|
host = "127.0.0.1";
|
|
port = agp.dns-listen-port;
|
|
} else {
|
|
host = cfg.resolver.ip;
|
|
port = cfg.resolver.port;
|
|
};
|
|
network = site.network;
|
|
dhcp-dynamic-network = site.dynamic-network;
|
|
search-domains = [ domain-name "fudo.org" ];
|
|
enable-reverse-mappings = true;
|
|
zone-definition = config.fudo.zones.${zone-name};
|
|
};
|
|
};
|
|
|
|
services.nginx = mkIf agp.enable {
|
|
enable = true;
|
|
recommendedGzipSettings = true;
|
|
recommendedOptimisation = true;
|
|
recommendedProxySettings = true;
|
|
|
|
virtualHosts = {
|
|
"${agp.http-host-alias}.${domain-name}" = {
|
|
locations."/".proxyPass =
|
|
"http://127.0.0.1:${toString agp.http-listen-port}";
|
|
};
|
|
};
|
|
};
|
|
});
|
|
}
|