{ config, lib, pkgs, ... }@toplevel: with lib; let hostname = config.instance.hostname; localDomain = "fudo.org"; domainSecrets = config.fudo.secrets.files.domain-secrets."${localDomain}"; hostSecrets = config.fudo.secrets.host-secrets."${hostname}"; inherit (pkgs.lib) getDomainHosts getHostIpv4 getHostIpv6 getHostFqdn getSiteV4PrefixLength; domain = config.fudo.domains."${localDomain}"; authentikHost = "legatus"; authentikImage = "ghcr.io/goauthentik/server:2023.10.7"; primaryNameserver = "germany"; webmailHost = "germany"; defaultHost = "germany"; mastodonHost = "germany"; mastodonHostname = "fudo.live"; giteaHost = "germany"; giteaHostname = "fudo.dev"; giteaIpv4Address = "208.81.3.118"; cloudHost = "germany"; cloudHostname = "fudo.cloud"; lemmyHost = "germany"; lemmyHostname = "fudo.social"; matrixHost = "germany"; matrixHostname = "fudo.im"; immichHost = "germany"; immichHostname = "pics.fudo.org"; servedDomains = [ "fudo.org" "test.fudo.org" "selby.ca" "fudo.ca" "fudo.im" "fudo.live" "fudo.social" "fudo.dev" "fudo.cloud" "stewartsoundservices.ca" ]; static = ../../static; in { imports = [ (import ./fudo.org/authentik.nix { inherit authentikHost authentikImage; }) (import ./fudo.org/mastodon.nix { mastodonHost = mastodonHost; mastodonHostname = mastodonHostname; mastodonWebDomain = mastodonHostname; mastodonOidcClientId = domainSecrets."mastodon-oidc.clientid"; mastodonOidcClientSecret = domainSecrets."mastodon-oidc.secret"; }) (import ./fudo.org/nextcloud.nix { nextcloudHost = cloudHost; nextcloudHostname = cloudHostname; nextcloudPackage = pkgs.nextcloud28; }) (import ./fudo.org/matrix.nix { matrixHost = matrixHost; matrixServerName = matrixHostname; openIdClientId = readFile domainSecrets."matrix-oidc.clientid"; openIdClientSecret = readFile domainSecrets."matrix-oidc.secret"; openIdJwtSecret = readFile domainSecrets."matrix-private.pem"; }) (import ./fudo.org/mail-server.nix (rec { primaryMailserver = "germany"; primaryDomain = "fudo.org"; authentikServer = "authentik.fudo.org"; ldapBase = "dc=fudo,dc=org"; ldapBindDn = "cn=userdb,ou=users,${ldapBase}"; ldapBindPwFile = domainSecrets."ldap-bind.passwd"; saslDomain = "FUDO.ORG"; authentikOutpostToken = domainSecrets."authentik-ldap.token"; inherit servedDomains; dkimRecord = '' mail._domainkey IN TXT ( "v=DKIM1;k=rsa;p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwoCgHwsfuu0lhj9Ayj4ntoy0bdcGBNsV46qoKbd8E8FKsJF5rL4EoytwXEFcKJwT3E+o3/BsZGi9J5irtjlfIhnxnPlhVRS3R/834NDSQyuwGTxAfhPOklhA0cTYA+4x2oGwAuraz+On2REDeSymMccXFDsTugEHVvn6qaeqkJwIDAQAB" );''; })) ]; config = { systemd.services = { lemmy.after = [ "postgresql.service" ]; }; services = { immichContainer = mkIf (hostname == immichHost) { enable = true; images = let immichVersion = "v1.94.1"; in { immich = "ghcr.io/immich-app/immich-server:${immichVersion}"; immich-ml = "ghcr.io/immich-app/immich-machine-learning:${immichVersion}"; redis = "redis:6.2-alpine"; postgresql = "tensorchord/pgvecto-rs:pg14-v0.1.11"; }; }; 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"; "pics.fudo.org" = mkIf (hostname == immichHost) { enableACME = true; forceSSL = true; locations."/" = { proxyPass = "http://localhost:${ toString config.services.immichContainer.port }/"; proxyWebsockets = true; }; }; "fudo.org" = mkIf (hostname == defaultHost) { enableACME = true; forceSSL = true; locations = let mkWellKnown = data: '' add_header Content-Type application/json; add_header Access-Control-Allow-Origin *; return 200 '${builtins.toJSON data}'; ''; in { # Mastodon "/.well-known/webfinger" = { return = "301 https://${mastodonHostname}"; extraConfig = "add_header Access-Control-Allow-Origin '*';"; }; "/.well-known/host-meta" = { return = "301 https://${mastodonHostname}$request_uri"; }; # Matrix "/.well-known/matrix/server".extraConfig = mkWellKnown { "m.server" = "matrix.${matrixHostname}:443"; }; "/.well-known/matrix/client".extraConfig = mkWellKnown { "m.homeserver".base_url = "https://web.${matrixHostname}:443"; }; "/.well-known/acme-challenge" = { root = "/var/lib/acme/acme-challenge/"; extraConfig = "auth_basic off;"; }; }; }; }; # lemmyContainer = { # enable = config.instance.hostname == lemmyHost; # hostname = lemmyHostname; # site-name = "Fudo Lemmy"; # smtp.host = "mail.fudo.org:587"; # # admin-password-file = hostSecrets.lemmyAdminPasswd.target-file; # server-package = pkgs.pkgsUnstable.lemmy-server; # }; }; fudo = { secrets.host-secrets."${hostname}" = { lemmyAdminPasswd = { source-file = pkgs.lib.passwd.stablerandom-passwd-file "lemmy-admin.passwd" config.instance.build-seed; target-file = "/run/lemmy/admin.passwd"; }; }; zones = { "fudo.org".aliases = { cloud = "germany.fudo.org."; pics = "germany.fudo.org."; webmail = "germany.fudo.org."; }; "selby.ca".aliases.webmail = "germany.fudo.org."; }; webmail = { enable = hostname == webmailHost; sites = { "webmail.fudo.org" = { title = "Fudo Webmail"; favicon = "${static}/fudo.org/favicon.ico"; mail-server = "mail.fudo.org"; domain = "fudo.org"; edit-mode = "Plain"; }; "webmail.fudo.link" = { title = "Fudo Link Webmail"; favicon = "${static}/fudo.link/favicon.ico"; mail-server = "mail.fudo.org"; domain = "fudo.link"; edit-mode = "Plain"; layout-mode = "bottom"; }; "webmail.selby.ca" = { title = "Selby Webmail"; favicon = "${static}/selby.ca/favicon.ico"; mail-server = "mail.fudo.org"; domain = "selby.ca"; }; }; }; services = { # DON'T enable, we're using mail-container instead 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"; }; }; lemmy = { enable = hostname == lemmyHost; hostname = "fudo.social"; site-name = "Fudo Lemmy"; smtp.host = "mail.fudo.org"; }; gitea-container = let siteName = config.fudo.hosts."${giteaHost}".site; in { enable = hostname == giteaHost; site-name = "Fudo Git"; hostname = giteaHostname; trusted-networks = config.instance.local-networks; networking.ipv4 = { address = giteaIpv4Address; prefixLength = getSiteV4PrefixLength siteName; }; }; authoritative-dns = { enable = hostname == primaryNameserver; enable-notifications = true; container = { hostname = "nameserver"; interface = "enp5s0f0"; }; nameservers = { primary = "nameserver"; external = map (hostname: { inherit (config.fudo.zones."fudo.org".hosts."${hostname}") ipv4-address ipv6-address description; }) [ "ns2-fudo" "ns3-fudo" "ns4-fudo" ]; }; ip-host-map = let networkHosts = getDomainHosts "fudo.org"; ipHostPairs = map (host: nameValuePair (getHostIpv4 host) (getHostFqdn host)) networkHosts; in listToAttrs ipHostPairs; zones = let defaultDeets = { inherit (config.fudo.zones."fudo.org".hosts."${defaultHost}") ipv4-address ipv6-address sshfp-records; description = "fudo.org"; }; # TODO: Fix email FFS! fudoMailservers = { smtp-servers = [ "mail.fudo.org." ]; imap-servers = [ "mail.fudo.org." ]; }; mkDomain = domain: extraConfig: { ksk = config.fudo.secrets.files.dns.key-signing-keys."${domain}"; } // extraConfig; getDeets = hostname: description: { inherit (config.fudo.zones."fudo.org".hosts."${hostname}") ipv4-address ipv6-address sshfp-records; }; in { "fudo.org" = mkDomain "fudo.org" { reverse-zones = [ "208.81.1.128/28" "208.81.3.112/28" ]; mail = fudoMailservers; default-host = defaultDeets; }; "test.fudo.org" = mkDomain "test.fudo.org" { }; "selby.ca" = mkDomain "selby.ca" { mail = fudoMailservers; default-host = defaultDeets; }; "fudo.ca" = mkDomain "fudo.ca" { mail = fudoMailservers; default-host = defaultDeets; }; "fudo.im" = mkDomain "fudo.im" { mail = fudoMailservers; default-host = getDeets matrixHost "fudo.im primary server"; }; "stewartsoundservices.ca" = mkDomain "stewartsoundservices.ca" { mail = fudoMailservers; default-host = defaultDeets; }; "fudo.live" = mkDomain "fudo.live" { mail = fudoMailservers; default-host = getDeets mastodonHost "fudo.live primary server"; }; "fudo.social" = mkDomain "fudo.social" { mail = fudoMailservers; default-host = getDeets lemmyHost "fudo.social primary server"; }; "fudo.dev" = mkDomain "fudo.dev" { mail = fudoMailservers; default-host = { ipv4-address = giteaIpv4Address; description = "fudo.dev"; }; }; "fudo.cloud" = mkDomain "fudo.cloud" { mail = fudoMailservers; default-host = getDeets cloudHost "fudo.dev primary server"; }; }; }; }; }; }; }