Tons of stuff, including 23.05 -> 23.11
This commit is contained in:
parent
0027566304
commit
7a73028ad2
|
@ -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; };
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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}
|
||||
'';
|
||||
}));
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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}";
|
||||
|
|
|
@ -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";
|
||||
};
|
||||
|
|
|
@ -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";
|
||||
};
|
||||
|
|
|
@ -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/#" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -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";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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;" ]);
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
}];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -41,7 +41,7 @@ in {
|
|||
fonts.fontconfig = {
|
||||
hinting = {
|
||||
enable = true;
|
||||
style = "hintfull";
|
||||
style = "full";
|
||||
};
|
||||
subpixel.lcdfilter = "default";
|
||||
antialias = true;
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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 = [
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -138,6 +138,7 @@ in {
|
|||
groups = {
|
||||
wheel.members = [ "niten" "reaper" ];
|
||||
dns = { members = [ "niten" "reaper" "named" ]; };
|
||||
fudo.members = [ "niten" "reaper" ];
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -20,6 +20,7 @@ in {
|
|||
prefixLength = 16;
|
||||
}];
|
||||
};
|
||||
firewall.enable = false;
|
||||
};
|
||||
|
||||
security.sudo.extraConfig = ''
|
||||
|
|
|
@ -47,8 +47,6 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
nixpkgs.config.allowUnfree = true;
|
||||
|
||||
hardware.enableAllFirmware = true;
|
||||
|
||||
services = {
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;" ]);
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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}";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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" ];
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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";
|
||||
|
|
842
flake.lock
842
flake.lock
File diff suppressed because it is too large
Load Diff
24
flake.nix
24
flake.nix
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue