From 372cf5fc6a3cfe6f055b1775c0fd214c000e3325 Mon Sep 17 00:00:00 2001 From: nostoromo root Date: Tue, 23 Feb 2021 12:58:29 -0800 Subject: [PATCH] Still very broken...moving to start testing --- bash.nix => config/bash.nix | 6 +- config/default.nix | 49 +- config/domains.nix | 56 +++ config/fudo/common.nix | 58 --- config/hardware/clunk.nix | 70 +++ config/hardware/france.nix | 85 ++++ config/hardware/lambda.nix | 65 +++ config/hardware/nostromo.nix | 68 +++ config/hardware/plato.nix | 79 +++ config/hosts.nix | 90 ++++ config/hosts/atom.nix | 9 + config/hosts/clunk.nix | 135 ++++++ config/hosts/france.nix | 179 +++++++ config/hosts/lambda.nix | 32 ++ config/hosts/nostromo.nix | 169 +++++++ config/hosts/plato.nix | 34 ++ config/hosts/zbox.nix | 10 + config/local-network/rus.selby.ca.nix | 84 ++++ config/local-network/sea.fudo.org.nix | 217 +++++++++ config/profiles.nix | 7 + config/profiles/common-ui.nix | 108 +++++ config/profiles/common.nix | 100 ++++ config/profiles/desktop.nix | 7 + config/profiles/gateway-server.nix | 30 ++ config/profiles/laptop.nix | 24 + config/profiles/server.nix | 71 +++ config/sites.nix | 59 +++ config/users.nix | 455 ++++++++++++++++++ config/wireless-networks.nix | 11 + default.nix | 10 + defaults.nix | 4 +- fudo/profiles/laptop.nix | 16 +- fudo/sites/seattle.nix | 39 +- hardware.nix | 6 + home-manager/niten.nix | 106 ++++ home-manager/root.nix | 39 ++ hosts/clunk.nix | 37 +- hosts/nostromo.nix | 42 +- lib/default.nix | 36 ++ {config => lib}/fudo/acme-for-hostname.nix | 0 {config => lib}/fudo/authentication.nix | 0 {config => lib}/fudo/backplane/default.nix | 0 {config => lib}/fudo/backplane/dns.nix | 0 {config => lib}/fudo/chat.nix | 0 {config => lib}/fudo/client/dns.nix | 0 lib/fudo/common.nix | 65 +++ {config => lib}/fudo/dns.nix | 163 ++++--- lib/fudo/domains.nix | 52 ++ {config => lib}/fudo/garbage-collector.nix | 0 {config => lib}/fudo/git.nix | 0 {config => lib}/fudo/grafana.nix | 0 lib/fudo/hosts.nix | 107 ++++ lib/fudo/hosts/local-network.nix | 142 ++++++ {config => lib}/fudo/include/rainloop.nix | 0 {config => lib}/fudo/ipfs.nix | 0 {config => lib}/fudo/kdc.nix | 0 {config => lib}/fudo/ldap.nix | 142 +++--- {config => lib}/fudo/local-network.nix | 0 {config => lib}/fudo/mail-container.nix | 0 {config => lib}/fudo/mail.nix | 0 {config => lib}/fudo/mail/clamav.nix | 0 {config => lib}/fudo/mail/dkim.nix | 0 {config => lib}/fudo/mail/dovecot.nix | 0 .../mail/dovecot/imap_sieve/report-ham.sieve | 0 .../mail/dovecot/imap_sieve/report-spam.sieve | 0 .../mail/dovecot/pipe_bin/sa-learn-ham.sh | 0 .../mail/dovecot/pipe_bin/sa-learn-spam.sh | 0 {config => lib}/fudo/mail/postfix.nix | 0 {config => lib}/fudo/mail/rspamd.nix | 0 {config => lib}/fudo/minecraft-server.nix | 0 {config => lib}/fudo/netinfo-email.nix | 0 {config => lib}/fudo/node-exporter.nix | 0 {config => lib}/fudo/password.nix | 0 {config => lib}/fudo/postgres.nix | 144 +++--- {config => lib}/fudo/prometheus.nix | 0 {config => lib}/fudo/secure-dns-proxy.nix | 0 lib/fudo/sites.nix | 47 ++ {config => lib}/fudo/slynk.nix | 0 {config => lib}/fudo/system.nix | 0 lib/fudo/users.nix | 212 ++++++++ {config => lib}/fudo/vpn.nix | 0 {config => lib}/fudo/webmail.nix | 0 lib/fudo/wireless-networks.nix | 32 ++ lib/fudolib.nix | 6 + lib/{ => fudolib}/dns.nix | 31 +- lib/fudolib/ip.nix | 80 +++ {config => lib}/informis/cl-gemini.nix | 0 lib/instance.nix | 12 + lib/ip.nix | 63 --- lib/utils.nix | 14 - packages/local.nix | 9 +- 91 files changed, 3535 insertions(+), 488 deletions(-) rename bash.nix => config/bash.nix (77%) create mode 100644 config/domains.nix delete mode 100644 config/fudo/common.nix create mode 100644 config/hardware/clunk.nix create mode 100644 config/hardware/france.nix create mode 100644 config/hardware/lambda.nix create mode 100644 config/hardware/nostromo.nix create mode 100644 config/hardware/plato.nix create mode 100644 config/hosts.nix create mode 100644 config/hosts/atom.nix create mode 100644 config/hosts/clunk.nix create mode 100644 config/hosts/france.nix create mode 100644 config/hosts/lambda.nix create mode 100644 config/hosts/nostromo.nix create mode 100644 config/hosts/plato.nix create mode 100644 config/hosts/zbox.nix create mode 100644 config/local-network/rus.selby.ca.nix create mode 100644 config/local-network/sea.fudo.org.nix create mode 100644 config/profiles.nix create mode 100644 config/profiles/common-ui.nix create mode 100644 config/profiles/common.nix create mode 100644 config/profiles/desktop.nix create mode 100644 config/profiles/gateway-server.nix create mode 100644 config/profiles/laptop.nix create mode 100644 config/profiles/server.nix create mode 100644 config/sites.nix create mode 100644 config/users.nix create mode 100644 config/wireless-networks.nix create mode 100644 default.nix create mode 100644 hardware.nix create mode 100644 home-manager/niten.nix create mode 100644 home-manager/root.nix create mode 100644 lib/default.nix rename {config => lib}/fudo/acme-for-hostname.nix (100%) rename {config => lib}/fudo/authentication.nix (100%) rename {config => lib}/fudo/backplane/default.nix (100%) rename {config => lib}/fudo/backplane/dns.nix (100%) rename {config => lib}/fudo/chat.nix (100%) rename {config => lib}/fudo/client/dns.nix (100%) create mode 100644 lib/fudo/common.nix rename {config => lib}/fudo/dns.nix (53%) create mode 100644 lib/fudo/domains.nix rename {config => lib}/fudo/garbage-collector.nix (100%) rename {config => lib}/fudo/git.nix (100%) rename {config => lib}/fudo/grafana.nix (100%) create mode 100644 lib/fudo/hosts.nix create mode 100644 lib/fudo/hosts/local-network.nix rename {config => lib}/fudo/include/rainloop.nix (100%) rename {config => lib}/fudo/ipfs.nix (100%) rename {config => lib}/fudo/kdc.nix (100%) rename {config => lib}/fudo/ldap.nix (73%) rename {config => lib}/fudo/local-network.nix (100%) rename {config => lib}/fudo/mail-container.nix (100%) rename {config => lib}/fudo/mail.nix (100%) rename {config => lib}/fudo/mail/clamav.nix (100%) rename {config => lib}/fudo/mail/dkim.nix (100%) rename {config => lib}/fudo/mail/dovecot.nix (100%) rename {config => lib}/fudo/mail/dovecot/imap_sieve/report-ham.sieve (100%) rename {config => lib}/fudo/mail/dovecot/imap_sieve/report-spam.sieve (100%) rename {config => lib}/fudo/mail/dovecot/pipe_bin/sa-learn-ham.sh (100%) rename {config => lib}/fudo/mail/dovecot/pipe_bin/sa-learn-spam.sh (100%) rename {config => lib}/fudo/mail/postfix.nix (100%) rename {config => lib}/fudo/mail/rspamd.nix (100%) rename {config => lib}/fudo/minecraft-server.nix (100%) rename {config => lib}/fudo/netinfo-email.nix (100%) rename {config => lib}/fudo/node-exporter.nix (100%) rename {config => lib}/fudo/password.nix (100%) rename {config => lib}/fudo/postgres.nix (67%) rename {config => lib}/fudo/prometheus.nix (100%) rename {config => lib}/fudo/secure-dns-proxy.nix (100%) create mode 100644 lib/fudo/sites.nix rename {config => lib}/fudo/slynk.nix (100%) rename {config => lib}/fudo/system.nix (100%) create mode 100644 lib/fudo/users.nix rename {config => lib}/fudo/vpn.nix (100%) rename {config => lib}/fudo/webmail.nix (100%) create mode 100644 lib/fudo/wireless-networks.nix create mode 100644 lib/fudolib.nix rename lib/{ => fudolib}/dns.nix (56%) create mode 100644 lib/fudolib/ip.nix rename {config => lib}/informis/cl-gemini.nix (100%) create mode 100644 lib/instance.nix delete mode 100644 lib/ip.nix delete mode 100644 lib/utils.nix diff --git a/bash.nix b/config/bash.nix similarity index 77% rename from bash.nix rename to config/bash.nix index cd7b65d..bc434d9 100644 --- a/bash.nix +++ b/config/bash.nix @@ -2,12 +2,12 @@ let helpers = pkgs.writeText "bash.helpers" - (builtins.readFile ./static/bash/bash.helpers); + (builtins.readFile ../static/bash/bash.helpers); colors = - pkgs.writeText "bash.colors" (builtins.readFile ./static/bash/bash.colors); + pkgs.writeText "bash.colors" (builtins.readFile ../static/bash/bash.colors); - env = pkgs.writeText "bash.env" (builtins.readFile ./static/bash/bash.env); + env = pkgs.writeText "bash.env" (builtins.readFile ../static/bash/bash.env); in { config.programs.bash = { diff --git a/config/default.nix b/config/default.nix index cd6fee6..139b538 100644 --- a/config/default.nix +++ b/config/default.nix @@ -1,38 +1,15 @@ -{ lib, config, pkgs, ... }: +{ config, lib, pkgs, ... }: -with lib; { - imports = [ - ./fudo/acme-for-hostname.nix - ./fudo/authentication.nix - ./fudo/backplane - ./fudo/chat.nix - ./fudo/client/dns.nix - ./fudo/common.nix - ./fudo/dns.nix - ./fudo/garbage-collector.nix - ./fudo/git.nix - ./fudo/grafana.nix - ./fudo/ipfs.nix - ./fudo/kdc.nix - ./fudo/ldap.nix - ./fudo/local-network.nix - ./fudo/mail.nix - ./fudo/mail-container.nix - ./fudo/minecraft-server.nix - ./fudo/netinfo-email.nix - ./fudo/node-exporter.nix - ./fudo/password.nix - ./fudo/postgres.nix - ./fudo/prometheus.nix - ./fudo/secure-dns-proxy.nix - ./fudo/slynk.nix - ./fudo/system.nix - ./fudo/vpn.nix - ./fudo/webmail.nix - - ./informis/cl-gemini.nix - - ../fudo/profiles - ../fudo/sites - ]; +{ + config = { + imports = [ + ./bash.nix + ./domains.nix + ./groups.nix + ./hosts.nix + ./sites.nix + ./users.nix + ./wireless-networks.nix + ]; + }; } diff --git a/config/domains.nix b/config/domains.nix new file mode 100644 index 0000000..d700ec5 --- /dev/null +++ b/config/domains.nix @@ -0,0 +1,56 @@ +{ config, lib, pkgs, ... }: + +{ + config.fudo.domains = { + fudo.org = { + local-networks = [ "208.81.1.128/28" "208.81.3.112/28" ]; + + local-users = [ "niten" "reaper" ]; + admin-users = [ "niten" "reaper" ]; + admin-email = "admin@fudo.org"; + gssapi-realm = "FUDO.ORG"; + }; + + sea.fudo.org = { + local-networks = [ "10.0.0.0/24" ]; + + local-users = [ "niten" "reaper" "xiaoxuan" "ken" ]; + admin-users = [ "niten" ]; + admin-email = "niten@fudo.org"; + gssapi-realm = "FUDO.ORG"; + + local-dns = import ./networks/sea.fudo.org.nix { }; + }; + + rus.selby.ca = { + local-networks = [ "10.0.0.0/24" ]; + + local-users = [ + "niten" + "ken" + "helen" + "xiaoxuan" + "laura" + "vee" + "kris" + "jeramy" + "jess" + "andrew" + ]; + local-admins = [ "niten" ]; + admin-email = "niten@fudo.org"; + gssapi-realm = "FUDO.ORG"; + + local-dns = import ./networks/rus.selby.ca.nix { }; + }; + + informis.land = { + local-networks = [ ]; + + local-users = [ "niten" "viator" ]; + admin-users = [ "niten" ]; + admin-email = "viator@informis.land"; + gssapi-realm = "INFORMIS.LAND"; + }; + }; +} diff --git a/config/fudo/common.nix b/config/fudo/common.nix deleted file mode 100644 index 78f3fd8..0000000 --- a/config/fudo/common.nix +++ /dev/null @@ -1,58 +0,0 @@ -# General Fudo config, shared across packages -{ config, lib, pkgs, ... }: - -with lib; -{ - options.fudo.common = { - local-networks = mkOption { - type = with types; listOf str; - description = '' - A list of networks to consider 'local'. Used by various services to - limit access to the external world. - ''; - default = []; - }; - - domain = mkOption { - type = types.str; - description = '' - Domain of the local network. - ''; - }; - - profile = mkOption { - type = with types; nullOr str; - example = "desktop"; - description = '' - The profile to use for this host. This will do some profile-dependent - configuration, for example removing X-libs from servers and adding UI - packages to desktops. - ''; - default = null; - }; - - site = mkOption { - type = with types; nullOr str; - example = "seattle"; - description = '' - The site at which this host is located. This will do some site-dependent - configuration. - ''; - default = null; - }; - - www-root = mkOption { - type = types.path; - description = "Path at which to store www files for serving."; - example = /var/www; - }; - - admin-email = mkOption { - type = types.str; - description = "Email for administrator of this system."; - default = "admin@fudo.org"; - }; - - enable-gui = mkEnableOption "Install desktop GUI software."; - }; -} diff --git a/config/hardware/clunk.nix b/config/hardware/clunk.nix new file mode 100644 index 0000000..4761098 --- /dev/null +++ b/config/hardware/clunk.nix @@ -0,0 +1,70 @@ +{ config, lib, pkgs, ... }: + +{ + imports = [ ]; + + boot = { + initrd = { + availableKernelModules = + [ "ahci" "xhci_pci" "usbhid" "usb_storage" "sd_mod" ]; + kernelModules = [ ]; + }; + kernelModules = [ "kvm-intel" ]; + extraModulePackages = [ ]; + kernelPackages = pkgs.linuxPackages_latest; + + loader = { + systemd-boot.enable = true; + efi.canTouchEfiVariables = true; + }; + + # Limit tmpfs size of /run + runSize = "50%"; + }; + + fileSystems = { + "/boot" = { + device = "/dev/disk/by-label/boot"; + fsType = "vfat"; + }; + + "/" = { + device = "/dev/disk/by-label/root"; + fsType = "ext4"; + }; + }; + + swapDevices = [{ device = "/dev/disk/by-label/swap"; }]; + + nix.maxJobs = lib.mkDefault 4; + + powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; + + hardware.bluetooth.enable = false; + + network = { + macvlans = { + intif0 = { + interface = "enp2s0"; + mode = "bridge"; + }; + + extif0 = { + interface = "enp1s0"; + mode = "bridge"; + }; + }; + + interfaces = { + intif0 = { + # output of: echo clunk-intif0|md5sum|sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:\1:\2:\3:\4:\5/' + macAddress = "02:44:d1:eb:c3:6b"; + }; + + extif0 = { + # output of: echo clunk-extif0|md5sum|sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:\1:\2:\3:\4:\5/' + macAddress = "02:5e:ff:e4:83:e4"; + }; + }; + }; +} diff --git a/config/hardware/france.nix b/config/hardware/france.nix new file mode 100644 index 0000000..4297626 --- /dev/null +++ b/config/hardware/france.nix @@ -0,0 +1,85 @@ +{ config, lib, pkgs, ... }: + +{ + imports = [ ]; + + boot = { + initrd = { + availableKernelModules = + [ "uhci_hcd" "ehci_pci" "ata_piix" "ahci" "floppy" "sd_mod" "sr_mod" ]; + kernelModules = [ "dm-snapshot" ]; + }; + + kernelModules = [ "kvm-intel" ]; + extraModulePackages = [ ]; + kernelPackages = pkgs.linuxPackages_latest; + + loader.grub = { + enable = true; + version = 2; + device = "/dev/sda"; + }; + }; + + boot.initrd.availableKernelModules = + [ "uhci_hcd" "ehci_pci" "ata_piix" "ahci" "floppy" "sd_mod" "sr_mod" ]; + boot.initrd.kernelModules = [ "dm-snapshot" ]; + boot.kernelModules = [ "kvm-intel" ]; + boot.extraModulePackages = [ ]; + + fileSystems = { + "/boot" = { + device = "/dev/disk/by-label/france-boot"; + fsType = "ext4"; + }; + + "/" = { + device = "/dev/disk/by-label/france-root"; + fsType = "ext4"; + }; + + "/var/lib/lxd/storage-pools/pool0" = { + device = "/dev/disk/by-label/pool0"; + fsType = "btrfs"; + label = "pool0"; + }; + + "/var/lib/lxd/storage-pools/pool1" = { + device = "/dev/france-user/fudo-user"; + fsType = "btrfs"; + label = "pool1"; + }; + }; + + swapDevices = [{ device = "/dev/disk/by-label/france-swap"; }]; + + nix.maxJobs = lib.mkDefault 24; + + hardware.bluetooth.enable = false; + + network = { + macvlans = { + intif0 = { + interface = "enp4s0f1"; + mode = "bridge"; + }; + + extif0 = { + interface = "enp4s0f0"; + mode = "bridge"; + }; + }; + + interfaces = { + intif0 = { + # output of: echo france-intif0|md5sum|sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:\1:\2:\3:\4:\5/' + macAddress = "02:44:d1:eb:c3:6b"; + }; + + extif0 = { + # output of: echo france-extif0|md5sum|sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:\1:\2:\3:\4:\5/' + macAddress = "02:5e:ff:e4:83:e4"; + }; + }; + }; +} diff --git a/config/hardware/lambda.nix b/config/hardware/lambda.nix new file mode 100644 index 0000000..1624afd --- /dev/null +++ b/config/hardware/lambda.nix @@ -0,0 +1,65 @@ +{ config, lib, pkgs, ... }: + +{ + imports = [ ]; + + boot = { + initrd = { + availableKernelModules = [ + "uhci_hcd" + "ehci_pci" + "ata_piix" + "hpsa" + "usb_storage" + "usbhid" + "sd_mod" + "sr_mod" + ]; + kernelModules = [ ]; + }; + + kernelModules = [ "kvm-amd" ]; + externalModulePackages = [ ]; + kernelPackages = pkgs.linuxPackages_latest; + + loader.grub = { + enable = true; + version = 2; + device = "/dev/disk/by-label/nixos-root"; + }; + }; + + fileSystems = { + "/" = { + device = "/dev/disk/by-label/nixos-root"; + fsType = "btrfs"; + }; + + "/boot" = { + device = "/dev/disk/by-label/nixos-boot"; + fsType = "ext4"; + }; + }; + + swapDevices = [{ device = "/dev/disk/by-label/nixos-swap"; }]; + + nix.maxJobs = lib.mkDefault 12; + + hardware.bluetooth.enable = false; + + networking = { + macvlans = { + intif0 = { + interface = "enp3s0f1"; + mode = "bridge"; + }; + }; + + interfaces = { + intif0 = { + # output of: echo lambda-intif0|md5sum|sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:\1:\2:\3:\4:\5/' + macAddress = "02:f5:fe:8c:22:fe"; + }; + }; + }; +} diff --git a/config/hardware/nostromo.nix b/config/hardware/nostromo.nix new file mode 100644 index 0000000..7345673 --- /dev/null +++ b/config/hardware/nostromo.nix @@ -0,0 +1,68 @@ +{ config, lib, pkgs, ... }: + +{ + imports = [ ]; + + boot = { + initrd = { + availableKernelModules = [ + "ahci" + "ohci_pci" + "ehci_pci" + "megaraid_sas" + "usbhid" + "sd_mod" + "sr_mod" + ]; + kernelModules = [ "dm-snapshot" ]; + }; + + kernelModules = [ "kvm-amd" ]; + externalModulePackages = [ ]; + + kernelPackages = pkgs.linuxPackages_latest; + + loader.grub = { + enable = true; + version = 2; + device = "/dev/sda"; + }; + }; + + fileSystems = { + "/" = { + device = "/dev/disk/by-label/nixos"; + fsType = "ext4"; + }; + }; + + nix.maxJobs = lib.mkDefault 24; + + hardware.bluetooth.enable = false; + + networking = { + macvlans = { + intif0 = { + interface = "eno1"; + mode = "bridge"; + }; + + extif0 = { + interface = "eno2"; + mode = "bridge"; + }; + }; + + interfaces = { + intif0 = { + # output of: echo nostromo-intif0|md5sum|sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:\1:\2:\3:\4:\5/' + macAddress = "02:14:25:55:ee:5a"; + }; + + extif0 = { + # echo nostromo-extif0|md5sum|sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:\1:\2:\3:\4:\5/' + macAddress = "02:cf:d7:de:f9:ad"; + }; + }; + }; +} diff --git a/config/hardware/plato.nix b/config/hardware/plato.nix new file mode 100644 index 0000000..4bc6f07 --- /dev/null +++ b/config/hardware/plato.nix @@ -0,0 +1,79 @@ +{ config, lib, pkgs, ... }: + +{ + imports = [ ]; + + boot = { + initrd = { + availableKernelModules = + [ "xhci_pci" "ehci_pci" "ahci" "usb_storage" "sd_mod" ]; + kernelModules = [ ]; + }; + kernelModules = [ "kvm-intel" ]; + extraModulePackages = [ ]; + loader = { + systemd-boot.enable = true; + efi.canTouchEfiVariables = true; + }; + + supportedFilesystems = [ "zfs" ]; + kernelPackages = pkgs.linuxPackages_latest; + }; + + fileSystems = { + "/boot" = { + device = "/dev/disk/by-label/PLATO-BOOT"; + fsType = "vfat"; + }; + + "/" = { + device = "zroot/transient/root"; + fsType = "zfs"; + }; + + "/nix" = { + device = "zroot/transient/nix"; + fsType = "zfs"; + }; + + "/var/log" = { + device = "zroot/transient/logs"; + fsType = "zfs"; + neededForBoot = true; + }; + + "/home" = { + device = "zroot/persistent/home"; + fsType = "zfs"; + }; + + "/state" = { + device = "zroot/persistent/state"; + fsType = "zfs"; + }; + }; + + services.autoScrub.enable = true; + + swapDevices = [{ device = "/dev/disk/by-label/plato-swap"; }]; + + nix.maxJobs = lib.mkDefault 4; + + hardware.bluetooth.enable = false; + + network = { + macvlans = { + intif0 = { + interface = "enp1s0"; + mode = "bridge"; + }; + }; + + interfaces = { + intif0 = { + # output of: echo plato-intif0|md5sum|sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:\1:\2:\3:\4:\5/' + macAddress = "02:25:b7:67:c4:c2"; + }; + }; + }; +} diff --git a/config/hosts.nix b/config/hosts.nix new file mode 100644 index 0000000..12b481f --- /dev/null +++ b/config/hosts.nix @@ -0,0 +1,90 @@ +{ config, lib, pkgs, ... }: + +{ + config.fudo.hosts = { + atom = { + description = "Niten's toy laptop."; + domain = "sea.fudo.org"; + site = "seattle"; + profile = "laptop"; + enable-gui = false; + hardware-config = ./hardware/atom.nix; + }; + + clunk = let + primary-ip = "10.0.0.1"; + internal-interfaces = [ "intif0" ]; + external-interface = "extif0"; + dns-over-https-port = 5353; + + in { + description = "rus.selby.ca gateway box."; + domain = "rus.selby.ca"; + site = "russell"; + profile = "gateway-server"; + docker-server = true; + hardware-config = ./hardware/clunk.nix; + extra-config = import ./hosts/clunk.nix { }; + }; + + france = { + description = "Primary fudo.org server."; + domain = "fudo.org"; + site = "portage"; + profile = "server"; + docker-server = true; + hardware-config = ./hardware/france.nix; + }; + + lambda = { + description = "Niten's experiment server."; + domain = "sea.fudo.org"; + site = "seattle"; + profile = "server"; + docker-server = true; + hardware-config = ./hardware/lambda.nix; + }; + + nostromo = { + description = "sea.fudo.org gateway box and primary server."; + domain = "sea.fudo.org"; + site = "seattle"; + profile = "gateway-server"; + docker-server = true; + hardware-config = ./hardware/nostromo.nix; + }; + + plato = { + description = "Niten's toy server."; + domain = "rus.selby.ca"; + site = "russell"; + profile = "server"; + hardware-config = ./hardware/plato.nix; + }; + + procul = { + description = "informis.land server."; + domain = "informis.land"; + site = "joes-datacenter-0"; + profile = "server"; + docker-server = true; + hardware-config = ./hardware/procul.nix; + }; + + spark = { + description = "Niten's backup desktop."; + domain = "sea.fudo.org"; + site = "seattle"; + profile = "desktop"; + hardware-config = ./hardware/spark.nix; + }; + + zbox = { + description = "Niten's primary desktop."; + domain = "sea.fudo.org"; + site = "seattle"; + profile = "desktop"; + hardware-config = ./hardware/zbox.nix; + }; + }; +} diff --git a/config/hosts/atom.nix b/config/hosts/atom.nix new file mode 100644 index 0000000..abc7d91 --- /dev/null +++ b/config/hosts/atom.nix @@ -0,0 +1,9 @@ +{ config, lib, pkgs, ... }: + +{ + fudo.laptop.use-network-manager = false; + + fudo.slynk.enable = true; + + services.xserver = { videoDrivers = [ "nvidia" ]; }; +} diff --git a/config/hosts/clunk.nix b/config/hosts/clunk.nix new file mode 100644 index 0000000..838b6ba --- /dev/null +++ b/config/hosts/clunk.nix @@ -0,0 +1,135 @@ +{ config, lib, pkgs, ... }: + +let + primary-ip = "10.0.0.1"; + dns-proxy-ip = "10.0.0.2"; + +in { + fudo.local-network = { + # FIXME: think about this -- actual network config? + enable = true; + # NOTE: requests go: + # - local bind instance + # - pi-hole + # - DoH resolver + dns-servers = [ primary-ip ]; + gateway = primary-ip; + dhcp-interfaces = [ "intif0" ]; + dns-serve-ips = [ primary-ip "127.0.0.1" "127.0.1.1" "::1" ]; + recursive-resolver = "${primary-ip} port 5353"; + server-ip = primary-ip; + domain = "rus.selby.ca"; + }; + + networking = { + firewall = { + enable = true; + trustedInterfaces = [ "intif0" "docker0" ]; + allowedTCPPorts = [ 22 ]; + }; + + interfaces = { + enp2s0.useDHCP = false; + enp3s0.useDHCP = false; + enp4s0.useDHCP = false; + + enp1s0.useDHCP = true; + + intif0 = { + useDHCP = false; + ipv4.addresses = [ + { + address = primary-ip; + prefixLength = 22; + } + { + address = dns-proxy-ip; + prefixLength = 32; + } + ]; + }; + + extif0 = { useDHCP = true; }; + }; + + nat = { + enable = true; + externalInterface = "extif0"; + internalInterfaces = [ "intif0" ]; + }; + }; + + fudo = { + garbage-collector = { + enable = true; + timing = "weekly"; + }; + + secure-dns-proxy = { + enable = true; + listen-port = 53; + upstream-dns = + [ "https://1.1.1.1/dns-query" "https://1.0.0.1/dns-query" ]; + bootstrap-dns = "1.1.1.1"; + listen-ips = [ dns-proxy-ip ]; + }; + }; + + # environment.systemPackages = with pkgs; [ dnsproxy ]; + + virtualization = { + docker = { + enable = true; + autoPrune.enable = true; + enableOnBoot = true; + }; + }; + + docker-containers = { + pihole = { + image = "pihole/pihole:v5.1.2"; + ports = [ "5353:53/tcp" "5353:53/udp" "3080:80/tcp" ]; + environment = { + ServerIP = primary-ip; + VIRTUAL_HOST = "dns-hole.rus.selby.ca"; + DNS1 = dns-proxy-ip; + }; + volumes = [ + "/srv/pihole/etc-pihole/:/etc/pihole/" + "/srv/pihole/etc-dnsmasq.d/:/etc/dnsmasq.d/" + ]; + }; + }; + + services.nginx = { + enable = true; + + recommendedOptimisation = true; + recommendedGzipSettings = true; + recommendedProxySettings = true; + + virtualHosts = { + "dns-hole.rus.selby.ca" = { + serverAliases = [ + "pihole.rus.selby.ca" + "hole.rus.selby.ca" + "pihole" + "dns-hole" + "hole" + ]; + + 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; + # ''; + }; + }; + }; + }; +} diff --git a/config/hosts/france.nix b/config/hosts/france.nix new file mode 100644 index 0000000..f4fe89a --- /dev/null +++ b/config/hosts/france.nix @@ -0,0 +1,179 @@ +{ config, lib, pkgs, ... }: + +let + primary-ip = "208.81.3.117"; + hostname = config.instance.hostname; + domain-name = config.fudo.hosts.${hostname}.domain; + domain = config.fudo.domains.${domain-name}; + host-fqdn = "${hostname}.${domain-name}"; + mail-hostname = "mail.fudo.org"; + +in { + imports = [ ./france/postgresql.nix ]; + + config = { + fudo = { + auth = { + ldap = { + enable = true; + base = "dc=fudo,dc=org"; + organization = "Fudo"; + rootpw-file = "FIXME"; + kerberos-host = host-fqdn; + kerberos-keytab = "FIXME"; + + sslCert = "FIXME"; + sslKey = "FIXME"; + sslCaCert = "FIXME"; + + listen-uris = [ "ldap:///" "ldaps:///" "ldapi:///" ]; + + users = config.fudo.users; + groups = config.fudo.groups; + system-users = config.fudo.system-users; + }; + + kdc = let realm = "FUDO.ORG"; + in { + enable = true; + database-path = "FIXME"; + realm = realm; + mkey-file = "FIXME"; + acl = [ + { + principal = "pam_migrate/*.fudo.org@${realm}"; + access = "add"; + } + { + principal = "host/*.fudo.org@${realm}"; + access = "add"; + } + ] ++ (concatMap (user: [ + { + principal = "${user}@${realm}"; + access = "add,list,modify"; + } + { + principal = "${user}/root@${realm}"; + access = "all"; + } + ]) domain.admin-users); + bind-addresses = [ primary-ip "127.0.0.1" "127.0.1.1" "::1" ]; + }; + }; + + prometheus = { + enable = true; + hostname = "metrics.fudo.org"; + service-discovery-dns = let dns-root = "_metrics._tcp.fudo.org"; + in { + node = [ "node.${dns-root}" ]; + postfix = [ "postfix.${dns-root}" ]; + dovecot = [ "dovecot.${dns-root}" ]; + rspamd = [ "rspamd.${dns-root}" ]; + }; + }; + + postgresql = { + enable = true; + # FIXME: ssl-private-key && ssl certificate + keytab = "/srv/postgres/secure/postgres.keytab"; + local-networks = getHostLocalNetworks hostname; + admin-users = domain.admin-users; + }; + + client.dns = { + enable = true; + ipv4 = true; + ipv6 = true; + user = "FIXME"; + external-interface = "extif0"; + password-file = "FIXME"; + }; + + mail-server = domain.mail-config // { + enableContainer = true; + monitoring = true; + + hostname = mail-hostname; + + state-directory = "FIXME"; + mail-directory = "FIXME"; + + dovecot.ldap = { + reader-dn = "FIXME"; + reader-password = "FIXME"; + server-urls = [ "FIXME" ]; + }; + + clamav.enable = true; + dkim.signing = true; + }; + + git = { + enable = true; + hostname = "git.fudo.org"; + site-name = "Fudo Git"; + user = "FIXME"; + database = { + user = "FIXME"; + password-file = "FIXME"; + hostname = "127.0.0.1"; + name = "FIXME"; + }; + repository-dir = "FIXME"; + state-dir = "FIXME"; + ssh = { + listen-ip = git-server-ip; + listen-port = 22; + }; + }; + + minecraft-server = { + enable = true; + package = pkgs.minecraft-current; + data-dir = "FIXME"; + world-name = "selbyland"; + motd = "Welcome to the Selby Minecraft server."; + }; + }; + + networking = { + intif0 = { + ipv4.addresses = [{ + address = "192.168.11.1"; + prefixLength = 24; + }]; + }; + extif0 = { + ipv4.addresses = [ + { + address = primary-ip; + prefixLength = 28; + } + { + address = git-server-ip; + prefixLength = 32; + } + ]; + }; + }; + + services = { + nginx = { + enable = true; + recommendedGzipSettings = true; + recommendedOptimisations = true; + recommendedTlsSettings = true; + recommendedProxySettings = true; + + virtualHosts = { + "mail.fudo.org" = { + enableACME = true; + locations."/".return = "301 https://webmail.fudo.org$request_uri"; + }; + }; + }; + }; + }; +} diff --git a/config/hosts/lambda.nix b/config/hosts/lambda.nix new file mode 100644 index 0000000..90349aa --- /dev/null +++ b/config/hosts/lambda.nix @@ -0,0 +1,32 @@ +{ config, lib, pkgs, ... }: + +let primary-ip = "10.0.0.3"; + +in { + fudo.slynk.enable = true; + + networking = { + interfaces = { + enp3s0f0.useDHCP = false; + enp3s0f1.useDHCP = false; + enp4s0f0.useDHCP = false; + enp4s0f1.useDHCP = false; + + extif0 = { + useDHCP = false; + ipv4.addresses = [{ + address = primary-ip; + prefixLength = 22; + }]; + }; + }; + }; + + fudo.ipfs = { + enable = true; + users = [ "niten" ]; + api-address = "/ip4/${primary-ip}/tcp/5001"; + }; + + # TODO: add camera +} diff --git a/config/hosts/nostromo.nix b/config/hosts/nostromo.nix new file mode 100644 index 0000000..deabe7d --- /dev/null +++ b/config/hosts/nostromo.nix @@ -0,0 +1,169 @@ +{ config, lib, pkgs, ... }: + +let + primary-ip = "10.0.0.1"; + dns-proxy-ip = "10.0.0.5"; + +in { + fudo.local-network = let + hostname = config.instance.hostname; + site-name = config.fudo.hosts.${hostname}.site; + site = config.fudo.site.${site-name}; + + in { + enable = true; + dns-servers = site.dns-servers; + gateway = site.gateway; + dhcp-interfaces = [ "intif0" ]; + dns-serve-ips = [ primary-ip "127.0.0.1" "127.0.1.1" "::1" ]; + recursive-resolver = "${primary-ip} port 5353"; + server-ip = primary-ip; + }; + + fudo.slynk.enable = true; + + # systemd.network.networks.eno2 = { + # extraConfig = { + # IPv6AcceptRA = true; + # IPv6PrefixDelegation = "dhcpv6"; + # }; + # }; + + networking = { + # dhcpd.extraConfig = '' + # interface eno2 + # ia_na 1 + # ia_pd 2 eno2/0 + # ''; + + eno1.useDHCP = false; + eno2.useDHCP = false; + eno3.useDHCP = false; + eno4.useDHCP = false; + enp33s0f0.useDHCP = false; + enp33s0f1.useDHCP = false; + enp9s0f0.useDHCP = false; + enp9s0f1.useDHCP = false; + + intif0 = { + useDHCP = false; + ipv4.addresses = [ + { + address = primary-ip; + prefixLength = 22; + } + { + address = dns-proxy-ip; + prefixLength = 32; + } + ]; + }; + + extif0 = { useDHCP = true; }; + + nat = { + enable = true; + externalInterface = "extif0"; + internalInterfaces = [ "intif0" ]; + }; + }; + + fudo = { + client.dns = { + enable = true; + ipv4 = true; + ipv6 = true; + user = "fudo-client"; + external-interface = "extif0"; + password-file = "/srv/client/secure/client.passwd"; + }; + + secure-dns-proxy = { + enable = true; + port = 3535; + upstream-dns = + [ "https://1.1.1.1/dns-query" "https://1.0.0.1/dns-query" ]; + bootstrap-dns = "1.1.1.1"; + listen-ips = [ dns-proxy-ip ]; + }; + }; + + virtualization = { + 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 = primary-ip; + VIRTUAL_HOST = "dns-hole.sea.fudo.org"; + DNS1 = dns-proxy-ip; + }; + volumes = [ + "/srv/pihole/etc-pihole/:/etc/pihole/" + "/srv/pihole/etc-dnsmasq.d/:/etc/dnsmasq.d/" + ]; + }; + }; + + security.acme.certs = { + "sea-camera.fudo.link".email = "niten@fudo.org"; + "sea-camera-od.fudo.link".email = "niten@fudo.org"; + }; + + services = { + nginx = { + enable = true; + recommendedGzipSettings = true; + recommendedOptimisation = true; + recommendedTlsSettings = true; + recommendedProxySettings = true; + + virtualHosts = { + "sea-camera.fudo.link" = { + enableACME = true; + forceSSL = true; + locations."/" = { + proxyPass = "http://panopticon.sea.fudo.org/"; + extraConfig = '' + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + ''; + }; + }; + + # Supposed to be for object detection... + "sea-camera-od.fudo.link" = { + enableACME = true; + forceSSL = true; + locations."/" = { + proxyPass = "http://panopticon-od.sea.fudo.org/"; + extraConfig = '' + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + ''; + }; + }; + + "pihole.sea.fudo.org" = { + serverAliases = [ "dns-hole.sea.fudo.org" "hole.sea.fudo.org" ]; + locations."/" = { proxyPass = "http://127.0.0.1:3000"; }; + }; + }; + }; + }; +} diff --git a/config/hosts/plato.nix b/config/hosts/plato.nix new file mode 100644 index 0000000..09de5ae --- /dev/null +++ b/config/hosts/plato.nix @@ -0,0 +1,34 @@ +{ config, lib, pkgs, ... }: + +with lib; { + config = { + environment.etc = { + nixos.source = "/state/nixos"; + adjtime.source = "/state/etc/adjtime"; + NIXOS.source = "/state/etc/NIXOS"; + machine-id.source = "/state/etc/machine-id"; + }; + + system.stateVersion = "20.09"; + + boot.initrd.postDeviceCommands = lib.mkAfter '' + ${pkgs.zfs}/bin/zfs rollback -r zroot/transient/root@blank + ''; + + services = { + openssh = { + hostKeys = [ + { + path = "/state/ssh/ssh_host_ed25519_key"; + type = "ed25519"; + } + { + path = "/state/ssh/ssh_host_rsa_key"; + type = "rsa"; + bits = 4096; + } + ]; + }; + }; + }; +} diff --git a/config/hosts/zbox.nix b/config/hosts/zbox.nix new file mode 100644 index 0000000..718db2e --- /dev/null +++ b/config/hosts/zbox.nix @@ -0,0 +1,10 @@ +{ config, lib, pkgs, ... }: + +{ + fudo.slynk.enable = true; + + networking = { + eno1.useDHCP = false; + intif0 = { useDHCP = true; }; + }; +} diff --git a/config/local-network/rus.selby.ca.nix b/config/local-network/rus.selby.ca.nix new file mode 100644 index 0000000..1478037 --- /dev/null +++ b/config/local-network/rus.selby.ca.nix @@ -0,0 +1,84 @@ +let local-domain = "rus.selby.ca"; +in { + domain = "${local-domain}"; + + 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 = "clunk.${local-domain}"; + }]; + kerberos = [{ + port = 88; + host = "france.fudo.org"; + }]; + kerberos-adm = [{ + port = 88; + host = "france.fudo.org"; + }]; + ssh = [{ + port = 22; + host = "clunk.${local-domain}"; + }]; + }; + + udp = { + domain = [{ + port = 53; + host = "clunk.${local-domain}"; + }]; + kerberos = [{ + port = 88; + host = "france.fudo.org"; + }]; + kerboros-master = [{ + port = 88; + host = "france.fudo.org"; + }]; + kpasswd = [{ + port = 464; + host = "france.fudo.org"; + }]; + }; + }; + + aliases = { dns-hole = "clunk"; }; + + hosts = { + clunk = { + ip-address = "10.0.0.1"; + mac-address = "02:44:d1:eb:c3:6b"; + }; + + dns-proxy = { + ip-address = "10.0.0.2"; + # This is just an alias for clunk's primary interface + }; + + google-wifi = { + ip-address = "10.0.0.11"; + mac-address = "70:3a:cb:c0:3b:09"; + }; + + pselby-work = { + ip-address = "10.0.0.151"; + mac-address = "00:50:b6:aa:bd:b3"; + }; + + downstairs-desktop = { + ip-address = "10.0.0.100"; + mac-address = "90:b1:1c:8e:29:cf"; + }; + + upstairs-desktop = { + ip-address = "10.0.0.101"; + mac-address = "80:e8:2c:22:65:c2"; + }; + }; +} diff --git a/config/local-network/sea.fudo.org.nix b/config/local-network/sea.fudo.org.nix new file mode 100644 index 0000000..cbe8144 --- /dev/null +++ b/config/local-network/sea.fudo.org.nix @@ -0,0 +1,217 @@ +let local-domain = "sea.fudo.org"; +in { + domain = "${local-domain}"; + + aliases = { + kadmin = "nostromo"; + kdc = "nostromo"; + photo = "doraemon"; + music = "doraemon"; + panopticon = "lambda"; + panopticon-od = "lambda"; + ipfs = "nostromo"; + hole = "nostromo"; + pihole = "nostromo"; + dns-hole = "nostromo"; + mon-1 = "srv-1"; + }; + + 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"; + }; + lambda = { + ip-address = "10.0.0.3"; + mac-address = "02:50:f6:52:9f:9d"; + }; + switch-master = { + ip-address = "10.0.0.5"; + mac-address = "00:14:1C:B6:BB:40"; + }; + google-wifi = { + ip-address = "10.0.0.7"; + mac-address = "7C:D9:5C:9F:6F:E9"; + }; + 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"; + }; + generator-wireless = { + ip-address = "10.0.0.130"; + mac-address = "B8:27:EB:A6:32:26"; + }; + 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"; + }; + + # Ceph network + srv-1 = { + ip-address = "10.0.10.1"; + mac-address = "02:65:d7:00:7d:1b"; + }; + 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"; + }; + node-4 = { + ip-address = "10.0.10.104"; + mac-address = "00:1e:06:36:dd:8c"; + }; + }; +} diff --git a/config/profiles.nix b/config/profiles.nix new file mode 100644 index 0000000..b4f6249 --- /dev/null +++ b/config/profiles.nix @@ -0,0 +1,7 @@ +{ config, lib, pkgs, ... }: + +let + host = config.instance.hostname; + host-profile = config.fudo.hosts.${host}.profile; + +in { imports = [ "./profiles/${host-profile}.nix" ]; } diff --git a/config/profiles/common-ui.nix b/config/profiles/common-ui.nix new file mode 100644 index 0000000..9e01d1e --- /dev/null +++ b/config/profiles/common-ui.nix @@ -0,0 +1,108 @@ +{ config, lib, pkgs, ... }: + +with lib; +let + hostname = config.instance.hostname; + enable-gui = config.fudo.hosts.${hostname}.enable-gui; + +in { + import = [ ./common.nix ]; + + boot.plymouth.enable = false; + + boot.tmpOnTmpfs = true; + + services.xserver = mkIf enable-gui { + enable = true; + + desktopManager.gnome3.enable = true; + + displayManager.gdm.enable = true; + + windowManager.stumpwm.enable = true; + + # windowManager.session = pkgs.lib.singleton { + # name = "stumpwm"; + # start = '' + # ${pkgs.lispPackages.stumpwm}/bin/stumpwm & + # waidPID=$! + # ''; + # }; + }; + + sound.enable = true; + hardware.pulseaudio.enable = true; + + console.font = + lib.mkDefault "${pkgs.terminus_font}/share/consolefonts/ter-g28n.psf.gz"; + + services.gnome3 = mkIf enable-gui { + evolution-data-server.enable = mkForce false; + gnome-user-share.enable = mkForce false; + }; + + fonts = mkIf enable-gui { + enableFontDir = true; + fontconfig.enable = true; + #fontconfig.antialias = true; + #fontconfig.penultimate.enable = true; + #fontconfig.subpixel.lcdfilter = "default"; + + fonts = with pkgs; [ + cantarell_fonts + dejavu_fonts + dina-font + dosemu_fonts + fira-code + fira-code-symbols + freefont_ttf + liberation_ttf + mplus-outline-fonts + nerdfonts + noto-fonts + noto-fonts-cjk + noto-fonts-emoji + proggyfonts + terminus_font + ubuntu_font_family + ucsFonts + ultimate-oldschool-pc-font-pack + unifont + vistafonts + xlibs.fontadobe100dpi + xlibs.fontadobe75dpi + xlibs.fontadobeutopia100dpi + xlibs.fontadobeutopia75dpi + xlibs.fontadobeutopiatype1 + xlibs.fontarabicmisc + xlibs.fontbh100dpi + xlibs.fontbh75dpi + xlibs.fontbhlucidatypewriter100dpi + xlibs.fontbhlucidatypewriter75dpi + xlibs.fontbhttf + xlibs.fontbhtype1 + xlibs.fontbitstream100dpi + xlibs.fontbitstream75dpi + xlibs.fontbitstreamtype1 + xlibs.fontcronyxcyrillic + xlibs.fontcursormisc + xlibs.fontdaewoomisc + xlibs.fontdecmisc + xlibs.fontibmtype1 + xlibs.fontisasmisc + xlibs.fontjismisc + xlibs.fontmicromisc + xlibs.fontmisccyrillic + xlibs.fontmiscethiopic + xlibs.fontmiscmeltho + xlibs.fontmiscmisc + xlibs.fontmuttmisc + xlibs.fontschumachermisc + xlibs.fontscreencyrillic + xlibs.fontsonymisc + xlibs.fontsunmisc + xlibs.fontwinitzkicyrillic + xlibs.fontxfree86type1 + ]; + }; +} diff --git a/config/profiles/common.nix b/config/profiles/common.nix new file mode 100644 index 0000000..a630f00 --- /dev/null +++ b/config/profiles/common.nix @@ -0,0 +1,100 @@ +{ config, lib, pkgs, ... }: + +with lib; +let + # Available to all users on the system. Keep it minimal. + global-packages = with pkgs; [ emacs openssh_gssapi vim wget ]; + +in { + environment = { + etc.current-nixos-config.source = ../../.; + + systemPackages = global-packages; + + environment.shellInit = '' + ${pkgs.gnupg}/bin/gpg-connect-agent /bye + export SSH_AUTH_SOCK=$(${pkgs.gnupg}/bin/gpgconf --list-dirs agent-ssh-socket) + ''; + }; + + nixpkgs.config.allowUnfree = true; + security.acme.acceptTerms = true; + + system.autoUpgrade.enable = true; + + services = { + emacs = { + enable = true; + defaultEditor = true; + }; + + openssh = { + enable = true; + startWhenNeeded = true; + useDns = true; + permitRootLogin = "prohibit-password"; + extraConfig = '' + GSSAPIAuthentication yes + GSSAPICleanupCredentials yes + ''; + # FIXME: add all the hosts we know about + knownHosts = { + # publicKey, hostNames + }; + }; + + xserver = { + layout = "us"; + xkbVariant = "dvp"; + xkbOptions = "ctrl:nocaps"; + }; + + # pcscd.enable = true; + # udev.packages = with pkgs; [ yubikey-personalization ]; + }; + + console.useXkbConfig = true; + + i18n.defaultLocale = "en_US.UTF-8"; + + programs = { + mosh.enable = true; + + bash.enableCompletion = true; + + fish.enable = true; + + gnupg.agent = { + enable = true; + enableSSHSupport = true; + # pinentryFlavor = if cfg.enable-gui then "gnome3" else "curses"; + }; + + ssh = { + # Use GPG agent instead + startAgent = false; + + package = pkgs.openssh_gssapi; + + extraConfig = '' + GSSAPIAuthentication yes + GSSAPIDelegateCredentials yes + ''; + }; + }; + + security.pam = { + enableSSHAgentAuth = true; + + services = { + sshd = { + makeHomeDir = true; + sshAgentAuth = true; + # This isn't supposed to ask for a code unless ~/.google_authenticator exists...but it does + # googleAuthenticator.enable = true; + }; + }; + }; + + services.dbus.socketActivated = true; +} diff --git a/config/profiles/desktop.nix b/config/profiles/desktop.nix new file mode 100644 index 0000000..5b46b5c --- /dev/null +++ b/config/profiles/desktop.nix @@ -0,0 +1,7 @@ +{ config, lib, pkgs, ... }: + +with lib; { + imports = [ ./common-ui.nix ]; + + config = { networking = { networkmanager.enable = mkForce false; }; }; +} diff --git a/config/profiles/gateway-server.nix b/config/profiles/gateway-server.nix new file mode 100644 index 0000000..e784a32 --- /dev/null +++ b/config/profiles/gateway-server.nix @@ -0,0 +1,30 @@ +{ 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; + }; + }; + }; + }; +} diff --git a/config/profiles/laptop.nix b/config/profiles/laptop.nix new file mode 100644 index 0000000..0df4bd8 --- /dev/null +++ b/config/profiles/laptop.nix @@ -0,0 +1,24 @@ +{ config, lib, pkgs, ... }: + +{ + options.fudo.profile.laptop = { + use-network-manager = + mkEnableOption "Use NetworkManager instead of wpa_supplicant."; + }; + + environment.systemPackages = with pkgs; [ acpi upower wpa_supplicant ]; + + networking = if (config.fudo.profile.laptop.use-network-manager) then { + networkmanager.enable = true; + } else { + networkmanager.enable = false; + wireless = { + enable = true; + userControlled = { + enable = true; + group = "wheel"; + }; + networks = config.fudo.wireless-networks; + }; + }; +} diff --git a/config/profiles/server.nix b/config/profiles/server.nix new file mode 100644 index 0000000..d7a29ee --- /dev/null +++ b/config/profiles/server.nix @@ -0,0 +1,71 @@ +{ config, lib, pkgs, ... }: + +with lib; +let + reboot-if-necessary = pkgs.writeShellScriptBin "reboot-if-necessary" '' + if [ $# -ne 1 ]; then + echo "FAILED: no sync file provided." + exit 1 + fi + + WALL=${pkgs.utillinux}/bin/wall + + if [ -f $1 ]; then + $WALL "$1 exists, rebooting system" + ${pkgs.systemd}/bin/reboot + else + $WALL "$1 does not exist, aborting reboot." + fi + + exit 0 + ''; + + test-config = pkgs.writeShellScriptBin "fudo-test-config" '' + if [ $# -gt 1 ]; then + echo "usage: $0 [timeout]" + exit 1 + elif [ $# -eq 1 ]; then + TIMEOUT=$1 + else + TIMEOUT=15m + fi + + SYNCFILE=$TMP/sync-$(date +"%Y%m%d-%H%M%N") + touch $SYNCFILE + ${pkgs.utillinux}/bin/wall "Launching config. System will restart in $TIMEOUT if $SYNCFILE still exists." + systemd-run --on-active=$TIMEOUT ${reboot-if-necessary} $SYNCFILE + nixos-rebuild test + + exit 0 + ''; + +in { + imports = [ ./common.nix ]; + + config = { + environment = { + systemPackages = with pkgs; [ + emacs-nox + ldns + ldns.examples + jdk12_headless + racket-minimal + reboot-if-necessary + test-config + ]; + + noXlibs = true; + }; + + security = { hideProcessInformation = true; }; + + networking.networkmanager.enable = mkForce false; + + boot.tmpOnTmpfs = true; + + services.xserver.enable = false; + + sound.enable = false; + hardware.pulseaudio.enable = false; + }; +} diff --git a/config/sites.nix b/config/sites.nix new file mode 100644 index 0000000..9d50568 --- /dev/null +++ b/config/sites.nix @@ -0,0 +1,59 @@ +{ config, lib, pkgs, ... }: + +{ + config.fudo.sites = { + seattle = { + gateway-v4 = "10.0.0.1"; + nameservers = [ "10.0.0.1" ]; + timezone = "America/Los_Angeles"; + gateway-host = "nostromo"; + # FIXME: good idea? + network-mounts = { + "/mnt/documents" = { + device = "whitedwarf:/volume1/Documents"; + fsType = "nfs4"; + }; + "/mnt/downloads" = { + device = "whitedwarf:/volume1/Downloads"; + fsType = "nfs4"; + }; + "/mnt/music" = { + device = "doraemon:/volume1/Music"; + fsType = "nfs4"; + }; + "/mnt/video" = { + device = "doraemon:/volume1/Video"; + fsType = "nfs4"; + }; + "/mnt/cargo_video" = { + device = "cargo:/volume1/video"; + fsType = "nfs4"; + }; + "/mnt/photo" = { + device = "cargo:/volume1/pictures"; + fsType = "nfs4"; + }; + }; + }; + + portage = { + gateway-v4 = "208.81.3.113"; + # gateway-v6 = "265:e200:d200:1::1"; + nameservers = [ "1.1.1.1" "208.81.7.14" "2606:4700:4700::1111" ]; + timezone = "America/Winnipeg"; + }; + + russell = { + gateway-v4 = "10.0.0.1"; + nameservers = [ "10.0.0.1" ]; + timezone = "America/Winnipeg"; + gateway-host = "clunk"; + }; + + joes-datacenter-0 = { + gateway-v4 = "172.86.179.17"; + nameservers = [ "1.1.1.1" "2606:4700:4700::1111" ]; + timezone = "America/Winnipeg"; + }; + }; +} diff --git a/config/users.nix b/config/users.nix new file mode 100644 index 0000000..949597a --- /dev/null +++ b/config/users.nix @@ -0,0 +1,455 @@ +{ config, lib, pkgs, ... }: + +{ + config.fudo.users = { + niten = { + uid = 10000; + primary-group = "admin"; + common-name = "Peter Selby"; + ldap-hashed-password = "{SSHA}dF/5NGkafL8M1kpa3LYZKdh0Pc7a02gA"; + login-hashed-password = + "$6$a1q2Duoe35hd5$IaZGXPfqyGv9uq5DQm7DZq0vIHsUs39sLktBiBBqMiwl/f/Z4jSvNZLJp9DZJYe5u2qGBYh1ca.jsXvQA8FPZ/"; + ssh-authorized-keys = [ + "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDoWkjyeIfgwm0b78weToVYOQSD0RQ0qbNzpsN5NokbIFv2/980kLtnYrQEgIJ/JwMLlT3uJYacbCT5/a6Fb8oLxNpj0AF1EKaWZ3Rrlg72Sq+9SEwJwWWmZizX83sovMwUBMaUp6jWLhAhPpzBW5pfc5YWoc89wxGbELSwzgt5EgHbSJgvDnaHSp3fVaY01wfDXbL/oO160iNe7wv2HLMZu/FkWBkIjz6HmoGJJzYM89bUpHbyYG28lmCHB/8UPog5/BsjOn3/qupgf4zh6mMdMsXLvbR2jVwVjxcEMj9N5nCvc+Y3oi7Mij6VNrWbhkaAJMEzeMhWYrF3/pFQxUqG37aK3d0gw9kp5tMDLIlAPX4y1lfA87pIzoa0+Alql0CJQA1IJvp9SFG7lBmSthWQLmZvwwfoGg/ZjF6rOgsVoZ8TizpQnydWJDr6NboU9LL9Oa64OM5Rs0AU3cR2UbOF4QIcWFJ/7oDe3dOnfZ8QYqx9eXJyxoAUpDanaaTHYBiAKkeOBwQU+MVLKCcONKw9FZclf/1TpDB5b3/JeUFANjHQTv0UXA4YYU7iCx6H7XB4qwwtU9O19CGQYYfCfULX12/fRpYJw6VJaQWyyU4Bn5dk/dcB2nGI36jwbLMfhbUTIApujioAnd/GQIMakHEZ1+syPhMx9BxMkZb99B0A1Q== openpgp:0x4EC95B64" + ]; + home = "/home/niten"; + }; + + andrew = { + uid = 10001; + primary-group = "selby"; + common-name = "Andrew Selby"; + ldap-hashed-password = ""; + }; + + animus = { + uid = 10002; + primary-group = "fudo"; + common-name = "James Frazer"; + ldap-hashed-password = ""; + }; + + ark = { + uid = 10005; + primary-group = "fudo"; + common-name = "Roger Wong"; + ldap-hashed-password = ""; + }; + + ben = { + uid = 10007; + primary-group = "fudo"; + common-name = "Ben"; + ldap-hashed-password = "{MD5}v0jY5bADu30cAR1Uu/eWYQ=="; + }; + + chad = { + uid = 10011; + primary-group = "fudo"; + common-name = "Chad Isbister"; + ldap-hashed-password = "{MD5}fQ309GUF2DvHlJ3R+5wNuA=="; + }; + + ckoo = { + uid = 10014; + primary-group = "fudo"; + common-name = "Jason Bush"; + ldap-hashed-password = "{MD5}KMFeaBc7e/gVzL/QUT0mYw=="; + }; + + dana = { + uid = 10015; + primary-group = "fudo"; + common-name = "Dana Eftodie"; + ldap-hashed-password = "{MD5}+ijTylKau4uot2kGMqKSTA=="; + }; + + jill = { + uid = 10030; + primary-group = "fudo"; + common-name = "Jill Isbister"; + ldap-hashed-password = "{MD5}fQ309GUF2DvHlJ3R+5wNuA=="; + }; + + joker4ever = { + uid = 10033; + primary-group = "fudo"; + common-name = "Jack Clarke"; + ldap-hashed-password = "{SSHA}w78XwSax9WywIDujMxEoO7o87d2LDJRo"; + }; + + ken = { + uid = 10035; + primary-group = "selby"; + common-name = "Ken Selby"; + ldap-hashed-password = "{SSHA}YvtkEpqsReXcMdrzlui/ZmhIUKN42YO1"; + login-hashed-password = + "$6$EwK9fpbH8$gYVzYY1IYw2/G0wCeUxXrZZqvjWCkCZbBqCOhxowbMuYtC5G0vp.AoYhVKWOJcHJM2c7TdPmAdnhLIe2KYStf."; + }; + + reaper = { + uid = 10049; + primary-group = "admin"; + common-name = "Jonathan Stewart"; + ldap-hashed-password = "{MD5}EBvifhJ6z9dIDx0KWkAPoQ=="; + login-hashed-password = + "$6$a1q2Duoe35hd5$IaZGXPfqyGv9uq5DQm7DZq0vIHsUs39sLktBiBBqMiwl/f/Z4jSvNZLJp9DZJYe5u2qGBYh1ca.jsXvQA8FPZ/"; + home = "/home/reaper"; + }; + + slickoil = { + uid = 10052; + primary-group = "fudo"; + common-name = "Connor Cooley"; + ldap-hashed-password = "{MD5}8Qrpagi8TYnZQdFoYe02rA=="; + }; + + splat1 = { + uid = 10053; + primary-group = "fudo"; + common-name = "Matt Evans"; + ldap-hashed-password = "{MD5}JeHNutGTBMHOqFgVlYjfpw=="; + }; + + swaff = { + uid = 10055; + primary-group = "fudo"; + common-name = "Mark Swaffer"; + ldap-hashed-password = "{MD5}C5gIsLsaKSvIPydu4uzhNg=="; + }; + + brian = { + uid = 10056; + primary-group = "selby"; + common-name = "Brian Selby"; + ldap-hashed-password = "{crypt}$1$npZLTPEO$p2bTx8TTlCg7XNiivTJsC1"; + }; + + rob = { + uid = 10057; + primary-group = "selby"; + common-name = "Robert Selby"; + ldap-hashed-password = "{crypt}HD1ESf1hAGdks"; + }; + + tarbash = { + uid = 10059; + primary-group = "fudo"; + common-name = "Neville"; + ldap-hashed-password = "{crypt}$1$cE6lVNbC$PLjlE9vK77SKNKwJBKiT//"; + }; + + darryl = { + uid = 10060; + primary-group = "selby"; + common-name = "Darryl Kissick"; + ldap-hashed-password = "{crypt}$1$oUNTMyKU$oUs6JqBRTPKE9A/sEzlSY0"; + }; + + ayumi = { + uid = 10061; + primary-group = "fudo"; + common-name = "Ayumi Kira"; + ldap-hashed-password = "{MD5}5OkpooOLxw94nF1lOfn/ZQ=="; + }; + + saphira = { + uid = 10063; + primary-group = "fudo"; + common-name = "Elizabeth Stewart"; + ldap-hashed-password = "{crypt}$1$cQ/Zq25x$fUQfUtpMB.f3rBWzttPns."; + }; + + banen = { + uid = 10064; + primary-group = "fudo"; + common-name = "Travis Neis"; + ldap-hashed-password = "{crypt}$1$cyfM/Vni$vIuirRln.MnWActOR6t8S."; + }; + + xiaoxuan = { + uid = 10065; + primary-group = "fudo"; + common-name = "Xiaoxuan Jin"; + ldap-hashed-password = "{MD5}iecbyMpyVkmOaMBzSFy58Q=="; + login-hashed-password = + "$6$C8lYHrK7KvdKm/RE$cHZ2hg5gEOEjTV8Zoayik8sz5h.Vh0.ClCgOlQn8l/2Qx/qdxqZ7xCsAZ1GZ.IEyESfhJeJbjLpykXDwPpfVF0"; + }; + + thibor = { + uid = 10066; + primary-group = "fudo"; + common-name = ""; + ldap-hashed-password = "{crypt}$1$HzQOn3zV$ogkeS5ByWrFstYo0FhXB/."; + }; + + flowchart = { + uid = 10067; + primary-group = "fudo"; + common-name = "BH Bieterse"; + ldap-hashed-password = "{crypt}$1$lQMZ42RZ$aAOsLHP0i.yfvD1a1EVsA/"; + }; + + gubbs = { + uid = 10068; + primary-group = "fudo"; + common-name = "Lorcan Gavin"; + ldap-hashed-password = "{MD5}AIf4bJZyHCnvJVL3YHRnIg=="; + }; + + debo = { + uid = 10069; + primary-group = "fudo"; + common-name = "Deborah Osti"; + ldap-hashed-password = "{crypt}$1$5wEBGh/8$Ggp2JAI/rQiBXxJ89G0iq1"; + }; + + leefolio = { + uid = 10070; + primary-group = "fudo"; + common-name = "Ze Artiste"; + ldap-hashed-password = "{crypt}$1$LRlAYBst$sS1bPu8yEPrdYkQhoZhAq1"; + }; + + zimm = { + uid = 10071; + primary-group = "fudo"; + common-name = "Ross Drinkwater"; + ldap-hashed-password = "{SSHA}er1cgYDNPJsfLwtqYLopKMGMxiZZRGdY"; + }; + + gaijin = { + uid = 10072; + primary-group = "fudo"; + common-name = "Tetsuo Torigai"; + ldap-hashed-password = "{crypt}$1$bw8hyDXm$pMLLUtlDlVLwBTZiC0Lzf0"; + }; + + anorthe = { + uid = 10073; + primary-group = "fudo"; + common-name = "Bonnie Wong"; + ldap-hashed-password = "{crypt}$1$DORfHzbp$nJkk0OXd7WzYDxx8LbdMK."; + }; + + stewartd = { + uid = 10076; + primary-group = "fudo"; + common-name = "Dwight Stewart"; + ldap-hashed-password = "{MD5}e2GSmH+l4ZZ808snWsFNYw=="; + }; + + jess = { + uid = 10078; + primary-group = "selby"; + common-name = "Jessica Selby"; + ldap-hashed-password = "{MD5}2tbtZre16apUTNtRIK98nQ=="; + }; + + kevin = { + uid = 10079; + primary-group = "selby"; + common-name = "Kevin Selby"; + ldap-hashed-password = "{crypt}$1$UYKrkMEe$SAABgc1pCBYgPFIMepNrM."; + }; + + theblacksun = { + uid = 10080; + primary-group = "fudo"; + common-name = "Brendan Goodfellow"; + ldap-hashed-password = "{MD5}Hmw6pFYYT87nmpLp0QxcQw=="; + }; + + kris = { + uid = 10082; + primary-group = "selby"; + common-name = "Kris Huberdeau"; + ldap-hashed-password = "{SSHA}RUYeAEUyblnCWa9uBzY9nwsmoksy8P3Y"; + }; + + jun = { + uid = 10083; + primary-group = "fudo"; + common-name = "Junichi Suzuki"; + ldap-hashed-password = "{crypt}$1$ExfgQXb8$b1ihvMRbG2dWbnlmzzI/h."; + }; + + jinny = { + uid = 10084; + primary-group = "fudo"; + common-name = "Hye-jin Kim"; + ldap-hashed-password = "{crypt}$1$6cld82N8$5a9ovCPXSacDmK3TWDaF30"; + }; + + helen = { + uid = 10086; + primary-group = "selby"; + common-name = "Helen Selby"; + ldap-hashed-password = "{SSHA}uckUXX09MjYq9++sF3f9b2IY8a9UBIxm"; + }; + + vee = { + uid = 10087; + primary-group = "selby"; + common-name = "Vee Selby"; + ldap-hashed-password = "snoinuer"; + }; + + dabar = { + uid = 10088; + primary-group = "fudo"; + common-name = "Dan Bernardic"; + ldap-hashed-password = "{MD5}ULrk46YUeUZQrl0+wAQiWA=="; + }; + + r3d3 = { + uid = 10089; + primary-group = "fudo"; + common-name = "Derek Veroni"; + ldap-hashed-password = "{SHA}2XyijGDovUhA1/Z/XR+9h9Ia4fY="; + }; + + laura = { + uid = 10090; + primary-group = "selby"; + common-name = "Laura Selby"; + ldap-hashed-password = "{MD5}MI65czN0duIudMhYH+BU9Q=="; + }; + + tuk = { + uid = 10091; + primary-group = "fudo"; + common-name = "Taku Koba"; + ldap-hashed-password = "{MD5}DQuoQluy50128r8MxAmFkQ=="; + }; + + aki = { + uid = 10092; + primary-group = "fudo"; + common-name = "Akihito Mori"; + ldap-hashed-password = "{MD5}oGAt2kJGKMqX+CmfV1w/GA=="; + }; + + ansyg = { + uid = 10095; + primary-group = "fudo"; + common-name = "Anseok Joo"; + ldap-hashed-password = "{MD5}AHhHl02D3uDmWhPJZ6QPOw=="; + }; + + jackie = { + uid = 10097; + primary-group = "selby"; + common-name = "Jackie Selby"; + ldap-hashed-password = "{MD5}fa6JfWySlH63sITsxrTt0Q=="; + }; + + mtopf = { + uid = 10100; + primary-group = "fudo"; + common-name = "Michael Topf"; + ldap-hashed-password = "{MD5}/pleD8SiLhmnRr1RVspNcA=="; + }; + + tat = { + uid = 10101; + primary-group = "fudo"; + common-name = "Tatsuro Akano"; + ldap-hashed-password = "{MD5}fAV5GX8UdjsXIFjU0Ex4SA=="; + }; + + blatzkrieg = { + uid = 10102; + primary-group = "fudo"; + common-name = "Brendan Blatz"; + ldap-hashed-password = "{MD5}1nE/ndFwGbfH/wLagxvt8w=="; + }; + + ellie = { + uid = 10103; + primary-group = "fudo"; + common-name = "Ellie Lee"; + ldap-hashed-password = "{MD5}gzjwt+kw2nmvJ1FKFTpSZA=="; + }; + + alan = { + uid = 10104; + primary-group = "fudo"; + common-name = "Alan Wong"; + ldap-hashed-password = "{MD5}WhohVE4xfo9RIOw1kG3s1Q=="; + }; + + omefire = { + uid = 10105; + primary-group = "fudo"; + common-name = "Omar Mefire"; + ldap-hashed-password = "{SSHA}W6KWo26wl/nawpV++wMqsKdwrIwrait5"; + }; + + gordon = { + uid = 10106; + primary-group = "fudo"; + common-name = "Gordon Stewart"; + ldap-hashed-password = "{SSHA}jaCOc1ZjCI9klVR+v676lIBOidEg7/u0"; + }; + + jeramy = { + uid = 10107; + primary-group = "selby"; + common-name = "Jeramy Ewbank"; + ldap-hashed-password = "{MD5}8j8vTniyRzylmeTNUoRwWA=="; + }; + + lauren = { + uid = 10108; + primary-group = "selby"; + common-name = "Lauren Hotel"; + ldap-hashed-password = "{SSHA}1q/MC5LKROlIT1nDrKrMvcFAXFtcQXIR"; + # ldap-hashed-password = "{SSHA}DKnhrycmXSu4HKWFPeBXA9xvZ0ytgXIpZA10tg=="; + }; + + # Used to send alerts from grafana + metrics = { + uid = 10109; + primary-group = "fudo"; + common-name = "Fudo Metrics"; + ldap-hashed-password = "{SSHA}FveEVy6kljQZey0xp0nF62SMlO5nATJ1"; + }; + + testuser = { + uid = 10110; + primary-group = "fudo"; + common-name = "Test User"; + ldap-hashed-password = "{SSHA}LSz1WjWfjRwAM3xm+QZ71vFj997dnZC6"; + }; + + # Used to send messages from the chat server + chat = { + uid = 10111; + primary-group = "fudo"; + common-name = "Fudo Chat"; + ldap-hashed-password = "{SSHA}XDYAM2JE4PXssywRzO4tVSbn5lUZOgg7"; + }; + + kevinyinjunjie = { + uid = 10112; + primary-group = "fudo"; + common-name = "Kevin"; + ldap-hashed-password = "{SSHA}1onx6HPMKCJvmLnRf1tiWFJ1D92DEtnl"; + }; + + netinfo = { + uid = 10113; + primary-group = "fudo"; + common-name = "Network Info Mailer"; + ldap-hashed-password = "{SSHA}UQHfW0IzjIbRU6VV+DraxvZFWt0to3oc"; + }; + + selby-forum = { + uid = 10114; + primary-group = "selby"; + common-name = "Selby Forum"; + ldap-hashed-password = "{SSHA}f7eDNuwFXRhvants5cJJ/FGtkCKheY2Q"; + }; + }; +} diff --git a/config/wireless-networks.nix b/config/wireless-networks.nix new file mode 100644 index 0000000..60a4461 --- /dev/null +++ b/config/wireless-networks.nix @@ -0,0 +1,11 @@ +{ config, lib, pkgs, ... }: + +{ + config.fudo.wireless-networks = { + "sea.fudo.org" = { key = "DahHaocheiD5"; }; + + "Pixel_9041" = { key = "ea72027e4e6"; }; + + "rus.selby.ca" = { key = "r204t683s2341"; }; + }; +} diff --git a/default.nix b/default.nix new file mode 100644 index 0000000..3585049 --- /dev/null +++ b/default.nix @@ -0,0 +1,10 @@ +{ config, lib, pkgs, local-hostname ? builtins.readFile ./instance-hostname.txt +, ... }: + +let local-hostname = builtins.readFile ./instance-hostname.txt; + +in { + lib = lib // { fudo = import ./lib/fudolib.nix { }; }; + instance.hostname = local-hostname; + imports = [ ./lib ./config ./hardware.nix ]; +} diff --git a/defaults.nix b/defaults.nix index 9cb1c34..1465310 100644 --- a/defaults.nix +++ b/defaults.nix @@ -157,8 +157,8 @@ in { }; environment.shellInit = '' - gpg-connect-agent /bye - export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket) + ${pkgs.gnupg}/bin/gpg-connect-agent /bye + export SSH_AUTH_SOCK=$(${pkgs.gnupg}/bin/gpgconf --list-dirs agent-ssh-socket) ''; security.pam = { diff --git a/fudo/profiles/laptop.nix b/fudo/profiles/laptop.nix index dfb41fc..4064377 100644 --- a/fudo/profiles/laptop.nix +++ b/fudo/profiles/laptop.nix @@ -11,11 +11,7 @@ with lib; }; }; config = mkIf (config.fudo.common.profile == "laptop") { - environment.systemPackages = with pkgs; [ - acpi - upower - wpa_supplicant - ]; + environment.systemPackages = with pkgs; [ acpi upower wpa_supplicant ]; networking = if (config.fudo.laptop.use-network-manager) then { networkmanager.enable = true; @@ -25,15 +21,11 @@ with lib; enable = true; userControlled = { enable = true; - group = "wheel"; + group = "wheel"; }; networks = { - "sea.fudo.org" = { - psk = "DahHaocheiD5"; - }; - "Pixel_9041" = { - psk = "ea72027e4e6"; - }; + "sea.fudo.org" = { psk = "DahHaocheiD5"; }; + "Pixel_9041" = { psk = "ea72027e4e6"; }; }; }; }; diff --git a/fudo/sites/seattle.nix b/fudo/sites/seattle.nix index 9a0384b..6989a3d 100644 --- a/fudo/sites/seattle.nix +++ b/fudo/sites/seattle.nix @@ -8,7 +8,7 @@ let gateway = "10.0.0.1"; - nameservers = ["10.0.0.1"]; + nameservers = [ "10.0.0.1" ]; in { @@ -16,26 +16,23 @@ in { time.timeZone = "America/Los_Angeles"; - services.printing = { - enable = true; - }; + services.printing = { enable = true; }; - services.cron = { - mailto = admin; - }; + services.cron = { mailto = admin; }; krb5.libdefaults.default_realm = "FUDO.ORG"; networking = { domain = local-domain; - search = [local-domain "fudo.org"]; + search = [ local-domain "fudo.org" ]; firewall.enable = false; nameservers = nameservers; # Don't set the gateway if we ARE the gateway. # This is the most generic way I can think of to do that. local-network is really # about running all the local servers (DNS, DHCP, and providing gateway). - defaultGateway = optionalString (config.fudo.local-network.enable != true) gateway; + defaultGateway = + optionalString (config.fudo.local-network.enable != true) gateway; enableIPv6 = true; @@ -43,7 +40,10 @@ in { # needs the full reverse-lookup name of the server, the latter wants # `hostname` to return just the host itself. hosts = { - "127.0.0.1" = [ "${config.networking.hostName}.${local-domain}" config.networking.hostName]; + "127.0.0.1" = [ + "${config.networking.hostName}.${local-domain}" + config.networking.hostName + ]; }; }; @@ -52,27 +52,32 @@ in { isNormalUser = true; uid = 1000; description = "Guest User"; - extraGroups = ["audio" "video" "disk" "floppy" "lp" "cdrom" "tape" "input"]; + extraGroups = + [ "audio" "video" "disk" "floppy" "lp" "cdrom" "tape" "input" ]; }; ken = { isNormalUser = true; uid = 10035; createHome = true; description = "Ken Selby"; - extraGroups = ["audio" "video" "disk" "floppy" "lp" "cdrom" "tape" "input"]; + extraGroups = + [ "audio" "video" "disk" "floppy" "lp" "cdrom" "tape" "input" ]; group = "users"; home = "/home/selby/ken"; - hashedPassword = "$6$EwK9fpbH8$gYVzYY1IYw2/G0wCeUxXrZZqvjWCkCZbBqCOhxowbMuYtC5G0vp.AoYhVKWOJcHJM2c7TdPmAdnhLIe2KYStf."; + hashedPassword = + "$6$EwK9fpbH8$gYVzYY1IYw2/G0wCeUxXrZZqvjWCkCZbBqCOhxowbMuYtC5G0vp.AoYhVKWOJcHJM2c7TdPmAdnhLIe2KYStf."; }; xiaoxuan = { isNormalUser = true; uid = 10065; createHome = true; description = "Xiaoxuan Jin"; - extraGroups = ["audio" "video" "disk" "floppy" "lp" "cdrom" "tape" "input"]; + extraGroups = + [ "audio" "video" "disk" "floppy" "lp" "cdrom" "tape" "input" ]; group = "users"; 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; @@ -122,7 +127,8 @@ in { kdc = "nostromo"; photo = "doraemon"; music = "doraemon"; - panopticon = "hyperion"; + panopticon = "lambda"; + panopticon-od = "lambda"; ipfs = "nostromo"; hole = "nostromo"; pihole = "nostromo"; @@ -310,7 +316,6 @@ in { mac-address = "94:10:3e:48:94:ed"; }; - # Ceph network srv-1 = { ip-address = "10.0.10.1"; diff --git a/hardware.nix b/hardware.nix new file mode 100644 index 0000000..38da2f0 --- /dev/null +++ b/hardware.nix @@ -0,0 +1,6 @@ +{ config, ... }: + +{ + imports = + [ config.fudo.hosts."${config.fudo.instance.hostname}".hardware-config ]; +} diff --git a/home-manager/niten.nix b/home-manager/niten.nix new file mode 100644 index 0000000..f62858b --- /dev/null +++ b/home-manager/niten.nix @@ -0,0 +1,106 @@ +{ config, lib, pkgs, ... }: + +let + name = "Niten"; + email = "niten@fudo.org"; + + packages = with pkgs; [ + asdf + atop + binutils + btrfs-progs + bundix + byobu + cdrtools + cargo + curl + doomEmacsInit + enca + file + fortune + git + gnupg + guile + imagemagick + ipfs + iptables + jq + leiningen + libisofs + lispPackages.quicklisp + lsof + lshw + mkpasswd + mtr + nixfmt + nix-index + nix-prefetch-git + nmap + openldap + pciutils + pv + pwgen + ruby + rustc + sbcl + signal-desktop + stdenv + telnet + texlive.combined.scheme-basic + tmux + unzip + xclip + yubikey-manager + yubikey-personalization + ]; + +in { + programs = { + bash = { enable = true; }; + + git = { + enable = true; + userName = name; + userEmail = email; + }; + }; + + xresources.properties = { + "Xft.antialias" = 1; + "Xft.autohint" = 0; + "Xft.dpi" = 192; + "Xft.hinting" = 1; + "Xft.hintstyle" = "hintfull"; + "Xft.lcdfilter" = "lcddefault"; + }; + + services.gpg-agent.enable = true; + + home = { + packages = packages; + + file = { + ".doom.d" = { + source = pkgs.doom-emacs-config; + recursive = true; + onChange = "${pkgs.doomEmacsInit}/bin/doom-emacs-init.sh"; + }; + + ".k5login" = { + source = pkgs.writeText "niten-k5login" '' + niten@FUDO.ORG + niten/root@FUDO.ORG + niten@INFORMIS.LAND + niten/root@INFORMIS.LAND + ''; + }; + }; + + sessionVariables = { + EDITOR = "emacsclient -t"; + ALTERNATE_EDITOR = ""; + + HISTCONTROL = "ignoredups:ignorespace"; + }; + }; +} diff --git a/home-manager/root.nix b/home-manager/root.nix new file mode 100644 index 0000000..ad5db06 --- /dev/null +++ b/home-manager/root.nix @@ -0,0 +1,39 @@ +{ config, lib, pkgs, ... }: + +let + name = "Root"; + email = "root@fudo.org"; + +in { + programs = { + git = { + enable = true; + userName = name; + userEmail = email; + }; + }; + + home = { + file = { + ".doom.d" = { + source = pkgs.doom-emacs-config; + recursive = true; + onChange = "${pkgs.doomEmacsInit}/bin/doom-emacs-init.sh"; + }; + + ".k5login" = { + source = pkgs.writeText "niten-k5login" '' + niten/root@FUDO.ORG + niten/root@INFORMIS.LAND + ''; + }; + }; + + sessionVariables = { + EDITOR = "emacsclient -t"; + ALTERNATE_EDITOR = ""; + + HISTCONTROL = "ignoredups:ignorespace"; + }; + }; +} diff --git a/hosts/clunk.nix b/hosts/clunk.nix index b93770a..0c34d35 100644 --- a/hosts/clunk.nix +++ b/hosts/clunk.nix @@ -12,16 +12,11 @@ in { boot.loader.systemd-boot.enable = true; boot.loader.efi.canTouchEfiVariables = true; - boot = { - runSize = "50%"; - }; + boot = { runSize = "50%"; }; hardware.bluetooth.enable = false; - imports = [ - ../defaults.nix - ../hardware-configuration.nix - ]; + imports = [ ../defaults.nix ../hardware-configuration.nix ]; fudo.common = { profile = "server"; @@ -66,7 +61,7 @@ in { intif0 = { useDHCP = false; - # Result of: + # Result of: # echo clunk-intif0|md5sum|sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:\1:\2:\3:\4:\5/' macAddress = "02:44:d1:eb:c3:6b"; ipv4.addresses = [ @@ -86,7 +81,7 @@ in { nat = { enable = true; externalInterface = "enp1s0"; - internalInterfaces = ["intif0"]; + internalInterfaces = [ "intif0" ]; }; }; @@ -105,13 +100,11 @@ in { #"https://9.9.9.9/dns-query" ]; bootstrap-dns = "1.1.1.1"; - listen-ips = [dns-proxy-ip]; + listen-ips = [ dns-proxy-ip ]; }; }; - environment.systemPackages = with pkgs; [ - dnsproxy - ]; + environment.systemPackages = with pkgs; [ dnsproxy ]; virtualisation = { docker = { @@ -124,11 +117,7 @@ in { docker-containers = { pihole = { image = "pihole/pihole:v5.1.2"; - ports = [ - "5353:53/tcp" - "5353:53/udp" - "3080:80/tcp" - ]; + ports = [ "5353:53/tcp" "5353:53/udp" "3080:80/tcp" ]; environment = { ServerIP = host-internal-ip; VIRTUAL_HOST = "dns-hole.rus.selby.ca"; @@ -163,12 +152,12 @@ in { 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; - ''; + 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; + ''; }; }; }; diff --git a/hosts/nostromo.nix b/hosts/nostromo.nix index 2ed9609..fdd05b7 100644 --- a/hosts/nostromo.nix +++ b/hosts/nostromo.nix @@ -191,26 +191,48 @@ in { api-address = "/ip4/${host-internal-ip}/tcp/5001"; }; + security.acme.certs."sea-camera.fudo.link".email = "niten@fudo.org"; + security.acme.certs."sea-camera-od.fudo.link".email = "niten@fudo.org"; + services = { nginx = { enable = true; + recommendedGzipSettings = true; + recommendedOptimisation = true; + recommendedTlsSettings = true; + recommendedProxySettings = true; virtualHosts = { - "pihole.sea.fudo.org" = { - serverAliases = [ "dns-hole.sea.fudo.org" "hole.sea.fudo.org" ]; - + "sea-camera.fudo.link" = { + enableACME = true; + forceSSL = true; locations."/" = { - proxyPass = "http://127.0.0.1:3080"; - + proxyPass = "http://panopticon.sea.fudo.org/"; 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; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; ''; }; }; + + "sea-camera-od.fudo.link" = { + enableACME = true; + forceSSL = true; + locations."/" = { + proxyPass = "http://panopticon-od.sea.fudo.org/"; + extraConfig = '' + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + ''; + }; + }; + + "pihole.sea.fudo.org" = { + serverAliases = [ "dns-hole.sea.fudo.org" "hole.sea.fudo.org" ]; + locations."/" = { proxyPass = "http://127.0.0.1:3000"; }; + }; }; }; }; diff --git a/lib/default.nix b/lib/default.nix new file mode 100644 index 0000000..770da01 --- /dev/null +++ b/lib/default.nix @@ -0,0 +1,36 @@ +{ lib, config, pkgs, ... }: + +with lib; { + imports = [ + ./instance.nix + + ./fudo/acme-for-hostname.nix + ./fudo/authentication.nix + ./fudo/backplane + ./fudo/chat.nix + ./fudo/client/dns.nix + ./fudo/dns.nix + ./fudo/garbage-collector.nix + ./fudo/git.nix + ./fudo/grafana.nix + ./fudo/ipfs.nix + ./fudo/kdc.nix + ./fudo/ldap.nix + ./fudo/local-network.nix + ./fudo/mail.nix + ./fudo/mail-container.nix + ./fudo/minecraft-server.nix + ./fudo/netinfo-email.nix + ./fudo/node-exporter.nix + ./fudo/password.nix + ./fudo/postgres.nix + ./fudo/prometheus.nix + ./fudo/secure-dns-proxy.nix + ./fudo/slynk.nix + ./fudo/system.nix + ./fudo/vpn.nix + ./fudo/webmail.nix + + ./informis/cl-gemini.nix + ]; +} diff --git a/config/fudo/acme-for-hostname.nix b/lib/fudo/acme-for-hostname.nix similarity index 100% rename from config/fudo/acme-for-hostname.nix rename to lib/fudo/acme-for-hostname.nix diff --git a/config/fudo/authentication.nix b/lib/fudo/authentication.nix similarity index 100% rename from config/fudo/authentication.nix rename to lib/fudo/authentication.nix diff --git a/config/fudo/backplane/default.nix b/lib/fudo/backplane/default.nix similarity index 100% rename from config/fudo/backplane/default.nix rename to lib/fudo/backplane/default.nix diff --git a/config/fudo/backplane/dns.nix b/lib/fudo/backplane/dns.nix similarity index 100% rename from config/fudo/backplane/dns.nix rename to lib/fudo/backplane/dns.nix diff --git a/config/fudo/chat.nix b/lib/fudo/chat.nix similarity index 100% rename from config/fudo/chat.nix rename to lib/fudo/chat.nix diff --git a/config/fudo/client/dns.nix b/lib/fudo/client/dns.nix similarity index 100% rename from config/fudo/client/dns.nix rename to lib/fudo/client/dns.nix diff --git a/lib/fudo/common.nix b/lib/fudo/common.nix new file mode 100644 index 0000000..98220d9 --- /dev/null +++ b/lib/fudo/common.nix @@ -0,0 +1,65 @@ +# General Fudo config, shared across packages +{ config, lib, pkgs, ... }: + +with lib; { + options.fudo.common = { + + hostname = mkOption { + type = types.str; + description = '' + Hostname of the local host (without domain). + ''; + }; + + # domain = mkOption { + # type = types.str; + # description = '' + # Domain of the local network. + # ''; + # }; + + # local-networks = mkOption { + # type = with types; listOf str; + # description = '' + # A list of networks to consider 'local'. Used by various services to + # limit access to the external world. + # ''; + # default = [ ]; + # }; + + # profile = mkOption { + # type = with types; nullOr str; + # example = "desktop"; + # description = '' + # The profile to use for this host. This will do some profile-dependent + # configuration, for example removing X-libs from servers and adding UI + # packages to desktops. + # ''; + # default = null; + # }; + + # site = mkOption { + # type = with types; nullOr str; + # example = "seattle"; + # description = '' + # The site at which this host is located. This will do some site-dependent + # configuration. + # ''; + # default = null; + # }; + + # www-root = mkOption { + # type = types.path; + # description = "Path at which to store www files for serving."; + # example = /var/www; + # }; + + # admin-email = mkOption { + # type = types.str; + # description = "Email for administrator of this system."; + # default = "admin@fudo.org"; + # }; + + # enable-gui = mkEnableOption "Install desktop GUI software."; + }; +} diff --git a/config/fudo/dns.nix b/lib/fudo/dns.nix similarity index 53% rename from config/fudo/dns.nix rename to lib/fudo/dns.nix index 6a345ef..8188bce 100644 --- a/config/fudo/dns.nix +++ b/lib/fudo/dns.nix @@ -7,14 +7,14 @@ let join-lines = concatStringsSep "\n"; - hostOpts = { host, ...}: { + hostOpts = { host, ... }: { options = { ip-addresses = mkOption { type = with types; listOf str; description = '' A list of IPv4 addresses assigned to this host. ''; - default = []; + default = [ ]; }; ipv6-addresses = mkOption { @@ -22,7 +22,7 @@ let description = '' A list of IPv6 addresses assigned to this host. ''; - default = []; + default = [ ]; }; ssh-fingerprints = mkOption { @@ -30,7 +30,7 @@ let description = '' A list of DNS SSHFP records for this host. ''; - default = []; + default = [ ]; }; description = mkOption { @@ -74,96 +74,101 @@ let }; }; - domainOpts = { domain, ... }: with types; { - options = { - hosts = mkOption { - type = loaOf (submodule hostOpts); - default = {}; - description = "A map of hostname to { host_attributes }."; - }; + domainOpts = { domain, ... }: + with types; { + options = { + hosts = mkOption { + type = loaOf (submodule hostOpts); + default = { }; + description = "A map of hostname to { host_attributes }."; + }; - dnssec = mkOption { - type = bool; - description = "Enable DNSSEC security for this zone."; - default = true; - }; + dnssec = mkOption { + type = bool; + description = "Enable DNSSEC security for this zone."; + default = true; + }; - mx = mkOption { - type = listOf str; - description = "A list of mail servers serving this domain."; - default = []; - }; + mx = mkOption { + type = listOf str; + description = "A list of mail servers serving this domain."; + default = [ ]; + }; - srv-records = mkOption { - type = attrsOf (attrsOf (listOf (submodule srvRecordOpts))); - description = "Map of traffic type to srv records."; - default = {}; - example = { - tcp = { - kerberos = { - port = 88; - host = "auth-host.my-domain.com"; + srv-records = mkOption { + type = attrsOf (attrsOf (listOf (submodule srvRecordOpts))); + description = "Map of traffic type to srv records."; + default = { }; + example = { + tcp = { + kerberos = { + port = 88; + host = "auth-host.my-domain.com"; + }; }; }; }; - }; - aliases = mkOption { - type = loaOf str; - default = {}; - description = "A mapping of host-alias => hostnames to add to DNS."; - example = { - "music" = "host.dom.com."; - "mail" = "hostname"; + aliases = mkOption { + type = loaOf str; + default = { }; + description = "A mapping of host-alias => hostnames to add to DNS."; + example = { + "music" = "host.dom.com."; + "mail" = "hostname"; + }; + }; + + extra-dns-records = mkOption { + type = listOf str; + description = "Records to be inserted verbatim into the DNS zone."; + example = [ "some-host IN CNAME base-host" ]; + default = [ ]; + }; + + dmarc-report-address = mkOption { + type = nullOr str; + description = "The email to use to recieve DMARC reports, if any."; + example = "admin-user@domain.com"; + default = null; + }; + + default-host = mkOption { + type = nullOr str; + description = + "IP of the host which will act as the default server for this domain, if any."; + default = null; }; }; - - extra-dns-records = mkOption { - type = listOf str; - description = "Records to be inserted verbatim into the DNS zone."; - example = ["some-host IN CNAME base-host"]; - default = []; - }; - - dmarc-report-address = mkOption { - type = nullOr str; - description = "The email to use to recieve DMARC reports, if any."; - example = "admin-user@domain.com"; - default = null; - }; - - default-host = mkOption { - type = nullOr str; - description = "IP of the host which will act as the default server for this domain, if any."; - default = null; - }; }; - }; hostRecords = host: data: - join-lines ((map (ip: "${host} IN A ${ip}") data.ip-addresses) ++ - (map (ip: "${host} IN AAAA ${ip}") data.ipv6-addresses) ++ - (map (sshfp: "${host} IN SSHFP ${sshfp}") data.ssh-fingerprints) ++ - (optional (data.rp != null) "${host} IN RP ${data.rp}") ++ - (optional (data.description != null) "${host} IN TXT ${data.description}")); + join-lines ((map (ip: "${host} IN A ${ip}") data.ip-addresses) + ++ (map (ip: "${host} IN AAAA ${ip}") data.ipv6-addresses) + ++ (map (sshfp: "${host} IN SSHFP ${sshfp}") data.ssh-fingerprints) + ++ (optional (data.rp != null) "${host} IN RP ${data.rp}") + ++ (optional (data.description != null) + "${host} IN TXT ${data.description}")); makeSrvRecords = protocol: type: records: - join-lines (map (record: "_${type}._${protocol} IN SRV ${toString record.priority} ${toString record.weight} ${toString record.port} ${toString record.host}.") - records); + join-lines (map (record: + "_${type}._${protocol} IN SRV ${toString record.priority} ${ + toString record.weight + } ${toString record.port} ${toString record.host}.") records); - makeSrvProtocolRecords = protocol: types: join-lines (mapAttrsToList (makeSrvRecords protocol) types); + makeSrvProtocolRecords = protocol: types: + join-lines (mapAttrsToList (makeSrvRecords protocol) types); cnameRecord = alias: host: "${alias} IN CNAME ${host}"; - mxRecords = mxs: - concatStringsSep "\n" - (map (mx: "@ IN MX 10 ${mx}.") mxs); + mxRecords = mxs: concatStringsSep "\n" (map (mx: "@ IN MX 10 ${mx}.") mxs); dmarcRecord = dmarc-email: - optionalString (dmarc-email != null) - ''_dmarc IN TXT "v=DMARC1;p=quarantine;sp=quarantine;rua=mailto:${dmarc-email};"''; + optionalString (dmarc-email != null) '' + _dmarc IN TXT "v=DMARC1;p=quarantine;sp=quarantine;rua=mailto:${dmarc-email};"''; - nsRecords = dom: ns-hosts: join-lines (mapAttrsToList (host: _: "@ IN NS ${host}.${dom}.") ns-hosts); + nsRecords = dom: ns-hosts: + join-lines (mapAttrsToList (host: _: "@ IN NS ${host}.${dom}.") ns-hosts); in { @@ -177,7 +182,7 @@ in { example = { "ns1.domain.com" = { ip-addresses = [ "1.1.1.1" ]; - ipv6-addresses = []; + ipv6-addresses = [ ]; description = "my fancy dns server"; }; }; @@ -190,14 +195,14 @@ in { domains = mkOption { type = loaOf (submodule domainOpts); - default = {}; + default = { }; description = "A map of domain to domain options."; }; listen-ips = mkOption { type = listOf str; description = "A list of IPs on which to listen for DNS queries."; - example = ["1.2.3.4"]; + example = [ "1.2.3.4" ]; }; }; @@ -221,7 +226,8 @@ in { 6w 5m) - ${optionalString (dom-cfg.default-host != null) "@ IN A ${dom-cfg.default-host}"} + ${optionalString (dom-cfg.default-host != null) + "@ IN A ${dom-cfg.default-host}"} ${mxRecords dom-cfg.mx} @@ -232,7 +238,8 @@ in { ${dmarcRecord dom-cfg.dmarc-report-address} - ${join-lines (mapAttrsToList makeSrvProtocolRecords dom-cfg.srv-records)} + ${join-lines + (mapAttrsToList makeSrvProtocolRecords dom-cfg.srv-records)} ${join-lines (mapAttrsToList hostRecords dom-cfg.hosts)} ${join-lines (mapAttrsToList cnameRecord dom-cfg.aliases)} ${join-lines dom-cfg.extra-dns-records} diff --git a/lib/fudo/domains.nix b/lib/fudo/domains.nix new file mode 100644 index 0000000..0d9a674 --- /dev/null +++ b/lib/fudo/domains.nix @@ -0,0 +1,52 @@ +{ config, lib, pkgs, ... }: + +let + domainOpts = { domain, ... }: { + options = { + domain = mkOption { + type = types.str; + description = "Domain name."; + default = domain; + }; + + local-networks = mkOption { + type = with types; listOf str; + description = + "A list of networks to be considered trusted on this network."; + default = [ ]; + }; + + local-users = mkOption { + type = with types; listOf str; + description = + "A list of users who should have local (i.e. login) access to _all_ hosts in this domain."; + default = [ ]; + }; + + local-admins = mkOption { + type = with types; listOf str; + description = + "A list of users who should have admin access to _all_ hosts in this domain."; + default = [ ]; + }; + + admin-email = mkOption { + type = types.str; + description = "Email for the administrator of this domain."; + default = "admin@fudo.org"; + }; + + gssapi-realm = mkOption { + type = with types; nullOr str; + description = "GSSAPI (i.e. Kerberos) realm of this domain."; + }; + }; + }; + +in { + options.fudo.domains = mkOption { + type = with types; attrsOf (submodule domainOpts); + description = "Domain configurations for all domains known to the system."; + default = { }; + }; +} diff --git a/config/fudo/garbage-collector.nix b/lib/fudo/garbage-collector.nix similarity index 100% rename from config/fudo/garbage-collector.nix rename to lib/fudo/garbage-collector.nix diff --git a/config/fudo/git.nix b/lib/fudo/git.nix similarity index 100% rename from config/fudo/git.nix rename to lib/fudo/git.nix diff --git a/config/fudo/grafana.nix b/lib/fudo/grafana.nix similarity index 100% rename from config/fudo/grafana.nix rename to lib/fudo/grafana.nix diff --git a/lib/fudo/hosts.nix b/lib/fudo/hosts.nix new file mode 100644 index 0000000..82a2a1c --- /dev/null +++ b/lib/fudo/hosts.nix @@ -0,0 +1,107 @@ +{ config, lib, pkgs, ... }: + +with lib; +let + hostOpts = { hostname, ... }: { + options = { + hostname = mkOption { + type = types.str; + description = "Hostname (without domain name)."; + default = hostname; + }; + + domain = mkOption { + type = types.str; + description = + "Domain to which the host belongs, in the form of a domain name."; + default = "fudo.org"; + }; + + local-networks = mkOption { + type = with types; listof str; + description = + "A list of networks to be considered trusted by this host."; + default = [ "127.0.0.0/8" ]; + }; + + profile = mkOption { + # FIXME: get this list from profiles directly + type = with types; + listof (enum "desktop" "laptop" "server" "gateway-server"); + description = + "The profile to be applied to the host, determining what software is included."; + }; + + admin-email = mkOption { + type = with types; nullOr str; + description = "Email for the administrator of this host."; + default = null; + }; + + hardware-configuration = mkOption { + type = types.attrs; + description = + "The hardware configuration of the host (i.e. the contents of hardware-configuration.nix)"; + }; + + local-users = mkOption { + type = with types; listOf str; + description = + "List of users who should have local (i.e. login) access to the host."; + default = [ ]; + }; + + local-admins = mkOption { + type = with types; listOf str; + description = + "A list of users who should have admin access to this host."; + default = [ ]; + }; + + enable-gui = mkEnableOption "Install desktop GUI software."; + + docker-server = mkEnableOption "Enable Docker on the current host."; + }; + }; + +in { + options.fudo.hosts = mkOption { + type = with types; attrsOf (submodule hostOpts); + description = "Host configurations for all hosts known to the system."; + default = { }; + }; + + config = let + hostname = config.instance.hostname; + host-cfg = config.fudo.hosts.${hostname}; + site-name = host-cfg.site; + site = config.fudo.site.${site-name}; + domain-name = host-cfg.domain; + domain = config.fudo.domain.${domain-name}; + + in { + networking = { + hostName = config.instance.hostname; + nameservers = site.nameservers; + defaultGateway = site.gateway-v4; + defaultGateway6 = site.gateway-v6; + + # Necessary to ensure that Kerberos and Avahi both work. Kerberos needs + # the fqdn of the host, whereas Avahi wants just the simple hostname.` + hosts = { "127.0.0.1" = [ "${hostname}.${domain-name}" "${hostname}" ]; }; + }; + + krb5.libdefaults.default_realm = domain.gssapi-realm; + + services.cron.mailto = domain.admin-email; + + environment.systemPackages = with pkgs; + mkIf (cfg.docker-server) [ docker nix-prefetch-docker ]; + + virtualisation.docker = mkIf (cfg.docker-server) { + enable = true; + enableOnBoot = true; + autoprune.enable = true; + }; + }; +} diff --git a/lib/fudo/hosts/local-network.nix b/lib/fudo/hosts/local-network.nix new file mode 100644 index 0000000..f4d2c70 --- /dev/null +++ b/lib/fudo/hosts/local-network.nix @@ -0,0 +1,142 @@ +# THROW THIS AWAY, NOT USED + +{ config, lib, pkgs, ... }: + +with lib; +let + cfg = config.fudo.hosts.local-network; + + gatewayServerOpts = { ... }: { + options = { + enable = mkEnableOption "Turn this host into a network gateway."; + + internal-interfaces = mkOption { + type = with types; listOf str; + description = + "List of internal interfaces from which to forward traffic."; + default = [ ]; + }; + + external-interface = mkOption { + type = types.str; + description = + "Interface facing public internet, to which traffic is forwarded."; + }; + + external-tcp-ports = mkOption { + type = with types; listOf port; + description = "List of TCP ports to open to the outside world."; + default = [ ]; + }; + + external-udp-ports = mkOption { + type = with types; listOf port; + description = "List of UDP ports to open to the outside world."; + default = [ ]; + }; + }; + }; + + dnsOverHttpsProxy = { + options = { + enable = mkEnableOption "Enable a DNS-over-HTTPS proxy server."; + + listen-port = mkOption { + type = types.port; + description = "Port on which to listen for DNS requests."; + default = 53; + }; + + upstream-dns = mkOption { + type = with types; listOf str; + description = "List of DoH DNS servers to use for recursion."; + default = [ ]; + }; + + bootstrap-dns = mkOption { + type = types.str; + description = "DNS server used to bootstrap the proxy server."; + default = "1.1.1.1"; + }; + }; + }; + + networkDhcpServerOpts = mkOption { + options = { + enable = mkEnableOption "Enable local DHCP server."; + + dns-servers = mkOption { + type = with types; listOf str; + description = "List of DNS servers for clients to use."; + default = [ ]; + }; + + listen-interfaces = mkOption { + type = with types; listOf str; + description = "List of interfaces on which to serve DHCP requests."; + default = [ ]; + }; + + server-ip = mkOption { + type = types.str; + description = "IP address of the server host."; + }; + }; + }; + + networkServerOpts = { + options = { + enable = mkEnableOption "Enable local networking server (DNS & DHCP)."; + + domain = mkOption { + type = types.str; + description = "Local network domain which this host will serve."; + }; + + dns-listen-addrs = mkOption { + type = with types; listOf str; + description = "List of IP addresses on which to listen for requests."; + default = [ ]; + }; + + dhcp = mkOption { + type = types.submodule networkDhcpServerOpts; + description = "Local DHCP server options."; + }; + }; + }; + +in { + options.fudo.hosts.local-network = with types; { + recursive-resolvers = mkOption { + type = listOf str; + description = "DNS server to use for recursive lookups."; + example = "1.2.3.4 port 53"; + }; + + gateway-server = mkOption { + type = submodule gatewayServerOpts; + description = "Gateway server options."; + }; + + dns-over-https-proxy = mkOption { + type = submodule dnsOverHttpsProxy; + description = "DNS-over-HTTPS proxy server."; + }; + + networkServerOpts = mkOption { + type = submodule networkServerOpts; + description = "Networking (DNS & DHCP) server for a local network."; + }; + }; + + config = { + fudo.secure-dns-proxy = mkIf cfg.dns-over-https-proxy.enable { + enable = true; + port = cfg.dns-over-https-proxy.listen-port; + upstream-dns = cfg.dns-over-https-proxy.upstream-dns; + bootstrap-dns = cfg.dns-over-https-proxy.bootstrap-dns; + listen-ips = cfg.dns-over-https-proxy.listen-ips; + }; + }; +} diff --git a/config/fudo/include/rainloop.nix b/lib/fudo/include/rainloop.nix similarity index 100% rename from config/fudo/include/rainloop.nix rename to lib/fudo/include/rainloop.nix diff --git a/config/fudo/ipfs.nix b/lib/fudo/ipfs.nix similarity index 100% rename from config/fudo/ipfs.nix rename to lib/fudo/ipfs.nix diff --git a/config/fudo/kdc.nix b/lib/fudo/kdc.nix similarity index 100% rename from config/fudo/kdc.nix rename to lib/fudo/kdc.nix diff --git a/config/fudo/ldap.nix b/lib/fudo/ldap.nix similarity index 73% rename from config/fudo/ldap.nix rename to lib/fudo/ldap.nix index d7a5578..2dc4fba 100644 --- a/config/fudo/ldap.nix +++ b/lib/fudo/ldap.nix @@ -19,6 +19,7 @@ let description = '' The password for this user, hashed with ldappasswd. ''; + default = ""; }; }; }; @@ -41,7 +42,7 @@ let members = mkOption { type = with types; listOf str; - default = []; + default = [ ]; description = '' A list of usernames representing the members of this group. ''; @@ -94,6 +95,7 @@ let description = '' The password for this user, hashed with ldappasswd. ''; + default = ""; }; }; }; @@ -102,12 +104,12 @@ let if (length attrList) == 0 then "" else - foldr(lAttr: rAttr: "${lAttr}${joiner}${rAttr}") (last attrList) (init attrList); + foldr (lAttr: rAttr: "${lAttr}${joiner}${rAttr}") (last attrList) + (init attrList); getUserGidNumber = user: group-map: group-map.${user.group}.gid; - attrOr = attrs: attr: value: - if attrs ? ${attr} then attrs.${attr} else value; + attrOr = attrs: attr: value: if attrs ? ${attr} then attrs.${attr} else value; mkHomeDir = username: user-opts: if (user-opts.group == "admin") then @@ -115,7 +117,6 @@ let else "/home/${user-opts.group}/${username}"; - userLdif = base: name: group-map: opts: '' dn: uid=${name},ou=members,${base} uid: ${name} @@ -123,15 +124,15 @@ let objectClass: shadowAccount objectClass: posixAccount cn: ${opts.common-name} - uidNumber: ${toString(opts.uid)} - gidNumber: ${toString(getUserGidNumber opts group-map)} + uidNumber: ${toString (opts.uid)} + gidNumber: ${toString (getUserGidNumber opts group-map)} homeDirectory: ${mkHomeDir name opts} description: ${opts.description} shadowLastChange: 12230 shadowMax: 99999 shadowWarning: 7 userPassword: ${opts.hashed-password} -''; + ''; systemUserLdif = base: name: opts: '' dn: cn=${name},${base} @@ -140,7 +141,7 @@ let cn: ${name} description: ${opts.description} userPassword: ${opts.hashed-password} -''; + ''; toMemberList = userList: stringJoin "\n" (map (username: "memberUid: ${username}") userList); @@ -149,25 +150,22 @@ let dn: cn=${name},ou=groups,${base} objectClass: posixGroup cn: ${name} - gidNumber: ${toString(opts.gid)} + gidNumber: ${toString (opts.gid)} description: ${opts.description} ${toMemberList opts.members} -''; + ''; systemUsersLdif = base: user-map: - stringJoin "\n" (mapAttrsToList (name: opts: - systemUserLdif base name opts - ) user-map); + stringJoin "\n" + (mapAttrsToList (name: opts: systemUserLdif base name opts) user-map); groupsLdif = base: group-map: - stringJoin "\n" (mapAttrsToList (name: opts: - groupLdif base name opts - ) group-map); + stringJoin "\n" + (mapAttrsToList (name: opts: groupLdif base name opts) group-map); usersLdif = base: group-map: user-map: - stringJoin "\n" (mapAttrsToList (name: opts: - userLdif base name group-map opts - ) user-map); + stringJoin "\n" + (mapAttrsToList (name: opts: userLdif base name group-map opts) user-map); in { @@ -236,19 +234,16 @@ in { }; listen-uris = mkOption { - default = []; + default = [ ]; type = with types; listOf str; description = '' A list of URIs on which the ldap server should listen. ''; - example = [ - "ldap://auth.fudo.org" - "ldaps://auth.fudo.org" - ]; + example = [ "ldap://auth.fudo.org" "ldaps://auth.fudo.org" ]; }; users = mkOption { - default = {}; + default = { }; type = with types; loaOf (submodule ldapUserOpts); example = { tester = { @@ -263,14 +258,12 @@ in { }; groups = mkOption { - default = {}; + default = { }; type = with types; loaOf (submodule ldapGroupOpts); example = { admin = { gid = 1099; - members = [ - "tester" - ]; + members = [ "tester" ]; }; }; description = '' @@ -279,7 +272,7 @@ in { }; system-users = mkOption { - default = {}; + default = { }; type = with types; loaOf (submodule ldapSystemUserOpts); example = { replicator = { @@ -313,9 +306,7 @@ in { }; systemd.services.openldap = { - environment = { - KRB5_KTNAME = cfg.kerberos-keytab; - }; + environment = { KRB5_KTNAME = cfg.kerberos-keytab; }; }; services.openldap = { @@ -330,7 +321,8 @@ in { TLSCertificateFile ${cfg.sslCert} TLSCertificateKeyFile ${cfg.sslKey} - ${optionalString (cfg.sslCACert != null) "TLSCACertificateFile ${cfg.sslCACert}"} + ${optionalString (cfg.sslCACert != null) + "TLSCACertificateFile ${cfg.sslCACert}"} authz-regexp "^uid=auth/([^.]+)\.fudo\.org,cn=fudo\.org,cn=gssapi,cn=auth$" "cn=$1,ou=hosts,dc=fudo,dc=org" authz-regexp "^uid=[^,/]+/root,cn=fudo\.org,cn=gssapi,cn=auth$" "cn=admin,dc=fudo,dc=org" @@ -341,55 +333,55 @@ in { ''; extraDatabaseConfig = '' -# access to dn=base="" -# by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage -# by * read + # access to dn=base="" + # by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage + # by * read -access to attrs=userPassword,shadowLastChange - by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage - by group.exact="cn=admin,ou=members,${cfg.base}" write - by dn.exact="cn=auth_reader,${cfg.base}" read - by dn.exact="cn=replicator,${cfg.base}" read - by self write - by * auth + access to attrs=userPassword,shadowLastChange + by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage + by group.exact="cn=admin,ou=members,${cfg.base}" write + by dn.exact="cn=auth_reader,${cfg.base}" read + by dn.exact="cn=replicator,${cfg.base}" read + by self write + by * auth -access to dn.exact="cn=admin,ou=groups,${cfg.base}" - by dn.exact="cn=admin,${cfg.base}" write - by users read - by * none + access to dn.exact="cn=admin,ou=groups,${cfg.base}" + by dn.exact="cn=admin,${cfg.base}" write + by users read + by * none -access to dn.subtree="ou=groups,${cfg.base}" attrs=memberUid - by dn.regex="cn=[a-zA-Z][a-zA-Z0-9_]+,ou=hosts,${cfg.base}" write - by group.exact="cn=admin,ou=groups,${cfg.base}" write - by users read - by * none + access to dn.subtree="ou=groups,${cfg.base}" attrs=memberUid + by dn.regex="cn=[a-zA-Z][a-zA-Z0-9_]+,ou=hosts,${cfg.base}" write + by group.exact="cn=admin,ou=groups,${cfg.base}" write + by users read + by * none -access to dn.subtree="ou=members,${cfg.base}" attrs=cn,sn,homeDirectory,loginShell,gecos,description,homeDirectory,uidNumber,gidNumber - by group.exact="cn=admin,ou=groups,${cfg.base}" write - by dn.exact="cn=user_db_reader,${cfg.base}" read - by users read - by * none + access to dn.subtree="ou=members,${cfg.base}" attrs=cn,sn,homeDirectory,loginShell,gecos,description,homeDirectory,uidNumber,gidNumber + by group.exact="cn=admin,ou=groups,${cfg.base}" write + by dn.exact="cn=user_db_reader,${cfg.base}" read + by users read + by * none -access to dn.exact="cn=admin,ou=groups,${cfg.base}" - by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage - by users read - by * none + access to dn.exact="cn=admin,ou=groups,${cfg.base}" + by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage + by users read + by * none -access to dn.subtree="ou=groups,${cfg.base}" attrs=memberUid - by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage - by dn.regex="cn=[a-zA-Z][a-zA-Z0-9_]+,ou=hosts,${cfg.base}" write - by group.exact="cn=admin,ou=groups,${cfg.base}" write - by users read - by * none + access to dn.subtree="ou=groups,${cfg.base}" attrs=memberUid + by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage + by dn.regex="cn=[a-zA-Z][a-zA-Z0-9_]+,ou=hosts,${cfg.base}" write + by group.exact="cn=admin,ou=groups,${cfg.base}" write + by users read + by * none -access to * - by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage - by users read - by * none + access to * + by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage + by users read + by * none -index objectClass,uid eq - ''; + index objectClass,uid eq + ''; declarativeContents = '' dn: ${cfg.base} diff --git a/config/fudo/local-network.nix b/lib/fudo/local-network.nix similarity index 100% rename from config/fudo/local-network.nix rename to lib/fudo/local-network.nix diff --git a/config/fudo/mail-container.nix b/lib/fudo/mail-container.nix similarity index 100% rename from config/fudo/mail-container.nix rename to lib/fudo/mail-container.nix diff --git a/config/fudo/mail.nix b/lib/fudo/mail.nix similarity index 100% rename from config/fudo/mail.nix rename to lib/fudo/mail.nix diff --git a/config/fudo/mail/clamav.nix b/lib/fudo/mail/clamav.nix similarity index 100% rename from config/fudo/mail/clamav.nix rename to lib/fudo/mail/clamav.nix diff --git a/config/fudo/mail/dkim.nix b/lib/fudo/mail/dkim.nix similarity index 100% rename from config/fudo/mail/dkim.nix rename to lib/fudo/mail/dkim.nix diff --git a/config/fudo/mail/dovecot.nix b/lib/fudo/mail/dovecot.nix similarity index 100% rename from config/fudo/mail/dovecot.nix rename to lib/fudo/mail/dovecot.nix diff --git a/config/fudo/mail/dovecot/imap_sieve/report-ham.sieve b/lib/fudo/mail/dovecot/imap_sieve/report-ham.sieve similarity index 100% rename from config/fudo/mail/dovecot/imap_sieve/report-ham.sieve rename to lib/fudo/mail/dovecot/imap_sieve/report-ham.sieve diff --git a/config/fudo/mail/dovecot/imap_sieve/report-spam.sieve b/lib/fudo/mail/dovecot/imap_sieve/report-spam.sieve similarity index 100% rename from config/fudo/mail/dovecot/imap_sieve/report-spam.sieve rename to lib/fudo/mail/dovecot/imap_sieve/report-spam.sieve diff --git a/config/fudo/mail/dovecot/pipe_bin/sa-learn-ham.sh b/lib/fudo/mail/dovecot/pipe_bin/sa-learn-ham.sh similarity index 100% rename from config/fudo/mail/dovecot/pipe_bin/sa-learn-ham.sh rename to lib/fudo/mail/dovecot/pipe_bin/sa-learn-ham.sh diff --git a/config/fudo/mail/dovecot/pipe_bin/sa-learn-spam.sh b/lib/fudo/mail/dovecot/pipe_bin/sa-learn-spam.sh similarity index 100% rename from config/fudo/mail/dovecot/pipe_bin/sa-learn-spam.sh rename to lib/fudo/mail/dovecot/pipe_bin/sa-learn-spam.sh diff --git a/config/fudo/mail/postfix.nix b/lib/fudo/mail/postfix.nix similarity index 100% rename from config/fudo/mail/postfix.nix rename to lib/fudo/mail/postfix.nix diff --git a/config/fudo/mail/rspamd.nix b/lib/fudo/mail/rspamd.nix similarity index 100% rename from config/fudo/mail/rspamd.nix rename to lib/fudo/mail/rspamd.nix diff --git a/config/fudo/minecraft-server.nix b/lib/fudo/minecraft-server.nix similarity index 100% rename from config/fudo/minecraft-server.nix rename to lib/fudo/minecraft-server.nix diff --git a/config/fudo/netinfo-email.nix b/lib/fudo/netinfo-email.nix similarity index 100% rename from config/fudo/netinfo-email.nix rename to lib/fudo/netinfo-email.nix diff --git a/config/fudo/node-exporter.nix b/lib/fudo/node-exporter.nix similarity index 100% rename from config/fudo/node-exporter.nix rename to lib/fudo/node-exporter.nix diff --git a/config/fudo/password.nix b/lib/fudo/password.nix similarity index 100% rename from config/fudo/password.nix rename to lib/fudo/password.nix diff --git a/config/fudo/postgres.nix b/lib/fudo/postgres.nix similarity index 67% rename from config/fudo/postgres.nix rename to lib/fudo/postgres.nix index 198db56..3a07c54 100644 --- a/config/fudo/postgres.nix +++ b/lib/fudo/postgres.nix @@ -4,8 +4,6 @@ with lib; let cfg = config.fudo.postgresql; - utils = import ../../lib/utils.nix { inherit lib; }; - join-lines = lib.concatStringsSep "\n"; userDatabaseOpts = { database, ... }: { @@ -18,8 +16,9 @@ let entity-access = mkOption { type = with types; attrsOf str; - description = "A list of entities mapped to the access this user should have."; - default = {}; + description = + "A list of entities mapped to the access this user should have."; + default = { }; example = { "TABLE users" = "SELECT,DELETE"; "ALL SEQUENCES IN public" = "SELECT"; @@ -39,13 +38,11 @@ let databases = mkOption { type = with types; attrsOf (submodule userDatabaseOpts); description = "Map of databases to required database/table perms."; - default = {}; + default = { }; example = { my_database = { access = "ALL PRIVILEGES"; - entity-access = { - "ALL TABLES" = "SELECT"; - }; + entity-access = { "ALL TABLES" = "SELECT"; }; }; }; }; @@ -56,8 +53,9 @@ let options = { users = mkOption { type = with types; listOf str; - description = "A list of users who should have full access to this database."; - default = []; + description = + "A list of users who should have full access to this database."; + default = [ ]; }; }; }; @@ -91,16 +89,14 @@ let exit 2 fi - ${join-lines - (mapAttrsToList - (user: opts: password-setter-script user opts.password-file "$OUTPUT_FILE") - (filterPasswordedUsers users))} + ${join-lines (mapAttrsToList (user: opts: + password-setter-script user opts.password-file "$OUTPUT_FILE") + (filterPasswordedUsers users))} ''; userDatabaseAccess = user: databases: mapAttrs' (database: databaseOpts: - nameValuePair "DATABASE ${database}" databaseOpts.access) - databases; + nameValuePair "DATABASE ${database}" databaseOpts.access) databases; makeEntry = nw: "host all all ${nw} gss include_realm=0 krb_realm=FUDO.ORG"; @@ -108,21 +104,22 @@ let makeNetworksEntry = networks: join-lines (map makeEntry networks); makeLocalUserPasswordEntries = users: - join-lines (mapAttrsToList - (user: opts: join-lines - (map (db: '' - local ${db} ${user} md5 - host ${db} ${user} 127.0.0.1/16 md5 - host ${db} ${user} ::1/128 md5 - '') (attrNames opts.databases))) - (filterPasswordedUsers users)); + join-lines (mapAttrsToList (user: opts: + join-lines (map (db: '' + local ${db} ${user} md5 + host ${db} ${user} 127.0.0.1/16 md5 + host ${db} ${user} ::1/128 md5 + '') (attrNames opts.databases))) (filterPasswordedUsers users)); - userTableAccessSql = user: entity: access: "GRANT ${access} ON ${entity} TO ${user};"; + userTableAccessSql = user: entity: access: + "GRANT ${access} ON ${entity} TO ${user};"; userDatabaseAccessSql = user: database: dbOpts: '' \c ${database} - ${join-lines (mapAttrsToList (userTableAccessSql user) dbOpts.entity-access)} + ${join-lines + (mapAttrsToList (userTableAccessSql user) dbOpts.entity-access)} ''; - userAccessSql = user: userOpts: join-lines (mapAttrsToList (userDatabaseAccessSql user) userOpts.databases); + userAccessSql = user: userOpts: + join-lines (mapAttrsToList (userDatabaseAccessSql user) userOpts.databases); usersAccessSql = users: join-lines (mapAttrsToList userAccessSql users); in { @@ -148,10 +145,8 @@ in { local-networks = mkOption { type = with types; listOf str; description = "A list of networks from which to accept connections."; - example = [ - "10.0.0.1/16" - ]; - default = []; + example = [ "10.0.0.1/16" ]; + default = [ ]; }; users = mkOption { @@ -163,20 +158,18 @@ in { databases = { some_database = { access = "CONNECT"; - entity-access = { - "TABLE some_table" = "SELECT,UPDATE"; - }; + entity-access = { "TABLE some_table" = "SELECT,UPDATE"; }; }; }; }; }; - default = {}; + default = { }; }; databases = mkOption { type = with types; loaOf (submodule databaseOpts); description = "A map of databases to database options."; - default = {}; + default = { }; }; socket-directory = mkOption { @@ -194,13 +187,13 @@ in { local-users = mkOption { type = with types; listOf str; description = "Users able to access the server via local socket."; - default = []; + default = [ ]; }; required-services = mkOption { type = with types; listOf str; description = "List of services that should run before postgresql."; - default = []; + default = [ ]; example = [ "password-generator.service" ]; }; }; @@ -208,9 +201,7 @@ in { config = mkIf cfg.enable { environment = { - systemPackages = with pkgs; [ - postgresql_11_gssapi - ]; + systemPackages = with pkgs; [ postgresql_11_gssapi ]; etc = { "postgresql/private/privkey.pem" = { @@ -237,9 +228,7 @@ in { }; users.groups = { - ${cfg.socket-group} = { - members = ["postgres"] ++ cfg.local-users; - }; + ${cfg.socket-group} = { members = [ "postgres" ] ++ cfg.local-users; }; }; services.postgresql = { @@ -247,20 +236,14 @@ in { package = pkgs.postgresql_11_gssapi; enableTCPIP = true; ensureDatabases = mapAttrsToList (name: value: name) cfg.databases; - ensureUsers = ((mapAttrsToList - (username: attrs: - { - name = username; - ensurePermissions = userDatabaseAccess username attrs.databases; - }) - cfg.users) ++ (flatten (mapAttrsToList - (database: opts: - (map (username: { - name = username; - ensurePermissions = { - "DATABASE ${database}" = "ALL PRIVILEGES"; - }; - }) opts.users)) cfg.databases))); + ensureUsers = ((mapAttrsToList (username: attrs: { + name = username; + ensurePermissions = userDatabaseAccess username attrs.databases; + }) cfg.users) ++ (flatten (mapAttrsToList (database: opts: + (map (username: { + name = username; + ensurePermissions = { "DATABASE ${database}" = "ALL PRIVILEGES"; }; + }) opts.users)) cfg.databases))); extraConfig = '' krb_server_keyfile = '/etc/postgresql/private/postgres.keytab' @@ -294,25 +277,29 @@ in { postgresql-password-setter = let passwords-script = passwords-setter-script cfg.users; - password-wrapper-script = pkgs.writeScriptBin "password-script-wrapper.sh" '' - #!${pkgs.bash}/bin/bash - TMPDIR=$(${pkgs.coreutils}/bin/mktemp -d -t postgres-XXXXXXXXXX) - echo "using temp dir $TMPDIR" - PASSWORD_SQL_FILE=$TMPDIR/user-passwords.sql - echo "password file $PASSWORD_SQL_FILE" - touch $PASSWORD_SQL_FILE - chown ${config.services.postgresql.superUser} $PASSWORD_SQL_FILE - chmod go-rwx $PASSWORD_SQL_FILE - ${passwords-script}/bin/postgres-set-passwords.sh $PASSWORD_SQL_FILE - echo "executing $PASSWORD_SQL_FILE" - ${pkgs.postgresql}/bin/psql --port ${toString config.services.postgresql.port} -d postgres -f $PASSWORD_SQL_FILE - echo rm $PASSWORD_SQL_FILE - echo "Postgresql user passwords set."; - exit 0 - ''; + password-wrapper-script = + pkgs.writeScriptBin "password-script-wrapper.sh" '' + #!${pkgs.bash}/bin/bash + TMPDIR=$(${pkgs.coreutils}/bin/mktemp -d -t postgres-XXXXXXXXXX) + echo "using temp dir $TMPDIR" + PASSWORD_SQL_FILE=$TMPDIR/user-passwords.sql + echo "password file $PASSWORD_SQL_FILE" + touch $PASSWORD_SQL_FILE + chown ${config.services.postgresql.superUser} $PASSWORD_SQL_FILE + chmod go-rwx $PASSWORD_SQL_FILE + ${passwords-script}/bin/postgres-set-passwords.sh $PASSWORD_SQL_FILE + echo "executing $PASSWORD_SQL_FILE" + ${pkgs.postgresql}/bin/psql --port ${ + toString config.services.postgresql.port + } -d postgres -f $PASSWORD_SQL_FILE + echo rm $PASSWORD_SQL_FILE + echo "Postgresql user passwords set."; + exit 0 + ''; in { - description = "A service to set postgresql user passwords after the server has started."; + description = + "A service to set postgresql user passwords after the server has started."; after = [ "postgresql.service" ] ++ cfg.required-services; requires = [ "postgresql.service" ] ++ cfg.required-services; serviceConfig = { @@ -326,11 +313,14 @@ in { allow-user-login = user: "ALTER ROLE ${user} WITH LOGIN;"; extra-settings-sql = pkgs.writeText "settings.sql" '' - ${concatStringsSep "\n" (map allow-user-login (mapAttrsToList (key: val: key) cfg.users))} + ${concatStringsSep "\n" + (map allow-user-login (mapAttrsToList (key: val: key) cfg.users))} ${usersAccessSql cfg.users} ''; in '' - ${pkgs.sudo}/bin/sudo -u ${config.services.postgresql.superUser} ${pkgs.postgresql}/bin/psql --port ${toString config.services.postgresql.port} -d postgres -f ${extra-settings-sql} + ${pkgs.sudo}/bin/sudo -u ${config.services.postgresql.superUser} ${pkgs.postgresql}/bin/psql --port ${ + toString config.services.postgresql.port + } -d postgres -f ${extra-settings-sql} ${pkgs.coreutils}/bin/chgrp ${cfg.socket-group} ${cfg.socket-directory}/.s.PGSQL* ''; }; diff --git a/config/fudo/prometheus.nix b/lib/fudo/prometheus.nix similarity index 100% rename from config/fudo/prometheus.nix rename to lib/fudo/prometheus.nix diff --git a/config/fudo/secure-dns-proxy.nix b/lib/fudo/secure-dns-proxy.nix similarity index 100% rename from config/fudo/secure-dns-proxy.nix rename to lib/fudo/secure-dns-proxy.nix diff --git a/lib/fudo/sites.nix b/lib/fudo/sites.nix new file mode 100644 index 0000000..1eddf53 --- /dev/null +++ b/lib/fudo/sites.nix @@ -0,0 +1,47 @@ +{ config, lib, pkgs, ... }: + +let + siteOpts = { site, ... }: { + options = { + site = mkOption { + type = types.str; + description = "Site name."; + default = site; + }; + + gateway-v4 = mkOption { + type = with types; nullOr str; + description = "Gateway to use for public ipv4 internet access."; + default = null; + }; + + gateway-v6 = mkOption { + type = with types; nullOr str; + description = "Gateway to use for public ipv6 internet access."; + default = null; + }; + + gateway-host = mkOption { + type = with types; nullOr str; + description = "Identity of the host to act as a gateway."; + default = null; + }; + + enable-monitoring = + mkEnableOption "Enable site-wide monitoring with prometheus."; + + nameservers = mkOption { + type = with types; listOf str; + description = "List of nameservers to be used by hosts at this site."; + default = [ ]; + }; + }; + }; + +in { + options.fudo.sites = mkOption { + type = with types; attrsOf (submodule domainOpts); + description = "Site configurations for all sites known to the system."; + default = { }; + }; +} diff --git a/config/fudo/slynk.nix b/lib/fudo/slynk.nix similarity index 100% rename from config/fudo/slynk.nix rename to lib/fudo/slynk.nix diff --git a/config/fudo/system.nix b/lib/fudo/system.nix similarity index 100% rename from config/fudo/system.nix rename to lib/fudo/system.nix diff --git a/lib/fudo/users.nix b/lib/fudo/users.nix new file mode 100644 index 0000000..47b7ad8 --- /dev/null +++ b/lib/fudo/users.nix @@ -0,0 +1,212 @@ +{ config, lib, pkgs, ... }: + +with lib; +let + cfg = config.fudo.users; + + systemUserOpts = { username, ... }: { + options = { + username = mkOption { + type = types.str; + description = "The system user's login name."; + default = username; + }; + + description = mkOption { + type = types.str; + description = "Description of this system user's purpose or role"; + }; + + ldap-hashed-password = mkOption { + type = types.str; + description = + "LDAP-formatted hashed password for this user. Generate with slappasswd."; + }; + }; + }; + + userOpts = { username, ... }: { + options = { + username = mkOption { + type = types.str; + description = "The user's login name."; + default = username; + }; + + uidNumber = mkOption { + type = types.int; + description = "Unique UID number for the user."; + }; + + common-name = mkOption { + type = types.str; + description = "The user's common or given name."; + }; + + primary-group = mkOption { + type = types.str; + description = "Primary group to which the user belongs."; + }; + + login-shell = mkOption { + type = with types; nullOr shellPackage; + description = "The user's preferred shell."; + }; + + description = mkOption { + type = types.str; + default = "Fudo Member"; + description = "A description of this user's role."; + }; + + ldap-hashed-passwd = mkOption { + type = with types; nullOr str; + description = + "LDAP-formatted hashed password, used for email and other services. Use slappasswd to generate the properly-formatted password."; + default = null; + }; + + login-hashed-passwd = mkOption { + type = with types; nullOr str; + description = + "Hashed password for shell, used for shell access to hosts. Use mkpasswd to generate the properly-formatted password."; + default = null; + }; + + ssh-authorized-keys = mkOption { + type = with types; listOf str; + description = "SSH public keys this user can use to log in."; + default = [ ]; + }; + + home-manager-config = mkOption { + type = with types; nullOr attrs; + description = "Home Manager configuration for the given user."; + default = null; + }; + + home-directory = mkOption { + type = types.str; + description = "Default home directory for the given user."; + }; + }; + }; + + groupOpts = { group-name, ... }: { + options = { + group-name = mkOption { + type = with types; nullOr str; + default = group-name; + description = "Group name."; + }; + + description = mkOption { + type = types.str; + description = "Description of the group or it's purpose."; + }; + + members = mkOption { + type = with types; listOf str; + default = [ ]; + description = "A list of users who are members of the current group."; + }; + + gidNumber = mkOption { + type = types.int; + description = "GID number of the group."; + }; + }; + }; + +in { + options.fudo = { + users = mkOption { + type = with types; attrsOf (submodule userOpts); + description = "Users"; + default = { }; + }; + + groups = mkOption { + type = with types; attrsOf (submodule groupOpts); + description = "Groups"; + default = { }; + }; + + system-users = mkOption { + type = with types; attrsOf (submodule systemUserOpts); + description = "System users (probably not what you're looking for!)"; + default = { }; + }; + }; + + config = let + local-host = config.fudo.common.hostname; + local-domain = config.fudo.common.domain; + + local-user-list = config.fudo.hosts."${local-host}".local-users; + domain-user-list = config.fudo.domains."${local-domain}".local-users; + local-users = getAttrs (local-user-list ++ domain-user-list) cfg.users; + + local-group-list = config.fudo.hosts."${local-host}".local-groups; + domain-group-list = config.fudo.domains."${local-domain}".local-groups; + local-groups = getAttrs (local-group-list ++ domain-group-list) cfg.groups; + + in { + fudo.auth.ldap = let + ldapUsers = (filterAttrs + (username: userOpts: userOpts.ldap-hashed-password != null)) cfg.users; + + list-includes = list: el: isNull (findFirst (this: this == el) list null); + + filterExistingUsers = users: group-members: + let user-list = attrNames users; + in filter (username: list-includes user-list username) users; + + in { + users = mapAttrs (username: userOpts: { + uid = userOpts.uid; + group = userOpts.primary-group; + common-name = userOpts.common-name; + hashed-password = userOpts.ldap-hashed-password; + }) ldapUsers; + + groups = mapAttrs (groupname: groupOpts: { + gid = groupOpts.gid-number; + description = groupOpts.description; + members = filterExistingUsers ldapUsers groupOpts.members; + }) cfg.groups; + + system-users = mapAttrs (username: userOpts: { + description = userOpts.description; + hashed-password = userOpts.ldap-hashed-passwd; + }) cfg.system-users; + }; + + users = { + users = mapAttrs (username: userOpts: { + isNormalUser = true; + uid = userOpts.uidNumber; + createHome = true; + description = userOpts.common-name; + group = userOpts.primary-group; + home = userOpts.home; + hashedPassword = userOpts.login-hashed-passwd; + openssh.authorizedKeys.keys = userOpts.ssh-authorized-keys; + }) local-users; + + groups = mapAttrs (groupname: groupOpts: { + gid = groupOpts.gidNumber; + description = groupOpts.description; + members = filterExistingUsers localUsers groupOpts.members; + }) local-groups; + }; + + home-manager.users = let + home-manager-users = + filterAttrs (username: userOpts: userOpts.home-manager-config != null) + local-users; + + in mapAttrs (username: userOpts: userOpts.home-manager-config) + home-manager-users; + }; +} diff --git a/config/fudo/vpn.nix b/lib/fudo/vpn.nix similarity index 100% rename from config/fudo/vpn.nix rename to lib/fudo/vpn.nix diff --git a/config/fudo/webmail.nix b/lib/fudo/webmail.nix similarity index 100% rename from config/fudo/webmail.nix rename to lib/fudo/webmail.nix diff --git a/lib/fudo/wireless-networks.nix b/lib/fudo/wireless-networks.nix new file mode 100644 index 0000000..48fd55c --- /dev/null +++ b/lib/fudo/wireless-networks.nix @@ -0,0 +1,32 @@ +{ config, lib, pkgs, ... }: + +with lib; +let + networkOpts = { network, ... }: { + options = { + network = mkOption { + type = types.str; + description = "Name of wireless network."; + default = network; + }; + + key = mkOption { + type = types.str; + description = "Secret key for wireless network."; + }; + }; + }; + +in { + option.fudo.wireless-networks = mkOption { + type = with types; listOf (submodule networkOpts); + description = "A map of wireless networks to attributes (including key)."; + default = { }; + }; + + config = { + wireless.networks = + mapAttrs (network: networkOpts: { psk = networkOpts.key; }) + config.fudo.wireless-networks; + }; +} diff --git a/lib/fudolib.nix b/lib/fudolib.nix new file mode 100644 index 0000000..f253011 --- /dev/null +++ b/lib/fudolib.nix @@ -0,0 +1,6 @@ +{ lib, ... }: + +{ + ip = import ./fudolib/ip.nix { }; + dns = import ./fudolib/dns.nix { }; +} diff --git a/lib/dns.nix b/lib/fudolib/dns.nix similarity index 56% rename from lib/dns.nix rename to lib/fudolib/dns.nix index 876b2a5..73eb40f 100644 --- a/lib/dns.nix +++ b/lib/fudolib/dns.nix @@ -1,15 +1,17 @@ -{ pkgs ? import {}, ... }: +{ lib, ... }: -with pkgs.lib; +with lib; let join-lines = concatStringsSep "\n"; makeSrvRecords = protocol: type: records: join-lines (map (record: - "_${type}._${protocol} IN SRV ${toString record.priority} ${toString record.weight} ${toString record.port} ${record.host}.") - records); + "_${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); + makeSrvProtocolRecords = protocol: types: + join-lines (mapAttrsToList (makeSrvRecords protocol) types); srvRecordOpts = with types; { options = { @@ -39,20 +41,25 @@ let }; srvRecordPair = domain: protocol: type: record: { - "_${type}._${protocol}.${domain}" = "${toString record.priority} ${toString record.weight} ${toString record.port} ${record.host}."; + "_${type}._${protocol}.${domain}" = + "${toString record.priority} ${toString record.weight} ${ + toString record.port + } ${record.host}."; }; in rec { srvRecords = with types; attrsOf (attrsOf (listOf (submodule srvRecordOpts))); - srvRecordsToBindZone = srvRecords: join-lines (mapAttrsToList makeSrvProtocolRecords srvRecords); + srvRecordsToBindZone = srvRecords: + join-lines (mapAttrsToList makeSrvProtocolRecords srvRecords); - concatMapAttrs = f: attrs: concatMap (x: x) (mapAttrsToList (key: val: f key val) attrs); + concatMapAttrs = f: attrs: + concatMap (x: x) (mapAttrsToList (key: val: f key val) attrs); srvRecordsToPairs = domain: srvRecords: - listToAttrs - (concatMapAttrs (protocol: types: - concatMapAttrs (type: records: map (srvRecordPair domain protocol type) records) types) - srvRecords); + listToAttrs (concatMapAttrs (protocol: types: + concatMapAttrs + (type: records: map (srvRecordPair domain protocol type) records) types) + srvRecords); } diff --git a/lib/fudolib/ip.nix b/lib/fudolib/ip.nix new file mode 100644 index 0000000..0fd7881 --- /dev/null +++ b/lib/fudolib/ip.nix @@ -0,0 +1,80 @@ +{ lib, ... }: + +with lib; +let + joinString = concatStringsSep; + + pow = x: e: if (e == 0) then 1 else x * (pow x (e - 1)); + + 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; + + rightPadBits = int: bits: bitOr int (generateNBits bits); + + 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); + +in rec { + + 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 ]); + + maskFromV32Network = network: + let + fullMask = ipv4ToInt "255.255.255.255"; + insignificantBits = 32 - (getNetworkMask network); + in intToIpv4 + (leftShift (rightShift fullMask 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); + + ipv4OnNetwork = ip: network: + let + ip-int = ipv4ToInt ip; + net-min = networkMinIp network; + net-max = networkMaxIp network; + in (ip-int >= networkMinIp) && (ip-int <= networkMaxIp); + + 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); +} diff --git a/config/informis/cl-gemini.nix b/lib/informis/cl-gemini.nix similarity index 100% rename from config/informis/cl-gemini.nix rename to lib/informis/cl-gemini.nix diff --git a/lib/instance.nix b/lib/instance.nix new file mode 100644 index 0000000..f3f0195 --- /dev/null +++ b/lib/instance.nix @@ -0,0 +1,12 @@ +{ config, lib, pkgs, ... }: + +{ + options.instance = { + hostname = mkOption { + type = types.str; + description = '' + Hostname of this specific host (without domain). + ''; + }; + }; +} diff --git a/lib/ip.nix b/lib/ip.nix deleted file mode 100644 index f5c8920..0000000 --- a/lib/ip.nix +++ /dev/null @@ -1,63 +0,0 @@ -{ pkgs ? import {}, ... }: - -with pkgs.lib; -let - joinString = concatStringsSep; - - pow = x: e: if (e == 0) then 1 else x * (pow x (e - 1)); - - 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; - - rightPadBits = int: bits: bitOr int (generateNBits bits); - - 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); - -in rec { - - 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 ]); - - maskFromV32Network = network: let - fullMask = ipv4ToInt "255.255.255.255"; - insignificantBits = 32 - (getNetworkMask network); - in intToIpv4 (leftShift (rightShift fullMask 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); - - ipv4OnNetwork = ip: network: let - ip-int = ipv4ToInt ip; - net-min = networkMinIp network; - net-max = networkMaxIp network; - in - (ip-int >= networkMinIp) && (ip-int <= networkMaxIp); - - 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); -} diff --git a/lib/utils.nix b/lib/utils.nix deleted file mode 100644 index 6c6a581..0000000 --- a/lib/utils.nix +++ /dev/null @@ -1,14 +0,0 @@ -{ lib }: - -with lib; -{ - recursiveMergeAttrs = a: b: let - commonAttrs = intersectLists (attrNames a) (attrNames b); - aAttrs = subtractLists (attrNames a) commonAttrs; - bAttrs = subtractLists (attrNames b) commonAttrs; - aSide = (filterAttrs (k: v: elem k aAttrs) a); - bSide = (filterAttrs (k: v: elem k bAttrs) b); - common = (foldr (a: b: a // b) {} - (map (k: { ${k} = a.${k} // b.${k}; }) commonAttrs)); - in aSide // bSide // common; -} diff --git a/packages/local.nix b/packages/local.nix index 9bf3af9..78af48f 100644 --- a/packages/local.nix +++ b/packages/local.nix @@ -10,6 +10,8 @@ in { fetchurl = builtins.fetchurl; }; + minecraft-current = pkgs.minecraft-server_1_16_4; + minecraft-server_1_16_4 = pkgs.minecraft-server.overrideAttrs (oldAttrs: rec { version = "1.15.1"; @@ -31,13 +33,6 @@ in { }; }); - minecraft-current = pkgs.minecraft.overrideAttrs (oldAttrs: rec { - src = builtins.fetchurl { - url = "https://launcher.mojang.com/download/Minecraft.tar.gz"; - sha256 = "1k9gf1v1law4kiz8f7i2fxkj5vq2cm37b3ys95zpyf4aiw5nzg33"; - }; - }); - # DON'T LEAVE THE HASH--Nix will think the package hasn't changed minecraft-server_1_16_1 = let version = "1.16.1";