Added live disk flake

This commit is contained in:
niten 2022-03-16 09:49:35 -07:00
parent 101a6afcd8
commit 9c9df8c3c2
32 changed files with 1328 additions and 871 deletions

View File

@ -1,3 +1,4 @@
# OBSOLETE
{ config, lib, pkgs, ... }:
with lib;

View File

@ -3,21 +3,19 @@
{
imports = [
./aliases.nix
./backplane-client.nix
# ./backplane-client.nix
./bash.nix
./common.nix
# ./dns.nix
./domains.nix
./groups.nix
./instance.nix
# ./kerberos.nix
./services.nix
./system-users.nix
./users.nix
./user-config.nix
./wireless-networks.nix
./service/chute.nix
./service/dns.nix
./service/fudo-auth.nix
./service/jabber.nix
./zones.nix
];
}

View File

@ -1,69 +0,0 @@
{ config, lib, pkgs, ... }:
with lib;
let
hostname = config.instance.hostname;
domain = config.instance.local-domain;
cfg = config.fudo.domains.${domain};
served-domain = cfg.primary-nameserver != null;
is-primary = hostname == cfg.primary-nameserver;
create-srv-record = port: hostname: {
port = port;
host = hostname;
};
in {
config = {
fudo.dns = mkIf is-primary (let
primary-ip = pkgs.lib.network.host-ipv4 config hostname;
all-ips = pkgs.lib.network.host-ips config hostname;
in {
enable = true;
identity = "${hostname}.${domain}";
nameservers = {
ns1 = {
ipv4-address = primary-ip;
description = "Primary ${domain} nameserver";
};
};
# Deliberately leaving out localhost so the primary nameserver
# can use a custom recursor
listen-ips = all-ips;
domains = {
${domain} = {
dnssec = true;
default-host = primary-ip;
gssapi-realm = cfg.gssapi-realm;
mx = optional (cfg.primary-mailserver != null)
cfg.primary-mailserver;
# TODO: there's no guarantee this exists...
dmarc-report-address = "dmarc-report@${domain}";
zone-definition = let
zone = config.fudo.zones.${domain};
in zone // {
srv-records = {
tcp = {
domain = [{
host = "ns1.${domain}";
port = 53;
}];
};
udp = {
domain = [{
host = "ns1.${domain}";
port = 53;
}];
};
};
};
};
};
});
};
}

View File

@ -1,4 +1,4 @@
{ config, lib, pkgs, ... }:
{
}
}

View File

@ -1,5 +1,3 @@
{ config, lib, pkgs, ... }:
{
}
{}

View File

@ -51,6 +51,12 @@ with lib; {
fsType = "btrfs";
options = [ "subvol=@state" "compress=zstd" "noatime" "nodiratime" "noexec" ];
};
"/var/lib/acme" = {
device = "/dev/disk/by-label/system";
fsType = "btrfs";
options = [ "subvol=@acme" "compress=zstd" "noatime" "nodiratime" "noexec" ];
};
};
swapDevices = [{ device = "/dev/disk/by-label/swap"; }];

View File

@ -55,6 +55,18 @@ with lib; {
fsType = "btrfs";
options = [ "subvol=@state" "compress=zstd" "noatime" "nodiratime" "noexec" ];
};
"/var/lib/acme" = {
device = "/dev/disk/by-label/data";
fsType = "btrfs";
options = [ "subvol=@acme" "compress=zstd" "noatime" "nodiratime" "noexec" ];
};
"/var/lib/prometheus" = {
device = "/dev/disk/by-label/data";
fsType = "btrfs";
options = [ "subvol=@prometheus" "compress=zstd" "noatime" "nodiratime" "noexec" ];
};
};
swapDevices = [{ device = "/dev/disk/by-label/swap"; }];

View File

@ -52,7 +52,7 @@
"/home" = {
device = "/dev/disk/by-label/zbox-data";
fsType = "btrfs";
options = [ "noatime" "nodiratime" "compress=zstd" "noexec" "subvol=@home" ];
options = [ "noatime" "nodiratime" "compress=zstd" "subvol=@home" ];
};
};

View File

