Tons of stuff, including 23.05 -> 23.11

This commit is contained in:
niten 2024-01-16 19:08:38 -08:00
parent 0027566304
commit 7a73028ad2
28 changed files with 837 additions and 1163 deletions

View File

@ -4,7 +4,8 @@ with lib;
let
hostname = config.instance.hostname;
localDomain = "fudo.org";
serviceSecrets = config.fudo.secrets.files.service-secrets."${hostname}";
domainSecrets = config.fudo.secrets.files.domain-secrets."${localDomain}";
inherit (pkgs.lib) getDomainHosts getHostIpv4 getHostIpv6 getHostFqdn;
@ -16,7 +17,10 @@ let
defaultHost = "germany";
mastodonHostname = "mastodon.fudo.org";
mastodonHostname = "fudo.live";
lemmyHost = "germany";
lemmyHostname = "fudo.social";
servedDomains = [
"fudo.org"
@ -24,86 +28,117 @@ let
"selby.ca"
"fudo.ca"
"fudo.im"
"fudo.live"
"fudo.social"
"stewartsoundservices.ca"
];
in {
imports = [
(import ./fudo.org/authentik.nix { inherit authentikHost; })
(import ./fudo.org/authentik.nix {
inherit authentikHost;
authentikImage = "ghcr.io/goauthentik/server:2023.10.6";
})
(import ./fudo.org/mastodon.nix {
mastodonHost = "legatus";
mastodonHost = "germany";
mastodonHostname = mastodonHostname;
mastodonWebDomain = "fudo.org";
mastodonOidcClientId = serviceSecrets."mastodon-oidc.clientid";
mastodonOidcClientSecret = serviceSecrets."mastodon-oidc.secret";
mastodonWebDomain = mastodonHostname;
mastodonOidcClientId = domainSecrets."mastodon-oidc.clientid";
mastodonOidcClientSecret = domainSecrets."mastodon-oidc.secret";
})
(import ./fudo.org/nextcloud.nix {
nextcloudHost = "legatus";
nextcloudHostname = "cloud.fudo.org";
nextcloudPackage = pkgs.nextcloud27;
nextcloudPackage = pkgs.nextcloud28;
})
(import ./fudo.org/matrix.nix {
matrixHost = "legatus";
matrixServerName = "fudo.org";
openIdClientId = readFile serviceSecrets."matrix-oidc.clientid";
openIdClientSecret = readFile serviceSecrets."matrix-oidc.secret";
matrixHost = "germany";
matrixServerName = "fudo.im";
openIdClientId = readFile domainSecrets."matrix-oidc.clientid";
openIdClientSecret = readFile domainSecrets."matrix-oidc.secret";
})
(import ./fudo.org/mail-server.nix (rec {
primaryMailserver = "germany";
primaryDomain = "test.fudo.org";
primaryMailserver = "france";
primaryDomain = "fudo.org";
authentikServer = "authentik.fudo.org";
ldapBase = "dc=fudo,dc=org";
ldapBindDn = "cn=userdb,ou=users,${ldapBase}";
ldapBindPwFile =
config.fudo.secrets.files.domain-secrets."${primaryDomain}"."ldap-bind.passwd";
ldapBindPwFile = domainSecrets."ldap-bind.passwd";
saslDomain = "FUDO.ORG";
authentikOutpostToken =
config.fudo.secrets.files.domain-secrets."${primaryDomain}"."authentik-ldap.token";
authentikOutpostToken = domainSecrets."authentik-ldap.token";
inherit servedDomains;
# TODO: FIXME!
dkimRecord = "";
dkimRecord = ''
mail._domainkey IN TXT ( "v=DKIM1;k=rsa;p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwoCgHwsfuu0lhj9Ayj4ntoy0bdcGBNsV46qoKbd8E8FKsJF5rL4EoytwXEFcKJwT3E+o3/BsZGi9J5irtjlfIhnxnPlhVRS3R/834NDSQyuwGTxAfhPOklhA0cTYA+4x2oGwAuraz+On2REDeSymMccXFDsTugEHVvn6qaeqkJwIDAQAB" );'';
}))
];
config = {
# All Fudo hosts should redirect selby.ca to the selbyhomecentre website.
services.nginx.virtualHosts = {
# Pass requests to selby on to selbyhomecentre
"selby.ca".locations."/".return =
"301 https://selbyhomecentre.com$request_uri";
"www.selby.ca".locations."/".return =
"301 https://selbyhomecentre.com$request_uri";
services = {
nginx.virtualHosts = {
# Pass requests to selby on to selbyhomecentre
"selby.ca".locations."/".return =
"301 https://selbyhomecentre.com$request_uri";
"www.selby.ca".locations."/".return =
"301 https://selbyhomecentre.com$request_uri";
# For Mastodon
"fudo.org".locations = {
"/.well-known/webfinger" = {
return = "301 http://${mastodonHostname}";
extraConfig = "add_header Access-Control-Allow-Origin '*';";
# For Mastodon
"fudo.org".locations = {
"/.well-known/webfinger" = {
return = "301 http://${mastodonHostname}";
extraConfig = "add_header Access-Control-Allow-Origin '*';";
};
"/.well-known/host-meta" = {
return = "301 https://${mastodonHostname}$request_uri";
};
};
"/.well-known/host-meta" = {
return = "301 https://${mastodonHostname}$request_uri";
};
lemmyDocker = {
enable = config.instance.hostname == lemmyHost;
hostname = lemmyHostname;
site-name = "Fudo Lemmy";
version = "0.19.2";
smtp-server = "mail.fudo.org:587";
docker-images = {
pictrs = "asonix/pictrs:0.5.1";
postgres = "postgres:15-alpine";
};
};
};
fudo = {
services = {
# TEMPORARY
mail-server.enable = false;
jabber = {
domain = "jabber.fudo.org";
ldap.servers =
map (host: "${host}.${localDomain}") domain.ldap-servers;
};
metrics.grafana = {
oauth = {
hostname = "authentik.fudo.org";
client-id = domainSecrets."grafana-oid-client-id";
client-secret = domainSecrets."grafana-oid-client-secret";
slug = "grafana-metrics";
};
};
authoritative-dns = {
enable = hostname == primaryNameserver;
enable-notifications = true;
container = {
hostname = "nameserver";
interface = "enp5s0f0";
};
nameservers = {
primary = primaryNameserver;
primary = "nameserver";
external = map (hostname: {
inherit (config.fudo.zones."fudo.org".hosts."${hostname}")
ipv4-address ipv6-address description;
@ -124,9 +159,10 @@ in {
description = "fudo.org";
};
# TODO: Fix email FFS!
fudoMailservers = {
smtp-servers = [ "smtp.fudo.org." ];
imap-servers = [ "imap.fudo.org." ];
smtp-servers = [ "mail.fudo.org." ];
imap-servers = [ "mail.fudo.org." ];
};
mkDomain = domain: extraConfig:
@ -147,6 +183,7 @@ in {
"stewartsoundservices.ca" =
mkDomain "stewartsoundservices.ca" { mail = fudoMailservers; };
"fudo.live" = mkDomain "fudo.live" { mail = fudoMailservers; };
"fudo.social" = mkDomain "fudo.social" { mail = fudoMailservers; };
};
};
};

View File

@ -1,4 +1,4 @@
{ authentikHost, ... }:
{ authentikHost, authentikImage, ... }:
{ config, lib, pkgs, ... }:
@ -24,7 +24,7 @@ in {
authentikContainer = mkIf isAuthentik {
enable = true;
images = {
authentik = "ghcr.io/goauthentik/server:2023.8.3";
authentik = authentikImage;
postgres = "docker.io/library/postgres:12-alpine";
redis = "docker.io/library/redis:alpine";
};
@ -50,32 +50,8 @@ in {
proxyWebsockets = true;
};
};
"fudo.ldap.fudo.org" = {
enableACME = true;
forceSSL = true;
locations."/".return = "403 Forbidden";
};
"selby.ldap.fudo.org" = {
enableACME = true;
forceSSL = true;
locations."/".return = "403 Forbidden";
};
};
};
};
security.acme.certs = mkIf isAuthentik
(genAttrs [ authentikHostname "fudo.ldap.fudo.org" "selby.ldap.fudo.org" ]
(domain: {
postRun = let
dst =
"${config.services.authentikContainer.state-directory}/certs/${domain}";
in ''
mkdir -p ${dst}
cp -v {cert,chain,fullchain,full,key}.pem ${dst}/
cp -v key.pem ${dst}/privkey.pem
chown -R authentik ${dst}
'';
}));
};
}

View File

@ -16,19 +16,17 @@ in {
after = [ "podman.service" ];
};
fudo = {
acme.host-domains = {
"imap.${primaryDomain}".extra-domain = [ "mail.${primaryDomain}" ];
"smtp.${primaryDomain}".extra-domain = [ "mail.${primaryDomain}" ];
};
# security.acme.certs = {
# "imap.${primaryDomain}".extraDomainNames = [ "mail.${primaryDomain}" ];
# "smtp.${primaryDomain}".extraDomainNames = [ "mail.${primaryDomain}" ];
# };
fudo = {
zones."${primaryDomain}" = let
mailserverDomain = config.fudo.hosts."${primaryMailserver}".domain;
mailserver =
config.fudo.domains."${mailserverDomain}".primary-mailserver;
mailserverIps = {
ipv4-address = getHostIpv4 mailserver;
ipv6-address = getHostIpv6 mailserver;
ipv4-address = getHostIpv4 primaryMailserver;
ipv6-address = getHostIpv6 primaryMailserver;
};
srvRecord = host: port: [{ inherit host port; }];
in {
@ -66,6 +64,7 @@ in {
enable = hostname == primaryMailserver;
debug = true;
primary-domain = primaryDomain;
extra-domains = servedDomains;
sasl-domain = saslDomain;
trusted-networks = config.instance.local-networks;
smtp = {
@ -110,12 +109,17 @@ in {
services.nginx = mkIf (hostname == primaryMailserver) {
enable = true;
virtualHosts = {
"smtp.${primaryDomain}" = {
"imap.${primaryDomain}" = {
enableACME = true;
forceSSL = true;
locations."/".return = "301 https://webmail.${primaryDomain}";
};
"imap.${primaryDomain}" = {
"mail.${primaryDomain}" = {
enableACME = true;
forceSSL = true;
locations."/".return = "301 https://webmail.${primaryDomain}";
};
"smtp.${primaryDomain}" = {
enableACME = true;
forceSSL = true;
locations."/".return = "301 https://webmail.${primaryDomain}";

View File

@ -5,17 +5,19 @@
with lib;
let
hostname = config.instance.hostname;
domainName = "fudo.org";
domainName = "fudo.im";
zoneName = config.fudo.domains."${domainName}".zone;
isMatrix = hostname == matrixHost;
matrixFqdn = "matrix.${domainName}";
in {
config = {
fudo = {
zones."${zoneName}".aliases = {
element = matrixHost;
matrix = matrixHost;
};
zones."${zoneName}".aliases =
let matrixHostFqdn = pkgs.lib.getHostFqdn matrixHost;
in {
web = "${matrixHostFqdn}.";
matrix = "${matrixHostFqdn}.";
};
services.matrix = mkIf isMatrix {
enable = true;
@ -31,7 +33,7 @@ in {
};
};
networking.firewall.allowedTCPPorts = [ 8008 8448 ];
networking.firewall.allowedTCPPorts = [ 80 443 8008 8448 ];
services.nginx.virtualHosts = mkIf isMatrix {
"${domainName}" = let
@ -42,6 +44,7 @@ in {
'';
in {
enableACME = true;
forceSSL = true;
listen = [
{
addr = "0.0.0.0";
@ -64,15 +67,20 @@ in {
ssl = true;
}
];
locations."/.well-known/matrix/server".extraConfig =
mkWellKnown { "m.server" = "${matrixFqdn}:443"; };
locations."/.well-known/matrix/client".extraConfig =
mkWellKnown { "m.homeserver".base_url = "https://${matrixFqdn}"; };
locations = {
"/.well-known/matrix/server".extraConfig =
mkWellKnown { "m.server" = "${matrixFqdn}:443"; };
"/.well-known/matrix/client".extraConfig = mkWellKnown {
"m.homeserver".base_url = "https://${matrixFqdn}:443";
};
"/.well-known/acme-challenge" = {
root = "/var/lib/acme/acme-challenge/";
extraConfig = "auth_basic off;";
};
"/".return = "301 https://web.${domainName}";
};
};
# "${matrixFqdn}" = {
# locations."^/$".return = "301 https://element.${domainName}";
# };
"element.${domainName}" = {
"web.${domainName}" = {
enableACME = true;
forceSSL = true;
root = pkgs.element-web.override {
@ -82,7 +90,7 @@ in {
"https://${matrixFqdn}";
brand = "Fudo";
room_directory.servers =
[ "fudo.org" "matrix.org" "libera.chat" "gitter.im" ];
[ matrixFqdn "matrix.org" "libera.chat" "gitter.im" ];
map_style_url =
"https://api.maptiler.com/maps/streets/style.json?key=fU3vlMsMn4Jb6dnEIFsx";
};

View File

@ -20,8 +20,8 @@ in {
package = nextcloudPackage;
extra-apps =
with config.services.nextcloudContainer.package.packages.apps; {
inherit news contacts calendar tasks maps memories mail bookmarks
files_markdown notes unsplash user_saml;
inherit contacts calendar tasks maps mail bookmarks notes user_saml;
# files_markdown memories news unsplash
};
timezone = "America/Winnipeg";
};

View File

@ -14,11 +14,25 @@ let
in {
config = {
fudo.zones."sea.fudo.org".aliases."frigate" = "zbox";
fudo.zones."sea.fudo.org".aliases = { "frigate" = "zbox"; };
fudo = {
services.mqtt.private.users.frigate = {
password-file = frigateMqttPassword;
acl = [ "frigate/#" ];
services = {
metrics = {
private-network = true;
grafana.oauth = {
hostname = "authentik.fudo.org";
client-id =
config.fudo.secrets.files.domain-secrets."fudo.org"."grafana-oid-client-id";
client-secret =
config.fudo.secrets.files.domain-secrets."fudo.org"."grafana-oid-client-secret";
slug = "grafana-metrics";
};
};
mqtt.private.users.frigate = {
password-file = frigateMqttPassword;
acl = [ "frigate/#" ];
};
};
};

View File

@ -73,6 +73,18 @@ in {
fsType = "btrfs";
options = [ "subvol=@acme" "compress=zstd" "noatime" "noexec" ];
};
"/state/services/mail/mail" = {
device = "/dev/disk/by-label/germany-data";
fsType = "btrfs";
options = [ "subvol=@mail" "compress=zstd" "noatime" "noexec" ];
};
"/var/lib/containers/storage" = {
device = "/dev/disk/by-label/germany-data";
fsType = "btrfs";
options = [ "subvol=@container-data" "noatime" "compress=zstd" "noexec" ];
};
};
swapDevices = [{ device = "/dev/disk/by-label/germany-swap"; }];
@ -87,30 +99,4 @@ in {
cpu.intel.updateMicrocode = true;
enableAllFirmware = true;
};
networking = {
useDHCP = false;
macvlans = {
extif0 = {
interface = "enp5s0f0";
mode = "bridge";
};
dnsif0 = {
interface = "enp5s0f0";
mode = "bridge";
};
extif1 = {
interface = "enp5s0f1";
mode = "bridge";
};
};
interfaces = {
extif0.macAddress = generateMac config.instance.hostname "extif0";
extif1.macAddress = generateMac config.instance.hostname "extif1";
};
};
}

View File

@ -93,6 +93,8 @@ in {
hosts.fimbria.external-interfaces = [ "enp1s0" ];
client.dns.external-interface = "enp1s0";
local-network.state-directory = "/state/services/local-network";
secrets.host-secrets."${hostname}" = {
sea-cam-auth-proxy-env = {
source-file = let
@ -135,7 +137,16 @@ in {
security.acme.defaults.email = "niten@fudo.org";
systemd.services.nginx.requires = [ "bind.service" ];
systemd.services = {
nginx = {
after = [ "bind.service" ];
requires = [ "bind.service" ];
};
podman-sea-cam-auth-proxy.after = [ "network-online.service" ];
podman-sea-red-auth-proxy.after = [ "network-online.service" ];
};
services = {
## TODO: enable when ready
@ -223,6 +234,20 @@ in {
target = "http://node-red.sea.fudo.org/";
authPort = 9001;
};
"metrics.fudo.link" = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://prometheus.sea.fudo.org";
extraConfig = let
trustedNetworkClauses = map (nw: "allow ${nw};")
(config.instance.local-networks
++ config.fudo.domains."fudo.org".local-networks);
in concatStringsSep "\n"
(trustedNetworkClauses ++ [ "deny all;" ]);
};
};
};
};

View File

@ -14,14 +14,15 @@ let
secrets = config.fudo.secrets.host-secrets.france;
secret-files = config.fudo.secrets.files;
letsencrypt-full-chain = name: chain: pkgs.stdenv.mkDerivation {
name = "${name}-letsencrypt-full-chain.pem";
phases = "installPhase";
installPhase = ''
cat ${chain} > $out
cat ${pkgs.letsencrypt-ca}/ca.pem >> $out
'';
};
letsencrypt-full-chain = name: chain:
pkgs.stdenv.mkDerivation {
name = "${name}-letsencrypt-full-chain.pem";
phases = "installPhase";
installPhase = ''
cat ${chain} > $out
cat ${pkgs.letsencrypt-ca}/ca.pem >> $out
'';
};
in {
# imports = let
@ -88,21 +89,17 @@ in {
};
fudo = let
backplane-dns-password-file = pkgs.lib.passwd.stablerandom-passwd-file
"dns-service-backplane-passwd"
backplane-dns-password-file =
pkgs.lib.passwd.stablerandom-passwd-file "dns-service-backplane-passwd"
"dns-service-backplane-passwd-${config.instance.build-seed}";
in {
hosts.france.external-interfaces = [ "extif0" ];
acme.host-domains.france."france.fudo.org" = {
email = "admin@fudo.org";
admin-email = "admin@fudo.org";
local-copies = {
postgres = {
user = "postgres";
};
openldap = {
user = config.services.openldap.user;
};
postgres = { user = "postgres"; };
openldap = { user = config.services.openldap.user; };
};
};
@ -142,93 +139,93 @@ in {
external-interface = "extif0";
};
# france = {
# ldap = let
# cert-copy = config.fudo.acme.host-domains.france."france.fudo.org".local-copies.openldap;
# chain = "${letsencrypt-full-chain "openldap-france" cert-copy.chain}";
# in {
# ssl-certificate = cert-copy.certificate;
# ssl-private-key = cert-copy.private-key;
# ssl-ca-certificate = chain;
# keytab = secrets.ldap-keytab.target-file;
# root-password-file = secrets.ldap-root-passwd.target-file;
# };
# france = {
# ldap = let
# cert-copy = config.fudo.acme.host-domains.france."france.fudo.org".local-copies.openldap;
# chain = "${letsencrypt-full-chain "openldap-france" cert-copy.chain}";
# in {
# ssl-certificate = cert-copy.certificate;
# ssl-private-key = cert-copy.private-key;
# ssl-ca-certificate = chain;
# keytab = secrets.ldap-keytab.target-file;
# root-password-file = secrets.ldap-root-passwd.target-file;
# };
# kdc = {
# state-directory = "/state/kerberos";
# master-key-file = secret-files.realm-master-keys."FUDO.ORG";
# listen-ips = [ primary-ip "127.0.0.1" "127.0.1.1" "::1" ];
# };
# kdc = {
# state-directory = "/state/kerberos";
# master-key-file = secret-files.realm-master-keys."FUDO.ORG";
# listen-ips = [ primary-ip "127.0.0.1" "127.0.1.1" "::1" ];
# };
# jabber = {
# ldap-servers = [ "france.fudo.org" ];
# listen-ips = [ primary-ip ];
# jabber = {
# ldap-servers = [ "france.fudo.org" ];
# listen-ips = [ primary-ip ];
# backplane = {
# host-passwd-files = let
# hosts = attrNames config.fudo.hosts;
# in mapAttrs (hostname: hostOpts: hostOpts.backplane-password-file)
# config.fudo.hosts;
# service-passwd-files = {
# dns = backplane-dns-password-file;
# };
# };
# };
# backplane = {
# host-passwd-files = let
# hosts = attrNames config.fudo.hosts;
# in mapAttrs (hostname: hostOpts: hostOpts.backplane-password-file)
# config.fudo.hosts;
# service-passwd-files = {
# dns = backplane-dns-password-file;
# };
# };
# };
# backplane-server = {
# listen-ips = [ primary-ip ];
# backplane-dns-password-file =
# secrets.backplane-dns-password.target-file;
# };
# backplane-server = {
# listen-ips = [ primary-ip ];
# backplane-dns-password-file =
# secrets.backplane-dns-password.target-file;
# };
# mail = {
# mail-directory = "${mail-directory}/mailboxes";
# state-directory = "${mail-directory}/var";
# ldap-server-urls = [
# "ldap://france.fudo.org"
# ];
# };
# mail = {
# mail-directory = "${mail-directory}/mailboxes";
# state-directory = "${mail-directory}/var";
# ldap-server-urls = [
# "ldap://france.fudo.org"
# ];
# };
# webmail = {
# mail-server = mail-hostname;
# database.hostname = "localhost";
# };
# webmail = {
# mail-server = mail-hostname;
# database.hostname = "localhost";
# };
# git = {
# repository-directory = "/state/gitea/repo";
# state-directory = "/state/gitea/state";
# ssh.listen-ip = git-server-ip;
# database-host = "localhost";
# };
# git = {
# repository-directory = "/state/gitea/repo";
# state-directory = "/state/gitea/state";
# ssh.listen-ip = git-server-ip;
# database-host = "localhost";
# };
# postgresql = let
# cert-copy = config.fudo.acme.host-domains.france."france.fudo.org".local-copies.postgres;
# in {
# keytab = secrets.postgres-keytab.target-file;
# ssl-certificate = cert-copy.certificate;
# ssl-private-key = cert-copy.private-key;
# };
# postgresql = let
# cert-copy = config.fudo.acme.host-domains.france."france.fudo.org".local-copies.postgres;
# in {
# keytab = secrets.postgres-keytab.target-file;
# ssl-certificate = cert-copy.certificate;
# ssl-private-key = cert-copy.private-key;
# };
# dns = {
# default-host = primary-ip;
# listen-ip = primary-ip;
# mail-hosts = [ "mail.fudo.org" ];
# };
# dns = {
# default-host = primary-ip;
# listen-ip = primary-ip;
# mail-hosts = [ "mail.fudo.org" ];
# };
# chat = {
# chat-hostname = "chat.fudo.org";
# mail-server = "mail.fudo.org";
# database-host = "localhost";
# };
# };
# chat = {
# chat-hostname = "chat.fudo.org";
# mail-server = "mail.fudo.org";
# database-host = "localhost";
# };
# };
# minecraft-server = {
# enable = true;
# package = pkgs.minecraft-current;
# data-dir = "/state/minecraft/selbyland";
# world-name = "selbyland";
# motd = "Welcome to the Selby Minecraft server.";
# };
# minecraft-server = {
# enable = true;
# package = pkgs.minecraft-current;
# data-dir = "/state/minecraft/selbyland";
# world-name = "selbyland";
# motd = "Welcome to the Selby Minecraft server.";
# };
};
networking = {
@ -240,12 +237,10 @@ in {
}];
};
extif0 = {
ipv4.addresses = [
{
address = primary-ip;
prefixLength = 28;
}
];
ipv4.addresses = [{
address = primary-ip;
prefixLength = 28;
}];
};
};
};

View File

@ -14,20 +14,25 @@ let
in {
config = {
networking = {
enableIPv6 = true;
enableIPv6 = false;
useDHCP = false;
nameservers = [ "1.1.1.1" ];
defaultGateway = {
interface = "extif0";
interface = "enp5s0f0";
address = site.gateway-v4;
};
interfaces = {
extif0 = {
enp5s0f0 = {
ipv4.addresses = [{
address = primary-ip;
prefixLength = 28;
}];
};
};
firewall = {
enable = false;
interfaces."podman+".allowedUDPPorts = [ 53 ];
};
};
systemd = {
@ -80,17 +85,19 @@ in {
arion.backend = "podman-socket";
};
services.lemmyDocker.state-directory = "/state/services/lemmy";
fudo = {
client.dns = {
ipv4 = true;
ipv6 = true;
user = "fudo-client";
external-interface = "extif0";
external-interface = "enp5s0f0";
};
mail.state-directory = "/state/services/mail";
nsd.zones."fudo.org".outgoingInterface = "extif0";
nsd.zones."fudo.org".outgoingInterface = "enp5s0f0";
# Necessary because germany isn't the default yet
postgresql = {
@ -106,6 +113,7 @@ in {
authoritative-dns.state-directory = "/state/services/dns";
jabber.state-directory = "/state/services/jabber";
logging.loki.state-directory = "/state/services/loki";
mail-server.state-directory = "/state/services/mail";
metrics = {
prometheus.state-directory = "/state/services/prometheus";
grafana.state-directory = "/state/services/grafana";
@ -117,6 +125,7 @@ in {
principals = [ "postgres/${hostFqdn}" ];
};
};
matrix.state-directory = "/state/services/matrix";
};
};
};

View File

@ -41,7 +41,7 @@ in {
fonts.fontconfig = {
hinting = {
enable = true;
style = "hintfull";
style = "full";
};
subpixel.lcdfilter = "default";
antialias = true;

View File

@ -35,9 +35,9 @@ in {
security.acme.defaults.email = "admin@legatus.fudo.org";
systemd.tmpfiles.rules = [
"L /etc/adjtime - - - - /state/etc/adjtime"
"L /etc/adjtime - - - - /state/etc/adjtime"
"d /state/services/podman/volumes 0700 root root - -"
"d /state/services/acme 0755 acme acme - -"
"d /state/services/acme 0755 acme acme - -"
];
fileSystems = {
@ -49,8 +49,6 @@ in {
environment.systemPackages = local-packages;
# networking.firewall.allowedTCPPorts = [ 80 443 ];
# informis.cl-gemini = {
# enable = true;
@ -63,24 +61,8 @@ in {
services = {
mastodonContainer.state-directory = "/state/services/mastodon";
lemmyDocker = {
enable = true;
hostname = "lemmy.fudo.org";
site-name = "Fudo Lemmy";
version = "0.18";
state-directory = "/state/services/lemmy";
smtp-server = "mail.fudo.org:587";
docker-images = {
pictrs = "asonix/pictrs:0.4";
postgres = "postgres:15-alpine";
};
};
authentikContainer.state-directory = "/state/services/authentik";
nextcloudContainer.state-directory = "/state/services/nextcloud";
nginx.virtualHosts."fudo.org" = {
enableACME = true;
forceSSL = true;
};
};
virtualisation = {
@ -98,12 +80,8 @@ in {
services = {
auth = {
ldap.state-directory = "/state/auth/ldap";
kerberos = {
state-directory = "/state/auth/kerberos";
# master-key-file = host-secrets.heimdal-master-key.target-file;
# ipropd-keytab = host-secrets.heimdal-ipropd-keytab.target-file;
};
ldap.state-directory = "/state/services/ldap";
kerberos.state-directory = "/state/services/heimdal-kdc";
};
chat = {
@ -112,40 +90,6 @@ in {
};
nexus.dns-server.listen-addresses = [ host-ipv4 ];
# lemmy = {
# enable = true;
# hostname = "lemmy.fudo.org";
# };
matrix.state-directory = "/state/services/matrix";
};
secrets.host-secrets.legatus = 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";
# };
# gitea-database-password = {
# source-file = files.service-passwords.procul.gitea-database;
# target-file = "/srv/gitea/secure/database.passwd";
# user = config.fudo.git.user;
# };
# heimdal-master-key = {
# source-file = files.realm-master-keys."FUDO.ORG";
# target-file = "/run/heimdal/master-key";
# user = config.fudo.auth.kdc.user;
# };
# heimdal-ipropd-keytab = {
# source-file = files.service-keytabs.legatus.ipropd;
# target-file = "/run/heimdal/ipropd.keytab";
# user = config.fudo.auth.kdc.user;
# };
};
client.dns = {

View File

@ -58,8 +58,12 @@ in {
# };
firewall = {
enable = true;
allowedTCPPorts = [ 80 443 25565 config.services.murmur.port ];
allowedUDPPorts = [ 25565 34197 ];
extraCommands = ''
iptables -A INPUT -s 141.98.7.36 -j DROP
'';
};
nat.forwardPorts = [

View File

@ -75,20 +75,10 @@ in {
"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};
fudo = let host-secrets = config.fudo.secrets.host-secrets."${hostname}";
in {
secrets.host-secrets.${hostname} = {
pricebot-auth-token = {
@ -117,7 +107,6 @@ in {
metrics.grafana = {
state-directory = "/state/services/grafana";
smtp.hostname = "mail.fudo.org";
ldap.base-dn = "dc=fudo,dc=org";
};
postgresql = {
@ -135,8 +124,6 @@ in {
enable = true;
local-networks = config.instance.local-networks;
state-directory = "/state/services/postgresql";
databases.grafana.users = config.instance.local-admins;
};
services.gitea-container = {
@ -146,10 +133,6 @@ in {
state-directory = "/state/services/gitea";
trusted-networks = config.instance.local-networks;
openid-urls = [ "https://authentik.fudo.org/" ];
secret-key-file =
pkgs.lib.passwd.stablerandom-passwd-file "gitea-seattle-secret-key"
config.instance.build-seed;
networking = {
interface = "eno2";
ipv4 = {

View File

@ -193,16 +193,5 @@ in {
# loadLatestSave = true;
# package = pkgs.factorio-headless-experimental;
# };
services.nginx.virtualHosts = {
"selby.ca" = {
enableACME = true;
locations."/".return = "301 https://selbyhomecentre.com$request_uri";
};
"www.selby.ca" = {
enableACME = true;
locations."/".return = "301 https://selbyhomecentre.com$request_uri";
};
};
};
}

View File

@ -138,6 +138,7 @@ in {
groups = {
wheel.members = [ "niten" "reaper" ];
dns = { members = [ "niten" "reaper" "named" ]; };
fudo.members = [ "niten" "reaper" ];
};
};

View File

@ -10,17 +10,23 @@ let
config = {
containers.tester = {
autoStart = true;
# hostAddress = "10.0.0.14";
# localAddress = "10.0.0.14";
additionalCapabilities = [ "CAP_NET_ADMIN" ];
# privateNetwork = true;
macvlans = [ "enp7s0" ];
# hostBridge = "tester0";
#hostBridge = "tester0";
#hostAddress = "10.0.0.14";
#privateNetwork = true;
config = {
imports = [ pkgs.moduleRegistry.authoritativeDns ];
services.openssh.enable = true;
users.users.niten = config.users.users.niten;
users = let groupName = config.users.users.niten.group;
in {
users.niten = config.users.users.niten;
groups."${groupName}" = config.users.groups."${groupName}";
};
services.authoritative-dns = {
enable = true;
@ -40,12 +46,16 @@ let
allowedTCPPorts = [ 22 53 ];
allowedUDPPorts = [ 53 ];
};
interfaces = {
mv-enp7s0.ipv4.addresses = [{
address = "10.0.0.14";
prefixLength = 24;
}];
};
# interfaces.eth0 = {
# ipv4.addresses = [{
# address = "10.0.0.14";
# prefixLength = 24;
# }];
# };
interfaces.mv-enp7s0.ipv4.addresses = [{
address = "10.0.0.14";
prefixLength = 24;
}];
};
};
};
@ -118,7 +128,7 @@ in {
fonts.fontconfig = {
hinting = {
enable = true;
style = "hintfull";
style = "full";
};
subpixel.lcdfilter = "default";
antialias = true;
@ -132,7 +142,7 @@ in {
hardware = {
bluetooth = {
enable = true;
package = pkgs.bluezFull;
package = pkgs.bluez;
};
xpadneo.enable = true;
};

View File

@ -20,6 +20,7 @@ in {
prefixLength = 16;
}];
};
firewall.enable = false;
};
security.sudo.extraConfig = ''

View File

@ -47,8 +47,6 @@ in {
};
};
nixpkgs.config.allowUnfree = true;
hardware.enableAllFirmware = true;
services = {

View File

@ -46,6 +46,7 @@ let
imports = [ pkgs.moduleRegistry.authoritativeDns ];
nixpkgs.pkgs = pkgs;
networking = {
enableIPv6 = false;
defaultGateway = {
address = getSiteGatewayV4 siteName;
interface = "mv-${cfg.container.interface}";
@ -57,8 +58,7 @@ let
};
interfaces."mv-${cfg.container.interface}" = {
ipv4.addresses = optional (nameserverDeets.ipv4-address != null) {
address = trace "IP ADDRESS: ${nameserverDeets.ipv4-address}"
nameserverDeets.ipv4-address;
address = nameserverDeets.ipv4-address;
prefixLength = getSiteV4PrefixLength siteName;
};
ipv6.addresses = optional (nameserverDeets.ipv6-address != null) {
@ -224,6 +224,7 @@ in {
};
};
});
default = null;
};
enable-notifications =
@ -283,7 +284,6 @@ in {
nameValuePair (zoneKeySecret zone) {
source-file = zoneCfg.ksk.private-key;
target-file = "/run/nsd/${baseNameOf zoneCfg.ksk.private-key}";
user = config.fudo.nsd.user;
}) (filterAttrs (_: zoneCfg: zoneCfg.ksk != null) cfg.zones);
zones = mapAttrs (zone-name: zoneCfg:

View File

@ -22,12 +22,6 @@ in {
description = "Path at which to store Gitea state.";
};
secret-key-file = mkOption {
type = str;
description =
"Path to file containing Gitea secret key, for encrypting secrets.";
};
trusted-networks = mkOption {
type = listOf str;
description =
@ -131,7 +125,6 @@ in {
service.DISABLE_REGISTRATION = true;
security = {
INSTALL_LOCK = true;
SECRET_KEY = "file:${cfg.secret-key-file}";
LOGIN_REMEMBER_DAYS = 30;
};
metrics.ENABLED = cfg.trusted-networks != [ ];
@ -153,11 +146,12 @@ in {
};
openid = {
ENABLE_OPENID_SIGNIN = true;
WHITELISTED_URIS = cfg.openid-urls;
WHITELISTED_URIS = concatStringsSep "," cfg.openid-urls;
};
oauth2_client = {
REGISTER_EMAIL_CONFIRM = false;
OPENID_CONNECT_SCOPES = [ "email" "profile" ];
OPENID_CONNECT_SCOPES =
concatStringsSep "," [ "email" "profile" ];
ENABLE_AUTO_REGISTRATION = true;
USERNAME = "email";
UPDATE_AVATAR = true;
@ -194,11 +188,14 @@ in {
# enableACME = true;
# forceSSL = true;
locations."/".proxyPass = "http://127.0.0.1:8080";
locations."/metrics" = mkIf (cfg.trusted-networks != [ ]) (let
networkAllowClauses =
map (net: "allow ${net};") cfg.trusted-networks;
in concatStringsSep "\n"
(networkAllowClauses ++ [ "deny all;" ]));
locations."/metrics" = mkIf (cfg.trusted-networks != [ ]) {
proxyPass = "http://127.0.0.1:8080/metrics";
extraConfig = let
networkAllowClauses =
map (net: "allow ${net};") cfg.trusted-networks;
in concatStringsSep "\n"
(networkAllowClauses ++ [ "deny all;" ]);
};
};
};
};

View File

@ -20,7 +20,7 @@ let
isLocalMailserver = domain-name == mailserver-domain-name;
metricsEnabled = mailserver-domain.prometheus-hosts != [ ];
metricsEnabled = !isNull mailserver-domain.metrics;
host-certs = config.fudo.acme.host-domains.${hostname};
@ -28,13 +28,20 @@ in {
options.fudo.services.mail-server = with types; {
debug = mkEnableOption "Enable debug options for mailserver.";
enable = mkOption {
type = bool;
default = true;
description =
"Temporary -- allow disabling mail server (in favor of mail container).";
};
state-directory = mkOption {
type = str;
description = "Directory at which to store mailserver state.";
};
};
config = mkIf hasMailServer {
config = mkIf (hasMailServer && cfg.enable) {
services.nginx = mkIf (isMailServer && metricsEnabled) {
enable = true;
recommendedOptimisation = true;
@ -106,17 +113,6 @@ in {
in {
aliases = mkIf metricsEnabled { mail-stats = "${mailserver-fqdn}."; };
# srv-records.tcp = {
# pop3 = srv-record mailserver-fqdn 110;
# pop3s = srv-record mailserver-fqdn 995;
# imap = srv-record mailserver-fqdn 143;
# imaps = srv-record mailserver-fqdn 993;
# smtp = srv-record mailserver-fqdn 25;
# submission = srv-record mailserver-fqdn 587;
# };
metric-records = mkIf metricsEnabled
(genAttrs [ "dovecot" "postfix" "rspamd" ]
(_: srv-record "mail-stats" 443));

View File

@ -3,54 +3,28 @@
with lib;
let
hostname = config.instance.hostname;
domain-name = config.fudo.hosts."${hostname}".domain;
domain = config.fudo.domains."${domain-name}";
domainName = config.fudo.hosts."${hostname}".domain;
domain = config.fudo.domains."${domainName}";
host-secrets = config.fudo.secrets.host-secrets."${hostname}";
inherit (pkgs.lib) getHostIpv4 getHostIpv6 getHostFqdn;
notEmpty = lst: (length lst) > 0;
hostSecrets = config.fudo.secrets.host-secrets."${hostname}";
metricsEnabled = notEmpty domain.prometheus-hosts;
metricsScraper = elem hostname domain.prometheus-hosts;
metricsMonitor = elem hostname domain.grafana-hosts;
metricsEnabled = !isNull domain.metrics;
isPrometheus = hostname == domain.metrics.prometheus-host;
isGrafana = hostname == domain.metrics.grafana-host;
prometheus-cfg = config.fudo.services.metrics.prometheus;
grafana-cfg = config.fudo.services.metrics.grafana;
grafanaHost = domain.metrics.grafana-host;
prometheusHost = domain.metrics.prometheus-host;
host-fqdn = hostname:
let host-domain = config.fudo.hosts.${hostname}.domain;
in "${hostname}.${host-domain}";
host-auth-fqdn = hostname: "${host-fqdn hostname}.";
make-alias-map = type: hosts:
listToAttrs
(imap0 (i: hostname: nameValuePair hostname "${type}-${toString i}") hosts);
headOrNull = lst: if notEmpty lst then head lst else null;
metrics-master = headOrNull domain.prometheus-hosts;
monitor-master = headOrNull domain.grafana-hosts;
metrics-alias-map = make-alias-map "metrics" domain.prometheus-hosts;
monitor-alias-map = make-alias-map "monitor" domain.grafana-hosts;
alias-map-to-cnames =
mapAttrs' (hostname: alias: nameValuePair alias (host-auth-fqdn hostname));
alias-map-to-hostnames =
mapAttrsToList (hostname: alias: "${alias}.${domain-name}");
prometheusCfg = config.fudo.services.metrics.prometheus;
grafanaCfg = config.fudo.services.metrics.grafana;
privateNetwork = config.fudo.services.metrics.private-network;
grafana-smtp-password-file =
pkgs.lib.passwd.stablerandom-passwd-file "grafana-smtp-passwd"
config.instance.build-seed;
grafana-auth-password-file =
pkgs.lib.passwd.stablerandom-passwd-file "grafana-auth-passwd"
config.instance.build-seed;
grafana-admin-password-file =
pkgs.lib.passwd.stablerandom-passwd-file "grafana-admin-passwd"
config.instance.build-seed;
@ -59,25 +33,14 @@ let
pkgs.lib.passwd.stablerandom-passwd-file "grafana-secret-key"
config.instance.build-seed;
grafana-database-password-file =
pkgs.lib.passwd.stablerandom-passwd-file "grafana-database-postgres"
config.instance.build-seed;
site = let site-name = config.fudo.hosts."${hostname}".site;
in config.fudo.sites."${site-name}";
is-private-network = site.local-gateway != null;
domainToBaseDn = domain:
concatStringsSep "," (map (el: "dc=${el}") (splitString "." domain));
ldapEnabled = domain.ldap-servers != [ ];
isPostgresServer = config.instance.hostname == domain.postgresql-server;
postgresServer = pkgs.lib.getHostFqdn domain.postgresql-server;
in {
options.fudo.services.metrics = with types; {
private-network = mkOption {
type = bool;
description = "Network is private, encryption not required.";
default = false;
};
prometheus = {
static-targets = mkOption {
type = attrsOf (listOf str);
@ -86,6 +49,7 @@ in {
example = { dovecot = [ "my.host.name:1111" ]; };
default = { };
};
state-directory = mkOption {
type = str;
description = "Path at which to store Prometheus state.";
@ -99,6 +63,7 @@ in {
description = "Username from which to send Grafana alerts.";
default = "monitor";
};
hostname = mkOption {
type = str;
description = "Hostname of the SMTP host.";
@ -106,50 +71,35 @@ in {
};
};
ldap = let base-dn = domainToBaseDn config.instance.local-domain;
in {
base-dn = mkOption {
type = str;
description = "DN under which to search for users.";
default = base-dn;
};
oauth = let
oauthOpts.options = {
hostname = mkOption {
type = str;
description = "Host of the OAuth server.";
};
bind-user = mkOption {
type = str;
description = "DN as which to bind to the LDAP server.";
default = "grafana_reader";
};
client-id = mkOption {
type = str;
description =
"Path to file containing the Grafana OAuth client ID.";
};
bind-passwd = mkOption {
type = nullOr str;
description = "Path to file with bind password. Generated if null.";
default = null;
client-secret = mkOption {
type = str;
description =
"Path to file containing the Grafana OAuth client secret.";
};
slug = mkOption {
type = str;
description = "The application slug on the OAuth server.";
};
};
in mkOption {
type = nullOr (submodule oauthOpts);
default = null;
};
# database = {
# hostname = mkOption {
# type = str;
# description = "Hostname of the postgresql database.";
# default = "localhost";
# };
# user = mkOption {
# type = str;
# description =
# "Username as which to authenticate to the postgresql database.";
# };
# password-file = mkOption {
# type = str;
# description =
# "Password file (on the target host) which to authenticate to the postgresql database.";
# };
# name = mkOption {
# type = str;
# description = "Database name.";
# default = "grafana";
# };
# };
state-directory = mkOption {
type = str;
description = "Path at which to store Grafana state.";
@ -159,189 +109,131 @@ in {
};
config = mkIf metricsEnabled {
fudo = {
system-users = {
"${grafana-cfg.smtp.username}" = {
description = "Grafana Alerts";
ldap-hashed-password =
pkgs.lib.passwd.hash-ldap-passwd "grafana-smtp-passwd"
grafana-smtp-password-file;
};
"${grafana-cfg.ldap.bind-user}" = mkIf ((domain.ldap-servers != [ ])
&& (grafana-cfg.ldap.bind-passwd == null)) {
description = "Grafana Authentication Reader";
ldap-hashed-password =
pkgs.lib.passwd.hash-ldap-passwd "grafana-auth-passwd"
grafana-auth-password-file;
};
};
secrets.host-secrets =
let grafana-user = config.systemd.services.grafana.serviceConfig.User;
in {
"${hostname}" = {
grafana-smtp-password = mkIf metricsMonitor {
source-file = grafana-smtp-password-file;
target-file = "/run/metrics/grafana/smtp.passwd";
user = grafana-user;
};
grafana-admin-password = mkIf metricsMonitor {
grafana-admin-password = mkIf isGrafana {
source-file = grafana-admin-password-file;
target-file = "/run/metrics/grafana/admin.passwd";
user = grafana-user;
};
grafana-secret-key = mkIf metricsMonitor {
grafana-secret-key = mkIf isGrafana {
source-file = grafana-secret-key-file;
target-file = "/run/metrics/grafana/secret.key";
user = grafana-user;
};
grafana-postgresql-password = mkIf metricsMonitor {
source-file = grafana-database-password-file;
target-file = "/run/metrics/grafana/postgres.passwd";
grafana-client-id = mkIf (isGrafana && !isNull grafanaCfg.oauth) {
source-file = grafanaCfg.oauth.client-id;
target-file = "/run/metrics/grafana/oauth-client-id";
user = grafana-user;
};
postgresql-grafana-password = mkIf isPostgresServer {
source-file = grafana-database-password-file;
target-file = "/run/postgres-users/grafana.passwd";
user = config.systemd.services.postgresql.serviceConfig.User;
};
grafana-client-secret =
mkIf (isGrafana && !isNull grafanaCfg.oauth) {
source-file = grafanaCfg.oauth.client-secret;
target-file = "/run/metrics/grafana/oauth-client-secret";
user = grafana-user;
};
};
};
zones."${domain.zone}" = {
aliases = let
metrics-aliases = alias-map-to-cnames metrics-alias-map;
monitor-aliases = alias-map-to-cnames monitor-alias-map;
metrics-master-cname = optionalAttrs (metrics-master != null) {
metrics = "${metrics-master}.${domain-name}.";
hosts = {
grafana = {
ipv4-address = getHostIpv4 grafanaHost;
ipv6-address = getHostIpv6 grafanaHost;
description = "Grafana Metrics Analysis on ${grafanaHost}.";
};
monitor-master-cname = optionalAttrs (monitor-master != null) {
monitor = "${monitor-master}.${domain-name}.";
prometheus = {
ipv4-address = getHostIpv4 prometheusHost;
ipv6-address = getHostIpv6 prometheusHost;
description = "Prometheus Metrics Aggregator on ${prometheusHost}.";
};
in metrics-aliases // monitor-aliases // metrics-master-cname
// monitor-master-cname;
};
aliases = {
metrics = "prometheus.${domainName}";
monitor = "grafana.${domainName}";
};
metric-records = let
domain-hosts = filterAttrs (hostname: hostOpts:
hostOpts.domain == domain-name && hostOpts.nixos-system)
domainHosts = filterAttrs (hostname: hostOpts:
hostOpts.domain == domainName && hostOpts.nixos-system)
config.fudo.hosts;
in {
node = map (hostname: {
host = "${hostname}.${domain-name}";
port = if is-private-network then 80 else 443;
}) (attrNames domain-hosts);
host = getHostFqdn hostname;
port = if privateNetwork then 80 else 443;
}) (attrNames domainHosts);
};
};
postgresql = mkIf isPostgresServer {
users.grafana = {
password-file = host-secrets.postgresql-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";
};
};
};
databases.grafana.users = config.instance.local-admins;
};
metrics = {
node-exporter = {
enable = true;
hostname = host-fqdn hostname;
private-network = is-private-network;
hostname = getHostFqdn hostname;
private-network = privateNetwork;
};
prometheus = mkIf metricsScraper {
prometheus = mkIf isPrometheus {
enable = true;
service-discovery-dns = {
node = [ "node._metrics._tcp.${domain-name}" ];
node = [ "node._metrics._tcp.${domainName}" ];
};
static-targets = prometheus-cfg.static-targets;
hostname = let alias = metrics-alias-map.${hostname};
in "${alias}.${domain-name}";
state-directory = prometheus-cfg.state-directory;
private-network = is-private-network;
static-targets = prometheusCfg.static-targets;
hostname = "prometheus.${domainName}";
state-directory = prometheusCfg.state-directory;
private-network = privateNetwork;
};
};
grafana = mkIf metricsMonitor {
enable = true;
hostname = let alias = monitor-alias-map.${hostname};
in "${alias}.${domain-name}";
smtp = let cfg = grafana-cfg.smtp;
in {
username = cfg.username;
password-file = host-secrets.grafana-smtp-password.target-file;
hostname = cfg.hostname;
email = "${cfg.username}@${domain-name}";
services.grafana = mkIf isGrafana {
enable = true;
state-directory = grafanaCfg.state-directory;
base-url = let scheme = if privateNetwork then "http" else "https";
in "${scheme}://grafana.${domainName}";
admin-password-file = hostSecrets.grafana-admin-password.target-file;
secret-key-file = hostSecrets.grafana-secret-key.target-file;
datasources = {
"${domainName}" = {
url = let scheme = if privateNetwork then "http" else "https";
in "${scheme}://prometheus.${domainName}";
type = "prometheus";
default = true;
};
database = let cfg = grafana-cfg.database;
in {
name = "grafana";
user = "grafana";
password-file =
host-secrets.grafana-postgresql-password.target-file;
hostname = postgresServer;
};
ldap = mkIf (domain.ldap-servers != [ ]) {
hosts = map host-fqdn domain.ldap-servers;
base-dn = grafana-cfg.ldap.base-dn;
bind-dn =
"cn=${grafana-cfg.ldap.bind-user},${grafana-cfg.ldap.base-dn}";
bind-passwd = if (grafana-cfg.ldap.bind-passwd != null) then
grafana-cfg.ldap.bind-passwd
else
(readFile grafana-auth-password-file);
};
admin-password-file = host-secrets.grafana-admin-password.target-file;
secret-key-file = host-secrets.grafana-secret-key.target-file;
datasources = let
scheme = if is-private-network then "http" else "https";
host-config = hostname: {
url = "${scheme}://${hostname}.${domain-name}";
type = "prometheus";
default = hostname == "metrics-0";
};
in listToAttrs
(map (host: nameValuePair "prometheus-${host}" (host-config host))
(attrValues metrics-alias-map));
state-directory = grafana-cfg.state-directory;
private-network = is-private-network;
};
oauth = mkIf (!isNull grafanaCfg.oauth) {
inherit (grafanaCfg.oauth) hostname slug;
client-id = hostSecrets.grafana-client-id.target-file;
client-secret = hostSecrets.grafana-client-secret.target-file;
};
};
};
services.nginx =
mkIf (hostname == metrics-master || hostname == monitor-master) {
enable = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
services.nginx = mkIf (isPrometheus || isGrafana) {
enable = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
virtualHosts =
let scheme = if is-private-network then "http" else "https";
in {
"metrics.${domain-name}" = mkIf (hostname == metrics-master) {
enableACME = !is-private-network;
forceSSL = !is-private-network;
locations."/".return = let alias = metrics-alias-map.${hostname};
in "301 ${scheme}://${alias}.${domain-name}$request_uri";
};
"monitor.${domain-name}" = mkIf (hostname == monitor-master) {
enableACME = !is-private-network;
forceSSL = !is-private-network;
locations."/".return = let alias = monitor-alias-map.${hostname};
in "301 ${scheme}://${alias}.${domain-name}$request_uri";
};
};
virtualHosts = let scheme = if privateNetwork then "http" else "https";
in {
"metrics.${domainName}".locations."/".return =
"302 http://prometheus.${domainName}";
"monitor.${domainName}".locations."/".return =
"302 http://grafana.${domainName}";
"grafana.${domainName}" = {
enableACME = !privateNetwork;
forceSSL = !privateNetwork;
locations."/".proxyPass =
"http://localhost:${toString config.fudo.services.grafana.port}";
};
};
};
};
}

View File

@ -3,14 +3,6 @@
with lib;
let local-domain = "sea.fudo.org";
in {
# imports = [ ./seattle/authelia.nix ./seattle/keycloak.nix ];
imports = [
# (import ./seattle/authentik.nix {
# authentikHost = "nostromo";
# proxyHost = "limina";
# externalHostname = "authentik.fudo.link";
# })
];
config = {
fudo = {
@ -63,16 +55,6 @@ in {
};
fileSystems = {
# "/mnt/documents" = {
# device = "whitedwarf.${local-domain}:/volume1/Documents";
# fsType = "nfs4";
# options = [ "comment=systemd.automount" ];
# };
# "/mnt/downloads" = {
# device = "whitedwarf.${local-domain}:/volume1/Downloads";
# fsType = "nfs4";
# options = [ "comment=systemd.automount" ];
# };
"/mnt/music" = {
device = "doraemon.${local-domain}:/volume1/Music";
fsType = "nfs";
@ -83,10 +65,6 @@ in {
fsType = "nfs";
options = [ "comment=systemd.automount" ];
};
# fileSystems."/mnt/security" = {
# device = "panopticon.${local-domain}:/srv/kerberos/data";
# fsType = "nfs4";
# };
"/mnt/cargo_video" = {
device = "cargo.${local-domain}:/volume1/video";
fsType = "nfs4";
@ -98,41 +76,21 @@ in {
options = [ "sec=krb5i" "x-systemd.automount" ];
};
# "proto=tcp"
# # NOTE: these are pointing directly to nostromo so the krb lookup works
"/net/documents" = {
device = "nostromo.${local-domain}:/export/documents";
fsType = "nfs4";
options = [
"sec=krb5p"
"x-systemd.automount"
# "vers=4"
# "minorversion=2"
# "proto=tcp"
];
options = [ "sec=krb5p" "x-systemd.automount" ];
};
"/net/downloads" = {
device = "nostromo.${local-domain}:/export/downloads";
fsType = "nfs4";
options = [
"sec=krb5i"
"x-systemd.automount"
# "vers=4"
# "minorversion=2"
# "proto=tcp"
];
options = [ "sec=krb5i" "x-systemd.automount" ];
};
"/net/projects" = {
device = "nostromo.${local-domain}:/export/projects";
fsType = "nfs4";
options = [
"sec=krb5p"
"x-systemd.automount"
# "vers=4"
# "minorversion=2"
# "proto=tcp"
];
options = [ "sec=krb5p" "x-systemd.automount" ];
};
};

View File

@ -1,12 +1,10 @@
{ config, lib, pkgs, ... }:
with lib;
{
with lib; {
config = let
filterExistingUsers = users: group-members:
let user-list = attrNames users;
in filter (username: elem username user-list)
group-members;
in filter (username: elem username user-list) group-members;
hostname = config.instance.hostname;
host-cfg = config.fudo.hosts.${hostname};
@ -14,8 +12,8 @@ with lib;
sys = config.instance;
in {
fudo.auth.ldap-server = {
users = filterAttrs
(username: userOpts: userOpts.ldap-hashed-passwd != null)
users =
filterAttrs (username: userOpts: userOpts.ldap-hashed-passwd != null)
config.fudo.users;
groups = config.fudo.groups;
@ -29,14 +27,10 @@ with lib;
'';
environment.etc = mapAttrs' (username: userOpts:
nameValuePair
"ssh/private_keys.d/${username}"
{
text = concatStringsSep "\n"
(map (keypair: readFile keypair.public-key)
userOpts.ssh-keys);
})
sys.local-users;
nameValuePair "ssh/private_keys.d/${username}" {
text = concatStringsSep "\n"
(map (keypair: readFile keypair.public-key) userOpts.ssh-keys);
}) sys.local-users;
users = {
users = mapAttrs (username: userOpts: {
@ -47,8 +41,8 @@ with lib;
group = userOpts.primary-group;
home = if (userOpts.home-directory != null) then
userOpts.home-directory
else
"/home/${userOpts.primary-group}/${username}";
else
"/home/${userOpts.primary-group}/${username}";
hashedPassword = userOpts.login-hashed-passwd;
openssh.authorizedKeys.keys = userOpts.ssh-authorized-keys;
}) sys.local-users;
@ -57,8 +51,7 @@ with lib;
gid = groupOpts.gid;
members = filterExistingUsers sys.local-users groupOpts.members;
}) sys.local-groups) // {
wheel = { members = sys.local-admins; };
docker = mkIf (host-cfg.docker-server) { members = sys.local-admins; };
wheel.members = sys.local-admins;
};
};
@ -73,9 +66,7 @@ with lib;
# Domain = local-domain;
"Local-Realms" = local-realm;
};
Translation = {
GSS-Methods = "static";
};
Translation = { GSS-Methods = "static"; };
Static = let
generate-admin-entry = admin: userOpts:
nameValuePair "${admin}/root@${local-realm}" "root";
@ -84,8 +75,7 @@ with lib;
admin-entries =
mapAttrs' generate-admin-entry (getAttrs local-admins local-users);
user-entries =
mapAttrs' generate-user-entry local-users;
user-entries = mapAttrs' generate-user-entry local-users;
in admin-entries // user-entries;
};
@ -94,6 +84,7 @@ with lib;
groups-with-members = attrNames
(filterAttrs (group: groupOpts: (length groupOpts.members) > 0)
sys.local-groups);
in map (group: "d /home/${group} 550 root ${group} - -") groups-with-members;
in map (group: "d /home/${group} 550 root ${group} - -")
groups-with-members;
};
}

View File

@ -5,7 +5,7 @@ with lib; {
users = {
niten = {
uid = 10000;
primary-group = "admin";
primary-group = "fudo";
common-name = "Peter Selby";
given-name = "Peter";
surname = "Selby";
@ -139,7 +139,7 @@ with lib; {
reaper = {
uid = 10049;
primary-group = "admin";
primary-group = "fudo";
common-name = "Jonathan Stewart";
given-name = "Jonathan";
surname = "Stewart";

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
description = "Fudo Host Configuration";
inputs = {
nixpkgs.url = "nixpkgs/nixos-23.05";
nixpkgs.url = "nixpkgs/nixos-23.11";
fudo-home = {
url = "git+https://git.fudo.org/fudo-nix/home.git";
@ -39,8 +39,6 @@
nixpkgsUnstable.url = "nixpkgs/nixos-unstable";
nixpkgs2111.url = "nixpkgs/nixos-21.11";
wallfly = {
url = "git+https://git.fudo.org/fudo-public/wallfly.git";
inputs.nixpkgs.follows = "nixpkgs";
@ -136,6 +134,11 @@
inputs.nixpkgs.follows = "nixpkgs";
};
grafana-module = {
url = "git+https://git.fudo.org/fudo-public/grafana-module.git";
inputs.nixpkgs.follows = "nixpkgs";
};
textfiles = {
url = "git+https://git.informis.land/informis/textfiles.git";
flake = false;
@ -143,11 +146,11 @@
};
outputs = { self, nixpkgs, fudo-home, fudo-lib, fudo-entities, fudo-pkgs
, fudo-secrets, chute, chuteUnstable, nixpkgsUnstable, nixpkgs2111, pricebot
, wallfly, objectifier, nexus, suanni, snooper, tattler, lemmy-docker
, fudo-secrets, chute, chuteUnstable, nixpkgsUnstable, pricebot, wallfly
, objectifier, nexus, suanni, snooper, tattler, lemmy-docker
, tesla-mate-container, mastodon-container, authentik-container
, nextcloud-container, textfiles, matrix-module, mail-server
, authoritative-dns, frigate-container, ... }@inputs:
, authoritative-dns, frigate-container, grafana-module, ... }@inputs:
with nixpkgs.lib;
let
fudo-nixos-hosts = filterAttrs (hostname: hostOpts: hostOpts.nixos-system)
@ -185,13 +188,7 @@
chute = chute.packages.${arch}.chute;
chuteUnstable = chuteUnstable.packages.${arch}.chute;
})
(final: prev: {
pkgs2111 = import nixpkgs2111 {
system = arch;
config.allowUnfree = true;
};
pkgsUnstable = unstable;
})
(final: prev: { pkgsUnstable = unstable; })
(final: prev: {
signal-desktop = unstable.signal-desktop;
factorio-experimental = unstable.factorio-experimental;
@ -234,6 +231,7 @@
mail-server.nixosModules.default
authoritative-dns.nixosModules.default
frigate-container.nixosModules.default
grafana-module.nixosModules.default
nexus.nixosModules.nexus-client
nexus.nixosModules.nexus-server