Still very broken...moving to start testing
This commit is contained in:
parent
d34fc495b4
commit
372cf5fc6a
@ -2,12 +2,12 @@
|
|||||||
|
|
||||||
let
|
let
|
||||||
helpers = pkgs.writeText "bash.helpers"
|
helpers = pkgs.writeText "bash.helpers"
|
||||||
(builtins.readFile ./static/bash/bash.helpers);
|
(builtins.readFile ../static/bash/bash.helpers);
|
||||||
|
|
||||||
colors =
|
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 {
|
in {
|
||||||
config.programs.bash = {
|
config.programs.bash = {
|
@ -1,38 +1,15 @@
|
|||||||
{ lib, config, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with lib; {
|
{
|
||||||
|
config = {
|
||||||
imports = [
|
imports = [
|
||||||
./fudo/acme-for-hostname.nix
|
./bash.nix
|
||||||
./fudo/authentication.nix
|
./domains.nix
|
||||||
./fudo/backplane
|
./groups.nix
|
||||||
./fudo/chat.nix
|
./hosts.nix
|
||||||
./fudo/client/dns.nix
|
./sites.nix
|
||||||
./fudo/common.nix
|
./users.nix
|
||||||
./fudo/dns.nix
|
./wireless-networks.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
|
|
||||||
];
|
];
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
56
config/domains.nix
Normal file
56
config/domains.nix
Normal file
@ -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";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
@ -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.";
|
|
||||||
};
|
|
||||||
}
|
|
70
config/hardware/clunk.nix
Normal file
70
config/hardware/clunk.nix
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [ <nixpkgs/nixos/modules/installer/scan/not-detected.nix> ];
|
||||||
|
|
||||||
|
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";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
85
config/hardware/france.nix
Normal file
85
config/hardware/france.nix
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [ <nixpkgs/nixos/modules/installer/scan/not-detected.nix> ];
|
||||||
|
|
||||||
|
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";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
65
config/hardware/lambda.nix
Normal file
65
config/hardware/lambda.nix
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [ <nixpkgs/nixos/modules/installer/scan/not-detected.nix> ];
|
||||||
|
|
||||||
|
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";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
68
config/hardware/nostromo.nix
Normal file
68
config/hardware/nostromo.nix
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [ <nixpkgs/nixos/modules/installer/scan/not-detected.nix> ];
|
||||||
|
|
||||||
|
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";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
79
config/hardware/plato.nix
Normal file
79
config/hardware/plato.nix
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [ <nixpkgs/nixos/modules/installer/scan/not-detected.nix> ];
|
||||||
|
|
||||||
|
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";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
90
config/hosts.nix
Normal file
90
config/hosts.nix
Normal file
@ -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;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
9
config/hosts/atom.nix
Normal file
9
config/hosts/atom.nix
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
fudo.laptop.use-network-manager = false;
|
||||||
|
|
||||||
|
fudo.slynk.enable = true;
|
||||||
|
|
||||||
|
services.xserver = { videoDrivers = [ "nvidia" ]; };
|
||||||
|
}
|
135
config/hosts/clunk.nix
Normal file
135
config/hosts/clunk.nix
Normal file
@ -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;
|
||||||
|
# '';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
179
config/hosts/france.nix
Normal file
179
config/hosts/france.nix
Normal file
@ -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";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
32
config/hosts/lambda.nix
Normal file
32
config/hosts/lambda.nix
Normal file
@ -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
|
||||||
|
}
|
169
config/hosts/nostromo.nix
Normal file
169
config/hosts/nostromo.nix
Normal file
@ -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"; };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
34
config/hosts/plato.nix
Normal file
34
config/hosts/plato.nix
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
10
config/hosts/zbox.nix
Normal file
10
config/hosts/zbox.nix
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
fudo.slynk.enable = true;
|
||||||
|
|
||||||
|
networking = {
|
||||||
|
eno1.useDHCP = false;
|
||||||
|
intif0 = { useDHCP = true; };
|
||||||
|
};
|
||||||
|
}
|
84
config/local-network/rus.selby.ca.nix
Normal file
84
config/local-network/rus.selby.ca.nix
Normal file
@ -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";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
217
config/local-network/sea.fudo.org.nix
Normal file
217
config/local-network/sea.fudo.org.nix
Normal file
@ -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";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
7
config/profiles.nix
Normal file
7
config/profiles.nix
Normal file
@ -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" ]; }
|
108
config/profiles/common-ui.nix
Normal file
108
config/profiles/common-ui.nix
Normal file
@ -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
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
100
config/profiles/common.nix
Normal file
100
config/profiles/common.nix
Normal file
@ -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;
|
||||||
|
}
|
7
config/profiles/desktop.nix
Normal file
7
config/profiles/desktop.nix
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib; {
|
||||||
|
imports = [ ./common-ui.nix ];
|
||||||
|
|
||||||
|
config = { networking = { networkmanager.enable = mkForce false; }; };
|
||||||
|
}
|
30
config/profiles/gateway-server.nix
Normal file
30
config/profiles/gateway-server.nix
Normal file
@ -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;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
24
config/profiles/laptop.nix
Normal file
24
config/profiles/laptop.nix
Normal file
@ -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;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
71
config/profiles/server.nix
Normal file
71
config/profiles/server.nix
Normal file
@ -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;
|
||||||
|
};
|
||||||
|
}
|
59
config/sites.nix
Normal file
59
config/sites.nix
Normal file
@ -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";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
455
config/users.nix
Normal file
455
config/users.nix
Normal file
@ -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";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
11
config/wireless-networks.nix
Normal file
11
config/wireless-networks.nix
Normal file
@ -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"; };
|
||||||
|
};
|
||||||
|
}
|
10
default.nix
Normal file
10
default.nix
Normal file
@ -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 ];
|
||||||
|
}
|
@ -157,8 +157,8 @@ in {
|
|||||||
};
|
};
|
||||||
|
|
||||||
environment.shellInit = ''
|
environment.shellInit = ''
|
||||||
gpg-connect-agent /bye
|
${pkgs.gnupg}/bin/gpg-connect-agent /bye
|
||||||
export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)
|
export SSH_AUTH_SOCK=$(${pkgs.gnupg}/bin/gpgconf --list-dirs agent-ssh-socket)
|
||||||
'';
|
'';
|
||||||
|
|
||||||
security.pam = {
|
security.pam = {
|
||||||
|
@ -11,11 +11,7 @@ with lib;
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
config = mkIf (config.fudo.common.profile == "laptop") {
|
config = mkIf (config.fudo.common.profile == "laptop") {
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [ acpi upower wpa_supplicant ];
|
||||||
acpi
|
|
||||||
upower
|
|
||||||
wpa_supplicant
|
|
||||||
];
|
|
||||||
|
|
||||||
networking = if (config.fudo.laptop.use-network-manager) then {
|
networking = if (config.fudo.laptop.use-network-manager) then {
|
||||||
networkmanager.enable = true;
|
networkmanager.enable = true;
|
||||||
@ -28,12 +24,8 @@ with lib;
|
|||||||
group = "wheel";
|
group = "wheel";
|
||||||
};
|
};
|
||||||
networks = {
|
networks = {
|
||||||
"sea.fudo.org" = {
|
"sea.fudo.org" = { psk = "DahHaocheiD5"; };
|
||||||
psk = "DahHaocheiD5";
|
"Pixel_9041" = { psk = "ea72027e4e6"; };
|
||||||
};
|
|
||||||
"Pixel_9041" = {
|
|
||||||
psk = "ea72027e4e6";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -8,7 +8,7 @@ let
|
|||||||
|
|
||||||
gateway = "10.0.0.1";
|
gateway = "10.0.0.1";
|
||||||
|
|
||||||
nameservers = ["10.0.0.1"];
|
nameservers = [ "10.0.0.1" ];
|
||||||
|
|
||||||
in {
|
in {
|
||||||
|
|
||||||
@ -16,26 +16,23 @@ in {
|
|||||||
|
|
||||||
time.timeZone = "America/Los_Angeles";
|
time.timeZone = "America/Los_Angeles";
|
||||||
|
|
||||||
services.printing = {
|
services.printing = { enable = true; };
|
||||||
enable = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
services.cron = {
|
services.cron = { mailto = admin; };
|
||||||
mailto = admin;
|
|
||||||
};
|
|
||||||
|
|
||||||
krb5.libdefaults.default_realm = "FUDO.ORG";
|
krb5.libdefaults.default_realm = "FUDO.ORG";
|
||||||
|
|
||||||
networking = {
|
networking = {
|
||||||
domain = local-domain;
|
domain = local-domain;
|
||||||
search = [local-domain "fudo.org"];
|
search = [ local-domain "fudo.org" ];
|
||||||
firewall.enable = false;
|
firewall.enable = false;
|
||||||
nameservers = nameservers;
|
nameservers = nameservers;
|
||||||
|
|
||||||
# Don't set the gateway if we ARE the gateway.
|
# 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
|
# 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).
|
# 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;
|
enableIPv6 = true;
|
||||||
|
|
||||||
@ -43,7 +40,10 @@ in {
|
|||||||
# needs the full reverse-lookup name of the server, the latter wants
|
# needs the full reverse-lookup name of the server, the latter wants
|
||||||
# `hostname` to return just the host itself.
|
# `hostname` to return just the host itself.
|
||||||
hosts = {
|
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;
|
isNormalUser = true;
|
||||||
uid = 1000;
|
uid = 1000;
|
||||||
description = "Guest User";
|
description = "Guest User";
|
||||||
extraGroups = ["audio" "video" "disk" "floppy" "lp" "cdrom" "tape" "input"];
|
extraGroups =
|
||||||
|
[ "audio" "video" "disk" "floppy" "lp" "cdrom" "tape" "input" ];
|
||||||
};
|
};
|
||||||
ken = {
|
ken = {
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
uid = 10035;
|
uid = 10035;
|
||||||
createHome = true;
|
createHome = true;
|
||||||
description = "Ken Selby";
|
description = "Ken Selby";
|
||||||
extraGroups = ["audio" "video" "disk" "floppy" "lp" "cdrom" "tape" "input"];
|
extraGroups =
|
||||||
|
[ "audio" "video" "disk" "floppy" "lp" "cdrom" "tape" "input" ];
|
||||||
group = "users";
|
group = "users";
|
||||||
home = "/home/selby/ken";
|
home = "/home/selby/ken";
|
||||||
hashedPassword = "$6$EwK9fpbH8$gYVzYY1IYw2/G0wCeUxXrZZqvjWCkCZbBqCOhxowbMuYtC5G0vp.AoYhVKWOJcHJM2c7TdPmAdnhLIe2KYStf.";
|
hashedPassword =
|
||||||
|
"$6$EwK9fpbH8$gYVzYY1IYw2/G0wCeUxXrZZqvjWCkCZbBqCOhxowbMuYtC5G0vp.AoYhVKWOJcHJM2c7TdPmAdnhLIe2KYStf.";
|
||||||
};
|
};
|
||||||
xiaoxuan = {
|
xiaoxuan = {
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
uid = 10065;
|
uid = 10065;
|
||||||
createHome = true;
|
createHome = true;
|
||||||
description = "Xiaoxuan Jin";
|
description = "Xiaoxuan Jin";
|
||||||
extraGroups = ["audio" "video" "disk" "floppy" "lp" "cdrom" "tape" "input"];
|
extraGroups =
|
||||||
|
[ "audio" "video" "disk" "floppy" "lp" "cdrom" "tape" "input" ];
|
||||||
group = "users";
|
group = "users";
|
||||||
home = "/home/xiaoxuan";
|
home = "/home/xiaoxuan";
|
||||||
hashedPassword = "$6$C8lYHrK7KvdKm/RE$cHZ2hg5gEOEjTV8Zoayik8sz5h.Vh0.ClCgOlQn8l/2Qx/qdxqZ7xCsAZ1GZ.IEyESfhJeJbjLpykXDwPpfVF0";
|
hashedPassword =
|
||||||
|
"$6$C8lYHrK7KvdKm/RE$cHZ2hg5gEOEjTV8Zoayik8sz5h.Vh0.ClCgOlQn8l/2Qx/qdxqZ7xCsAZ1GZ.IEyESfhJeJbjLpykXDwPpfVF0";
|
||||||
};
|
};
|
||||||
kevin = {
|
kevin = {
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
@ -122,7 +127,8 @@ in {
|
|||||||
kdc = "nostromo";
|
kdc = "nostromo";
|
||||||
photo = "doraemon";
|
photo = "doraemon";
|
||||||
music = "doraemon";
|
music = "doraemon";
|
||||||
panopticon = "hyperion";
|
panopticon = "lambda";
|
||||||
|
panopticon-od = "lambda";
|
||||||
ipfs = "nostromo";
|
ipfs = "nostromo";
|
||||||
hole = "nostromo";
|
hole = "nostromo";
|
||||||
pihole = "nostromo";
|
pihole = "nostromo";
|
||||||
@ -310,7 +316,6 @@ in {
|
|||||||
mac-address = "94:10:3e:48:94:ed";
|
mac-address = "94:10:3e:48:94:ed";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
# Ceph network
|
# Ceph network
|
||||||
srv-1 = {
|
srv-1 = {
|
||||||
ip-address = "10.0.10.1";
|
ip-address = "10.0.10.1";
|
||||||
|
6
hardware.nix
Normal file
6
hardware.nix
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{ config, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports =
|
||||||
|
[ config.fudo.hosts."${config.fudo.instance.hostname}".hardware-config ];
|
||||||
|
}
|
106
home-manager/niten.nix
Normal file
106
home-manager/niten.nix
Normal file
@ -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";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
39
home-manager/root.nix
Normal file
39
home-manager/root.nix
Normal file
@ -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";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
@ -12,16 +12,11 @@ in {
|
|||||||
boot.loader.systemd-boot.enable = true;
|
boot.loader.systemd-boot.enable = true;
|
||||||
boot.loader.efi.canTouchEfiVariables = true;
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
|
|
||||||
boot = {
|
boot = { runSize = "50%"; };
|
||||||
runSize = "50%";
|
|
||||||
};
|
|
||||||
|
|
||||||
hardware.bluetooth.enable = false;
|
hardware.bluetooth.enable = false;
|
||||||
|
|
||||||
imports = [
|
imports = [ ../defaults.nix ../hardware-configuration.nix ];
|
||||||
../defaults.nix
|
|
||||||
../hardware-configuration.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
fudo.common = {
|
fudo.common = {
|
||||||
profile = "server";
|
profile = "server";
|
||||||
@ -86,7 +81,7 @@ in {
|
|||||||
nat = {
|
nat = {
|
||||||
enable = true;
|
enable = true;
|
||||||
externalInterface = "enp1s0";
|
externalInterface = "enp1s0";
|
||||||
internalInterfaces = ["intif0"];
|
internalInterfaces = [ "intif0" ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -105,13 +100,11 @@ in {
|
|||||||
#"https://9.9.9.9/dns-query"
|
#"https://9.9.9.9/dns-query"
|
||||||
];
|
];
|
||||||
bootstrap-dns = "1.1.1.1";
|
bootstrap-dns = "1.1.1.1";
|
||||||
listen-ips = [dns-proxy-ip];
|
listen-ips = [ dns-proxy-ip ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [ dnsproxy ];
|
||||||
dnsproxy
|
|
||||||
];
|
|
||||||
|
|
||||||
virtualisation = {
|
virtualisation = {
|
||||||
docker = {
|
docker = {
|
||||||
@ -124,11 +117,7 @@ in {
|
|||||||
docker-containers = {
|
docker-containers = {
|
||||||
pihole = {
|
pihole = {
|
||||||
image = "pihole/pihole:v5.1.2";
|
image = "pihole/pihole:v5.1.2";
|
||||||
ports = [
|
ports = [ "5353:53/tcp" "5353:53/udp" "3080:80/tcp" ];
|
||||||
"5353:53/tcp"
|
|
||||||
"5353:53/udp"
|
|
||||||
"3080:80/tcp"
|
|
||||||
];
|
|
||||||
environment = {
|
environment = {
|
||||||
ServerIP = host-internal-ip;
|
ServerIP = host-internal-ip;
|
||||||
VIRTUAL_HOST = "dns-hole.rus.selby.ca";
|
VIRTUAL_HOST = "dns-hole.rus.selby.ca";
|
||||||
|
@ -191,26 +191,48 @@ in {
|
|||||||
api-address = "/ip4/${host-internal-ip}/tcp/5001";
|
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 = {
|
services = {
|
||||||
nginx = {
|
nginx = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
recommendedGzipSettings = true;
|
||||||
|
recommendedOptimisation = true;
|
||||||
|
recommendedTlsSettings = true;
|
||||||
|
recommendedProxySettings = true;
|
||||||
|
|
||||||
virtualHosts = {
|
virtualHosts = {
|
||||||
"pihole.sea.fudo.org" = {
|
"sea-camera.fudo.link" = {
|
||||||
serverAliases = [ "dns-hole.sea.fudo.org" "hole.sea.fudo.org" ];
|
enableACME = true;
|
||||||
|
forceSSL = true;
|
||||||
locations."/" = {
|
locations."/" = {
|
||||||
proxyPass = "http://127.0.0.1:3080";
|
proxyPass = "http://panopticon.sea.fudo.org/";
|
||||||
|
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
proxy_set_header Host $host;
|
proxy_http_version 1.1;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
proxy_set_header X-Forwarded-By $server_addr:$server_port;
|
proxy_set_header Connection "Upgrade";
|
||||||
proxy_set_header X-Forwarded-For $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
"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"; };
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
36
lib/default.nix
Normal file
36
lib/default.nix
Normal file
@ -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
|
||||||
|
];
|
||||||
|
}
|
65
lib/fudo/common.nix
Normal file
65
lib/fudo/common.nix
Normal file
@ -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.";
|
||||||
|
};
|
||||||
|
}
|
@ -7,14 +7,14 @@ let
|
|||||||
|
|
||||||
join-lines = concatStringsSep "\n";
|
join-lines = concatStringsSep "\n";
|
||||||
|
|
||||||
hostOpts = { host, ...}: {
|
hostOpts = { host, ... }: {
|
||||||
options = {
|
options = {
|
||||||
ip-addresses = mkOption {
|
ip-addresses = mkOption {
|
||||||
type = with types; listOf str;
|
type = with types; listOf str;
|
||||||
description = ''
|
description = ''
|
||||||
A list of IPv4 addresses assigned to this host.
|
A list of IPv4 addresses assigned to this host.
|
||||||
'';
|
'';
|
||||||
default = [];
|
default = [ ];
|
||||||
};
|
};
|
||||||
|
|
||||||
ipv6-addresses = mkOption {
|
ipv6-addresses = mkOption {
|
||||||
@ -22,7 +22,7 @@ let
|
|||||||
description = ''
|
description = ''
|
||||||
A list of IPv6 addresses assigned to this host.
|
A list of IPv6 addresses assigned to this host.
|
||||||
'';
|
'';
|
||||||
default = [];
|
default = [ ];
|
||||||
};
|
};
|
||||||
|
|
||||||
ssh-fingerprints = mkOption {
|
ssh-fingerprints = mkOption {
|
||||||
@ -30,7 +30,7 @@ let
|
|||||||
description = ''
|
description = ''
|
||||||
A list of DNS SSHFP records for this host.
|
A list of DNS SSHFP records for this host.
|
||||||
'';
|
'';
|
||||||
default = [];
|
default = [ ];
|
||||||
};
|
};
|
||||||
|
|
||||||
description = mkOption {
|
description = mkOption {
|
||||||
@ -74,11 +74,12 @@ let
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
domainOpts = { domain, ... }: with types; {
|
domainOpts = { domain, ... }:
|
||||||
|
with types; {
|
||||||
options = {
|
options = {
|
||||||
hosts = mkOption {
|
hosts = mkOption {
|
||||||
type = loaOf (submodule hostOpts);
|
type = loaOf (submodule hostOpts);
|
||||||
default = {};
|
default = { };
|
||||||
description = "A map of hostname to { host_attributes }.";
|
description = "A map of hostname to { host_attributes }.";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -91,13 +92,13 @@ let
|
|||||||
mx = mkOption {
|
mx = mkOption {
|
||||||
type = listOf str;
|
type = listOf str;
|
||||||
description = "A list of mail servers serving this domain.";
|
description = "A list of mail servers serving this domain.";
|
||||||
default = [];
|
default = [ ];
|
||||||
};
|
};
|
||||||
|
|
||||||
srv-records = mkOption {
|
srv-records = mkOption {
|
||||||
type = attrsOf (attrsOf (listOf (submodule srvRecordOpts)));
|
type = attrsOf (attrsOf (listOf (submodule srvRecordOpts)));
|
||||||
description = "Map of traffic type to srv records.";
|
description = "Map of traffic type to srv records.";
|
||||||
default = {};
|
default = { };
|
||||||
example = {
|
example = {
|
||||||
tcp = {
|
tcp = {
|
||||||
kerberos = {
|
kerberos = {
|
||||||
@ -110,7 +111,7 @@ let
|
|||||||
|
|
||||||
aliases = mkOption {
|
aliases = mkOption {
|
||||||
type = loaOf str;
|
type = loaOf str;
|
||||||
default = {};
|
default = { };
|
||||||
description = "A mapping of host-alias => hostnames to add to DNS.";
|
description = "A mapping of host-alias => hostnames to add to DNS.";
|
||||||
example = {
|
example = {
|
||||||
"music" = "host.dom.com.";
|
"music" = "host.dom.com.";
|
||||||
@ -121,8 +122,8 @@ let
|
|||||||
extra-dns-records = mkOption {
|
extra-dns-records = mkOption {
|
||||||
type = listOf str;
|
type = listOf str;
|
||||||
description = "Records to be inserted verbatim into the DNS zone.";
|
description = "Records to be inserted verbatim into the DNS zone.";
|
||||||
example = ["some-host IN CNAME base-host"];
|
example = [ "some-host IN CNAME base-host" ];
|
||||||
default = [];
|
default = [ ];
|
||||||
};
|
};
|
||||||
|
|
||||||
dmarc-report-address = mkOption {
|
dmarc-report-address = mkOption {
|
||||||
@ -134,36 +135,40 @@ let
|
|||||||
|
|
||||||
default-host = mkOption {
|
default-host = mkOption {
|
||||||
type = nullOr str;
|
type = nullOr str;
|
||||||
description = "IP of the host which will act as the default server for this domain, if any.";
|
description =
|
||||||
|
"IP of the host which will act as the default server for this domain, if any.";
|
||||||
default = null;
|
default = null;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
hostRecords = host: data:
|
hostRecords = host: data:
|
||||||
join-lines ((map (ip: "${host} IN A ${ip}") data.ip-addresses) ++
|
join-lines ((map (ip: "${host} IN A ${ip}") data.ip-addresses)
|
||||||
(map (ip: "${host} IN AAAA ${ip}") data.ipv6-addresses) ++
|
++ (map (ip: "${host} IN AAAA ${ip}") data.ipv6-addresses)
|
||||||
(map (sshfp: "${host} IN SSHFP ${sshfp}") data.ssh-fingerprints) ++
|
++ (map (sshfp: "${host} IN SSHFP ${sshfp}") data.ssh-fingerprints)
|
||||||
(optional (data.rp != null) "${host} IN RP ${data.rp}") ++
|
++ (optional (data.rp != null) "${host} IN RP ${data.rp}")
|
||||||
(optional (data.description != null) "${host} IN TXT ${data.description}"));
|
++ (optional (data.description != null)
|
||||||
|
"${host} IN TXT ${data.description}"));
|
||||||
|
|
||||||
makeSrvRecords = protocol: type: records:
|
makeSrvRecords = protocol: type: records:
|
||||||
join-lines (map (record: "_${type}._${protocol} IN SRV ${toString record.priority} ${toString record.weight} ${toString record.port} ${toString record.host}.")
|
join-lines (map (record:
|
||||||
records);
|
"_${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}";
|
cnameRecord = alias: host: "${alias} IN CNAME ${host}";
|
||||||
|
|
||||||
mxRecords = mxs:
|
mxRecords = mxs: concatStringsSep "\n" (map (mx: "@ IN MX 10 ${mx}.") mxs);
|
||||||
concatStringsSep "\n"
|
|
||||||
(map (mx: "@ IN MX 10 ${mx}.") mxs);
|
|
||||||
|
|
||||||
dmarcRecord = dmarc-email:
|
dmarcRecord = dmarc-email:
|
||||||
optionalString (dmarc-email != null)
|
optionalString (dmarc-email != null) ''
|
||||||
''_dmarc IN TXT "v=DMARC1;p=quarantine;sp=quarantine;rua=mailto:${dmarc-email};"'';
|
_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 {
|
in {
|
||||||
|
|
||||||
@ -177,7 +182,7 @@ in {
|
|||||||
example = {
|
example = {
|
||||||
"ns1.domain.com" = {
|
"ns1.domain.com" = {
|
||||||
ip-addresses = [ "1.1.1.1" ];
|
ip-addresses = [ "1.1.1.1" ];
|
||||||
ipv6-addresses = [];
|
ipv6-addresses = [ ];
|
||||||
description = "my fancy dns server";
|
description = "my fancy dns server";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -190,14 +195,14 @@ in {
|
|||||||
|
|
||||||
domains = mkOption {
|
domains = mkOption {
|
||||||
type = loaOf (submodule domainOpts);
|
type = loaOf (submodule domainOpts);
|
||||||
default = {};
|
default = { };
|
||||||
description = "A map of domain to domain options.";
|
description = "A map of domain to domain options.";
|
||||||
};
|
};
|
||||||
|
|
||||||
listen-ips = mkOption {
|
listen-ips = mkOption {
|
||||||
type = listOf str;
|
type = listOf str;
|
||||||
description = "A list of IPs on which to listen for DNS queries.";
|
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
|
6w
|
||||||
5m)
|
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}
|
${mxRecords dom-cfg.mx}
|
||||||
|
|
||||||
@ -232,7 +238,8 @@ in {
|
|||||||
|
|
||||||
${dmarcRecord dom-cfg.dmarc-report-address}
|
${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 hostRecords dom-cfg.hosts)}
|
||||||
${join-lines (mapAttrsToList cnameRecord dom-cfg.aliases)}
|
${join-lines (mapAttrsToList cnameRecord dom-cfg.aliases)}
|
||||||
${join-lines dom-cfg.extra-dns-records}
|
${join-lines dom-cfg.extra-dns-records}
|
52
lib/fudo/domains.nix
Normal file
52
lib/fudo/domains.nix
Normal file
@ -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 = { };
|
||||||
|
};
|
||||||
|
}
|
107
lib/fudo/hosts.nix
Normal file
107
lib/fudo/hosts.nix
Normal file
@ -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;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
142
lib/fudo/hosts/local-network.nix
Normal file
142
lib/fudo/hosts/local-network.nix
Normal file
@ -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;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
@ -19,6 +19,7 @@ let
|
|||||||
description = ''
|
description = ''
|
||||||
The password for this user, hashed with ldappasswd.
|
The password for this user, hashed with ldappasswd.
|
||||||
'';
|
'';
|
||||||
|
default = "";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -41,7 +42,7 @@ let
|
|||||||
|
|
||||||
members = mkOption {
|
members = mkOption {
|
||||||
type = with types; listOf str;
|
type = with types; listOf str;
|
||||||
default = [];
|
default = [ ];
|
||||||
description = ''
|
description = ''
|
||||||
A list of usernames representing the members of this group.
|
A list of usernames representing the members of this group.
|
||||||
'';
|
'';
|
||||||
@ -94,6 +95,7 @@ let
|
|||||||
description = ''
|
description = ''
|
||||||
The password for this user, hashed with ldappasswd.
|
The password for this user, hashed with ldappasswd.
|
||||||
'';
|
'';
|
||||||
|
default = "";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -102,12 +104,12 @@ let
|
|||||||
if (length attrList) == 0 then
|
if (length attrList) == 0 then
|
||||||
""
|
""
|
||||||
else
|
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;
|
getUserGidNumber = user: group-map: group-map.${user.group}.gid;
|
||||||
|
|
||||||
attrOr = attrs: attr: value:
|
attrOr = attrs: attr: value: if attrs ? ${attr} then attrs.${attr} else value;
|
||||||
if attrs ? ${attr} then attrs.${attr} else value;
|
|
||||||
|
|
||||||
mkHomeDir = username: user-opts:
|
mkHomeDir = username: user-opts:
|
||||||
if (user-opts.group == "admin") then
|
if (user-opts.group == "admin") then
|
||||||
@ -115,7 +117,6 @@ let
|
|||||||
else
|
else
|
||||||
"/home/${user-opts.group}/${username}";
|
"/home/${user-opts.group}/${username}";
|
||||||
|
|
||||||
|
|
||||||
userLdif = base: name: group-map: opts: ''
|
userLdif = base: name: group-map: opts: ''
|
||||||
dn: uid=${name},ou=members,${base}
|
dn: uid=${name},ou=members,${base}
|
||||||
uid: ${name}
|
uid: ${name}
|
||||||
@ -123,15 +124,15 @@ let
|
|||||||
objectClass: shadowAccount
|
objectClass: shadowAccount
|
||||||
objectClass: posixAccount
|
objectClass: posixAccount
|
||||||
cn: ${opts.common-name}
|
cn: ${opts.common-name}
|
||||||
uidNumber: ${toString(opts.uid)}
|
uidNumber: ${toString (opts.uid)}
|
||||||
gidNumber: ${toString(getUserGidNumber opts group-map)}
|
gidNumber: ${toString (getUserGidNumber opts group-map)}
|
||||||
homeDirectory: ${mkHomeDir name opts}
|
homeDirectory: ${mkHomeDir name opts}
|
||||||
description: ${opts.description}
|
description: ${opts.description}
|
||||||
shadowLastChange: 12230
|
shadowLastChange: 12230
|
||||||
shadowMax: 99999
|
shadowMax: 99999
|
||||||
shadowWarning: 7
|
shadowWarning: 7
|
||||||
userPassword: ${opts.hashed-password}
|
userPassword: ${opts.hashed-password}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
systemUserLdif = base: name: opts: ''
|
systemUserLdif = base: name: opts: ''
|
||||||
dn: cn=${name},${base}
|
dn: cn=${name},${base}
|
||||||
@ -140,7 +141,7 @@ let
|
|||||||
cn: ${name}
|
cn: ${name}
|
||||||
description: ${opts.description}
|
description: ${opts.description}
|
||||||
userPassword: ${opts.hashed-password}
|
userPassword: ${opts.hashed-password}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
toMemberList = userList:
|
toMemberList = userList:
|
||||||
stringJoin "\n" (map (username: "memberUid: ${username}") userList);
|
stringJoin "\n" (map (username: "memberUid: ${username}") userList);
|
||||||
@ -149,25 +150,22 @@ let
|
|||||||
dn: cn=${name},ou=groups,${base}
|
dn: cn=${name},ou=groups,${base}
|
||||||
objectClass: posixGroup
|
objectClass: posixGroup
|
||||||
cn: ${name}
|
cn: ${name}
|
||||||
gidNumber: ${toString(opts.gid)}
|
gidNumber: ${toString (opts.gid)}
|
||||||
description: ${opts.description}
|
description: ${opts.description}
|
||||||
${toMemberList opts.members}
|
${toMemberList opts.members}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
systemUsersLdif = base: user-map:
|
systemUsersLdif = base: user-map:
|
||||||
stringJoin "\n" (mapAttrsToList (name: opts:
|
stringJoin "\n"
|
||||||
systemUserLdif base name opts
|
(mapAttrsToList (name: opts: systemUserLdif base name opts) user-map);
|
||||||
) user-map);
|
|
||||||
|
|
||||||
groupsLdif = base: group-map:
|
groupsLdif = base: group-map:
|
||||||
stringJoin "\n" (mapAttrsToList (name: opts:
|
stringJoin "\n"
|
||||||
groupLdif base name opts
|
(mapAttrsToList (name: opts: groupLdif base name opts) group-map);
|
||||||
) group-map);
|
|
||||||
|
|
||||||
usersLdif = base: group-map: user-map:
|
usersLdif = base: group-map: user-map:
|
||||||
stringJoin "\n" (mapAttrsToList (name: opts:
|
stringJoin "\n"
|
||||||
userLdif base name group-map opts
|
(mapAttrsToList (name: opts: userLdif base name group-map opts) user-map);
|
||||||
) user-map);
|
|
||||||
|
|
||||||
in {
|
in {
|
||||||
|
|
||||||
@ -236,19 +234,16 @@ in {
|
|||||||
};
|
};
|
||||||
|
|
||||||
listen-uris = mkOption {
|
listen-uris = mkOption {
|
||||||
default = [];
|
default = [ ];
|
||||||
type = with types; listOf str;
|
type = with types; listOf str;
|
||||||
description = ''
|
description = ''
|
||||||
A list of URIs on which the ldap server should listen.
|
A list of URIs on which the ldap server should listen.
|
||||||
'';
|
'';
|
||||||
example = [
|
example = [ "ldap://auth.fudo.org" "ldaps://auth.fudo.org" ];
|
||||||
"ldap://auth.fudo.org"
|
|
||||||
"ldaps://auth.fudo.org"
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
users = mkOption {
|
users = mkOption {
|
||||||
default = {};
|
default = { };
|
||||||
type = with types; loaOf (submodule ldapUserOpts);
|
type = with types; loaOf (submodule ldapUserOpts);
|
||||||
example = {
|
example = {
|
||||||
tester = {
|
tester = {
|
||||||
@ -263,14 +258,12 @@ in {
|
|||||||
};
|
};
|
||||||
|
|
||||||
groups = mkOption {
|
groups = mkOption {
|
||||||
default = {};
|
default = { };
|
||||||
type = with types; loaOf (submodule ldapGroupOpts);
|
type = with types; loaOf (submodule ldapGroupOpts);
|
||||||
example = {
|
example = {
|
||||||
admin = {
|
admin = {
|
||||||
gid = 1099;
|
gid = 1099;
|
||||||
members = [
|
members = [ "tester" ];
|
||||||
"tester"
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
description = ''
|
description = ''
|
||||||
@ -279,7 +272,7 @@ in {
|
|||||||
};
|
};
|
||||||
|
|
||||||
system-users = mkOption {
|
system-users = mkOption {
|
||||||
default = {};
|
default = { };
|
||||||
type = with types; loaOf (submodule ldapSystemUserOpts);
|
type = with types; loaOf (submodule ldapSystemUserOpts);
|
||||||
example = {
|
example = {
|
||||||
replicator = {
|
replicator = {
|
||||||
@ -313,9 +306,7 @@ in {
|
|||||||
};
|
};
|
||||||
|
|
||||||
systemd.services.openldap = {
|
systemd.services.openldap = {
|
||||||
environment = {
|
environment = { KRB5_KTNAME = cfg.kerberos-keytab; };
|
||||||
KRB5_KTNAME = cfg.kerberos-keytab;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
services.openldap = {
|
services.openldap = {
|
||||||
@ -330,7 +321,8 @@ in {
|
|||||||
|
|
||||||
TLSCertificateFile ${cfg.sslCert}
|
TLSCertificateFile ${cfg.sslCert}
|
||||||
TLSCertificateKeyFile ${cfg.sslKey}
|
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=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"
|
authz-regexp "^uid=[^,/]+/root,cn=fudo\.org,cn=gssapi,cn=auth$" "cn=admin,dc=fudo,dc=org"
|
||||||
@ -341,11 +333,11 @@ in {
|
|||||||
'';
|
'';
|
||||||
|
|
||||||
extraDatabaseConfig = ''
|
extraDatabaseConfig = ''
|
||||||
# access to dn=base=""
|
# access to dn=base=""
|
||||||
# by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage
|
# by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage
|
||||||
# by * read
|
# by * read
|
||||||
|
|
||||||
access to attrs=userPassword,shadowLastChange
|
access to attrs=userPassword,shadowLastChange
|
||||||
by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage
|
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 group.exact="cn=admin,ou=members,${cfg.base}" write
|
||||||
by dn.exact="cn=auth_reader,${cfg.base}" read
|
by dn.exact="cn=auth_reader,${cfg.base}" read
|
||||||
@ -353,42 +345,42 @@ access to attrs=userPassword,shadowLastChange
|
|||||||
by self write
|
by self write
|
||||||
by * auth
|
by * auth
|
||||||
|
|
||||||
access to dn.exact="cn=admin,ou=groups,${cfg.base}"
|
access to dn.exact="cn=admin,ou=groups,${cfg.base}"
|
||||||
by dn.exact="cn=admin,${cfg.base}" write
|
by dn.exact="cn=admin,${cfg.base}" write
|
||||||
by users read
|
by users read
|
||||||
by * none
|
by * none
|
||||||
|
|
||||||
access to dn.subtree="ou=groups,${cfg.base}" attrs=memberUid
|
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 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 group.exact="cn=admin,ou=groups,${cfg.base}" write
|
||||||
by users read
|
by users read
|
||||||
by * none
|
by * none
|
||||||
|
|
||||||
access to dn.subtree="ou=members,${cfg.base}" attrs=cn,sn,homeDirectory,loginShell,gecos,description,homeDirectory,uidNumber,gidNumber
|
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 group.exact="cn=admin,ou=groups,${cfg.base}" write
|
||||||
by dn.exact="cn=user_db_reader,${cfg.base}" read
|
by dn.exact="cn=user_db_reader,${cfg.base}" read
|
||||||
by users read
|
by users read
|
||||||
by * none
|
by * none
|
||||||
|
|
||||||
access to dn.exact="cn=admin,ou=groups,${cfg.base}"
|
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 dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage
|
||||||
by users read
|
by users read
|
||||||
by * none
|
by * none
|
||||||
|
|
||||||
access to dn.subtree="ou=groups,${cfg.base}" attrs=memberUid
|
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.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 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 group.exact="cn=admin,ou=groups,${cfg.base}" write
|
||||||
by users read
|
by users read
|
||||||
by * none
|
by * none
|
||||||
|
|
||||||
access to *
|
access to *
|
||||||
by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage
|
by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage
|
||||||
by users read
|
by users read
|
||||||
by * none
|
by * none
|
||||||
|
|
||||||
|
|
||||||
index objectClass,uid eq
|
index objectClass,uid eq
|
||||||
'';
|
'';
|
||||||
|
|
||||||
declarativeContents = ''
|
declarativeContents = ''
|
@ -4,8 +4,6 @@ with lib;
|
|||||||
let
|
let
|
||||||
cfg = config.fudo.postgresql;
|
cfg = config.fudo.postgresql;
|
||||||
|
|
||||||
utils = import ../../lib/utils.nix { inherit lib; };
|
|
||||||
|
|
||||||
join-lines = lib.concatStringsSep "\n";
|
join-lines = lib.concatStringsSep "\n";
|
||||||
|
|
||||||
userDatabaseOpts = { database, ... }: {
|
userDatabaseOpts = { database, ... }: {
|
||||||
@ -18,8 +16,9 @@ let
|
|||||||
|
|
||||||
entity-access = mkOption {
|
entity-access = mkOption {
|
||||||
type = with types; attrsOf str;
|
type = with types; attrsOf str;
|
||||||
description = "A list of entities mapped to the access this user should have.";
|
description =
|
||||||
default = {};
|
"A list of entities mapped to the access this user should have.";
|
||||||
|
default = { };
|
||||||
example = {
|
example = {
|
||||||
"TABLE users" = "SELECT,DELETE";
|
"TABLE users" = "SELECT,DELETE";
|
||||||
"ALL SEQUENCES IN public" = "SELECT";
|
"ALL SEQUENCES IN public" = "SELECT";
|
||||||
@ -39,13 +38,11 @@ let
|
|||||||
databases = mkOption {
|
databases = mkOption {
|
||||||
type = with types; attrsOf (submodule userDatabaseOpts);
|
type = with types; attrsOf (submodule userDatabaseOpts);
|
||||||
description = "Map of databases to required database/table perms.";
|
description = "Map of databases to required database/table perms.";
|
||||||
default = {};
|
default = { };
|
||||||
example = {
|
example = {
|
||||||
my_database = {
|
my_database = {
|
||||||
access = "ALL PRIVILEGES";
|
access = "ALL PRIVILEGES";
|
||||||
entity-access = {
|
entity-access = { "ALL TABLES" = "SELECT"; };
|
||||||
"ALL TABLES" = "SELECT";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -56,8 +53,9 @@ let
|
|||||||
options = {
|
options = {
|
||||||
users = mkOption {
|
users = mkOption {
|
||||||
type = with types; listOf str;
|
type = with types; listOf str;
|
||||||
description = "A list of users who should have full access to this database.";
|
description =
|
||||||
default = [];
|
"A list of users who should have full access to this database.";
|
||||||
|
default = [ ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -91,16 +89,14 @@ let
|
|||||||
exit 2
|
exit 2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
${join-lines
|
${join-lines (mapAttrsToList (user: opts:
|
||||||
(mapAttrsToList
|
password-setter-script user opts.password-file "$OUTPUT_FILE")
|
||||||
(user: opts: password-setter-script user opts.password-file "$OUTPUT_FILE")
|
|
||||||
(filterPasswordedUsers users))}
|
(filterPasswordedUsers users))}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
userDatabaseAccess = user: databases:
|
userDatabaseAccess = user: databases:
|
||||||
mapAttrs' (database: databaseOpts:
|
mapAttrs' (database: databaseOpts:
|
||||||
nameValuePair "DATABASE ${database}" databaseOpts.access)
|
nameValuePair "DATABASE ${database}" databaseOpts.access) databases;
|
||||||
databases;
|
|
||||||
|
|
||||||
makeEntry = nw:
|
makeEntry = nw:
|
||||||
"host all all ${nw} gss include_realm=0 krb_realm=FUDO.ORG";
|
"host all all ${nw} gss include_realm=0 krb_realm=FUDO.ORG";
|
||||||
@ -108,21 +104,22 @@ let
|
|||||||
makeNetworksEntry = networks: join-lines (map makeEntry networks);
|
makeNetworksEntry = networks: join-lines (map makeEntry networks);
|
||||||
|
|
||||||
makeLocalUserPasswordEntries = users:
|
makeLocalUserPasswordEntries = users:
|
||||||
join-lines (mapAttrsToList
|
join-lines (mapAttrsToList (user: opts:
|
||||||
(user: opts: join-lines
|
join-lines (map (db: ''
|
||||||
(map (db: ''
|
|
||||||
local ${db} ${user} md5
|
local ${db} ${user} md5
|
||||||
host ${db} ${user} 127.0.0.1/16 md5
|
host ${db} ${user} 127.0.0.1/16 md5
|
||||||
host ${db} ${user} ::1/128 md5
|
host ${db} ${user} ::1/128 md5
|
||||||
'') (attrNames opts.databases)))
|
'') (attrNames opts.databases))) (filterPasswordedUsers users));
|
||||||
(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: ''
|
userDatabaseAccessSql = user: database: dbOpts: ''
|
||||||
\c ${database}
|
\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);
|
usersAccessSql = users: join-lines (mapAttrsToList userAccessSql users);
|
||||||
|
|
||||||
in {
|
in {
|
||||||
@ -148,10 +145,8 @@ in {
|
|||||||
local-networks = mkOption {
|
local-networks = mkOption {
|
||||||
type = with types; listOf str;
|
type = with types; listOf str;
|
||||||
description = "A list of networks from which to accept connections.";
|
description = "A list of networks from which to accept connections.";
|
||||||
example = [
|
example = [ "10.0.0.1/16" ];
|
||||||
"10.0.0.1/16"
|
default = [ ];
|
||||||
];
|
|
||||||
default = [];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
users = mkOption {
|
users = mkOption {
|
||||||
@ -163,20 +158,18 @@ in {
|
|||||||
databases = {
|
databases = {
|
||||||
some_database = {
|
some_database = {
|
||||||
access = "CONNECT";
|
access = "CONNECT";
|
||||||
entity-access = {
|
entity-access = { "TABLE some_table" = "SELECT,UPDATE"; };
|
||||||
"TABLE some_table" = "SELECT,UPDATE";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
default = { };
|
||||||
default = {};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
databases = mkOption {
|
databases = mkOption {
|
||||||
type = with types; loaOf (submodule databaseOpts);
|
type = with types; loaOf (submodule databaseOpts);
|
||||||
description = "A map of databases to database options.";
|
description = "A map of databases to database options.";
|
||||||
default = {};
|
default = { };
|
||||||
};
|
};
|
||||||
|
|
||||||
socket-directory = mkOption {
|
socket-directory = mkOption {
|
||||||
@ -194,13 +187,13 @@ in {
|
|||||||
local-users = mkOption {
|
local-users = mkOption {
|
||||||
type = with types; listOf str;
|
type = with types; listOf str;
|
||||||
description = "Users able to access the server via local socket.";
|
description = "Users able to access the server via local socket.";
|
||||||
default = [];
|
default = [ ];
|
||||||
};
|
};
|
||||||
|
|
||||||
required-services = mkOption {
|
required-services = mkOption {
|
||||||
type = with types; listOf str;
|
type = with types; listOf str;
|
||||||
description = "List of services that should run before postgresql.";
|
description = "List of services that should run before postgresql.";
|
||||||
default = [];
|
default = [ ];
|
||||||
example = [ "password-generator.service" ];
|
example = [ "password-generator.service" ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -208,9 +201,7 @@ in {
|
|||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
|
|
||||||
environment = {
|
environment = {
|
||||||
systemPackages = with pkgs; [
|
systemPackages = with pkgs; [ postgresql_11_gssapi ];
|
||||||
postgresql_11_gssapi
|
|
||||||
];
|
|
||||||
|
|
||||||
etc = {
|
etc = {
|
||||||
"postgresql/private/privkey.pem" = {
|
"postgresql/private/privkey.pem" = {
|
||||||
@ -237,9 +228,7 @@ in {
|
|||||||
};
|
};
|
||||||
|
|
||||||
users.groups = {
|
users.groups = {
|
||||||
${cfg.socket-group} = {
|
${cfg.socket-group} = { members = [ "postgres" ] ++ cfg.local-users; };
|
||||||
members = ["postgres"] ++ cfg.local-users;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
services.postgresql = {
|
services.postgresql = {
|
||||||
@ -247,19 +236,13 @@ in {
|
|||||||
package = pkgs.postgresql_11_gssapi;
|
package = pkgs.postgresql_11_gssapi;
|
||||||
enableTCPIP = true;
|
enableTCPIP = true;
|
||||||
ensureDatabases = mapAttrsToList (name: value: name) cfg.databases;
|
ensureDatabases = mapAttrsToList (name: value: name) cfg.databases;
|
||||||
ensureUsers = ((mapAttrsToList
|
ensureUsers = ((mapAttrsToList (username: attrs: {
|
||||||
(username: attrs:
|
|
||||||
{
|
|
||||||
name = username;
|
name = username;
|
||||||
ensurePermissions = userDatabaseAccess username attrs.databases;
|
ensurePermissions = userDatabaseAccess username attrs.databases;
|
||||||
})
|
}) cfg.users) ++ (flatten (mapAttrsToList (database: opts:
|
||||||
cfg.users) ++ (flatten (mapAttrsToList
|
|
||||||
(database: opts:
|
|
||||||
(map (username: {
|
(map (username: {
|
||||||
name = username;
|
name = username;
|
||||||
ensurePermissions = {
|
ensurePermissions = { "DATABASE ${database}" = "ALL PRIVILEGES"; };
|
||||||
"DATABASE ${database}" = "ALL PRIVILEGES";
|
|
||||||
};
|
|
||||||
}) opts.users)) cfg.databases)));
|
}) opts.users)) cfg.databases)));
|
||||||
|
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
@ -294,7 +277,8 @@ in {
|
|||||||
|
|
||||||
postgresql-password-setter = let
|
postgresql-password-setter = let
|
||||||
passwords-script = passwords-setter-script cfg.users;
|
passwords-script = passwords-setter-script cfg.users;
|
||||||
password-wrapper-script = pkgs.writeScriptBin "password-script-wrapper.sh" ''
|
password-wrapper-script =
|
||||||
|
pkgs.writeScriptBin "password-script-wrapper.sh" ''
|
||||||
#!${pkgs.bash}/bin/bash
|
#!${pkgs.bash}/bin/bash
|
||||||
TMPDIR=$(${pkgs.coreutils}/bin/mktemp -d -t postgres-XXXXXXXXXX)
|
TMPDIR=$(${pkgs.coreutils}/bin/mktemp -d -t postgres-XXXXXXXXXX)
|
||||||
echo "using temp dir $TMPDIR"
|
echo "using temp dir $TMPDIR"
|
||||||
@ -305,14 +289,17 @@ in {
|
|||||||
chmod go-rwx $PASSWORD_SQL_FILE
|
chmod go-rwx $PASSWORD_SQL_FILE
|
||||||
${passwords-script}/bin/postgres-set-passwords.sh $PASSWORD_SQL_FILE
|
${passwords-script}/bin/postgres-set-passwords.sh $PASSWORD_SQL_FILE
|
||||||
echo "executing $PASSWORD_SQL_FILE"
|
echo "executing $PASSWORD_SQL_FILE"
|
||||||
${pkgs.postgresql}/bin/psql --port ${toString config.services.postgresql.port} -d postgres -f $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 rm $PASSWORD_SQL_FILE
|
||||||
echo "Postgresql user passwords set.";
|
echo "Postgresql user passwords set.";
|
||||||
exit 0
|
exit 0
|
||||||
'';
|
'';
|
||||||
|
|
||||||
in {
|
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;
|
after = [ "postgresql.service" ] ++ cfg.required-services;
|
||||||
requires = [ "postgresql.service" ] ++ cfg.required-services;
|
requires = [ "postgresql.service" ] ++ cfg.required-services;
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
@ -326,11 +313,14 @@ in {
|
|||||||
allow-user-login = user: "ALTER ROLE ${user} WITH LOGIN;";
|
allow-user-login = user: "ALTER ROLE ${user} WITH LOGIN;";
|
||||||
|
|
||||||
extra-settings-sql = pkgs.writeText "settings.sql" ''
|
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}
|
${usersAccessSql cfg.users}
|
||||||
'';
|
'';
|
||||||
in ''
|
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*
|
${pkgs.coreutils}/bin/chgrp ${cfg.socket-group} ${cfg.socket-directory}/.s.PGSQL*
|
||||||
'';
|
'';
|
||||||
};
|
};
|
47
lib/fudo/sites.nix
Normal file
47
lib/fudo/sites.nix
Normal file
@ -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 = { };
|
||||||
|
};
|
||||||
|
}
|
212
lib/fudo/users.nix
Normal file
212
lib/fudo/users.nix
Normal file
@ -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;
|
||||||
|
};
|
||||||
|
}
|
32
lib/fudo/wireless-networks.nix
Normal file
32
lib/fudo/wireless-networks.nix
Normal file
@ -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;
|
||||||
|
};
|
||||||
|
}
|
6
lib/fudolib.nix
Normal file
6
lib/fudolib.nix
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{ lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
ip = import ./fudolib/ip.nix { };
|
||||||
|
dns = import ./fudolib/dns.nix { };
|
||||||
|
}
|
@ -1,15 +1,17 @@
|
|||||||
{ pkgs ? import <nixpkgs> {}, ... }:
|
{ lib, ... }:
|
||||||
|
|
||||||
with pkgs.lib;
|
with lib;
|
||||||
let
|
let
|
||||||
join-lines = concatStringsSep "\n";
|
join-lines = concatStringsSep "\n";
|
||||||
|
|
||||||
makeSrvRecords = protocol: type: records:
|
makeSrvRecords = protocol: type: records:
|
||||||
join-lines (map (record:
|
join-lines (map (record:
|
||||||
"_${type}._${protocol} IN SRV ${toString record.priority} ${toString record.weight} ${toString record.port} ${record.host}.")
|
"_${type}._${protocol} IN SRV ${toString record.priority} ${
|
||||||
records);
|
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; {
|
srvRecordOpts = with types; {
|
||||||
options = {
|
options = {
|
||||||
@ -39,20 +41,25 @@ let
|
|||||||
};
|
};
|
||||||
|
|
||||||
srvRecordPair = domain: protocol: type: record: {
|
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 {
|
in rec {
|
||||||
|
|
||||||
srvRecords = with types; attrsOf (attrsOf (listOf (submodule srvRecordOpts)));
|
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:
|
srvRecordsToPairs = domain: srvRecords:
|
||||||
listToAttrs
|
listToAttrs (concatMapAttrs (protocol: types:
|
||||||
(concatMapAttrs (protocol: types:
|
concatMapAttrs
|
||||||
concatMapAttrs (type: records: map (srvRecordPair domain protocol type) records) types)
|
(type: records: map (srvRecordPair domain protocol type) records) types)
|
||||||
srvRecords);
|
srvRecords);
|
||||||
}
|
}
|
80
lib/fudolib/ip.nix
Normal file
80
lib/fudolib/ip.nix
Normal file
@ -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);
|
||||||
|
}
|
12
lib/instance.nix
Normal file
12
lib/instance.nix
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
options.instance = {
|
||||||
|
hostname = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = ''
|
||||||
|
Hostname of this specific host (without domain).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
63
lib/ip.nix
63
lib/ip.nix
@ -1,63 +0,0 @@
|
|||||||
{ pkgs ? import <nixpkgs> {}, ... }:
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
@ -10,6 +10,8 @@ in {
|
|||||||
fetchurl = builtins.fetchurl;
|
fetchurl = builtins.fetchurl;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
minecraft-current = pkgs.minecraft-server_1_16_4;
|
||||||
|
|
||||||
minecraft-server_1_16_4 = pkgs.minecraft-server.overrideAttrs
|
minecraft-server_1_16_4 = pkgs.minecraft-server.overrideAttrs
|
||||||
(oldAttrs: rec {
|
(oldAttrs: rec {
|
||||||
version = "1.15.1";
|
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
|
# DON'T LEAVE THE HASH--Nix will think the package hasn't changed
|
||||||
minecraft-server_1_16_1 = let
|
minecraft-server_1_16_1 = let
|
||||||
version = "1.16.1";
|
version = "1.16.1";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user