@ -54,7 +54,7 @@ in {
ssl-private-key = "${mail-ssl-dir}/key.pem";
in {
enableContainer = true;
monitoring = true;
monitoring.enable = true;
domain = domain-name;
mail-hostname = "mail.${domain-name}";

View File

@ -5,6 +5,12 @@ let
shinobi-od-port = "7082";
state-dir = "/state"; # This must be a string!
home-assistant-port = 8123;
parent-config = config;
generate-mac = pkgs.lib.network.generate-mac-address;
in {
boot = {
loader.grub.copyKernels = true;
@ -22,20 +28,6 @@ in {
};
};
# fudo.secrets = {
# host-secrets.lambda = {
# host-keytab = {
# source-file = /state/secrets/kerberos/lambda.keytab;
# target-file = "/etc/krb5.keytab";
# user = "root";
# };
# };
# secret-group = "fudo-secrets";
# secret-users = [ "niten" ];
# secret-paths = [ "/state/secrets" ];
# };
systemd.tmpfiles.rules = [
"L /root/.gnupg - - - - ${state-dir}/user/root/gnupg"
"L /root/.ssh/id_rsa - - - - ${state-dir}/user/root/ssh/id_rsa"
@ -92,6 +84,21 @@ in {
Defaults lecture = never
'';
services.nginx = {
enable = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
recommendedGzipSettings = true;
virtualHosts."home.sea.fudo.org" = {
locations."/" = {
proxyPass =
"http://localhost:${toString home-assistant-port}";
proxyWebsockets = true;
};
};
};
virtualisation = {
docker = {
enable = true;
@ -100,19 +107,30 @@ in {
};
oci-containers = {
backend = "docker";
containers = {
shinobi = {
image = "shinobisystems/shinobi:latest";
ports = [ "${shinobi-port}:8080" ];
home-assistant = {
image = "homeassistant/home-assistant:stable";
autoStart = true;
environment.TZ = config.time.timeZone;
ports = [ "${toString home-assistant-port}:8123" ];
volumes = [
"/state/shinobi/plugins:/home/Shinobi/plugins"
"/state/shinobi/config:/home/Shinobi/config"
"/state/shinobi/videos:/home/Shinobi/videos"
"/state/shinobi/db-data:/var/lib/mysql"
"/etc/localtime:/etc/localtime:ro"
"/state/services/home-assistant:/config"
];
};
# shinobi = {
# image = "shinobisystems/shinobi:latest";
# ports = [ "${shinobi-port}:8080" ];
# volumes = [
# "/state/shinobi/plugins:/home/Shinobi/plugins"
# "/state/shinobi/config:/home/Shinobi/config"
# "/state/shinobi/videos:/home/Shinobi/videos"
# "/state/shinobi/db-data:/var/lib/mysql"
# "/etc/localtime:/etc/localtime:ro"
# ];
# };
# shinobi-od = {
# image = "shinobisystems/shinobi-tensorflow:latest";
# volumes =
@ -129,41 +147,4 @@ in {
};
};
};
services.nginx = {
enable = true;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
virtualHosts = {
"panopticon.sea.fudo.org" = {
locations."/" = {
# localhost defaults to IPv6
proxyPass = "http://127.0.0.1:${shinobi-port}/";
extraConfig = ''
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
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;
'';
};
};
# "panopticon-od.sea.fudo.org" = {
# locations."/" = {
# proxyPass = "http://localhost:${shinobi-od-port}";
# extraConfig = ''
# proxy_http_version 1.1;
# proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection "Upgrade";
# '';
# };
# };
};
};
}

View File

@ -42,19 +42,19 @@ in {
# informis.cl-gemini = {
# enable = true;
# hostname = "gemini.informis.land";
# hostname = "gemini.fudo.org";
# server-ip = host-ipv4;
# document-root = "/srv/gemini/root";
# textfiles-archive = "${pkgs.textfiles}";
# document-root = "/state/gemini/root";
# # textfiles-archive = "${pkgs.textfiles}";
# slynk-port = 4005;
# feeds = {
# viator = {
# title = "viator's phlog";
# path = "/home/viator/gemini-public/feed/";
# url = "gemini://informis.land/user/viator/feed/";
# };
# };
# # feeds = {
# # viator = {
# # title = "viator's phlog";
# # path = "/home/viator/gemini-public/feed/";
# # url = "gemini://informis.land/user/viator/feed/";
# # };
# # };
# };
fudo = {

View File

@ -10,7 +10,7 @@ let
domain-name = host-config.domain;
domain = config.fudo.domains.${domain-name};
dns-proxy-port = 5335;
# dns-proxy-port = 5335;
in {
config = {
@ -29,37 +29,24 @@ in {
intif2 = { useDHCP = false; };
};
nameservers = [ "10.0.0.1" ];
enableIPv6 = false;
# nameservers = [ "10.0.0.1" ];
# FIXME: this should be automatic
firewall.trustedInterfaces =
[ "intif0" "intif1" "intif2" "lo" "docker0" ];
# firewall.trustedInterfaces =
# [ "intif0" "intif1" "intif2" "lo" "docker0" ];
nat = {
enable = true;
externalInterface = "enp1s0";
internalInterfaces = [ "intif0" "intif1" "intif2" ];
};
# nat = {
# enable = true;
# externalInterface = "enp1s0";
# internalInterfaces = [ "intif0" "intif1" "intif2" ];
# };
};
fudo = {
hosts.limina.external-interfaces = [ "enp1s0" ];
local-network = {
enable = true;
domain = domain-name;
dns-servers = [ primary-ip ];
gateway = primary-ip;
dhcp-interfaces = [ "intif0" ];
dns-listen-ips = [ primary-ip "127.0.0.1" "127.0.1.1" "::1" ];
recursive-resolver = "${primary-ip} port 5353";
network = site.network;
dhcp-dynamic-network = site.dynamic-network;
search-domains = [ domain-name "fudo.org" ];
enable-reverse-mappings = true;
zone-definition = config.fudo.zones.${domain-name};
};
client.dns.external-interface = "enp1s0";
garbage-collector = {
@ -67,59 +54,67 @@ in {
timing = "weekly";
};
secure-dns-proxy = {
enable = true;
listen-port = dns-proxy-port;
upstream-dns =
[ "https://1.1.1.1/dns-query" "https://1.0.0.1/dns-query" ];
bootstrap-dns = "1.1.1.1";
allowed-networks =
[ "1.1.1.1/32" "1.0.0.1/32" "10.0.0.0/16" "localhost" "link-local" ];
listen-ips = [ primary-ip ];
};
};
virtualisation = {
docker = {
enable = true;
autoPrune.enable = true;
enableOnBoot = true;
};
oci-containers = {
backend = "docker";
containers = {
pihole = {
image = "pihole/pihole:2021.10";
autoStart = true;
ports = [ "5353:53/tcp" "5353:53/udp" "3080:80/tcp" ];
environment = {
# ServerIP = primary-ip;
VIRTUAL_HOST = "dns-hole.sea.fudo.org";
DNS1 = "${primary-ip}#${toString dns-proxy-port}";
};
volumes = [
"/state/pihole/etc-pihole/:/etc/pihole/"
"/state/pihole/etc-dnsmasq.d/:/etc/dnsmasq.d/"
];
};
services = {
local-network = {
enable = true;
internal-interfaces = [ "intif0" "intif1" "intif2" ];
external-interface = "enp1s0";
dns-filter-proxy.enable = true;
};
metrics = {
prometheus.state-directory = "/state/services/prometheus";
};
# wireguard-gateway = {
# enable = true;
# network = "10.0.200.0/24";
# peers = {
# niten-phone = {
# public-key = "";
# assigned-ip = "10.0.200.2";
# };
# };
# };
};
};
# virtualisation = {
# docker = {
# enable = true;
# autoPrune.enable = true;
# enableOnBoot = true;
# };
# oci-containers = {
# backend = "docker";
# containers = {
# pihole = {
# image = "pihole/pihole:2021.10";
# autoStart = true;
# ports = [ "5353:53/tcp" "5353:53/udp" "3080:80/tcp" ];
# environment = {
# # ServerIP = primary-ip;
# VIRTUAL_HOST = "dns-hole.sea.fudo.org";
# DNS1 = "${primary-ip}#${toString dns-proxy-port}";
# };
# volumes = [
# "/state/pihole/etc-pihole/:/etc/pihole/"
# "/state/pihole/etc-dnsmasq.d/:/etc/dnsmasq.d/"
# ];
# };
# };
# };
# };
# Support for statelessness
environment.etc = {
# TODO: replace with current config
nixos.source = "/state/nixos";
# nixos.source = "/state/nixos";
NIXOS.source = "/state/etc/NIXOS";
"host-config.nix".source = "/state/etc/host-config.nix";
};
security.sudo.extraConfig = ''
# rollback results in sudo lectures after each reboot
Defaults lecture = never
'';
systemd.tmpfiles.rules = [
"L /etc/adjtime - - - - /state/etc/adjtime"
"L /root/.gnupg - - - - /state/root/gnupg"
@ -135,72 +130,72 @@ in {
systemd.services.nginx.requires = [ "bind.service" ];
services = {
nginx = {
enable = true;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
# nginx = {
# enable = true;
# recommendedGzipSettings = true;
# recommendedOptimisation = true;
# recommendedProxySettings = true;
virtualHosts = {
"dns-hole.${domain-name}" = {
serverAliases = [
"pi-hole.${domain-name}"
"pihole.${domain-name}"
"hole.${domain-name}"
"pi-hole"
"pihole"
"dns-hole"
"hole"
];
# virtualHosts = {
# "dns-hole.${domain-name}" = {
# serverAliases = [
# "pi-hole.${domain-name}"
# "pihole.${domain-name}"
# "hole.${domain-name}"
# "pi-hole"
# "pihole"
# "dns-hole"
# "hole"
# ];
locations."/" = { proxyPass = "http://127.0.0.1:3080"; };
};
# locations."/" = { proxyPass = "http://127.0.0.1:3080"; };
# };
## This keeps failing, too many requests...give it a rest for now
# "sea-camera.fudo.link" = {
# enableACME = true;
# forceSSL = true;
# ## This keeps failing, too many requests...give it a rest for now
# # "sea-camera.fudo.link" = {
# # enableACME = true;
# # forceSSL = true;
# locations."/" = {
# # proxyPass = "http://cargo.sea.fudo.org:5000/webman/3rdparty/SurveillanceStation/";
# proxyPass = "http://cargo.sea.fudo.org:5000/";
# # locations."/" = {
# # # proxyPass = "http://cargo.sea.fudo.org:5000/webman/3rdparty/SurveillanceStation/";
# # proxyPass = "http://cargo.sea.fudo.org:5000/";
# extraConfig = ''
# proxy_http_version 1.1;
# proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection "Upgrade";
# # extraConfig = ''
# # proxy_http_version 1.1;
# # proxy_set_header Upgrade $http_upgrade;
# # proxy_set_header Connection "Upgrade";
# proxy_set_header Host $host;
# # proxy_set_header X-Real-IP $remote_addr;
# # proxy_set_header X-Forwarded-By $server_addr:$server_port;
# # proxy_set_header X-Forwarded-For $remote_addr;
# # proxy_set_header X-Forwarded-Proto $scheme;
# '';
# };
# };
# # proxy_set_header Host $host;
# # # proxy_set_header X-Real-IP $remote_addr;
# # # proxy_set_header X-Forwarded-By $server_addr:$server_port;
# # # proxy_set_header X-Forwarded-For $remote_addr;
# # # proxy_set_header X-Forwarded-Proto $scheme;
# # '';
# # };
# # };
# "sea-camera-od.fudo.link" = {
# enableACME = true;
# forceSSL = true;
# # "sea-camera-od.fudo.link" = {
# # enableACME = true;
# # forceSSL = true;
# locations."/" = {
# proxyPass = "http://panopticon-od.sea.fudo.org";
# # 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";
# # extraConfig = ''
# # proxy_http_version 1.1;
# # proxy_set_header Upgrade $http_upgrade;
# # proxy_set_header Connection "Upgrade";
# proxy_set_header Host $host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-By $server_addr:$server_port;
# proxy_set_header X-Forwarded-For $remote_addr;
# proxy_set_header X-Forwarded-Proto $scheme;
# '';
# };
# };
};
};
# # proxy_set_header Host $host;
# # proxy_set_header X-Real-IP $remote_addr;
# # proxy_set_header X-Forwarded-By $server_addr:$server_port;
# # proxy_set_header X-Forwarded-For $remote_addr;
# # proxy_set_header X-Forwarded-Proto $scheme;
# # '';
# # };
# # };
# };
# };
openssh = {
hostKeys = [

View File

@ -41,15 +41,79 @@ in {
};
};
systemd.services.nfs-server = {
# Don't start on boot
wantedBy = mkForce [ "sea-store.target" ];
# Only start after filesystem mounts are available
after = [
"export-documents.mount"
"export-downloads.mount"
"export-projects.mount"
];
systemd = {
tmpfiles.rules = [ "d /state/services 0755 root root - -" ];
services = {
nfs-server = {
# Don't start on boot
wantedBy = mkForce [ "sea-store.target" ];
# Only start after filesystem mounts are available
after = [
"export-documents.mount"
"export-downloads.mount"
"export-projects.mount"
];
};
grafana = {
requires = [ "postgresql.service" ];
bindsTo = [ "postgresql.service" ];
};
};
};
fudo = let
grafana-database-passwd-file = pkgs.lib.passwd.stablerandom-passwd-file
"grafana-database-nostromo-password"
"grafana-database-nostromo-password-${config.instance.build-seed}";
host-secrets = config.fudo.secrets.host-secrets.${hostname};
in {
secrets.host-secrets.${hostname} = {
grafana-database-password = {
source-file = grafana-database-passwd-file;
target-file = "/run/services/grafana/db.passwd";
user = config.systemd.services.grafana.serviceConfig.User;
};
postgres-grafana-password = {
source-file = grafana-database-passwd-file;
target-file = "/run/services/postgres/db.passwd";
user = config.services.postgresql.superUser;
};
};
services = {
logging.loki.state-directory = "/state/services/loki";
metrics.grafana = {
state-directory = "/state/services/grafana";
smtp.hostname = "mail.fudo.org";
database = {
user = "grafana";
password-file = host-secrets.grafana-database-password.target-file;
};
ldap.base-dn = "dc=fudo,dc=org";
};
};
postgresql = {
enable = true;
local-networks = config.instance.local-networks;
state-directory = "/state/services/postgresql";
databases.grafana.users = config.instance.local-admins;
users.grafana = {
password-file = host-secrets.postgres-grafana-password.target-file;
databases.grafana = {
entity-access = {
"ALL TABLES IN SCHEMA public" = "ALL PRIVILEGES";
"ALL SEQUENCES IN SCHEMA public" = "ALL PRIVILEGES";
};
};
};
};
};
## Until I can figure out how to use one common host API, forget this

View File

@ -14,18 +14,21 @@ let
host-secrets = config.fudo.secrets.host-secrets.${hostname};
postgresql-user =
config.systemd.services.postgresql.serviceConfig.User;
postgresql-user = config.systemd.services.postgresql.serviceConfig.User;
files = config.fudo.secrets.files;
acme-copies = config.fudo.acme.host-domains.${hostname};
grafana-database-passwd-file =
pkgs.lib.passwd.stablerandom-passwd-file "grafana-database-password"
"grafana-database-password-${config.instance.build-seed}";
in {
imports = [
./nutboy3/cashew.nix
./nutboy3/forum_selby_ca.nix
# ./nutboy3/forum_selby_ca.nix
];
config = {
@ -42,15 +45,25 @@ in {
}];
};
systemd.tmpfiles.rules = [ "L /etc/adjtime - - - - /state/etc/adjtime" ];
systemd = {
tmpfiles.rules = [
"L /etc/adjtime - - - - /state/etc/adjtime"
"d /state/services 0555 - - - -"
];
services.grafana = {
bindsTo = [ "postgresql.service" ];
requires = [ "postgresql.service" ];
};
};
environment.systemPackages = local-packages;
environment = { systemPackages = local-packages; };
security.acme.email = "admin@fudo.org";
fudo = {
hosts.${hostname}.external-interfaces = [ "extif0" ];
secrets.host-secrets.nutboy3 = let
files = config.fudo.secrets.files;
secrets.host-secrets.${hostname} = let files = config.fudo.secrets.files;
in {
heimdal-master-key = {
source-file = files.realm-master-keys."FUDO.ORG";
@ -69,6 +82,18 @@ in {
target-file = "/run/postgresql/postgres.keytab";
user = postgresql-user;
};
grafana-database-password = {
source-file = grafana-database-passwd-file;
target-file = "/run/metrics/grafana/db.passwd";
user = config.systemd.services.grafana.serviceConfig.User;
};
postgres-grafana-password = {
source-file = grafana-database-passwd-file;
target-file = "/run/postgres-users/grafana.passwd";
user = config.services.postgresql.superUser;
};
};
acme.host-domains.${hostname} = {
@ -96,12 +121,11 @@ in {
services = {
jabber = {
enable = true;
domain = "jabber.fudo.org";
hostname = "jabber.fudo.org";
ldap.servers = [ "nutboy3.fudo.org" ];
state-directory = "/state/ejabberd";
};
auth = {
ldap.state-directory = "/state/auth/ldap";
kerberos = {
@ -109,6 +133,34 @@ in {
master-key-file = host-secrets.heimdal-master-key.target-file;
};
};
postgresql = {
state-directory = "/state/services/postgresql";
keytab =
config.fudo.secrets.files.service-keytabs.${hostname}.postgres;
};
metrics = {
prometheus.state-directory = "/state/services/prometheus";
grafana = {
state-directory = "/state/services/grafana";
database = {
user = "grafana";
password-file =
host-secrets.grafana-database-password.target-file;
};
};
};
logging.loki.state-directory = "/state/services/loki";
selby-forum = {
enable = true;
state-directory = "/state/services/selby-forum";
legacy-forum-data = files.blobs."selby-forum-2021-12-14.clean";
external-interface = "extif0";
mail.host = "mail.fudo.org";
};
};
# dns.state-directory = "/state/nsd";
@ -155,16 +207,21 @@ in {
# };
# };
postgresql = let
cert-copy = acme-copies.${host-fqdn}.local-copies.postgresql;
in {
enable = true;
ssl-certificate = cert-copy.full-certificate;
ssl-private-key = cert-copy.private-key;
keytab = host-secrets.postgresql-keytab.target-file;
local-networks = config.instance.local-networks;
state-directory = "/state/postgresql";
required-services = [ cert-copy.service config.fudo.secrets.secret-target ];
postgresql = {
databases.grafana.users = config.instance.local-admins;
users.grafana = {
password-file = host-secrets.postgres-grafana-password.target-file;
databases.grafana = {
access = "CONNECT";
entity-access = {
"ALL TABLES IN SCHEMA public" = "ALL PRIVILEGES";
# "SELECT,INSERT,UPDATE,DELETE";
"ALL SEQUENCES IN SCHEMA public" = "ALL PRIVILEGES";
# "SELECT, UPDATE";
};
};
};
};
# git = {

View File

@ -6,8 +6,6 @@ let
hostname = config.instance.hostname;
host-secrets = config.fudo.secrets.host-secrets.${hostname};
discourse-user = config.systemd.services.discourse.serviceConfig.User;
database-name = "forum_selby_ca";
database-user = "forum_selby_ca";
@ -35,31 +33,24 @@ let
}
'';
in {
config = {
services.discourse = {
enable = true;
hostname = site;
enableACME = true;
plugins = with config.services.discourse.package.plugins; [
discourse-migratepassword
];
admin = {
username = "admin";
fullName = "Admin";
email = "admin@selby.ca";
passwordFile = host-secrets.selby-discourse-admin.target-file;
};
database = {
name = database-name;
host = "localhost";
username = database-user;
passwordFile =
host-secrets.selby-discourse-database-passwd.target-file;
};
head-pkgs = let
nixos = pkgs.fetchgit {
url = "https://github.com/nixos/nixpkgs.git";
rev = "21.11";
sha256 = "162dywda2dvfj1248afxc45kcrg83appjd0nmdb541hl7rnncf02";
};
in import "${nixos}" {
system = pkgs.system;
config = pkgs.config;
overlays = pkgs.overlays;
};
in {
config = let
admin-pw-file = "admin.passwd";
db-pw-file = "database.passwd";
data-file = "data-forum_selby_ca.txt";
in {
fudo = {
secrets.host-secrets.${hostname} = let
@ -72,8 +63,8 @@ in {
in {
selby-discourse-database-passwd = {
source-file = selby-discourse-db-password;
target-file = "/run/selby/forum/database.passwd";
user = discourse-user;
target-file = "/run/selby/forum/${db-pw-file}";
user = "root";
};
postgresql-selby-discourse-password = {
@ -86,14 +77,14 @@ in {
source-file = pkgs.lib.passwd.stablerandom-passwd-file
"selby-discourse-admin"
"selby-discourse-admin-${config.instance.build-seed}";
target-file = "/run/selby/forum/admin.passwd";
user = discourse-user;
target-file = "/run/selby/forum/${admin-pw-file}";
user = "root";
};
selby-forum-data = {
source-file = files.blobs."selby-forum-2021-12-14.clean";
target-file = "/run/selby/forum/forum-data.txt";
user = discourse-user;
target-file = "/run/selby/forum/${data-file}";
user = "root";
};
selby-forum-passwords-sql = {
@ -118,27 +109,139 @@ in {
};
};
security.acme.certs.${site}.email = "admin@selby.ca";
## Fuckin what why won't this cert work?
services.nginx = {
enable = true;
recommendedOptimisation = true;
recommendedGzipSettings = true;
recommendedProxySettings = true;
virtualHosts = {
"${site}" = {
enableACME = true;
forceSSL = true;
locations."/".proxyPass = "http://192.168.55.2:80";
};
};
};
containers.selby-forum = let
parent-host = "192.168.55.1";
container-host = "192.168.55.2";
in {
ephemeral = true;
privateNetwork = true;
localAddress = container-host;
hostAddress = parent-host;
autoStart = true;
bindMounts = {
"/run/selby-discourse" = {
hostPath = "/run/selby/forum";
isReadOnly = true;
};
"/var/lib/discourse" = {
hostPath = state-directory;
isReadOnly = false;
};
};
config = { config, lib, ... }: let
discourse-user = config.systemd.services.discourse.serviceConfig.User;
in {
nixpkgs.pkgs = head-pkgs;
environment.systemPackages = with pkgs; [
nmap
];
networking.firewall.enable = false;
services.discourse = {
enable = true;
hostname = site;
enableACME = false;
plugins = with config.services.discourse.package.plugins; [
discourse-migratepassword
];
admin = {
username = "admin";
fullName = "Admin";
email = "admin@selby.ca";
passwordFile = "/etc/selby-discourse/${admin-pw-file}";
};
database = {
name = database-name;
host = parent-host;
username = database-user;
passwordFile = "/etc/selby-discourse/${db-pw-file}";
};
};
environment.etc = {
"selby-discourse/${admin-pw-file}" = {
source = "/run/selby-discourse/${admin-pw-file}";
user = discourse-user;
mode = "0400";
};
"selby-discourse/${db-pw-file}" = {
source = "/run/selby-discourse/${db-pw-file}";
user = discourse-user;
mode = "0400";
};
"selby-discourse/${data-file}" = {
source = "/run/selby-discourse/${data-file}";
user = discourse-user;
mode = "0400";
};
};
systemd = {
tmpfiles.rules = [
"/run/discourse 750 ${discourse-user} ${discourse-user} - -"
"/var/lib/discourse 750 ${discourse-user} ${discourse-user} - -"
];
services = {
discourse = {
after = [ "multi-user.target" ];
};
discourse-import-vanilla = let
env-without-path =
filterAttrs (attr: _: attr != "PATH")
config.systemd.services.discourse.environment;
selby-forum-data = container-selby-forum-data-file;
in {
description = "One-off job to import Vanilla forum.";
path = config.systemd.services.discourse.path;
environment = env-without-path;
serviceConfig = {
User = config.systemd.services.discourse.serviceConfig.User;
Group = config.systemd.services.discourse.serviceConfig.Group;
Type = "oneshot";
WorkingDirectory = config.systemd.services.discourse.serviceConfig.WorkingDirectory;
ExecStart = pkgs.writeShellScript "import-vanilla-forum.sh" ''
ruby script/import_scripts/vanilla.rb /etc/selby-discourse/${data-file}
'';
};
};
};
};
};
};
systemd = {
tmpfiles.rules = [
"d ${state-directory} 750 ${discourse-user} - - -"
"L /var/lib/discourse - - - - ${state-directory}"
"d ${state-directory} 750 - - - -"
];
services = {
discourse = {
bindsTo = [ "postgresql.service" ];
after = [
config.fudo.postgresql.systemd-target
"postgresql.service"
];
};
discourse-prepare = {
description = "Do discourse's superuser-requiring database work for it.";
wantedBy = [ "discourse.service" ];
before = [ "discourse.service" ];
wantedBy = [ "container@forum-selby-ca.service" ];
before = [ "container@forum-selby-ca.service" ];
requires = [ config.fudo.postgresql.systemd-target ];
after = [ config.fudo.postgresql.systemd-target ];
path = with pkgs; [ postgresql ];
@ -151,34 +254,13 @@ in {
};
};
discourse-import-vanilla = let
env-without-path =
filterAttrs (attr: _: attr != "PATH")
config.systemd.services.discourse.environment;
selby-forum-data = host-secrets.selby-forum-data.target-file;
in {
description = "One-off job to import Vanilla forum.";
path = config.systemd.services.discourse.path;
environment = env-without-path;
serviceConfig = {
User = config.systemd.services.discourse.serviceConfig.User;
Group = config.systemd.services.discourse.serviceConfig.Group;
Type = "oneshot";
WorkingDirectory = config.systemd.services.discourse.serviceConfig.WorkingDirectory;
ExecStart = pkgs.writeShellScript "import-vanilla-forum.sh" ''
ruby script/import_scripts/vanilla.rb ${selby-forum-data}
'';
};
};
discourse-add-password-hash = let
alter-user-script = pkgs.writeText "create-password-column.sql" ''
ALTER TABLE users ADD COLUMN IF NOT EXISTS import_pass VARCHAR (64);
ALTER TABLE users ADD COLUMN IF NOT EXISTS import_pass VARCHAR (128);
'';
in {
description = "One-off job to add user password hashes from Vanilla forum.";
path = with pkgs; [ postgresql ];
wantedBy = [ "discourse.service" ];
serviceConfig = {
User = config.services.postgresql.superUser;
Type = "oneshot";

View File

@ -23,6 +23,11 @@ let
host-certs = config.fudo.acme.host-domains.${hostname};
grafana-database-password =
pkgs.lib.passwd.stablerandom-passwd-file
"grafana-database-password-${hostname}"
"grafana-database-password-${hostname}-${config.instance.build-seed}";
in {
networking = {
dhcpcd.enable = false;
@ -55,6 +60,8 @@ in {
networking.firewall.allowedTCPPorts = [ 80 443 ];
security.acme.email = "viator@informis.land";
users = {
users = {
gituser = {
@ -84,17 +91,17 @@ in {
};
};
services.chute = let
secret-files = config.fudo.secrets.files.service-secrets.procul;
in {
enable = true;
jabber-user = "niten@jabber.fudo.org";
staging = {
secret-file = secret-files."chute-staging.secret";
passphrase-file = secret-files."chute-staging.passphrase";
key-file = secret-files."chute-staging.key";
};
};
# services.chute = let
# secret-files = config.fudo.secrets.files.service-secrets.procul;
# in {
# enable = true;
# jabber-user = "niten@jabber.fudo.org";
# staging = {
# secret-file = secret-files."chute-staging.secret";
# passphrase-file = secret-files."chute-staging.passphrase";
# key-file = secret-files."chute-staging.key";
# };
# };
};
fudo = {
@ -112,31 +119,31 @@ in {
};
};
"imap.${domain-name}" = {
admin-email = "admin@${domain-name}";
local-copies.dovecot = {
user = config.services.dovecot2.user;
dependent-services = [ "dovecot2.service" ];
};
};
# "imap.${domain-name}" = {
# admin-email = "admin@${domain-name}";
# local-copies.dovecot = {
# user = config.services.dovecot2.user;
# dependent-services = [ "dovecot2.service" ];
# };
# };
"smtp.${domain-name}" = {
admin-email = "admin@${domain-name}";
local-copies.postfix = {
user = config.services.postfix.user;
dependent-services = [ "postfix.service" ];
};
};
# "smtp.${domain-name}" = {
# admin-email = "admin@${domain-name}";
# local-copies.postfix = {
# user = config.services.postfix.user;
# dependent-services = [ "postfix.service" ];
# };
# };
};
secrets.host-secrets.procul = let
files = config.fudo.secrets.files;
in {
postgres-keytab = {
source-file = files.service-keytabs.procul.postgres;
target-file = "/srv/postgres/secure/postgres.keytab";
user = "root";
};
# postgres-keytab = {
# source-file = files.service-keytabs.procul.postgres;
# target-file = "/srv/postgres/secure/postgres.keytab";
# user = "root";
# };
gitea-database-password = {
source-file = files.service-passwords.procul.gitea-database;
@ -144,6 +151,12 @@ in {
user = config.fudo.git.user;
};
postgres-gitea-password = {
source-file = files.service-passwords.procul.gitea-database;
target-file = "/srv/postgres-users/database.passwd";
user = config.services.postgresql.superUser;
};
heimdal-master-key = {
source-file = files.realm-master-keys."INFORMIS.LAND";
target-file = "/run/heimdal/master-key";
@ -155,6 +168,18 @@ in {
target-file = "/run/chute/staging/credentials.env";
user = "root";
};
grafana-postgres-password = {
source-file = grafana-database-password;
target-file = "/run/metrics/grafana/db.passwd";
user = config.systemd.services.grafana.serviceConfig.User;
};
postgres-grafana-password = {
source-file = grafana-database-password;
target-file = "/run/postgres-users/grafana.passwd";
user = config.services.postgresql.superUser;
};
};
client.dns = {
@ -164,15 +189,6 @@ in {
external-interface = "extif0";
};
services = {
auth = {
kerberos = {
state-directory = "/var/lib/kerberos";
master-key-file = host-secrets.heimdal-master-key.target-file;
};
};
};
secure-dns-proxy = {
enable = true;
upstream-dns =
@ -183,67 +199,112 @@ in {
allowed-networks = [ "1.1.1.1/32" "1.0.0.1/32" "localhost" "link-local" ];
};
mail-server = {
enable = true;
debug = true;
services.mail-server = {
state-directory = "/srv/mailserver";
};
domain = domain-name;
mail-hostname = "${host-fqdn}";
monitoring = false;
mail-user = "mailuser";
mail-user-id = 525;
mail-group = "mailgroup";
clamav.enable = true;
dkim.signing = true;
# mail-server = {
# enable = true;
# debug = true;
dovecot = let
cert-copy =
host-certs."imap.${domain-name}".local-copies.dovecot;
in {
ssl-certificate = cert-copy.full-certificate;
ssl-private-key = cert-copy.private-key;
# domain = domain-name;
# mail-hostname = "${host-fqdn}";
# monitoring = false;
# mail-user = "mailuser";
# mail-user-id = 525;
# mail-group = "mailgroup";
# clamav.enable = true;
# dkim.signing = true;
# dovecot = let
# cert-copy =
# host-certs."imap.${domain-name}".local-copies.dovecot;
# in {
# ssl-certificate = cert-copy.full-certificate;
# ssl-private-key = cert-copy.private-key;
# };
# postfix = let
# cert-copy =
# host-certs."smtp.${domain-name}".local-copies.postfix;
# in {
# ssl-certificate = cert-copy.full-certificate;
# ssl-private-key = cert-copy.private-key;
# };
# # This should NOT include the primary domain
# local-domains = [ host-fqdn "smtp.${domain-name}" ];
# mail-directory = "/srv/mailserver/mail";
# state-directory = "/srv/mailserver/state";
# trusted-networks = [ "172.86.179.16/29" "127.0.0.0/16" ];
# alias-users = {
# root = [ "niten" ];
# postmaster = [ "niten" ];
# hostmaster = [ "niten" ];
# webmaster = [ "niten" ];
# system = [ "niten" ];
# admin = [ "niten" ];
# dmarc-report = [ "niten" ];
# };
# };
services = {
auth = {
kerberos = {
state-directory = "/var/lib/kerberos";
master-key-file = host-secrets.heimdal-master-key.target-file;
};
};
postfix = let
cert-copy =
host-certs."smtp.${domain-name}".local-copies.postfix;
in {
ssl-certificate = cert-copy.full-certificate;
ssl-private-key = cert-copy.private-key;
dns.zones."informis.land" = {
enable = true;
default-host = host-ipv4;
};
# This should NOT include the primary domain
local-domains = [ host-fqdn "smtp.${domain-name}" ];
mail-directory = "/srv/mailserver/mail";
state-directory = "/srv/mailserver/state";
trusted-networks = [ "172.86.179.16/29" "127.0.0.0/16" ];
alias-users = {
root = [ "niten" ];
postmaster = [ "niten" ];
hostmaster = [ "niten" ];
webmaster = [ "niten" ];
system = [ "niten" ];
admin = [ "niten" ];
dmarc-report = [ "niten" ];
postgresql = {
state-directory = "/state/services/postgresql";
keytab = config.fudo.secrets.files.service-keytabs.procul.postgres;
};
logging.loki.state-directory = "/state/services/loki";
metrics = {
prometheus.state-directory = "/state/services/prometheus";
grafana = {
state-directory = "/state/services/grafana";
database = {
user = "grafana";
password-file = host-secrets.grafana-postgres-password.target-file;
};
};
};
};
postgresql = let
cert-copy = host-certs.${host-fqdn}.local-copies.postgresql;
# cert-copy = host-certs.${host-fqdn}.local-copies.postgresql;
in {
enable = true;
ssl-certificate = cert-copy.full-certificate;
ssl-private-key = cert-copy.private-key;
keytab = host-secrets.postgres-keytab.target-file;
local-networks = local-networks;
# enable = true;
# ssl-certificate = cert-copy.full-certificate;
# ssl-private-key = cert-copy.private-key;
# keytab = host-secrets.postgres-keytab.target-file;
# local-networks = local-networks;
users = {
grafana = {
password-file = host-secrets.postgres-grafana-password.target-file;
databases.grafana = {
access = "CONNECT";
entity-access = {
"ALL TABLES IN SCHEMA public" = "ALL PRIVILEGES";
# "SELECT,INSERT,UPDATE,DELETE";
"ALL SEQUENCES IN SCHEMA public" = "ALL PRIVILEGES";
# "SELECT, UPDATE";
};
};
};
gituser = {
password-file =
host-secrets.gitea-database-password.target-file;
host-secrets.postgres-gitea-password.target-file;
databases = {
git = {
access = "CONNECT";
@ -256,7 +317,10 @@ in {
};
};
databases = { git = { users = [ "niten" ]; }; };
databases = {
grafana.users = config.instance.local-admins;
git.users = config.instance.local-admins;
};
};
git = {

View File

@ -35,6 +35,7 @@ in {
environment = {
systemPackages = with pkgs; [
nixopsUnstable
openssl
];
etc = {

View File

@ -7,6 +7,7 @@
interfaces = {
intif0.useDHCP = true;
};
firewall.enable = false;
};
i18n.inputMethod = {
@ -16,4 +17,12 @@
fcitx5-rime
];
};
# fudo.adguard-dns-proxy = {
# enable = true;
# http.listen-ip = "10.0.0.108";
# dns.listen-port = 1053;
# local-domain-name = "sea.fudo.org";
# verbose = true;
# };
}

View File

@ -19,18 +19,21 @@ in {
"L /var/lib/flatpak - - - - ${state-dir}/lib/flatpak"
];
services.openssh.hostKeys = [
{
path = "${state-dir}/ssh/ssh_host_rsa_key";
type = "rsa";
bits = 4096;
}
{
path = "${state-dir}/ssh/ssh_host_ed25519_key";
type = "ed25519";
bits = 4096;
}
];
services = {
blueman.enable = true;
openssh.hostKeys = [
{
path = "${state-dir}/ssh/ssh_host_rsa_key";
type = "rsa";
bits = 4096;
}
{
path = "${state-dir}/ssh/ssh_host_ed25519_key";
type = "ed25519";
bits = 4096;
}
];
};
environment.etc = {
"ssh/ssh_host_rsa_key" = {
@ -63,8 +66,13 @@ in {
NIXOS.source = "${state-dir}/host/NIXOS";
};
hardware.bluetooth.enable = true;
hardware.xpadneo.enable = true;
hardware = {
bluetooth = {
enable = true;
package = pkgs.bluezFull;
};
xpadneo.enable = true;
};
security.sudo.extraConfig = ''
# Due to rollback, sudo will lecture after every reboot

View File

@ -6,6 +6,7 @@ with lib;
local-host = config.instance.hostname;
local-domain = config.fudo.hosts.${local-host}.domain;
local-site = config.fudo.hosts.${local-host}.site;
local-zone = config.fudo.domains.${local-domain}.zone;
host = config.fudo.hosts.${local-host};
@ -55,7 +56,8 @@ with lib;
local-groups
local-hosts
local-profile
local-networks;
local-networks
local-zone;
};
};
}

View File

@ -4,6 +4,7 @@ with lib;
let
hostname = config.instance.hostname;
domain = config.instance.local-domain;
zone-name = domain.zone;
cfg = config.fudo.domains.${domain};
in {
@ -38,33 +39,31 @@ in {
};
};
dns.domains.${domain} = {
zone-definition = mkIf kerberized-domain {
srv-records = let
get-fqdn = hostname:
"${hostname}.${config.fudo.hosts.${hostname}.domain}";
zones.${zone-name} = {
srv-records = let
get-fqdn = hostname:
"${hostname}.${config.fudo.hosts.${hostname}.domain}";
create-srv-record = port: hostname: {
port = port;
host = hostname;
};
create-srv-record = port: hostname: {
port = port;
host = hostname;
};
all-servers = map get-fqdn
([cfg.kerberos-master] ++ cfg.kerberos-slaves);
all-servers = map get-fqdn
([cfg.kerberos-master] ++ cfg.kerberos-slaves);
master-servers =
map get-fqdn [cfg.kerberos-master];
master-servers =
map get-fqdn [cfg.kerberos-master];
in {
tcp = {
kerberos = map (create-srv-record 88) all-servers;
kerberos-adm = map (create-srv-record 749) master-servers;
};
udp = {
kerberos = map (create-srv-record 88) all-servers;
kerberos-master = map (create-srv-record 88) master-servers;
kpasswd = map (create-srv-record 464) master-servers;
};
in {
tcp = {
kerberos = map (create-srv-record 88) all-servers;
kerberos-adm = map (create-srv-record 749) master-servers;
};
udp = {
kerberos = map (create-srv-record 88) all-servers;
kerberos-master = map (create-srv-record 88) master-servers;
kpasswd = map (create-srv-record 464) master-servers;
};
};
};

View File

@ -2,6 +2,8 @@
with lib;
let
hostname = config.instance.hostname;
# Available to all users on the system. Keep it minimal.
global-packages = with pkgs; [
bind
@ -15,11 +17,7 @@ let
wget
];
import-paths = [
./build
./host
./user
];
import-paths = [ ./build ./host ./user ];
in {
@ -27,31 +25,25 @@ in {
is-regular-file = filename: type: type == "regular" || type == "link";
regular-files = path:
attrNames (filterAttrs is-regular-file (builtins.readDir path));
is-nix-file = filename: (builtins.match "^(.+)\.nix$" filename) != null;
is-nix-file = filename: (builtins.match "^(.+).nix$" filename) != null;
nix-files = path:
map
(file: path + "/${file}")
(filter is-nix-file (regular-files path));
map (file: path + "/${file}") (filter is-nix-file (regular-files path));
in concatMap nix-files import-paths;
config = {
environment = {
etc.nixos-live.source = ../../.;
systemPackages = global-packages;
};
fudo.hosts.${hostname}.local-networks = [ "::1/128" ];
system.autoUpgrade.enable = false;
nix = {
package = pkgs.nixFlakes;
extraOptions = ''
experimental-features = nix-command flakes
'';
experimental-features = nix-command flakes
'';
};
nixpkgs.config.allowUnfree = true;
security.acme.acceptTerms = true;
hardware.enableRedistributableFirmware = true;
krb5 = {
@ -82,19 +74,19 @@ in {
useDns = true;
permitRootLogin = "prohibit-password";
extraConfig = ''
GSSAPIAuthentication yes
GSSAPICleanupCredentials yes
GSSAPIKeyExchange yes
GSSAPIStoreCredentialsOnRekey yes
'';
GSSAPIAuthentication yes
GSSAPICleanupCredentials yes
GSSAPIKeyExchange yes
GSSAPIStoreCredentialsOnRekey yes
'';
};
fail2ban = let
domain-name = config.fudo.hosts.${config.instance.hostname}.domain;
in {
enable = config.networking.firewall.enable;
bantime-increment.enable = true;
};
fail2ban =
let domain-name = config.fudo.hosts.${config.instance.hostname}.domain;
in {
enable = config.networking.firewall.enable;
bantime-increment.enable = true;
};
xserver = {
layout = "us";
@ -102,6 +94,11 @@ in {
xkbOptions = "ctrl:nocaps";
};
btrfs.autoScrub.enable = let
btrfsFilesystems = filter (fsOpts: fsOpts.fsType == "btrfs")
(attrValues config.fileSystems);
in length btrfsFilesystems > 0;
# pcscd.enable = true;
# udev.packages = with pkgs; [ yubikey-personalization ];
};
@ -143,21 +140,27 @@ in {
};
};
security.pam = {
enableSSHAgentAuth = true;
security = {
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;
acme.acceptTerms = true;
sudo.extraConfig = ''
# rollback results in sudo lectures after each reboot
Defaults lecture = never
'';
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;
};
};
};
};
home-manager = {
useGlobalPkgs = true;
};
home-manager = { useGlobalPkgs = true; };
};
}

View File

@ -4,7 +4,7 @@ with lib;
let
list-contains = lst: item: any (i: i == item) lst;
domain-realm = domain: domainOpts: domainOpts.gssapi-realm;
domain-realm = _: domainOpts: domainOpts.gssapi-realm;
user-realms = username:
mapAttrsToList domain-realm

View File

@ -1,59 +1,217 @@
{ config, lib, pkgs, ... }:
{ config, lib, pkgs, ... } @ toplevel:
with lib;
let
hostname = config.instance.hostname;
domain-name = config.instance.local-domain;
domain = config.fudo.domains.${domain-name};
served-domain = domain.primary-nameserver != null;
cfg = config.fudo.services.dns;
is-primary-nameserver = hostname == domain.primary-nameserver;
nameserverOpts = { name, ... }: {
options = with types; {
hostname = mkOption {
type = str;
description = "Hostname of the external nameserver.";
default = name;
};
primary-nameserver = domain.primary-nameserver;
primary-nameserver-ip = pkgs.lib.network.host-ipv4 config primary-nameserver;
ipv4-address = mkOption {
type = nullOr str;
description = "Host ipv4 address of the external nameserver.";
default = null;
};
ipv6-address = mkOption {
type = nullOr str;
description = "Host ipv6 address of the external nameserver.";
default = null;
};
authoritative-hostname = mkOption {
type = nullOr str;
description = "Authoritative hostname of this nameserver.";
default = null;
};
description = mkOption {
type = str;
description = "Description of the external nameserver.";
};
};
};
zoneOpts = { name, ... }: let
zone-name = name;
in {
options = with types; {
enable = mkOption {
type = bool;
description = "Enable ${zone-name} zone on the local nameserver.";
default = zone-name == toplevel.config.instance.local-zone;
};
default-host = mkOption {
type = nullOr str;
description = "IP which will respond to requests for the base domain.";
default = null;
};
external-nameservers = mkOption {
type = listOf (submodule nameserverOpts);
description = "Off-network secondary nameservers.";
default = [];
};
domain = mkOption {
type = str;
description = "Domain which this zone serves.";
default = zone-name;
};
};
};
pthru = obj:
builtins.trace "TRACE: ${ obj }" obj;
in {
config = mkIf (served-domain) {
fudo.dns = {
enable = is-primary-nameserver;
options.fudo.services.dns = with types; {
zones = mkOption {
type = attrsOf (submodule zoneOpts);
description = "Map of served zone to extra zone details.";
default = {};
};
};
identity = "${hostname}.${domain-name}.";
config.fudo = {
zones = mapAttrs (zone-name: zone-cfg: let
domain-name = zone-cfg.domain;
domain = config.fudo.domains.${domain-name};
nameservers = {
ns1 = {
ipv4-address = primary-nameserver-ip;
description = "Primary ${domain-name} nameserver";
make-srv-record = port: host: {
inherit port host;
};
served-domain = domain.primary-nameserver != null;
primary-nameserver = domain.primary-nameserver;
is-primary-nameserver = hostname == primary-nameserver;
internal-nameserver-hostnames =
[domain.primary-nameserver] ++ domain.secondary-nameservers;
get-host-deets = description: hostname: {
ipv4-address = pkgs.lib.network.host-ipv4 config hostname;
ipv6-address = pkgs.lib.network.host-ipv6 config hostname;
description = description;
};
get-ns-deets = hostname: let
host-domain = config.fudo.hosts.${hostname}.domain;
desc = "${domain-name} nameserver ${hostname}.${host-domain}.";
in get-host-deets desc hostname;
nameserver-deets = let
internal-nameservers = map get-ns-deets internal-nameserver-hostnames;
in internal-nameservers ++ zone-cfg.external-nameservers;
has-auth-hostname = ns-host: ns-opts:
(hasAttr "authoritative-hostname" ns-opts) &&
(ns-opts.authoritative-hostname != null);
all-nameservers = listToAttrs
(imap1
(i: nsOpts:
nameValuePair "ns${toString i}" nsOpts)
nameserver-deets);
nameserver-aliases =
mapAttrs (hostname: opts: "${opts.authoritative-hostname}.")
(filterAttrs has-auth-hostname all-nameservers);
nameserver-hosts = mapAttrs (hostname: opts: {
inherit (opts) ipv4-address ipv6-address description;
}) (filterAttrs (hostname: opts: ! has-auth-hostname hostname opts)
all-nameservers);
dns-srv-records = let
nameserver-srv-records = mapAttrsToList
(hostname: hostOpts: let
target-host = if (has-auth-hostname hostname hostOpts) then
"${hostOpts.authoritative-hostname}" else
"${hostname}.${domain-name}";
in make-srv-record 53 target-host)
all-nameservers;
in {
tcp.domain = nameserver-srv-records;
udp.domain = nameserver-srv-records;
};
# TODO: move this to a mail service
mail-srv-records = optionalAttrs (domain.primary-mailserver != null) {
tcp = let
mailserver-domain = config.fudo.hosts.${domain.primary-mailserver}.domain;
fqdn = "mail.${mailserver-domain}";
in {
smtp = [(make-srv-record 25 fqdn)];
submission = [(make-srv-record 587 fqdn)];
imap = [(make-srv-record 143 fqdn)];
imaps = [(make-srv-record 993 fqdn)];
pop3 = [(make-srv-record 110 fqdn)];
pop3s = [(make-srv-record 995 fqdn)];
};
};
in {
gssapi-realm = domain.gssapi-realm;
hosts = nameserver-hosts // {
mail = mkIf (domain.primary-nameserver != null) (let
mailserver-deets = host: let
host-domain = config.fudo.hosts.${host}.domain;
in get-host-deets "Primary ${domain-name} mailserver ${host}.${host-domain}." host;
in mailserver-deets domain.primary-nameserver);
};
aliases = nameserver-aliases;
mx = optional (domain.primary-mailserver != null)
(let
mail-domain-name = config.fudo.hosts.${domain.primary-mailserver}.domain;
in "mail.${mail-domain-name}");
dmarc-report-address = "dmarc-report@${domain-name}";
nameservers = let
direct-external = attrValues nameserver-aliases;
internal = map (hostname: "${hostname}.${domain-name}.")
(attrNames nameserver-hosts);
in internal ++ direct-external;
srv-records = dns-srv-records // mail-srv-records;
}) cfg.zones;
dns = let
domain-name = config.instance.local-domain;
domain = config.fudo.domains.${domain-name};
primary-nameserver = domain.primary-nameserver;
primary-nameserver-ip = pkgs.lib.network.host-ipv4 config primary-nameserver;
primary-nameserver-fqdn = "${primary-nameserver}.${domain-name}";
is-primary-nameserver = primary-nameserver == hostname;
in {
enable = is-primary-nameserver;
identity = "${hostname}.${domain-name}";
listen-ips = optionals is-primary-nameserver
(pkgs.lib.network.host-ips config hostname);
domains = {
${domain-name} = {
dnssec = true;
default-host = primary-nameserver-ip;
gssapi-realm = domain.gssapi-realm;
mx = optional (domain.primary-mailserver != null)
domain.primary-mailserver;
dmarc-report-address = "dmarc-report@${domain-name}";
zone-definition = let
zone = config.fudo.zones.${domain-name};
make-dns-srv-record = hostname: {
port = 53;
host = hostname;
};
in zone // {
srv-records = {
tcp.domain = map make-dns-srv-record [ "ns1.${domain-name}" ];
udp.domain = map make-dns-srv-record [ "ns1.${domain-name}" ];
};
};
};
};
domains = mapAttrs' (zone-name: zone-cfg:
nameValuePair zone-cfg.domain
{
dnssec = true;
zone-definition = config.fudo.zones.${zone-name};
}) cfg.zones;
};
};
}

View File

@ -6,6 +6,8 @@ let
domain-name = config.fudo.services.auth.domain;
domain = config.fudo.domains.${domain-name};
zone-name = domain.zone;
ldap-server = elem hostname domain.ldap-servers;
kerberos-master = hostname == domain.kerberos-master;
@ -62,95 +64,97 @@ in {
};
};
config.fudo = {
acme.host-domains.${hostname} = mkIf (ldap-server) {
${cfg.ldap.hostname}.local-copies.openldap = {
user = config.services.openldap.user;
part-of = [ config.fudo.auth.ldap-server.systemd-target ];
config = {
fudo = {
acme.host-domains.${hostname} = mkIf (ldap-server) {
${cfg.ldap.hostname}.local-copies.openldap = {
user = config.services.openldap.user;
part-of = [ config.fudo.auth.ldap-server.systemd-target ];
};
};
};
auth = {
ldap-server = mkIf (ldap-server)
(let
ldap-cert-copy =
config.fudo.acme.host-domains.${hostname}.${cfg.ldap.hostname}.local-copies.openldap;
in {
enable = ldap-server;
base = "dc=fudo,dc=org";
organization = "Fudo";
listen-uris = [ "ldap:///" "ldaps:///" ];
required-services = [ ldap-cert-copy.service ];
auth = {
ldap-server = mkIf (ldap-server)
(let
ldap-cert-copy =
config.fudo.acme.host-domains.${hostname}.${cfg.ldap.hostname}.local-copies.openldap;
in {
enable = ldap-server;
base = "dc=fudo,dc=org";
organization = "Fudo";
listen-uris = [ "ldap:///" "ldaps:///" ];
required-services = [ ldap-cert-copy.service ];
# TODO: Maybe filter to Fudo-only?
users = config.fudo.users;
groups = config.fudo.groups;
system-users = config.fudo.system-users;
# TODO: Maybe filter to Fudo-only?
users = config.fudo.users;
groups = config.fudo.groups;
system-users = config.fudo.system-users;
state-directory = "${cfg.ldap.state-directory}";
state-directory = "${cfg.ldap.state-directory}";
ssl-chain = ldap-cert-copy.chain;
ssl-certificate = ldap-cert-copy.certificate;
ssl-private-key = ldap-cert-copy.private-key;
ssl-ca-certificate = "${pkgs.letsencrypt-ca}";
});
ssl-chain = ldap-cert-copy.chain;
ssl-certificate = ldap-cert-copy.certificate;
ssl-private-key = ldap-cert-copy.private-key;
ssl-ca-certificate = "${pkgs.letsencrypt-ca}";
});
kdc = mkIf (kerberos-master || kerberos-slave) {
enable = true;
realm = domain.gssapi-realm;
bind-addresses =
(pkgs.lib.network.host-ips config hostname) ++
[ "127.0.0.1" ] ++ (optional config.networking.enableIPv6 "::1");
state-directory = cfg.kerberos.state-directory;
master-key-file = cfg.kerberos.master-key-file;
master-config = mkIf (kerberos-master) {
acl = let
admin-entries = genAttrs config.instance.local-admins
(admin: {
perms = [ "add" "change-password" "list" ];
});
in admin-entries // {
"*/root".perms = [ "all" ];
kdc = mkIf (kerberos-master || kerberos-slave) {
enable = true;
realm = domain.gssapi-realm;
bind-addresses =
(pkgs.lib.network.host-ips config hostname) ++
[ "127.0.0.1" ] ++ (optional config.networking.enableIPv6 "::1");
state-directory = cfg.kerberos.state-directory;
master-key-file = cfg.kerberos.master-key-file;
master-config = mkIf (kerberos-master) {
acl = let
admin-entries = genAttrs config.instance.local-admins
(admin: {
perms = [ "add" "change-password" "list" ];
});
in admin-entries // {
"*/root".perms = [ "all" ];
};
};
slave-config = mkIf (kerberos-slave) {
master-host = domain.kerberos-master;
ipropd-keytab = cfg.kerberos.ipropd-keytab;
};
};
slave-config = mkIf (kerberos-slave) {
master-host = domain.kerberos-master;
ipropd-keytab = cfg.kerberos.ipropd-keytab;
};
};
};
dns.domains.${domain-name} = let
make-srv-record = port: hostname: {
port = port;
host = hostname;
};
get-fqdn = host:
"${host}.${config.fudo.hosts.${host}.domain}";
kerberos-masters = optional (kerberized-domain)
domain.kerberos-master;
kerberos-servers = map get-fqdn
(kerberos-masters ++ domain.kerberos-slaves);
master-servers = map get-fqdn kerberos-masters;
ldap-servers = map get-fqdn domain.ldap-servers;
in {
zone-definition.srv-records = {
tcp = {
kerberos = map (make-srv-record 88) kerberos-servers;
kerberos-adm = map (make-srv-record 749) kerberos-masters;
ldap = map (make-srv-record 389) ldap-servers;
ldaps = map (make-srv-record 636) ldap-servers;
zones.${zone-name} = let
make-srv-record = port: hostname: {
port = port;
host = hostname;
};
udp = {
kerberos = map (make-srv-record 88) kerberos-servers;
kerberos-master = map (make-srv-record 88) kerberos-masters;
kpasswd = map (make-srv-record 464) kerberos-masters;
get-fqdn = host:
"${host}.${config.fudo.hosts.${host}.domain}";
kerberos-master-hosts = optional (kerberized-domain)
domain.kerberos-master;
kerberos-servers = map get-fqdn
(kerberos-master-hosts ++ domain.kerberos-slaves);
kerberos-masters = map get-fqdn kerberos-master-hosts;
ldap-servers = map get-fqdn domain.ldap-servers;
in {
srv-records = {
tcp = {
kerberos = map (make-srv-record 88) kerberos-servers;
kerberos-adm = map (make-srv-record 749) kerberos-masters;
ldap = map (make-srv-record 389) ldap-servers;
ldaps = map (make-srv-record 636) ldap-servers;
};
udp = {
kerberos = map (make-srv-record 88) kerberos-servers;
kerberos-master = map (make-srv-record 88) kerberos-masters;
kpasswd = map (make-srv-record 464) kerberos-masters;
};
};
};
};

View File

@ -3,13 +3,16 @@
with lib;
let
cfg = config.fudo.services.jabber;
domain-name = config.instance.local-domain;
domain = config.fudo.domains.${domain-name};
zone-name = domain.zone;
hostname = config.instance.hostname;
host-secrets = config.fudo.secrets.host-secrets.${hostname};
xmpp-server = elem hostname domain.xmpp-servers;
in {
options.fudo.services.jabber = with types; {
enable = mkEnableOption "Enable Jabber server on this host.";
user = mkOption {
type = str;
description = "User as which to run the ejabberd server.";
@ -22,11 +25,13 @@ in {
default = "ejabberd";
};
hostname = mkOption {
type = str;
description = "Hostname of the user jabber server.";
default = "jabber.fudo.org";
};
# hostname = mkOption {
# type = str;
# description = "Hostname of the user jabber server.";
# default = "jabber.${domain-name}";
# };
enable-pubsub = mkEnableOption "Enable PubSub module.";
domain = mkOption {
type = str;
@ -57,6 +62,10 @@ in {
ejabberd-ldap-auth-passwd-file =
pkgs.lib.passwd.stablerandom-passwd-file "ejabberd-auth-passwd-file"
"ejabberd-auth-passwd-file-${config.instance.build-seed}";
hostname-map = listToAttrs
(imap0 (i: hostname: nameValuePair hostname "xmpp-${toString i}")
domain.xmpp-servers);
in {
system-users.${cfg.ldap.user} = {
description = "ejabberd authentication user.";
@ -65,7 +74,25 @@ in {
ejabberd-ldap-auth-passwd-file;
};
jabber = mkIf cfg.enable {
zones.${zone-name} = {
srv-records.tcp = let
to-fqdn = server: "${hostname-map.${server}}.${domain-name}";
in {
xmpp-server = map (host: {
host = to-fqdn host;
port = 5269;
}) domain.xmpp-servers;
xmpp-client = map (host: {
host = to-fqdn host;
port = 5222;
}) domain.xmpp-servers;
};
aliases = mapAttrs' (host: alias: nameValuePair alias host)
hostname-map;
};
jabber = mkIf xmpp-server {
enable = true;
state-directory = cfg.state-directory;
@ -76,7 +103,7 @@ in {
sites = {
${cfg.domain} = {
hostname = cfg.hostname;
hostname = "${hostname-map.${hostname}}.${domain-name}";
site-config = {
auth_method = "ldap";
ldap_servers = cfg.ldap.servers;

View File

@ -1,5 +1,6 @@
{ config, lib, pkgs, ... }:
with lib;
let local-domain = "sea.fudo.org";
in {
fileSystems = {
@ -15,12 +16,12 @@ in {
# };
"/mnt/music" = {
device = "doraemon.${local-domain}:/volume1/Music";
fsType = "nfs4";
fsType = "nfs";
options = [ "comment=systemd.automount" ];
};
"/mnt/video" = {
device = "doraemon.${local-domain}:/volume1/Video";
fsType = "nfs4";
fsType = "nfs";
options = [ "comment=systemd.automount" ];
};
# fileSystems."/mnt/security" = {
@ -29,68 +30,136 @@ in {
# };
"/mnt/cargo_video" = {
device = "cargo.${local-domain}:/volume1/video";
fsType = "nfs4";
options = [ "comment=systemd.automount" ];
fsType = "nfs";
options = [ "comment=systemd.automount" "nfsvers=4.2" ];
};
"/mnt/photo" = {
device = "cargo.${local-domain}:/volume1/pictures";
fsType = "nfs4";
options = [ "comment=systemd.automount" ];
fsType = "nfs";
options = [ "comment=systemd.automount" "nfsvers=4.2" ];
};
# "proto=tcp"
# NOTE: these are pointing directly to nostromo so the krb lookup works
# # NOTE: these are pointing directly to nostromo so the krb lookup works
"/net/documents" = {
device = "nostromo.sea.fudo.org:/export/documents";
fsType = "nfs4";
options = [ "comment=systemd.automount" "sec=krb5p" "nfsvers=4" ];
options = [
"sec=krb5p"
"x-systemd.automount"
# "vers=4"
# "minorversion=2"
# "proto=tcp"
];
};
"/net/downloads" = {
device = "nostromo.sea.fudo.org:/export/downloads";
fsType = "nfs4";
options = [ "comment=systemd.automount" "sec=krb5i" "nfsvers=4" ];
options = [
"sec=krb5i"
"x-systemd.automount"
# "vers=4"
# "minorversion=2"
# "proto=tcp"
];
};
"/net/projects" = {
device = "nostromo.sea.fudo.org:/export/projects";
fsType = "nfs4";
options = [ "comment=systemd.automount" "sec=krb5p" "nfsvers=4" ];
options = [
"sec=krb5p"
"x-systemd.automount"
# "vers=4"
# "minorversion=2"
# "proto=tcp"
];
};
};
systemd = {
## This fails if the filesystems already exist
# tmpfiles.rules = [
# "d /net/documents - root sea-documents - -"
# "d /net/downloads - root sea-downloads - -"
# "d /net/projects - root sea-projects - -"
# ];
# mounts = [
# {
# what = "nostromo.sea.fudo.org:/export/documents";
# where = "/net/documents";
# type = "nfs4";
# options = "sec=krb5p";
# description = "sea-store documents on encrypted filesysem.";
# }
# {
# what = "nostromo.sea.fudo.org:/export/downloads";
# where = "/net/downloads";
# type = "nfs4";
# options = "sec=krb5i";
# description = "sea-store downloads on encrypted filesysem.";
# }
# {
# what = "nostromo.sea.fudo.org:/export/projects";
# where = "/net/projects";
# type = "nfs4";
# options = "sec=krb5p";
# description = "sea-store projects on encrypted filesysem.";
# }
# ];
# paths.host-keytab-modified = {
# wantedBy = [ "multi-user.target" ];
# pathConfig = {
# PathChanged = "/etc/krb5.keytab";
# Unit = "host-keytab-modified.service";
# };
# };
# services.host-keytab-modified = {
# description = "Operations to execute when keytab is changed.";
# script = "${pkgs.systemd}/bin/systemctl restart rpc-gssd.service";
# };
services.host-keytab-watcher = {
wantedBy = [ "rpc-gssd.service" "rpc-svcgssd.service" ];
before = [ "rpc-gssd.service" "rpc-svcgssd.service" ];
unitConfig = { ConditionPathExists = [ "/etc/krb5.keytab" ]; };
serviceConfig = {
ExecStart = "${pkgs.coreutils}/bin/sleep 500";
TimeoutStartSec = "3600";
RemainAfterExit = true;
};
};
};
# systemd = {
# ## This fails if the filesystems already exist
# # tmpfiles.rules = [
# # "d /net/documents - root sea-documents - -"
# # "d /net/downloads - root sea-downloads - -"
# # "d /net/projects - root sea-projects - -"
# # ];
# mounts = let
# mkOpts =
# concatStringsSep ",";
# in [
# {
# enable = true;
# what = "nostromo.sea.fudo.org:/export/documents";
# where = "/net/documents";
# type = "nfs";
# options = mkOpts [
# "vers=4"
# "minorversion=2"
# "sec=krb5p"
# "x-systemd.automount"
# "proto=tcp"
# ];
# description = "sea-store documents on encrypted filesysem.";
# }
# {
# enable = true;
# what = "nostromo.sea.fudo.org:/export/downloads";
# where = "/net/downloads";
# type = "nfs";
# options = mkOpts [
# "vers=4"
# "minorversion=2"
# "sec=krb5i"
# "x-systemd.automount"
# "proto=tcp"
# ];
# description = "sea-store downloads on encrypted filesysem.";
# }
# {
# enable = true;
# what = "nostromo.sea.fudo.org:/export/projects";
# where = "/net/projects";
# type = "nfs";
# options = mkOpts [
# "vers=4"
# "minorversion=2"
# "sec=krb5p"
# "x-systemd.automount"
# "proto=tcp"
# ];
# description = "sea-store projects on encrypted filesysem.";
# }
# ];
# };
services.printing = {
enable = true;
drivers = [

View File

@ -338,9 +338,7 @@
primary-group = "selby";
common-name = "Vee Selby";
ldap-hashed-passwd = "snoinuer";
email-aliases = [
"virginia@selby.ca"
];
email-aliases = [ "virginia@selby.ca" ];
};
dabar = {

View File

@ -136,15 +136,22 @@
"inputs": {
"doom-emacs": "doom-emacs_2",
"doom-snippets": "doom-snippets",
"emacs-overlay": "emacs-overlay",
"emacs-overlay": [
"fudo-home",
"emacs-overlay"
],
"emacs-so-long": "emacs-so-long",
"evil-markdown": "evil-markdown",
"evil-org-mode": "evil-org-mode",
"evil-quick-diff": "evil-quick-diff",
"explain-pause-mode": "explain-pause-mode",
"flake-utils": "flake-utils",
"format-all": "format-all",
"nix-straight": "nix-straight",
"nixpkgs": "nixpkgs_5",
"nixpkgs": [
"fudo-home",
"nixpkgs"
],
"nose": "nose",
"ob-racket": "ob-racket",
"org": "org",
@ -155,15 +162,15 @@
"rotate-text": "rotate-text"
},
"locked": {
"lastModified": 1627398156,
"narHash": "sha256-Ru1aV3NuIFXAsvUE3de8KR7xDZOo1GCBJdsWKJn+Ebw=",
"owner": "vlaci",
"lastModified": 1645751511,
"narHash": "sha256-i3cMaHdaxwfeJEKVgk3Sxx/IRfjwNcThaCMcq4uv9jg=",
"owner": "nix-community",
"repo": "nix-doom-emacs",
"rev": "fee14d217b7a911aad507679dafbeaa8c1ebf5ff",
"rev": "ef434602f6f2a8b469d1b01f9edff4f5b6d7f555",
"type": "github"
},
"original": {
"owner": "vlaci",
"owner": "nix-community",
"repo": "nix-doom-emacs",
"type": "github"
}
@ -171,16 +178,16 @@
"doom-emacs_2": {
"flake": false,
"locked": {
"lastModified": 1626604817,
"narHash": "sha256-z+dvjB02cHU+VQ5EMkzqSdX817PZar9AkmmfK27q0vo=",
"lastModified": 1645634993,
"narHash": "sha256-QeE6aUJxoaqHM28Cpt2rKC817VQvXGuuFUyLzehaC50=",
"owner": "hlissner",
"repo": "doom-emacs",
"rev": "46732c0adaef147144418f9f284ca6b1183ab96f",
"rev": "42e5763782fdc1aabb9f2624d468248d6978abe2",
"type": "github"
},
"original": {
"owner": "hlissner",
"ref": "develop",
"ref": "master",
"repo": "doom-emacs",
"type": "github"
}
@ -188,11 +195,11 @@
"doom-snippets": {
"flake": false,
"locked": {
"lastModified": 1625547004,
"narHash": "sha256-V+ytAjB4ZZ+5dJJAu1OY7SbnqrokX5PVBWs0AsgQ8Vs=",
"lastModified": 1645652740,
"narHash": "sha256-ci5QsTkzmfSd7Pfoe+RActuSOmMY2TvJL7f2giCwNEI=",
"owner": "hlissner",
"repo": "doom-snippets",
"rev": "5c0eb5bd70f035cefb981c2ce64f4367498bdda6",
"rev": "02aca23fef94fc7a58836fd1812d62e731249fa3",
"type": "github"
},
"original": {
@ -204,11 +211,11 @@
"emacs-overlay": {
"flake": false,
"locked": {
"lastModified": 1626972035,
"narHash": "sha256-YhBtnKmLDYiEzP5ZEMEQMg6oMP5EV+ToCkku7ZYfL+A=",
"lastModified": 1645953123,
"narHash": "sha256-Be06ikbfQTuRwsU6nxNbMSvSUOzmGzDOLBKXFMekrcA=",
"owner": "nix-community",
"repo": "emacs-overlay",
"rev": "be04b45efb35db58e6ac6aa86b84f850c85b5dfe",
"rev": "058e38892484c1ab517c890b0aaee5d53565a494",
"type": "github"
},
"original": {
@ -343,11 +350,11 @@
},
"flake-utils": {
"locked": {
"lastModified": 1623875721,
"narHash": "sha256-A8BU7bjS5GirpAUv4QA+QnJ4CceLHkcXdRp4xITDB0s=",
"lastModified": 1644229661,
"narHash": "sha256-1YdnJAsNy69bpcjuoKdOYQX0YxZBiCYZo4Twxerqv7k=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "f7e004a55b120c02ecb6219596820fcd32ca8772",
"rev": "3cecb5b042f7f209c56ffd8371b2711a290ec797",
"type": "github"
},
"original": {
@ -356,6 +363,23 @@
"type": "github"
}
},
"format-all": {
"flake": false,
"locked": {
"lastModified": 1581716637,
"narHash": "sha256-ul7LCe60W8TIvUmUtZtZRo8489TK9iTPDsLHmzxY57M=",
"owner": "lassik",
"repo": "emacs-format-all-the-code",
"rev": "47d862d40a088ca089c92cd393c6dca4628f87d3",
"type": "github"
},
"original": {
"owner": "lassik",
"repo": "emacs-format-all-the-code",
"rev": "47d862d40a088ca089c92cd393c6dca4628f87d3",
"type": "github"
}
},
"fudo-entities": {
"inputs": {
"fudo-lib": "fudo-lib",
@ -364,11 +388,11 @@
]
},
"locked": {
"lastModified": 1639927391,
"narHash": "sha256-fptxLDQu9dKzOz8XVtw/tGEsua1XHUF7pzYpzZ4igjU=",
"lastModified": 1646155824,
"narHash": "sha256-cVQ4mQNNblY2MjK4kaoW71wUccUOdczVt2Y3umGEkTw=",
"ref": "master",
"rev": "e29d67c9ea522672e3fcf2e8d48edc61ba72ff0d",
"revCount": 25,
"rev": "4799d7704ae703693065c47e1e454e58f5e767f4",
"revCount": 76,
"type": "git",
"url": "https://git.fudo.org/fudo-nix/entities.git"
},
@ -380,17 +404,20 @@
"fudo-home": {
"inputs": {
"doom-emacs": "doom-emacs",
"emacs-overlay": "emacs-overlay",
"fudo-pkgs": "fudo-pkgs",
"home-manager": "home-manager",
"niten-doom-config": "niten-doom-config",
"nixpkgs": "nixpkgs_7"
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1641413339,
"narHash": "sha256-31N7ovrwD6IagxFRGVDFNKq162h7s7wpBKAt+7bEhV0=",
"lastModified": 1646777521,
"narHash": "sha256-0WtNjhJ+66l+3l/s4bhqgIfsuROBtD4GJ0B3yJRipxM=",
"ref": "master",
"rev": "3d18a37c6ef9815428d4a8babafa83cfbdafea57",
"revCount": 75,
"rev": "e860b7aee67d8f0dabcf95fdfde138722fca1f32",
"revCount": 124,
"type": "git",
"url": "https://git.fudo.org/fudo-nix/home.git"
},
@ -401,11 +428,11 @@
},
"fudo-lib": {
"locked": {
"lastModified": 1638990149,
"narHash": "sha256-p1T0GMJXIJvTpVdn5nK7RZJX8izkabADJ/LsaL442zI=",
"lastModified": 1641848738,
"narHash": "sha256-9+xyFqyUIzIkNo2HyXxp6Lm9/f0EZqRqkRz52AQoW6Q=",
"ref": "master",
"rev": "c87448ff1365c3d5230690f68d1ba246652581d1",
"revCount": 24,
"rev": "63b80fb5dc1e6ad69252a233b7c6a20f649884c6",
"revCount": 59,
"type": "git",
"url": "https://git.fudo.org/fudo-nix/lib.git"
},
@ -416,7 +443,7 @@
},
"fudo-lib_2": {
"locked": {
"narHash": "sha256-hlQ7nQYuIH7AfRu7O3yr8Xf8Ppqbf7lIU2QNQvnOAbU=",
"narHash": "sha256-JWs8GEoZdR9sqf1nQJgIIQCwe4sQDZoK3C7WzQN3hAo=",
"path": "/state/fudo-lib",
"type": "path"
},
@ -426,15 +453,12 @@
}
},
"fudo-pkgs": {
"inputs": {
"unstableNixpkgs": "unstableNixpkgs"
},
"locked": {
"lastModified": 1641413309,
"narHash": "sha256-FPLBuS9714BxkU6uLJSoRL7VQUj3yvTK4xkl7+RSzaM=",
"lastModified": 1643841844,
"narHash": "sha256-rmTIL94RQQaFhMHCopmeFUVAoP71nSA6sB46riDq2Ik=",
"ref": "master",
"rev": "042aa2f4cea9ad8acdf93b4b54196aefd94c0408",
"revCount": 22,
"rev": "7e02ad0e7d9ac42605ed318e9d76364ec1d339ec",
"revCount": 41,
"type": "git",
"url": "https://git.fudo.org/fudo-nix/pkgs.git"
},
@ -444,15 +468,12 @@
}
},
"fudo-pkgs_2": {
"inputs": {
"unstableNixpkgs": "unstableNixpkgs_2"
},
"locked": {
"lastModified": 1641413309,
"narHash": "sha256-FPLBuS9714BxkU6uLJSoRL7VQUj3yvTK4xkl7+RSzaM=",
"lastModified": 1646862825,
"narHash": "sha256-Zqtx4cJXuMG0dNKgmcJgfy3twLfRSMRqI/UMfl2hbsA=",
"ref": "master",
"rev": "042aa2f4cea9ad8acdf93b4b54196aefd94c0408",
"revCount": 22,
"rev": "4ee3fb603b5b9d55c51213acbf90a52ce4c08cf1",
"revCount": 49,
"type": "git",
"url": "https://git.fudo.org/fudo-nix/pkgs.git"
},
@ -529,14 +550,17 @@
},
"home-manager": {
"inputs": {
"nixpkgs": "nixpkgs_6"
"nixpkgs": [
"fudo-home",
"nixpkgs"
]
},
"locked": {
"lastModified": 1639871969,
"narHash": "sha256-6feWUnMygRzA9tzkrfAzpA5/NBYg75bkFxnqb1DtD7E=",
"lastModified": 1643933536,
"narHash": "sha256-yRmsWAG4DnLxLIUtlaZsl0kH7rN5xSoyNRlf0YZrcH4=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "697cc8c68ed6a606296efbbe9614c32537078756",
"rev": "2860d7e3bb350f18f7477858f3513f9798896831",
"type": "github"
},
"original": {
@ -577,16 +601,15 @@
"nix-straight": {
"flake": false,
"locked": {
"lastModified": 1621543597,
"narHash": "sha256-E/m2Hrw2og//CfOCOWe2yapYC01Tqhozn4YMPYJsC3o=",
"owner": "vlaci",
"lastModified": 1643475817,
"narHash": "sha256-NpExq5nbPbj/ppkBX3SnETEJuOne1MKJxen8vVHsDFg=",
"owner": "nix-community",
"repo": "nix-straight.el",
"rev": "8e84d04f10b2298de856b2b8b9a0d13abc91b5ca",
"rev": "08d75e5651cb52f8a07e03408ed19e04bee07505",
"type": "github"
},
"original": {
"owner": "vlaci",
"ref": "v2.2.0",
"owner": "nix-community",
"repo": "nix-straight.el",
"type": "github"
}
@ -606,6 +629,21 @@
"type": "github"
}
},
"nixpkgsUnstable": {
"locked": {
"lastModified": 1647297614,
"narHash": "sha256-ulGq3W5XsrBMU/u5k9d4oPy65pQTkunR4HKKtTq0RwY=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "73ad5f9e147c0d2a2061f1d4bd91e05078dc0b58",
"type": "github"
},
"original": {
"id": "nixpkgs",
"ref": "nixos-unstable",
"type": "indirect"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1638196344,
@ -653,56 +691,11 @@
},
"nixpkgs_5": {
"locked": {
"lastModified": 1638407071,
"narHash": "sha256-xbveILjgtBVh6B5F6i2k3T0IrE8lZp1vsqfDY+Df/cg=",
"lastModified": 1645296114,
"narHash": "sha256-y53N7TyIkXsjMpOG7RhvqJFGDacLs9HlyHeSTBioqYU=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "971b383a28f4baee8ea3931af4840fa221929fd6",
"type": "github"
},
"original": {
"id": "nixpkgs",
"ref": "nixpkgs-unstable",
"type": "indirect"
}
},
"nixpkgs_6": {
"locked": {
"lastModified": 1638407071,
"narHash": "sha256-xbveILjgtBVh6B5F6i2k3T0IrE8lZp1vsqfDY+Df/cg=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "971b383a28f4baee8ea3931af4840fa221929fd6",
"type": "github"
},
"original": {
"id": "nixpkgs",
"type": "indirect"
}
},
"nixpkgs_7": {
"locked": {
"lastModified": 1638407071,
"narHash": "sha256-xbveILjgtBVh6B5F6i2k3T0IrE8lZp1vsqfDY+Df/cg=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "971b383a28f4baee8ea3931af4840fa221929fd6",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "971b383a28f4baee8ea3931af4840fa221929fd6",
"type": "github"
}
},
"nixpkgs_8": {
"locked": {
"lastModified": 1641229786,
"narHash": "sha256-WPPcLNbVu6ryj772GooUpF285LOvRHdOo/UNJgPnFYI=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "88579effa7e88c25087faf6de6388d0cd1738dc0",
"rev": "530a53dcbc9437363471167a5e4762c5fcfa34a1",
"type": "github"
},
"original": {
@ -746,11 +739,11 @@
"org": {
"flake": false,
"locked": {
"lastModified": 1627155762,
"narHash": "sha256-XS1eA6P0ePabdrnUNe5lN19EA9dfK615gMGObr9wfBQ=",
"lastModified": 1645557265,
"narHash": "sha256-vBOWOOfdUbvpTkqs2Lx+OCPfUdZdzAOdGxzHBSAslmo=",
"owner": "emacs-straight",
"repo": "org-mode",
"rev": "c9dfed48a607c7f6524f1c6480f09cf61a5d6237",
"rev": "282a01f22159b4855071ffd54a9ae6ce681c3690",
"type": "github"
},
"original": {
@ -762,11 +755,11 @@
"org-contrib": {
"flake": false,
"locked": {
"lastModified": 1623339452,
"narHash": "sha256-E3pioqkmAKQm5N7YsgJZil0/ozkdRE7//tE9FGbrluM=",
"lastModified": 1639727892,
"narHash": "sha256-+T6Y87aSAx7kMpigm8d1ODDQIyPBM6a+4qGolXjCEXs=",
"ref": "master",
"rev": "fc81309cf6756607a836f93049a9393c2967c4e0",
"revCount": 2599,
"rev": "5766ff1088191e4df5fecd55007ba4271e609bcc",
"revCount": 2611,
"type": "git",
"url": "https://git.sr.ht/~bzg/org-contrib"
},
@ -822,11 +815,11 @@
"revealjs": {
"flake": false,
"locked": {
"lastModified": 1625811744,
"narHash": "sha256-Y67nVqcovn2PbHXmWOFWMq10Qz2ZIRyyWEO6qsZLbIM=",
"lastModified": 1645450091,
"narHash": "sha256-3fM1hKCbuIy8HzBv9JjjZW/RwE1CKeq++delBhbSvys=",
"owner": "hakimel",
"repo": "reveal.js",
"rev": "b18f12d964ef80bd9ffb061aae48ff4c15fb43ad",
"rev": "5e12c6aeb7a37acca7ca22c0bd29548f9ff282ea",
"type": "github"
},
"original": {
@ -844,7 +837,8 @@
"fudo-lib": "fudo-lib_2",
"fudo-pkgs": "fudo-pkgs_2",
"fudo-secrets": "fudo-secrets",
"nixpkgs": "nixpkgs_8"
"nixpkgs": "nixpkgs_5",
"nixpkgsUnstable": "nixpkgsUnstable"
}
},
"rotate-text": {
@ -911,36 +905,6 @@
"type": "path"
}
},
"unstableNixpkgs": {
"locked": {
"lastModified": 1641230035,
"narHash": "sha256-hFyqihERaTbLxCOlugy/rpp22VLtLh8SPRnA2uu3F/8=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "78cd22c1b8604de423546cd49bfe264b786eca13",
"type": "github"
},
"original": {
"id": "nixpkgs",
"ref": "nixos-unstable",
"type": "indirect"
}
},
"unstableNixpkgs_2": {
"locked": {
"lastModified": 1641230035,
"narHash": "sha256-hFyqihERaTbLxCOlugy/rpp22VLtLh8SPRnA2uu3F/8=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "78cd22c1b8604de423546cd49bfe264b786eca13",
"type": "github"
},
"original": {
"id": "nixpkgs",
"ref": "nixos-unstable",
"type": "indirect"
}
},
"utils": {
"locked": {
"lastModified": 1637014545,

View File

@ -4,7 +4,10 @@
inputs = {
nixpkgs.url = "nixpkgs/nixos-21.05";
fudo-home.url = "git+https://git.fudo.org/fudo-nix/home.git";
fudo-home = {
url = "git+https://git.fudo.org/fudo-nix/home.git";
inputs.nixpkgs.follows = "nixpkgs";
};
# This MUST be a clean git repo, because we use the timestamp.
fudo-entities = {
@ -25,6 +28,8 @@
chute.url = "git+https://git.fudo.org/chute/chute.git?ref=stable";
chuteUnstable.url = "git+https://git.fudo.org/chute/chute.git?ref=master";
nixpkgsUnstable.url = "nixpkgs/nixos-unstable";
};
outputs = { self,
@ -36,6 +41,7 @@
fudo-secrets,
chute,
chuteUnstable,
nixpkgsUnstable,
... } @ inputs:
with nixpkgs.lib;
let
@ -45,7 +51,19 @@
fudo-networks = fudo-entities.entities.networks;
pkgs-for = arch: import nixpkgs {
unstable-for = arch: import nixpkgsUnstable {
system = arch;
config = {
allowUnfree = true;
permittedInsecurePackages = [
"openssh-with-gssapi-8.4p1"
];
};
};
pkgs-for = arch: let
unstable = unstable-for arch;
in import nixpkgs {
system = arch;
config = {
allowUnfree = true;
@ -60,6 +78,9 @@
chute = chute.packages.${arch}.chute;
chuteUnstable = chuteUnstable.packages.${arch}.chute;
})
(final: prev: {
nyxt = unstable.nyxt;
})
];
};
@ -91,7 +112,9 @@
(config-dir + /site-config/${hostOpts.site}.nix)
];
config = {
config = let
pkgs = pkgs-for hostOpts.arch;
in {
instance = let
build-seed = builtins.readFile
config.fudo.secrets.files.build-seed;
@ -99,14 +122,24 @@
inherit hostname build-timestamp build-seed;
};
nix.registry = {
fudo-nixos.flake = self;
fudo-entities.flake = fudo-entities;
fudo-lib.flake = fudo-lib;
fudo-pkgs.flake = fudo-pkgs;
environment.etc.nixos-live.source = ./.;
nix = {
registry = {
nixpkgs.flake = nixpkgs;
fudo-nixos.flake = self;
fudo-entities.flake = fudo-entities;
fudo-lib.flake = fudo-lib;
fudo-pkgs.flake = fudo-pkgs;
};
nixPath = let
lib = nixpkgs.lib;
in lib.mkDefault (lib.mkBefore [
"nixpkgs=${nixpkgs}"
]);
};
nixpkgs.pkgs = pkgs-for hostOpts.arch;
nixpkgs.pkgs = pkgs;
};
};

View File

@ -7,14 +7,10 @@ let
pkgs = import <nixpkgs> {
config = {
allowUnfree = true;
permittedInsecurePackages = [
"openssh-with-gssapi-8.4p1"
];
permittedInsecurePackages = [ "openssh-with-gssapi-8.4p1" ];
};
overlays = [
(import ./fudo-pkgs/overlay.nix)
];
overlays = [ (import /state/fudo-pkgs/overlay.nix) ];
};
in {
@ -64,8 +60,7 @@ in {
# groups = { wheel = { members = [ "niten" ]; }; };
};
home-manager = let
home-generator = pkgs.callPackage ./nix-home {};
home-manager = let home-generator = pkgs.callPackage ./nix-home { };
in {
useGlobalPkgs = true;
@ -74,9 +69,7 @@ in {
username = "niten";
user-email = "niten@fudo.org";
home-dir = "/home/niten";
}) {
enable-gui = false;
};
}) { enable-gui = false; };
};
};

View File

@ -8,12 +8,12 @@
(define *host-passwd-file* (getenv "FUDO_HOST_PASSWD_FILE"))
(when (not *host-passwd-file*)
(format (current-error-port "FUDO_HOST_PASSWD_FILE not set~%"))
(format #t (current-error-port "FUDO_HOST_PASSWD_FILE not set~%"))
(exit 1))
(define *service-passwd-file* (getenv "FUDO_SERVICE_PASSWD_FILE"))
(when (not *service-passwd-file*)
(format (current-error-port "FUDO_SERVICE_PASSWD_FILE not set~%"))
(format #t (current-error-port "FUDO_SERVICE_PASSWD_FILE not set~%"))
(exit 1))
(define host-regex "^host-([a-zA-Z][a-zA-Z0-9_-]+)$")
@ -35,7 +35,7 @@
(service-verifier (match:substring (string-match service-regex username) 1)
password))
(else #f))))
(else (begin (format #t "unrecognized username: ~s @ ~s~%" username hostname))))))
(define (make-handler handlers)
(lambda (request)