Changes to nixops for clunk (but still broken)

This commit is contained in:
Niten 2021-02-26 09:30:38 -06:00
parent 4143610c0f
commit 3d4fb6c336
15 changed files with 130 additions and 120 deletions

View File

@ -42,7 +42,7 @@
hardware.bluetooth.enable = false; hardware.bluetooth.enable = false;
network = { networking = {
macvlans = { macvlans = {
intif0 = { intif0 = {
interface = "enp2s0"; interface = "enp2s0";

View File

@ -4,8 +4,14 @@ let
primary-ip = "10.0.0.1"; primary-ip = "10.0.0.1";
dns-proxy-ip = "10.0.0.2"; dns-proxy-ip = "10.0.0.2";
site-name = config.fudo.hosts.${config.instance.hostname}.site;
site = config.fudo.site.${site-name};
in { in {
fudo.local-network = { fudo.local-network = let
site-name = config.fudo.hosts.${config.instance.hostname}.site;
site = config.fudo.sites.${site-name};
in {
# FIXME: think about this -- actual network config? # FIXME: think about this -- actual network config?
enable = true; enable = true;
# NOTE: requests go: # NOTE: requests go:
@ -19,6 +25,8 @@ in {
recursive-resolver = "${primary-ip} port 5353"; recursive-resolver = "${primary-ip} port 5353";
server-ip = primary-ip; server-ip = primary-ip;
domain = "rus.selby.ca"; domain = "rus.selby.ca";
network = site.network;
dhcp-dynamic-network = site.dynamic-network;
}; };
networking = { networking = {
@ -77,7 +85,7 @@ in {
# environment.systemPackages = with pkgs; [ dnsproxy ]; # environment.systemPackages = with pkgs; [ dnsproxy ];
virtualization = { virtualisation = {
docker = { docker = {
enable = true; enable = true;
autoPrune.enable = true; autoPrune.enable = true;

View File

@ -1,30 +0,0 @@
{ config, lib, pkgs, ... }:
let
hostname = config.instance.hostname;
host-config = config.fudo.hosts.${hostname};
external-interface = host-config.gateway-config.external-interface;
internal-interfaces = host-config.gateway-config.internal-interfaces;
in {
imports = [ ./server.nix ];
config = {
networking = {
nat = {
enable = true;
externalInterface = external-interface;
internalInterfaces = internal-interfaces;
};
firewall = {
enable = true;
trustedInterfaces = internal-interfaces;
interfaces."${external-interface}" = {
allowedTCPPorts = host-config.gateway-config.external-tcp-ports;
allowedUDPPorts = host-config.gateway-config.external-udp-ports;
};
};
};
};
}

View File

@ -5,6 +5,8 @@
seattle = { seattle = {
gateway-v4 = "10.0.0.1"; gateway-v4 = "10.0.0.1";
nameservers = [ "10.0.0.1" ]; nameservers = [ "10.0.0.1" ];
network = "10.0.0.0/16";
dynamic-network = "10.0.1.0/24";
timezone = "America/Los_Angeles"; timezone = "America/Los_Angeles";
gateway-host = "nostromo"; gateway-host = "nostromo";
# FIXME: good idea? # FIXME: good idea?
@ -39,6 +41,7 @@
portage = { portage = {
gateway-v4 = "208.81.3.113"; gateway-v4 = "208.81.3.113";
# gateway-v6 = "265:e200:d200:1::1"; # gateway-v6 = "265:e200:d200:1::1";
network = "208.81.3.112/28";
nameservers = [ "1.1.1.1" "208.81.7.14" "2606:4700:4700::1111" ]; nameservers = [ "1.1.1.1" "208.81.7.14" "2606:4700:4700::1111" ];
timezone = "America/Winnipeg"; timezone = "America/Winnipeg";
}; };
@ -46,12 +49,15 @@
russell = { russell = {
gateway-v4 = "10.0.0.1"; gateway-v4 = "10.0.0.1";
nameservers = [ "10.0.0.1" ]; nameservers = [ "10.0.0.1" ];
network = "10.0.0.0/16";
dynamic-network = "10.0.1.0/24";
timezone = "America/Winnipeg"; timezone = "America/Winnipeg";
gateway-host = "clunk"; gateway-host = "clunk";
}; };
joes-datacenter-0 = { joes-datacenter-0 = {
gateway-v4 = "172.86.179.17"; gateway-v4 = "172.86.179.17";
network = "FIXME";
nameservers = [ "1.1.1.1" "2606:4700:4700::1111" ]; nameservers = [ "1.1.1.1" "2606:4700:4700::1111" ];
timezone = "America/Winnipeg"; timezone = "America/Winnipeg";
}; };

View File

@ -4,9 +4,7 @@ let
local = import ../host-config.nix; local = import ../host-config.nix;
initialize = import ./initialize.nix; initialize = import ./initialize.nix;
# (import "${builtins.fetchTarball https://github.com/rycee/home-manager/archive/master.tar.gz}/nixos") in {
in {
imports = [ imports = [
(initialize { (initialize {
hostname = local.hostname; hostname = local.hostname;
@ -15,7 +13,7 @@ in {
domain = local.domain; domain = local.domain;
home-manager-package = builtins.fetchGit { home-manager-package = builtins.fetchGit {
url = "https://github.com/nix-community/home-manager.git"; url = "https://github.com/nix-community/home-manager.git";
ref = "release-20.09"; ref = "release-20.09";
}; };
}) })
]; ];

View File

@ -6,19 +6,17 @@
./config ./config
./packages ./packages
(import "${home-manager-package}/nixos")
(./. + "/config/hardware/${hostname}.nix") (./. + "/config/hardware/${hostname}.nix")
(./. + "/config/hosts/${hostname}.nix") (./. + "/config/hosts/${hostname}.nix")
(./. + "/config/profiles/${profile}.nix") (./. + "/config/profiles/${profile}.nix")
(./. + "/config/domains/${domain}.nix") (./. + "/config/domains/${domain}.nix")
(./. + "/config/sites/${site}.nix") (./. + "/config/sites/${site}.nix")
(import "${home-manager-package}/nixos")
]; ];
config = { config = {
instance = { instance = { hostname = hostname; };
hostname = hostname;
};
fudo.hosts."${hostname}" = { fudo.hosts."${hostname}" = {
domain = domain; domain = domain;
@ -27,4 +25,4 @@
profile = profile; profile = profile;
}; };
}; };
} }

View File

@ -1,9 +1,13 @@
{ lib, config, pkgs, ... }: { lib, config, pkgs, ... }:
with lib; { with lib; {
lib = lib // { fudo = import ./lib/fudolib.nix { }; };
lib = lib // { fudo = import ./lib/lib.nix { inherit lib; }; };
imports = [ imports = [
../config
../packages
./instance.nix ./instance.nix
./fudo/acme-for-hostname.nix ./fudo/acme-for-hostname.nix

View File

@ -32,7 +32,7 @@ let
profile = mkOption { profile = mkOption {
# FIXME: get this list from profiles directly # FIXME: get this list from profiles directly
type = with types; type = with types;
listof (enum "desktop" "laptop" "server" "gateway-server"); listof (enum "desktop" "laptop" "server");
description = description =
"The profile to be applied to the host, determining what software is included."; "The profile to be applied to the host, determining what software is included.";
}; };

View File

@ -5,8 +5,8 @@ with lib;
let let
cfg = config.fudo.local-network; cfg = config.fudo.local-network;
ip = import ../../lib/ip.nix {}; dns = import ../lib/dns.nix { inherit lib; };
dns = import ../../lib/dns.nix {}; ip = import ../lib/ip.nix { inherit lib; };
join-lines = concatStringsSep "\n"; join-lines = concatStringsSep "\n";
@ -30,7 +30,7 @@ let
ssh-fingerprints = mkOption { ssh-fingerprints = mkOption {
type = with types; listOf str; type = with types; listOf str;
description = "A list of DNS SSHFP records for this host."; description = "A list of DNS SSHFP records for this host.";
default = []; default = [ ];
}; };
}; };
}; };
@ -45,7 +45,7 @@ in {
hosts = mkOption { hosts = mkOption {
type = with types; attrsOf (submodule hostOpts); type = with types; attrsOf (submodule hostOpts);
default = {}; default = { };
description = "A map of hostname => { host_attributes }."; description = "A map of hostname => { host_attributes }.";
}; };
@ -56,7 +56,8 @@ in {
dns-servers = mkOption { dns-servers = mkOption {
type = with types; listOf str; type = with types; listOf str;
description = "A list of domain name server to use for the local network."; description =
"A list of domain name server to use for the local network.";
}; };
dhcp-interfaces = mkOption { dhcp-interfaces = mkOption {
@ -76,8 +77,9 @@ in {
aliases = mkOption { aliases = mkOption {
type = with types; attrsOf str; type = with types; attrsOf str;
default = {}; default = { };
description = "A mapping of host-alias => hostname to use on the local network."; description =
"A mapping of host-alias => hostname to use on the local network.";
}; };
network = mkOption { network = mkOption {
@ -113,14 +115,14 @@ in {
extra-dns-records = mkOption { extra-dns-records = mkOption {
type = with types; listOf str; type = with types; listOf str;
description = "Records to be inserted verbatim into the DNS zone."; description = "Records to be inserted verbatim into the DNS zone.";
example = ["some-host IN CNAME other-host"]; example = [ "some-host IN CNAME other-host" ];
default = []; default = [ ];
}; };
srv-records = mkOption { srv-records = mkOption {
type = dns.srvRecords; type = dns.srvRecords;
description = "Map of traffic type to srv records."; description = "Map of traffic type to srv records.";
default = {}; default = { };
example = { example = {
tcp = { tcp = {
kerberos = { kerberos = {
@ -134,8 +136,8 @@ in {
search-domains = mkOption { search-domains = mkOption {
type = with types; listOf str; type = with types; listOf str;
description = "A list of domains to search for DNS names."; description = "A list of domains to search for DNS names.";
example = ["my-domain.com" "other-domain.com"]; example = [ "my-domain.com" "other-domain.com" ];
default = []; default = [ ];
}; };
# TODO: srv records # TODO: srv records
@ -154,15 +156,22 @@ in {
interfaces = cfg.dhcp-interfaces; interfaces = cfg.dhcp-interfaces;
extraConfig = '' extraConfig = ''
subnet ${ip.getNetworkBase cfg.network} netmask ${ip.maskFromV32Network cfg.network} { subnet ${ip.getNetworkBase cfg.network} netmask ${
ip.maskFromV32Network cfg.network
} {
authoritative; authoritative;
option subnet-mask ${ip.maskFromV32Network cfg.network}; option subnet-mask ${ip.maskFromV32Network cfg.network};
option broadcast-address ${ip.networkMaxIp cfg.network}; option broadcast-address ${ip.networkMaxIp cfg.network};
option routers ${cfg.gateway}; option routers ${cfg.gateway};
option domain-name-servers ${concatStringsSep " " cfg.dns-servers}; option domain-name-servers ${concatStringsSep " " cfg.dns-servers};
option domain-name "${cfg.domain}"; option domain-name "${cfg.domain}";
option domain-search ${join-lines (map (dom: "\"${dom}\"") ([cfg.domain] ++ cfg.search-domains))}; option domain-search ${
range ${ip.networkMinIp cfg.dhcp-dynamic-network} ${ip.networkMaxButOneIp cfg.dhcp-dynamic-network}; join-lines
(map (dom: ''"${dom}"'') ([ cfg.domain ] ++ cfg.search-domains))
};
range ${ip.networkMinIp cfg.dhcp-dynamic-network} ${
ip.networkMaxButOneIp cfg.dhcp-dynamic-network
};
} }
''; '';
}; };
@ -194,16 +203,23 @@ in {
''; '';
}; };
ipToBlock = ip: concatStringsSep "." (reverseList (take 3 (splitString "." ip))); ipToBlock = ip:
compactHosts = mapAttrsToList (host: data: data // { host = host; }) cfg.hosts; concatStringsSep "." (reverseList (take 3 (splitString "." ip)));
hostsByBlock = groupBy (host-data: ipToBlock host-data.ip-address) compactHosts; compactHosts =
mapAttrsToList (host: data: data // { host = host; }) cfg.hosts;
hostsByBlock =
groupBy (host-data: ipToBlock host-data.ip-address) compactHosts;
hostPtrRecord = host-data: hostPtrRecord = host-data:
"${last (splitString "." host-data.ip-address)} IN PTR ${host-data.host}.${cfg.domain}."; "${
last (splitString "." host-data.ip-address)
} IN PTR ${host-data.host}.${cfg.domain}.";
blockZones = mapAttrsToList blockHostsToZone hostsByBlock; blockZones = mapAttrsToList blockHostsToZone hostsByBlock;
hostARecord = host: data: "${host} IN A ${data.ip-address}"; hostARecord = host: data: "${host} IN A ${data.ip-address}";
hostSshFpRecords = host: data: join-lines (map (sshfp: "${host} IN SSHFP ${sshfp}") data.ssh-fingerprints); hostSshFpRecords = host: data:
join-lines
(map (sshfp: "${host} IN SSHFP ${sshfp}") data.ssh-fingerprints);
cnameRecord = alias: host: "${alias} IN CNAME ${host}"; cnameRecord = alias: host: "${alias} IN CNAME ${host}";
in { in {
@ -218,35 +234,33 @@ in {
"recursion yes;" "recursion yes;"
"allow-recursion { any; };" "allow-recursion { any; };"
]; ];
zones = [ zones = [{
{ master = true;
master = true; name = cfg.domain;
name = cfg.domain; file = pkgs.writeText "${cfg.domain}-zone" ''
file = pkgs.writeText "${cfg.domain}-zone" '' @ IN SOA ns1.${cfg.domain}. hostmaster.${cfg.domain}. (
@ IN SOA ns1.${cfg.domain}. hostmaster.${cfg.domain}. ( ${toString builtins.currentTime}
${toString builtins.currentTime} 5m
5m 2m
2m 6w
6w 5m)
5m)
$TTL 1h $TTL 1h
@ IN NS ns1.${cfg.domain}. @ IN NS ns1.${cfg.domain}.
$ORIGIN ${cfg.domain}. $ORIGIN ${cfg.domain}.
$TTL 30m $TTL 30m
ns1 IN A ${cfg.server-ip} ns1 IN A ${cfg.server-ip}
${join-lines (mapAttrsToList hostARecord cfg.hosts)} ${join-lines (mapAttrsToList hostARecord cfg.hosts)}
${join-lines (mapAttrsToList hostSshFpRecords cfg.hosts)} ${join-lines (mapAttrsToList hostSshFpRecords cfg.hosts)}
${join-lines (mapAttrsToList cnameRecord cfg.aliases)} ${join-lines (mapAttrsToList cnameRecord cfg.aliases)}
${join-lines cfg.extra-dns-records} ${join-lines cfg.extra-dns-records}
${dns.srvRecordsToBindZone cfg.srv-records} ${dns.srvRecordsToBindZone cfg.srv-records}
''; '';
} }] ++ blockZones;
] ++ blockZones;
}; };
}; };
} }

View File

@ -1,14 +1,14 @@
{ lib, pkgs, config, ... }: { lib, pkgs, config, ... }:
with lib; with lib;
let let cfg = config.fudo.secure-dns-proxy;
cfg = config.fudo.secure-dns-proxy;
in { in {
options.fudo.secure-dns-proxy = { options.fudo.secure-dns-proxy = {
enable = mkEnableOption "Enable a DNS server using an encrypted upstream source."; enable =
mkEnableOption "Enable a DNS server using an encrypted upstream source.";
port = mkOption { listen-port = mkOption {
type = types.port; type = types.port;
description = "Port on which to listen for DNS queries."; description = "Port on which to listen for DNS queries.";
default = 53; default = 53;
@ -21,26 +21,25 @@ in {
See: https://github.com/AdguardTeam/dnsproxy See: https://github.com/AdguardTeam/dnsproxy
''; '';
default = ["https://cloudflare-dns.com/dns-query"]; default = [ "https://cloudflare-dns.com/dns-query" ];
}; };
bootstrap-dns = mkOption { bootstrap-dns = mkOption {
type = types.str; type = types.str;
description = "A simple DNS server from which HTTPS DNS can be bootstrapped, if necessary."; description =
"A simple DNS server from which HTTPS DNS can be bootstrapped, if necessary.";
default = "1.1.1.1"; default = "1.1.1.1";
}; };
listen-ips = mkOption { listen-ips = mkOption {
type = with types; listOf str; type = with types; listOf str;
description = "A list of local IP addresses on which to listen."; description = "A list of local IP addresses on which to listen.";
default = ["0.0.0.0"]; default = [ "0.0.0.0" ];
}; };
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [ dnsproxy ];
dnsproxy
];
systemd.services.secure-dns-proxy = { systemd.services.secure-dns-proxy = {
enable = true; enable = true;
@ -50,13 +49,13 @@ in {
serviceConfig = let serviceConfig = let
upstreams = map (upstream: "-u ${upstream}") cfg.upstream-dns; upstreams = map (upstream: "-u ${upstream}") cfg.upstream-dns;
upstream-line = concatStringsSep " " upstreams; upstream-line = concatStringsSep " " upstreams;
listen-line = concatStringsSep " " listen-line =
(map (listen: "-l ${listen}") cfg.listen-ips); concatStringsSep " " (map (listen: "-l ${listen}") cfg.listen-ips);
cmd = "${pkgs.dnsproxy}/bin/dnsproxy -p ${toString cfg.port} ${upstream-line} ${listen-line} -b ${cfg.bootstrap-dns}"; cmd = "${pkgs.dnsproxy}/bin/dnsproxy -p ${
toString cfg.listen-port
} ${upstream-line} ${listen-line} -b ${cfg.bootstrap-dns}";
in { in { ExecStart = cmd; };
ExecStart = cmd;
};
}; };
}; };
} }

View File

@ -10,6 +10,17 @@ let
default = site; default = site;
}; };
network = mkOption {
type = types.str;
description = "Network to be treated as local.";
};
dynamic-network = mkOption {
type = with types; nullOr str;
description = "Network to be allocated by DHCP.";
default = null;
};
gateway-v4 = mkOption { gateway-v4 = mkOption {
type = with types; nullOr str; type = with types; nullOr str;
description = "Gateway to use for public ipv4 internet access."; description = "Gateway to use for public ipv4 internet access.";
@ -30,20 +41,22 @@ let
local-groups = mkOption { local-groups = mkOption {
type = with types; listOf str; type = with types; listOf str;
description = "List of groups which should exist at this site."; description = "List of groups which should exist at this site.";
default = [ ]; default = [ ];
}; };
local-users = mkOption { local-users = mkOption {
type = with types; listOf str; type = with types; listOf str;
description = "List of users which should exist on all hosts at this site."; description =
default = [ ]; "List of users which should exist on all hosts at this site.";
default = [ ];
}; };
local-admins = mkOption { local-admins = mkOption {
type = with types; listOf str; type = with types; listOf str;
description = "List of admin users which should exist on all hosts at this site."; description =
default = [ ]; "List of admin users which should exist on all hosts at this site.";
default = [ ];
}; };
enable-monitoring = enable-monitoring =
@ -57,8 +70,8 @@ let
timezone = mkOption { timezone = mkOption {
type = types.str; type = types.str;
description = "Timezone of the site."; description = "Timezone of the site.";
example = "America/Winnipeg"; example = "America/Winnipeg";
}; };
}; };
}; };

View File

@ -1,6 +0,0 @@
{ lib, ... }:
{
ip = import ./fudolib/ip.nix { };
dns = import ./fudolib/dns.nix { };
}

6
lib/lib.nix Normal file
View File

@ -0,0 +1,6 @@
{ lib, ... }:
{
ip = import ./lib/ip.nix { };
dns = import ./lib/dns.nix { };
}