From 248fc8599cd74842be60417d1427b8687adb2459 Mon Sep 17 00:00:00 2001 From: nostoromo root Date: Sun, 7 Jun 2020 19:11:58 -0700 Subject: [PATCH] Commit from nostromo --- config/fudo/local-network.nix | 276 ++++++++++++++++++++++++------ config/local.nix | 2 + defaults.nix | 5 +- fudo/sites/seattle.nix | 313 ++++++++++++++++++++++------------ hosts/nostromo.nix | 136 +++++++++++++-- lib/ip.nix | 56 ++++++ packages/cloudflared.nix | 29 ++++ packages/local.nix | 5 + 8 files changed, 647 insertions(+), 175 deletions(-) create mode 100644 lib/ip.nix create mode 100644 packages/cloudflared.nix diff --git a/config/fudo/local-network.nix b/config/fudo/local-network.nix index 29967c2..4cc653a 100644 --- a/config/fudo/local-network.nix +++ b/config/fudo/local-network.nix @@ -1,96 +1,276 @@ -# UNFINISHED! -# -# The plan is to bootstrap a local network config: DNS, DHCP, etc. - { lib, config, pkgs, ... }: with lib; let - hostOpts = { config, ... }: { - options = { - ipv6Address = mkOption { - type = types.str; - description = '' - The V6 IP of a given host, if any. - ''; - }; + cfg = config.fudo.local-network; - ipv4Address = mkOption { + join-lines = concatStringsSep "\n"; + + ip = import ../../lib/ip.nix { lib = lib; }; + + hostOpts = { hostname, ... }: { + options = { + ip-address = mkOption { type = types.str; description = '' The V4 IP of a given host, if any. ''; }; - macAddress = mkOption { + mac-address = mkOption { type = types.str; description = '' 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 = { - ipv6Address = mkOption { - type = types.str; - description = '' - The V6 IP of this nameserver, if any. - ''; + weight = mkOption { + type = int; + description = "Weight relative to other records."; + default = 1; }; - ipv4Address = mkOption { - type = types.str; - description = '' - The V4 IP of this nameserver, if any. - ''; + priority = mkOption { + type = int; + description = "Priority to give this record."; + default = 0; }; - ipv4ReverseDomain = mkOption { - type = types.str; - description = '' - The domain of the IPv4 address range for which this nameserver is responsible. + port = mkOption { + type = port; + description = "Port to use when connecting."; + }; - Eg: 0.10.in-addr.arpa - ''; + host = mkOption { + type = str; + description = "Host to contact for this service."; + example = "my-host.my-domain.com."; }; }; }; in { - options = { + options.fudo.local-network = { - fudo.localNetwork.hosts = mkOption { - type = types.listOf (submodule hostOpts); + enable = mkEnableOption "Enable local network configuration (DHCP & DNS)."; + + hosts = mkOption { + type = with types; loaOf (submodule hostOpts); default = {}; - description = '' - A map of hostname => { host_attributes }. - ''; + description = "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; description = '' - The domain to use for the local network. + The network from which to dynamically allocate IPs via DHCP. + + Must be a subnet of . ''; }; - fudo.localNetwork.hostAliases = mkOption { - type = types.attrsOf types.str; + recursive-resolver = mkOption { + 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 = {}; - description = '' - A mapping of hostAlias => hostName to use on the local network. + example = { + 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 { - type = (submodule localNameServerOpts); - description = '' - The master nameserver of the local network. - ''; + services.bind = let + blockHostsToZone = block: hosts-data: { + master = true; + 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; }; }; } diff --git a/config/local.nix b/config/local.nix index 2da9c2c..ffc5cf4 100644 --- a/config/local.nix +++ b/config/local.nix @@ -10,12 +10,14 @@ with lib; ./fudo/grafana.nix ./fudo/kdc.nix ./fudo/ldap.nix + ./fudo/local-network.nix ./fudo/mail.nix ./fudo/mail-container.nix ./fudo/minecraft-server.nix ./fudo/node-exporter.nix ./fudo/postgres.nix ./fudo/prometheus.nix + ./fudo/secure-dns.nix ./fudo/webmail.nix ../fudo/profiles diff --git a/defaults.nix b/defaults.nix index 02b03a1..aa3a03f 100644 --- a/defaults.nix +++ b/defaults.nix @@ -85,11 +85,10 @@ krb5.libdefaults.default_realm = "FUDO.ORG"; krb5.kerberos = pkgs.heimdalFull; + console.keyMap = "dvp"; + i18n = { - # consoleFont = "Lat2-Terminus16"; - consoleKeyMap = "dvp"; defaultLocale = "en_US.UTF-8"; - # consoleUseXkbConfig = true; }; programs = { diff --git a/fudo/sites/seattle.nix b/fudo/sites/seattle.nix index ac42e1c..f3f2406 100644 --- a/fudo/sites/seattle.nix +++ b/fudo/sites/seattle.nix @@ -55,6 +55,12 @@ in { home = "/home/xiaoxuan"; hashedPassword = "$6$C8lYHrK7KvdKm/RE$cHZ2hg5gEOEjTV8Zoayik8sz5h.Vh0.ClCgOlQn8l/2Qx/qdxqZ7xCsAZ1GZ.IEyESfhJeJbjLpykXDwPpfVF0"; }; + kevin = { + isNormalUser = true; + createHome = true; + home = "/home/kevin"; + hashedPassword = ""; + }; }; fileSystems."/mnt/documents" = { @@ -86,118 +92,205 @@ in { fsType = "nfs4"; }; - # Should use this eventually... - # fudo.localNetwork = { - # masterNameServer = { - # ip = "10.0.0.1"; - # ipReverseDomain = "0.10.in-addr.arpa"; - # }; + fudo.local-network = { - # domain = "${local-domain}"; + domain = "${local-domain}"; - # hostAliases = { - # kadmin = "slab"; - # kdc = "slab"; - # photo = "doraemon"; - # music = "doraemon"; - # panopticon = "hyperion"; - # hole = "dnshole"; - # ipfs = "nostromo"; - # }; + aliases = { + kadmin = "slab"; + kdc = "slab"; + photo = "doraemon"; + music = "doraemon"; + panopticon = "hyperion"; + ipfs = "nostromo"; + hole = "nostromo"; + pihole = "nostromo"; + dns-hole = "nostromo"; + }; - # hosts = { - # slab = { - # ipv4Address = "10.0.0.1"; - # }; - # volsung = { - # ipv4Address = "10.0.0.106"; - # macAddress = "ac:bc:32:7b:75:a5"; - # }; - # nest = { - # ipv4Address = "10.0.0.176"; - # macAddress = "18:b4:30:16:7c:5a"; - # }; - # monolith = { - # ipv4Address = "10.0.0.100"; - # macAddress = "6c:62:6d:c8:b0:d8"; - # }; - # brother-wireless = { - # ipv4Address = "10.0.0.160"; - # macAddress = "c0:38:96:64:49:65"; - # }; - # doraemon = { - # ipv4Address = "10.0.0.52"; - # macAddress = "00:11:32:0a:06:c5"; - # }; - # lm = { - # ipv4Address = "10.0.0.21"; - # macAddress = "52:54:00:D8:34:92"; - # }; - # ubiquiti-wifi = { - # ipv4Address = "10.0.0.126"; - # macAddress = "04:18:d6:20:48:fb"; - # }; - # front-light = { - # ipv4Address = "10.0.0.221"; - # macAddress = "94:10:3e:48:94:ed"; - # }; - # ipad = { - # ipv4Address = "10.0.0.202"; - # macAddress = "9c:35:eb:48:6e:71"; - # }; - # chromecast-2 = { - # ipv4Address = "10.0.0.215"; - # macAddress = "a4:77:33:59:a2:ba"; - # }; - # taipan = { - # ipv4Address = "10.0.0.107"; - # macAddress = "52:54:00:34:c4:78"; - # }; - # dns-hole = { - # ipv4Address = "10.0.0.185"; - # macAddress = "b8:27:eb:b2:95:fd"; - # }; - # family-tv = { - # ipv4Address = "10.0.0.205"; - # macAddress = "84:a4:66:3a:b1:f8"; - # }; - # spark = { - # ipv4Address = "10.0.0.108"; - # macAddress = "78:24:af:04:f7:dd"; - # }; - # babycam = { - # ipv4Address = "10.0.0.206"; - # macAddress = "08:ea:40:59:5f:9e"; - # }; - # hyperion = { - # ipv4Address = "10.0.0.109"; - # macAddress = "52:54:00:33:46:de"; - # }; - # cargo = { - # ipv4Address = "10.0.0.50"; - # macAddress = "00:11:32:75:d8:b7"; - # }; - # cam-entrance = { - # ipv4Address = "10.0.0.31"; - # macAddress = "9c:8e:cd:0e:99:7b"; - # }; - # cam-driveway = { - # ipv4Address = "10.0.0.32"; - # macAddress = "9c:8e:cd:0d:3b:09"; - # }; - # cam-deck = { - # ipv4Address = "10.0.0.33"; - # macAddress = "9c:8e:cd:0e:98:c8"; - # }; - # nostromo = { - # ipv4Address = "10.0.0.2"; - # macAddress = "14:fe:b5:ca:a2:c9"; - # }; - # zbox = { - # ipv4Address = "10.0.0.110"; - # macAddress = "18:60:24:91:CC:27"; - # }; - # }; - # }; + network = "10.0.0.0/16"; + + dhcp-dynamic-network = "10.0.1.0/24"; + + enable-reverse-mappings = true; + + srv-records = { + tcp = { + domain = [{ + port = 53; + host = "nostromo.sea.fudo.org"; + }]; + kerberos = [{ + port = 88; + host = "france.fudo.org"; + }]; + kerberos-adm = [{ + port = 88; + host = "france.fudo.org"; + }]; + ssh = [{ + port = 22; + host = "nostromo.sea.fudo.org"; + }]; + ldap = [{ + port = 389; + host = "france.fudo.org"; + }]; + }; + + udp = { + domain = [{ + port = 53; + host = "nostromo.sea.fudo.org"; + }]; + kerberos = [{ + port = 88; + host = "france.fudo.org"; + }]; + kerboros-master = [{ + port = 88; + host = "france.fudo.org"; + }]; + kpasswd = [{ + port = 464; + host = "france.fudo.org"; + }]; + }; + }; + + hosts = { + nostromo = { + ip-address = "10.0.0.1"; + mac-address = "46:54:76:06:f1:10"; + }; + lm = { + ip-address = "10.0.0.2"; + mac-address = "00:23:7d:e6:d9:ea"; + }; + switch-master = { + ip-address = "10.0.0.5"; + mac-address = "00:14:1C:B6:BB:40"; + }; + # lm = { + # ip-address = "10.0.0.21"; + # mac-address = "52:54:00:D8:34:92"; + # }; + cam-entrance = { + ip-address = "10.0.0.31"; + mac-address = "9c:8e:cd:0e:99:7b"; + }; + cam-driveway = { + ip-address = "10.0.0.32"; + mac-address = "9c:8e:cd:0d:3b:09"; + }; + cam-deck = { + ip-address = "10.0.0.33"; + mac-address = "9c:8e:cd:0e:98:c8"; + }; + cargo = { + ip-address = "10.0.0.50"; + mac-address = "00:11:32:75:d8:b7"; + }; + whitedwarf = { + ip-address = "10.0.0.51"; + mac-address = "00:11:32:12:14:1d"; + }; + doraemon = { + ip-address = "10.0.0.52"; + mac-address = "00:11:32:0a:06:c5"; + }; + 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"; + }; + }; + }; }; } diff --git a/hosts/nostromo.nix b/hosts/nostromo.nix index 5b6d60e..d2cd4ec 100644 --- a/hosts/nostromo.nix +++ b/hosts/nostromo.nix @@ -2,6 +2,8 @@ let hostname = "nostromo.sea.fudo.org"; + host-internal-ip = "10.0.0.1"; + local-gateway = "10.0.0.1"; inherit (lib.strings) concatStringsSep; in { @@ -10,7 +12,7 @@ in { boot.loader.grub.enable = true; boot.loader.grub.version = 2; - boot.loader.grub.device = "/dev/sdb"; + boot.loader.grub.device = "/dev/sda"; hardware.bluetooth.enable = false; @@ -24,28 +26,60 @@ in { 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 = { 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. - dhcpcd.enable = false; + #dhcpcd.enable = true; # Create a bridge for VMs to use - macvlans.intlan0 = { - interface = "eno1"; - mode = "bridge"; + macvlans = { + intif0 = { + interface = "eno1"; + mode = "bridge"; + }; + + # extif0 = { + # interface = "eno2"; + # mode = "bridge"; + # }; }; 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"; ipv4.addresses = [ { - address = "10.0.0.2"; + address = host-internal-ip; 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" ]; }; + + # secure-dns = { + # enable = true; + # port = 9053; + # }; }; environment.systemPackages = with pkgs; [ - ceph libguestfs-with-appliance libvirt virtmanager ]; - virtualisation.libvirtd = { - enable = true; - qemuPackage = pkgs.qemu_kvm; - onShutdown = "shutdown"; + virtualisation = { + docker = { + enable = true; + 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 = { + dhcpd6.enable = false; + # glusterfs = { # enable = true; # enableGlustereventsd = 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 = { enable = true; diff --git a/lib/ip.nix b/lib/ip.nix new file mode 100644 index 0000000..7f55bf0 --- /dev/null +++ b/lib/ip.nix @@ -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); +} diff --git a/packages/cloudflared.nix b/packages/cloudflared.nix new file mode 100644 index 0000000..5daf85c --- /dev/null +++ b/packages/cloudflared.nix @@ -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" + ''; +} diff --git a/packages/local.nix b/packages/local.nix index 5318f41..ff5111a 100644 --- a/packages/local.nix +++ b/packages/local.nix @@ -2,6 +2,11 @@ { nixpkgs.config.packageOverrides = pkgs: rec { + cloudflared = import ./cloudflared.nix { + stdenv = pkgs.stdenv; + fetchurl = builtins.fetchurl; + }; + letsencrypt-ca = import ./letsencrypt-ca.nix { stdenv = pkgs.stdenv; fetchurl = builtins.fetchurl;