Commit from nostromo
This commit is contained in:
parent
61b3ca6dd6
commit
248fc8599c
@ -1,96 +1,276 @@
|
|||||||
# UNFINISHED!
|
|
||||||
#
|
|
||||||
# The plan is to bootstrap a local network config: DNS, DHCP, etc.
|
|
||||||
|
|
||||||
{ lib, config, pkgs, ... }:
|
{ lib, config, pkgs, ... }:
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
hostOpts = { config, ... }: {
|
cfg = config.fudo.local-network;
|
||||||
options = {
|
|
||||||
ipv6Address = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
description = ''
|
|
||||||
The V6 IP of a given host, if any.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
ipv4Address = mkOption {
|
join-lines = concatStringsSep "\n";
|
||||||
|
|
||||||
|
ip = import ../../lib/ip.nix { lib = lib; };
|
||||||
|
|
||||||
|
hostOpts = { hostname, ... }: {
|
||||||
|
options = {
|
||||||
|
ip-address = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
description = ''
|
description = ''
|
||||||
The V4 IP of a given host, if any.
|
The V4 IP of a given host, if any.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
macAddress = mkOption {
|
mac-address = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
description = ''
|
description = ''
|
||||||
The MAC address of a given host, if desired for IP reservation.
|
The MAC address of a given host, if desired for IP reservation.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ssh-fingerprints = mkOption {
|
||||||
|
type = with types; listOf str;
|
||||||
|
description = "A list of DNS SSHFP records for this host.";
|
||||||
|
default = [];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
localNameServerOpts = { config, ... }: {
|
traceout = out: builtins.trace out out;
|
||||||
|
|
||||||
|
srvRecordOpts = with types; {
|
||||||
options = {
|
options = {
|
||||||
ipv6Address = mkOption {
|
weight = mkOption {
|
||||||
type = types.str;
|
type = int;
|
||||||
description = ''
|
description = "Weight relative to other records.";
|
||||||
The V6 IP of this nameserver, if any.
|
default = 1;
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ipv4Address = mkOption {
|
priority = mkOption {
|
||||||
type = types.str;
|
type = int;
|
||||||
description = ''
|
description = "Priority to give this record.";
|
||||||
The V4 IP of this nameserver, if any.
|
default = 0;
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ipv4ReverseDomain = mkOption {
|
port = mkOption {
|
||||||
type = types.str;
|
type = port;
|
||||||
description = ''
|
description = "Port to use when connecting.";
|
||||||
The domain of the IPv4 address range for which this nameserver is responsible.
|
};
|
||||||
|
|
||||||
Eg: 0.10.in-addr.arpa
|
host = mkOption {
|
||||||
'';
|
type = str;
|
||||||
|
description = "Host to contact for this service.";
|
||||||
|
example = "my-host.my-domain.com.";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
in {
|
in {
|
||||||
|
|
||||||
options = {
|
options.fudo.local-network = {
|
||||||
|
|
||||||
fudo.localNetwork.hosts = mkOption {
|
enable = mkEnableOption "Enable local network configuration (DHCP & DNS).";
|
||||||
type = types.listOf (submodule hostOpts);
|
|
||||||
|
hosts = mkOption {
|
||||||
|
type = with types; loaOf (submodule hostOpts);
|
||||||
default = {};
|
default = {};
|
||||||
description = ''
|
description = "A map of hostname => { host_attributes }.";
|
||||||
A map of hostname => { host_attributes }.
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
fudo.localNetwork.domain = mkOption {
|
domain = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "The domain to use for the local network.";
|
||||||
|
};
|
||||||
|
|
||||||
|
dns-servers = mkOption {
|
||||||
|
type = with types; listOf str;
|
||||||
|
description = "A list of domain name server to use for the local network.";
|
||||||
|
};
|
||||||
|
|
||||||
|
dhcp-interfaces = mkOption {
|
||||||
|
type = with types; listOf str;
|
||||||
|
description = "A list of interfaces on which to serve DHCP.";
|
||||||
|
};
|
||||||
|
|
||||||
|
dns-serve-ips = mkOption {
|
||||||
|
type = with types; listOf str;
|
||||||
|
description = "A list of IPs on which to server DNS queries.";
|
||||||
|
};
|
||||||
|
|
||||||
|
gateway = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "The gateway to use for the local network.";
|
||||||
|
};
|
||||||
|
|
||||||
|
aliases = mkOption {
|
||||||
|
type = with types; loaOf str;
|
||||||
|
default = {};
|
||||||
|
description = "A mapping of host-alias => hostname to use on the local network.";
|
||||||
|
};
|
||||||
|
|
||||||
|
network = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "Network to treat as local.";
|
||||||
|
};
|
||||||
|
|
||||||
|
enable-reverse-mappings = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
description = "Genereate PTR reverse lookup records.";
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
dhcp-dynamic-network = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
description = ''
|
description = ''
|
||||||
The domain to use for the local network.
|
The network from which to dynamically allocate IPs via DHCP.
|
||||||
|
|
||||||
|
Must be a subnet of <network>.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
fudo.localNetwork.hostAliases = mkOption {
|
recursive-resolver = mkOption {
|
||||||
type = types.attrsOf types.str;
|
type = types.str;
|
||||||
|
description = "DNS nameserver to use for recursive resolution.";
|
||||||
|
};
|
||||||
|
|
||||||
|
server-ip = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "IP of the DNS server.";
|
||||||
|
};
|
||||||
|
|
||||||
|
extra-dns-records = mkOption {
|
||||||
|
type = with types; listOf str;
|
||||||
|
description = "Records to be inserted verbatim into the DNS zone.";
|
||||||
|
example = ["some-host IN CNAME other-host"];
|
||||||
|
default = [];
|
||||||
|
};
|
||||||
|
|
||||||
|
srv-records = mkOption {
|
||||||
|
type = with types; attrsOf (attrsOf (listOf (submodule srvRecordOpts)));
|
||||||
|
description = "Map of traffic type to srv records.";
|
||||||
default = {};
|
default = {};
|
||||||
description = ''
|
example = {
|
||||||
A mapping of hostAlias => hostName to use on the local network.
|
tcp = {
|
||||||
|
kerberos = {
|
||||||
|
port = 88;
|
||||||
|
host = "auth-host.my-domain.com";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
search-domains = mkOption {
|
||||||
|
type = with types; listOf str;
|
||||||
|
description = "A list of domains to search for DNS names.";
|
||||||
|
example = ["my-domain.com" "other-domain.com"];
|
||||||
|
default = [];
|
||||||
|
};
|
||||||
|
|
||||||
|
# TODO: srv records
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
services.dhcpd4 = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
machines = mapAttrsToList (hostname: hostOpts: {
|
||||||
|
ethernetAddress = hostOpts.mac-address;
|
||||||
|
hostName = hostname;
|
||||||
|
ipAddress = hostOpts.ip-address;
|
||||||
|
}) cfg.hosts;
|
||||||
|
|
||||||
|
interfaces = cfg.dhcp-interfaces;
|
||||||
|
|
||||||
|
extraConfig = ''
|
||||||
|
subnet ${ip.getNetworkBase cfg.network} netmask ${ip.maskFromV32Network cfg.network} {
|
||||||
|
authoritative;
|
||||||
|
option subnet-mask ${ip.maskFromV32Network cfg.network};
|
||||||
|
option broadcast-address ${ip.networkMaxIp cfg.network};
|
||||||
|
option routers ${cfg.gateway};
|
||||||
|
option domain-name-servers ${concatStringsSep " " cfg.dns-servers};
|
||||||
|
option domain-name "${cfg.domain}";
|
||||||
|
option domain-search ${join-lines (map (dom: "\"${dom}\"") ([cfg.domain] ++ cfg.search-domains))};
|
||||||
|
range ${ip.networkMinIp cfg.dhcp-dynamic-network} ${ip.networkMaxButOneIp cfg.dhcp-dynamic-network};
|
||||||
|
}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
fudo.localNetwork.localNameServer = mkOption {
|
services.bind = let
|
||||||
type = (submodule localNameServerOpts);
|
blockHostsToZone = block: hosts-data: {
|
||||||
description = ''
|
master = true;
|
||||||
The master nameserver of the local network.
|
name = "${block}.in-addr.arpa";
|
||||||
'';
|
file = let
|
||||||
|
# We should add these...but need a domain to assign them to.
|
||||||
|
# ip-last-el = ip: toInt (last (splitString "." ip));
|
||||||
|
# used-els = map (host-data: ip-last-el host-data.ip-address) hosts-data;
|
||||||
|
# unused-els = subtractLists used-els (map toString (range 1 255));
|
||||||
|
|
||||||
|
in pkgs.writeText "db.${block}-zone" ''
|
||||||
|
$ORIGIN ${block}.in-addr.arpa.
|
||||||
|
$TTL 1h
|
||||||
|
|
||||||
|
@ IN SOA ns1.${cfg.domain}. hostmaster.${cfg.domain}. (
|
||||||
|
${toString builtins.currentTime}
|
||||||
|
1800
|
||||||
|
900
|
||||||
|
604800
|
||||||
|
1800)
|
||||||
|
|
||||||
|
@ IN NS ns1.${cfg.domain}.
|
||||||
|
|
||||||
|
${join-lines (map hostPtrRecord hosts-data)}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
ipToBlock = ip: concatStringsSep "." (reverseList (take 3 (splitString "." ip)));
|
||||||
|
compactHosts = mapAttrsToList (host: data: data // { host = host; }) cfg.hosts;
|
||||||
|
hostsByBlock = groupBy (host-data: ipToBlock host-data.ip-address) compactHosts;
|
||||||
|
hostPtrRecord = host-data:
|
||||||
|
"${last (splitString "." host-data.ip-address)} IN PTR ${host-data.host}.${cfg.domain}.";
|
||||||
|
|
||||||
|
blockZones = mapAttrsToList blockHostsToZone hostsByBlock;
|
||||||
|
|
||||||
|
hostARecord = host: data: "${host} IN A ${data.ip-address}";
|
||||||
|
hostSshFpRecords = host: data: join-lines (map (sshfp: "${host} IN SSHFP ${sshfp}") data.ssh-fingerprints);
|
||||||
|
cnameRecord = alias: host: "${alias} IN CNAME ${host}";
|
||||||
|
|
||||||
|
makeSrvRecords = protocol: type: records:
|
||||||
|
join-lines (map (record: "_${type}._${protocol} IN SRV ${toString record.priority} ${toString record.weight} ${toString record.port} ${record.host}.")
|
||||||
|
records);
|
||||||
|
|
||||||
|
makeSrvProtocolRecords = protocol: types: join-lines (mapAttrsToList (makeSrvRecords protocol) types);
|
||||||
|
|
||||||
|
in {
|
||||||
|
enable = true;
|
||||||
|
cacheNetworks = [ cfg.network "localhost" "localnets" ];
|
||||||
|
forwarders = [ cfg.recursive-resolver ];
|
||||||
|
listenOn = cfg.dns-serve-ips;
|
||||||
|
zones = [
|
||||||
|
{
|
||||||
|
master = true;
|
||||||
|
name = cfg.domain;
|
||||||
|
file = pkgs.writeText "${cfg.domain}-zone" ''
|
||||||
|
@ IN SOA ns1.${cfg.domain}. hostmaster.${cfg.domain}. (
|
||||||
|
${toString builtins.currentTime}
|
||||||
|
5m
|
||||||
|
2m
|
||||||
|
6w
|
||||||
|
5m)
|
||||||
|
|
||||||
|
$TTL 1h
|
||||||
|
|
||||||
|
@ IN NS ns1.${cfg.domain}.
|
||||||
|
|
||||||
|
$ORIGIN ${cfg.domain}.
|
||||||
|
|
||||||
|
$TTL 30m
|
||||||
|
|
||||||
|
ns1 IN A ${cfg.server-ip}
|
||||||
|
${join-lines (mapAttrsToList hostARecord cfg.hosts)}
|
||||||
|
${join-lines (mapAttrsToList hostSshFpRecords cfg.hosts)}
|
||||||
|
${join-lines (mapAttrsToList cnameRecord cfg.aliases)}
|
||||||
|
${join-lines cfg.extra-dns-records}
|
||||||
|
${join-lines (mapAttrsToList makeSrvProtocolRecords cfg.srv-records)}
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
] ++ blockZones;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -10,12 +10,14 @@ with lib;
|
|||||||
./fudo/grafana.nix
|
./fudo/grafana.nix
|
||||||
./fudo/kdc.nix
|
./fudo/kdc.nix
|
||||||
./fudo/ldap.nix
|
./fudo/ldap.nix
|
||||||
|
./fudo/local-network.nix
|
||||||
./fudo/mail.nix
|
./fudo/mail.nix
|
||||||
./fudo/mail-container.nix
|
./fudo/mail-container.nix
|
||||||
./fudo/minecraft-server.nix
|
./fudo/minecraft-server.nix
|
||||||
./fudo/node-exporter.nix
|
./fudo/node-exporter.nix
|
||||||
./fudo/postgres.nix
|
./fudo/postgres.nix
|
||||||
./fudo/prometheus.nix
|
./fudo/prometheus.nix
|
||||||
|
./fudo/secure-dns.nix
|
||||||
./fudo/webmail.nix
|
./fudo/webmail.nix
|
||||||
|
|
||||||
../fudo/profiles
|
../fudo/profiles
|
||||||
|
@ -85,11 +85,10 @@
|
|||||||
krb5.libdefaults.default_realm = "FUDO.ORG";
|
krb5.libdefaults.default_realm = "FUDO.ORG";
|
||||||
krb5.kerberos = pkgs.heimdalFull;
|
krb5.kerberos = pkgs.heimdalFull;
|
||||||
|
|
||||||
|
console.keyMap = "dvp";
|
||||||
|
|
||||||
i18n = {
|
i18n = {
|
||||||
# consoleFont = "Lat2-Terminus16";
|
|
||||||
consoleKeyMap = "dvp";
|
|
||||||
defaultLocale = "en_US.UTF-8";
|
defaultLocale = "en_US.UTF-8";
|
||||||
# consoleUseXkbConfig = true;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
programs = {
|
programs = {
|
||||||
|
@ -55,6 +55,12 @@ in {
|
|||||||
home = "/home/xiaoxuan";
|
home = "/home/xiaoxuan";
|
||||||
hashedPassword = "$6$C8lYHrK7KvdKm/RE$cHZ2hg5gEOEjTV8Zoayik8sz5h.Vh0.ClCgOlQn8l/2Qx/qdxqZ7xCsAZ1GZ.IEyESfhJeJbjLpykXDwPpfVF0";
|
hashedPassword = "$6$C8lYHrK7KvdKm/RE$cHZ2hg5gEOEjTV8Zoayik8sz5h.Vh0.ClCgOlQn8l/2Qx/qdxqZ7xCsAZ1GZ.IEyESfhJeJbjLpykXDwPpfVF0";
|
||||||
};
|
};
|
||||||
|
kevin = {
|
||||||
|
isNormalUser = true;
|
||||||
|
createHome = true;
|
||||||
|
home = "/home/kevin";
|
||||||
|
hashedPassword = "";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/mnt/documents" = {
|
fileSystems."/mnt/documents" = {
|
||||||
@ -86,118 +92,205 @@ in {
|
|||||||
fsType = "nfs4";
|
fsType = "nfs4";
|
||||||
};
|
};
|
||||||
|
|
||||||
# Should use this eventually...
|
fudo.local-network = {
|
||||||
# fudo.localNetwork = {
|
|
||||||
# masterNameServer = {
|
|
||||||
# ip = "10.0.0.1";
|
|
||||||
# ipReverseDomain = "0.10.in-addr.arpa";
|
|
||||||
# };
|
|
||||||
|
|
||||||
# domain = "${local-domain}";
|
domain = "${local-domain}";
|
||||||
|
|
||||||
# hostAliases = {
|
aliases = {
|
||||||
# kadmin = "slab";
|
kadmin = "slab";
|
||||||
# kdc = "slab";
|
kdc = "slab";
|
||||||
# photo = "doraemon";
|
photo = "doraemon";
|
||||||
# music = "doraemon";
|
music = "doraemon";
|
||||||
# panopticon = "hyperion";
|
panopticon = "hyperion";
|
||||||
# hole = "dnshole";
|
ipfs = "nostromo";
|
||||||
# ipfs = "nostromo";
|
hole = "nostromo";
|
||||||
# };
|
pihole = "nostromo";
|
||||||
|
dns-hole = "nostromo";
|
||||||
|
};
|
||||||
|
|
||||||
# hosts = {
|
network = "10.0.0.0/16";
|
||||||
# slab = {
|
|
||||||
# ipv4Address = "10.0.0.1";
|
dhcp-dynamic-network = "10.0.1.0/24";
|
||||||
# };
|
|
||||||
# volsung = {
|
enable-reverse-mappings = true;
|
||||||
# ipv4Address = "10.0.0.106";
|
|
||||||
# macAddress = "ac:bc:32:7b:75:a5";
|
srv-records = {
|
||||||
# };
|
tcp = {
|
||||||
# nest = {
|
domain = [{
|
||||||
# ipv4Address = "10.0.0.176";
|
port = 53;
|
||||||
# macAddress = "18:b4:30:16:7c:5a";
|
host = "nostromo.sea.fudo.org";
|
||||||
# };
|
}];
|
||||||
# monolith = {
|
kerberos = [{
|
||||||
# ipv4Address = "10.0.0.100";
|
port = 88;
|
||||||
# macAddress = "6c:62:6d:c8:b0:d8";
|
host = "france.fudo.org";
|
||||||
# };
|
}];
|
||||||
# brother-wireless = {
|
kerberos-adm = [{
|
||||||
# ipv4Address = "10.0.0.160";
|
port = 88;
|
||||||
# macAddress = "c0:38:96:64:49:65";
|
host = "france.fudo.org";
|
||||||
# };
|
}];
|
||||||
# doraemon = {
|
ssh = [{
|
||||||
# ipv4Address = "10.0.0.52";
|
port = 22;
|
||||||
# macAddress = "00:11:32:0a:06:c5";
|
host = "nostromo.sea.fudo.org";
|
||||||
# };
|
}];
|
||||||
# lm = {
|
ldap = [{
|
||||||
# ipv4Address = "10.0.0.21";
|
port = 389;
|
||||||
# macAddress = "52:54:00:D8:34:92";
|
host = "france.fudo.org";
|
||||||
# };
|
}];
|
||||||
# ubiquiti-wifi = {
|
};
|
||||||
# ipv4Address = "10.0.0.126";
|
|
||||||
# macAddress = "04:18:d6:20:48:fb";
|
udp = {
|
||||||
# };
|
domain = [{
|
||||||
# front-light = {
|
port = 53;
|
||||||
# ipv4Address = "10.0.0.221";
|
host = "nostromo.sea.fudo.org";
|
||||||
# macAddress = "94:10:3e:48:94:ed";
|
}];
|
||||||
# };
|
kerberos = [{
|
||||||
# ipad = {
|
port = 88;
|
||||||
# ipv4Address = "10.0.0.202";
|
host = "france.fudo.org";
|
||||||
# macAddress = "9c:35:eb:48:6e:71";
|
}];
|
||||||
# };
|
kerboros-master = [{
|
||||||
# chromecast-2 = {
|
port = 88;
|
||||||
# ipv4Address = "10.0.0.215";
|
host = "france.fudo.org";
|
||||||
# macAddress = "a4:77:33:59:a2:ba";
|
}];
|
||||||
# };
|
kpasswd = [{
|
||||||
# taipan = {
|
port = 464;
|
||||||
# ipv4Address = "10.0.0.107";
|
host = "france.fudo.org";
|
||||||
# macAddress = "52:54:00:34:c4:78";
|
}];
|
||||||
# };
|
};
|
||||||
# dns-hole = {
|
};
|
||||||
# ipv4Address = "10.0.0.185";
|
|
||||||
# macAddress = "b8:27:eb:b2:95:fd";
|
hosts = {
|
||||||
# };
|
nostromo = {
|
||||||
# family-tv = {
|
ip-address = "10.0.0.1";
|
||||||
# ipv4Address = "10.0.0.205";
|
mac-address = "46:54:76:06:f1:10";
|
||||||
# macAddress = "84:a4:66:3a:b1:f8";
|
};
|
||||||
# };
|
lm = {
|
||||||
# spark = {
|
ip-address = "10.0.0.2";
|
||||||
# ipv4Address = "10.0.0.108";
|
mac-address = "00:23:7d:e6:d9:ea";
|
||||||
# macAddress = "78:24:af:04:f7:dd";
|
};
|
||||||
# };
|
switch-master = {
|
||||||
# babycam = {
|
ip-address = "10.0.0.5";
|
||||||
# ipv4Address = "10.0.0.206";
|
mac-address = "00:14:1C:B6:BB:40";
|
||||||
# macAddress = "08:ea:40:59:5f:9e";
|
};
|
||||||
# };
|
# lm = {
|
||||||
# hyperion = {
|
# ip-address = "10.0.0.21";
|
||||||
# ipv4Address = "10.0.0.109";
|
# mac-address = "52:54:00:D8:34:92";
|
||||||
# macAddress = "52:54:00:33:46:de";
|
# };
|
||||||
# };
|
cam-entrance = {
|
||||||
# cargo = {
|
ip-address = "10.0.0.31";
|
||||||
# ipv4Address = "10.0.0.50";
|
mac-address = "9c:8e:cd:0e:99:7b";
|
||||||
# macAddress = "00:11:32:75:d8:b7";
|
};
|
||||||
# };
|
cam-driveway = {
|
||||||
# cam-entrance = {
|
ip-address = "10.0.0.32";
|
||||||
# ipv4Address = "10.0.0.31";
|
mac-address = "9c:8e:cd:0d:3b:09";
|
||||||
# macAddress = "9c:8e:cd:0e:99:7b";
|
};
|
||||||
# };
|
cam-deck = {
|
||||||
# cam-driveway = {
|
ip-address = "10.0.0.33";
|
||||||
# ipv4Address = "10.0.0.32";
|
mac-address = "9c:8e:cd:0e:98:c8";
|
||||||
# macAddress = "9c:8e:cd:0d:3b:09";
|
};
|
||||||
# };
|
cargo = {
|
||||||
# cam-deck = {
|
ip-address = "10.0.0.50";
|
||||||
# ipv4Address = "10.0.0.33";
|
mac-address = "00:11:32:75:d8:b7";
|
||||||
# macAddress = "9c:8e:cd:0e:98:c8";
|
};
|
||||||
# };
|
whitedwarf = {
|
||||||
# nostromo = {
|
ip-address = "10.0.0.51";
|
||||||
# ipv4Address = "10.0.0.2";
|
mac-address = "00:11:32:12:14:1d";
|
||||||
# macAddress = "14:fe:b5:ca:a2:c9";
|
};
|
||||||
# };
|
doraemon = {
|
||||||
# zbox = {
|
ip-address = "10.0.0.52";
|
||||||
# ipv4Address = "10.0.0.110";
|
mac-address = "00:11:32:0a:06:c5";
|
||||||
# macAddress = "18:60:24:91:CC:27";
|
};
|
||||||
# };
|
android = {
|
||||||
# };
|
ip-address = "10.0.0.81";
|
||||||
# };
|
mac-address = "00:16:3e:43:39:fc";
|
||||||
|
};
|
||||||
|
retro-wired = {
|
||||||
|
ip-address = "10.0.0.82";
|
||||||
|
mac-address = "dc:a6:32:6b:57:43";
|
||||||
|
};
|
||||||
|
retro = {
|
||||||
|
ip-address = "10.0.0.83";
|
||||||
|
mac-address = "dc:a6:32:6b:57:45";
|
||||||
|
};
|
||||||
|
monolith = {
|
||||||
|
ip-address = "10.0.0.100";
|
||||||
|
mac-address = "6c:62:6d:c8:b0:d8";
|
||||||
|
};
|
||||||
|
taipan = {
|
||||||
|
ip-address = "10.0.0.107";
|
||||||
|
mac-address = "52:54:00:34:c4:78";
|
||||||
|
};
|
||||||
|
spark = {
|
||||||
|
ip-address = "10.0.0.108";
|
||||||
|
mac-address = "78:24:af:04:f7:dd";
|
||||||
|
};
|
||||||
|
hyperion = {
|
||||||
|
ip-address = "10.0.0.109";
|
||||||
|
mac-address = "52:54:00:33:46:de";
|
||||||
|
};
|
||||||
|
zbox = {
|
||||||
|
ip-address = "10.0.0.110";
|
||||||
|
mac-address = "02:dd:80:52:83:9b";
|
||||||
|
};
|
||||||
|
ubiquiti-wifi = {
|
||||||
|
ip-address = "10.0.0.126";
|
||||||
|
mac-address = "04:18:d6:20:48:fb";
|
||||||
|
};
|
||||||
|
brother-wireless = {
|
||||||
|
ip-address = "10.0.0.160";
|
||||||
|
mac-address = "c0:38:96:64:49:65";
|
||||||
|
};
|
||||||
|
nest = {
|
||||||
|
ip-address = "10.0.0.176";
|
||||||
|
mac-address = "18:b4:30:16:7c:5a";
|
||||||
|
};
|
||||||
|
xixi-phone = {
|
||||||
|
ip-address = "10.0.0.193";
|
||||||
|
mac-address = "48:43:7c:75:89:42";
|
||||||
|
};
|
||||||
|
ipad = {
|
||||||
|
ip-address = "10.0.0.202";
|
||||||
|
mac-address = "9c:35:eb:48:6e:71";
|
||||||
|
};
|
||||||
|
cam-front = {
|
||||||
|
ip-address = "10.0.0.203";
|
||||||
|
mac-address = "c4:d6:55:3e:b4:c3";
|
||||||
|
};
|
||||||
|
family-tv = {
|
||||||
|
ip-address = "10.0.0.205";
|
||||||
|
mac-address = "84:a4:66:3a:b1:f8";
|
||||||
|
};
|
||||||
|
babycam = {
|
||||||
|
ip-address = "10.0.0.206";
|
||||||
|
mac-address = "08:ea:40:59:5f:9e";
|
||||||
|
};
|
||||||
|
workphone = {
|
||||||
|
ip-address = "10.0.0.211";
|
||||||
|
mac-address = "a8:8e:24:5c:12:67";
|
||||||
|
};
|
||||||
|
chromecast-2 = {
|
||||||
|
ip-address = "10.0.0.215";
|
||||||
|
mac-address = "a4:77:33:59:a2:ba";
|
||||||
|
};
|
||||||
|
front-light = {
|
||||||
|
ip-address = "10.0.0.221";
|
||||||
|
mac-address = "94:10:3e:48:94:ed";
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
# Storage network
|
||||||
|
node-1 = {
|
||||||
|
ip-address = "10.0.10.101";
|
||||||
|
mac-address = "00:1e:06:36:81:cf";
|
||||||
|
};
|
||||||
|
node-2 = {
|
||||||
|
ip-address = "10.0.10.102";
|
||||||
|
mac-address = "00:1e:06:36:ec:3e";
|
||||||
|
};
|
||||||
|
node-3 = {
|
||||||
|
ip-address = "10.0.10.103";
|
||||||
|
mac-address = "00:1e:06:36:ec:4b";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
let
|
let
|
||||||
hostname = "nostromo.sea.fudo.org";
|
hostname = "nostromo.sea.fudo.org";
|
||||||
|
host-internal-ip = "10.0.0.1";
|
||||||
|
local-gateway = "10.0.0.1";
|
||||||
inherit (lib.strings) concatStringsSep;
|
inherit (lib.strings) concatStringsSep;
|
||||||
|
|
||||||
in {
|
in {
|
||||||
@ -10,7 +12,7 @@ in {
|
|||||||
|
|
||||||
boot.loader.grub.enable = true;
|
boot.loader.grub.enable = true;
|
||||||
boot.loader.grub.version = 2;
|
boot.loader.grub.version = 2;
|
||||||
boot.loader.grub.device = "/dev/sdb";
|
boot.loader.grub.device = "/dev/sda";
|
||||||
|
|
||||||
hardware.bluetooth.enable = false;
|
hardware.bluetooth.enable = false;
|
||||||
|
|
||||||
@ -24,28 +26,60 @@ in {
|
|||||||
site = "seattle";
|
site = "seattle";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
fudo.local-network = {
|
||||||
|
enable = true;
|
||||||
|
# See fudo/sites/seattle.nix for general settings
|
||||||
|
dns-servers = [ host-internal-ip ];
|
||||||
|
gateway = local-gateway;
|
||||||
|
dhcp-interfaces = [ "intif0" ];
|
||||||
|
dns-serve-ips = [ host-internal-ip "127.0.0.1" "127.0.1.1" ];
|
||||||
|
# Using a pihole running in docker, see below
|
||||||
|
recursive-resolver = "${host-internal-ip} port 5353";
|
||||||
|
# recursive-resolver = "1.1.1.1";
|
||||||
|
server-ip = host-internal-ip;
|
||||||
|
};
|
||||||
|
|
||||||
networking = {
|
networking = {
|
||||||
hostName = hostname;
|
hostName = hostname;
|
||||||
|
|
||||||
defaultGateway = "10.0.0.1";
|
# defaultGateway = local-gateway;
|
||||||
|
|
||||||
nameservers = [ "10.0.0.1" ];
|
nameservers = [ host-internal-ip ];
|
||||||
|
|
||||||
# Turn off for hypervisor: dhcp by default everywhere is a fuckin pain.
|
# Turn off for hypervisor: dhcp by default everywhere is a fuckin pain.
|
||||||
dhcpcd.enable = false;
|
#dhcpcd.enable = true;
|
||||||
|
|
||||||
# Create a bridge for VMs to use
|
# Create a bridge for VMs to use
|
||||||
macvlans.intlan0 = {
|
macvlans = {
|
||||||
interface = "eno1";
|
intif0 = {
|
||||||
mode = "bridge";
|
interface = "eno1";
|
||||||
|
mode = "bridge";
|
||||||
|
};
|
||||||
|
|
||||||
|
# extif0 = {
|
||||||
|
# interface = "eno2";
|
||||||
|
# mode = "bridge";
|
||||||
|
# };
|
||||||
};
|
};
|
||||||
|
|
||||||
interfaces = {
|
interfaces = {
|
||||||
intlan0 = {
|
eno1.useDHCP = false;
|
||||||
|
eno3.useDHCP = false;
|
||||||
|
eno4.useDHCP = false;
|
||||||
|
enp33s0f0.useDHCP = false;
|
||||||
|
enp33s0f1.useDHCP = false;
|
||||||
|
enp9s0f0.useDHCP = false;
|
||||||
|
enp9s0f1.useDHCP = false;
|
||||||
|
|
||||||
|
eno2.useDHCP = true;
|
||||||
|
|
||||||
|
|
||||||
|
intif0 = {
|
||||||
|
useDHCP = false;
|
||||||
macAddress = "46:54:76:06:f1:10";
|
macAddress = "46:54:76:06:f1:10";
|
||||||
ipv4.addresses = [
|
ipv4.addresses = [
|
||||||
{
|
{
|
||||||
address = "10.0.0.2";
|
address = host-internal-ip;
|
||||||
prefixLength = 22;
|
prefixLength = 22;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
@ -54,6 +88,16 @@ in {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# extif0 = {
|
||||||
|
# useDHCP = true;
|
||||||
|
# };
|
||||||
|
};
|
||||||
|
|
||||||
|
nat = {
|
||||||
|
enable = true;
|
||||||
|
externalInterface = "eno2";
|
||||||
|
internalInterfaces = ["intif0"];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -69,28 +113,92 @@ in {
|
|||||||
"127.0.0.1/8"
|
"127.0.0.1/8"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# secure-dns = {
|
||||||
|
# enable = true;
|
||||||
|
# port = 9053;
|
||||||
|
# };
|
||||||
};
|
};
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
ceph
|
|
||||||
libguestfs-with-appliance
|
libguestfs-with-appliance
|
||||||
libvirt
|
libvirt
|
||||||
virtmanager
|
virtmanager
|
||||||
];
|
];
|
||||||
|
|
||||||
virtualisation.libvirtd = {
|
virtualisation = {
|
||||||
enable = true;
|
docker = {
|
||||||
qemuPackage = pkgs.qemu_kvm;
|
enable = true;
|
||||||
onShutdown = "shutdown";
|
autoPrune.enable = true;
|
||||||
|
enableOnBoot = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
libvirtd = {
|
||||||
|
enable = true;
|
||||||
|
qemuPackage = pkgs.qemu_kvm;
|
||||||
|
onShutdown = "shutdown";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
docker-containers = {
|
||||||
|
pihole = {
|
||||||
|
image = "pihole/pihole:4.3.2-1";
|
||||||
|
ports = [
|
||||||
|
"5353:53/tcp"
|
||||||
|
"5353:53/udp"
|
||||||
|
"3080:80/tcp"
|
||||||
|
];
|
||||||
|
environment = {
|
||||||
|
ServerIP = host-internal-ip;
|
||||||
|
VIRTUAL_HOST = "dns-hole.sea.fudo.org";
|
||||||
|
DNS1 = "1.1.1.1";
|
||||||
|
DNS2 = "8.8.8.8";
|
||||||
|
};
|
||||||
|
volumes = [
|
||||||
|
"/srv/pihole/etc-pihole/:/etc/pihole/"
|
||||||
|
"/srv/pihole/etc-dnsmasq.d/:/etc/dnsmasq.d/"
|
||||||
|
];
|
||||||
|
# TODO: DNS-over-HTTPS via cloudflared
|
||||||
|
extraDockerOptions = [
|
||||||
|
"--dns=1.1.1.1"
|
||||||
|
];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services = {
|
services = {
|
||||||
|
dhcpd6.enable = false;
|
||||||
|
|
||||||
# glusterfs = {
|
# glusterfs = {
|
||||||
# enable = true;
|
# enable = true;
|
||||||
# enableGlustereventsd = true;
|
# enableGlustereventsd = true;
|
||||||
# useRpcbind = true;
|
# useRpcbind = true;
|
||||||
# };
|
# };
|
||||||
|
|
||||||
|
nginx = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
virtualHosts = {
|
||||||
|
"pihole.sea.fudo.org" = {
|
||||||
|
serverAliases = [
|
||||||
|
"dns-hole.sea.fudo.org"
|
||||||
|
"hole.sea.fudo.org"
|
||||||
|
];
|
||||||
|
|
||||||
|
locations."/" = {
|
||||||
|
proxyPass = "http://127.0.0.1:3080";
|
||||||
|
|
||||||
|
extraConfig = ''
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-By $server_addr:$server_port;
|
||||||
|
proxy_set_header X-Forwarded-For $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
ceph = {
|
ceph = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
||||||
|
56
lib/ip.nix
Normal file
56
lib/ip.nix
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
{ lib }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
joinString = lib.concatStringsSep;
|
||||||
|
|
||||||
|
pow = x: e: if (e == 0) then 1 else x * (pow x (e - 1));
|
||||||
|
|
||||||
|
in rec {
|
||||||
|
|
||||||
|
generateNBits = n: let
|
||||||
|
helper = n: c: if (c == n) then pow 2 c else (pow 2 c) + (helper n (c + 1));
|
||||||
|
in if (n <= 0) then throw "Can't generate 0 or fewer bits" else helper (n - 1) 0;
|
||||||
|
|
||||||
|
reverseIpv4 = ip: joinString "." (reverseList (splitString "." ip));
|
||||||
|
|
||||||
|
intToBinaryList = int: let
|
||||||
|
helper = int: cur: let
|
||||||
|
curExp = pow 2 cur;
|
||||||
|
in if (curExp > int) then
|
||||||
|
[]
|
||||||
|
else
|
||||||
|
[(if ((bitAnd curExp int) > 0) then 1 else 0)] ++ (helper int (cur + 1));
|
||||||
|
in reverseList (helper int 0);
|
||||||
|
|
||||||
|
leftShift = int: n: int * (pow 2 n);
|
||||||
|
|
||||||
|
rightShift = int: n: int / (pow 2 n);
|
||||||
|
|
||||||
|
ipv4ToInt = ip: let
|
||||||
|
els = map toInt (reverseList (splitString "." ip));
|
||||||
|
in foldr (a: b: a + b) 0 (imap0 (i: el: (leftShift el (i * 8))) els);
|
||||||
|
|
||||||
|
intToIpv4 = int: joinString "." (map (i: toString (bitAnd (rightShift int (i * 8)) 255)) [ 3 2 1 0 ]);
|
||||||
|
|
||||||
|
rightPadBits = int: bits: bitOr int (generateNBits bits);
|
||||||
|
|
||||||
|
maskFromV32Network = network: let
|
||||||
|
fullMask = ipv4ToInt "255.255.255.255";
|
||||||
|
insignificantBits = 32 - (getNetworkMask network);
|
||||||
|
in intToIpv4 (leftShift (rightShift fullMask insignificantBits) insignificantBits);
|
||||||
|
|
||||||
|
getNetworkMask = network: toInt (elemAt (splitString "/" network) 1);
|
||||||
|
|
||||||
|
getNetworkBase = network: let
|
||||||
|
ip = elemAt (splitString "/" network) 0;
|
||||||
|
insignificantBits = 32 - (getNetworkMask network);
|
||||||
|
in intToIpv4 (leftShift (rightShift (ipv4ToInt ip) insignificantBits) insignificantBits);
|
||||||
|
|
||||||
|
networkMinIp = network: intToIpv4 (1 + (ipv4ToInt (getNetworkBase network)));
|
||||||
|
|
||||||
|
networkMaxIp = network: intToIpv4 (rightPadBits (ipv4ToInt (getNetworkBase network)) (32 - (getNetworkMask network)));
|
||||||
|
|
||||||
|
# To avoid broadcast IP...
|
||||||
|
networkMaxButOneIp = network: intToIpv4 ((rightPadBits (ipv4ToInt (getNetworkBase network)) (32 - (getNetworkMask network))) - 1);
|
||||||
|
}
|
29
packages/cloudflared.nix
Normal file
29
packages/cloudflared.nix
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
{ stdenv, fetchgit }:
|
||||||
|
|
||||||
|
let
|
||||||
|
url = "https://github.com/cloudflare/cloudflared.git";
|
||||||
|
version = "2020.2.1";
|
||||||
|
hash = "";
|
||||||
|
|
||||||
|
in stdenv.mkDerivation {
|
||||||
|
name = "cloudflared";
|
||||||
|
|
||||||
|
src = fetchgit {
|
||||||
|
url = url;
|
||||||
|
rev = version;
|
||||||
|
sha256 = "abc";
|
||||||
|
};
|
||||||
|
|
||||||
|
configurePhase = ''
|
||||||
|
# Nothing to do
|
||||||
|
'';
|
||||||
|
|
||||||
|
buildPhase = ''
|
||||||
|
# Nothing to do
|
||||||
|
'';
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p "$out/bin"
|
||||||
|
cp ./cloudflared "$out/bin"
|
||||||
|
'';
|
||||||
|
}
|
@ -2,6 +2,11 @@
|
|||||||
|
|
||||||
{
|
{
|
||||||
nixpkgs.config.packageOverrides = pkgs: rec {
|
nixpkgs.config.packageOverrides = pkgs: rec {
|
||||||
|
cloudflared = import ./cloudflared.nix {
|
||||||
|
stdenv = pkgs.stdenv;
|
||||||
|
fetchurl = builtins.fetchurl;
|
||||||
|
};
|
||||||
|
|
||||||
letsencrypt-ca = import ./letsencrypt-ca.nix {
|
letsencrypt-ca = import ./letsencrypt-ca.nix {
|
||||||
stdenv = pkgs.stdenv;
|
stdenv = pkgs.stdenv;
|
||||||
fetchurl = builtins.fetchurl;
|
fetchurl = builtins.fetchurl;
|
||||||
|
Loading…
Reference in New Issue
Block a user