diff --git a/heimserver/configuration.nix b/heimserver/configuration.nix index a7ad4c6..c244737 100644 --- a/heimserver/configuration.nix +++ b/heimserver/configuration.nix @@ -20,20 +20,22 @@ time.timeZone = "Europe/Vienna"; # Bootloader and kernel - boot.loader.systemd-boot.enable = true; - boot.loader.efi.canTouchEfiVariables = true; - boot.kernelParams = [ - "vga=791" - "nomodeset" - ]; - boot.kernel.sysctl = { - "net.ipv4.ip_forward" = 1; - # "net.bridge.bridge-nf-call-iptables" = 1; - # "net.bridge.bridge-nf-call-ip6tables" = 1; - }; + boot = { + loader.systemd-boot.enable = true; + loader.efi.canTouchEfiVariables = true; + kernelParams = [ + "vga=791" + "nomodeset" + ]; + kernel.sysctl = { + "net.ipv4.ip_forward" = 1; + # "net.bridge.bridge-nf-call-iptables" = 1; + # "net.bridge.bridge-nf-call-ip6tables" = 1; + }; - boot.supportedFilesystems = [ "zfs" ]; - boot.zfs.forceImportRoot = false; + supportedFilesystems = [ "zfs" ]; + zfs.forceImportRoot = false; + }; hardware.graphics.enable = true; hardware.nvidia.open = true; @@ -46,8 +48,6 @@ keyMap = "de"; # useXkbConfig = true; # use xkb.options in tty. }; - # i18n.defaultLocale = "en_US.UTF-8"; - # Networking networking = { hostName = "heimserver"; @@ -60,15 +60,17 @@ } ]; defaultGateway = "192.168.69.1"; - #nameservers = [ "1.1.1.1" ]; + #nameservers = [ "127.0.0.1" ]; firewall.enable = true; firewall.allowedTCPPorts = [ 22 + 25 53 80 443 + 587 2222 # forgejo ssh - 8184 # forgejo frontend + 8084 # forgejo frontend 8123 # homeassistant 5580 # homeassistant matter 2283 # immich @@ -78,11 +80,13 @@ 8554 # frigate rtsp 8555 # frigate rtsp 2055 # ntopng sink - 8182 # ntopng frontend - 8183 # adguardhome frontend - 8185 # scrutiny frontend - 8186 # wud frontend - 8187 # paperless frontend + 8088 # ntopng frontend + 8083 # adguardhome frontend + 8085 # scrutiny frontend + 8089 # wud frontend + 8087 # paperless frontend + 8090 # mail + 8091 # mail jmap 8080 # homepage ]; firewall.allowedUDPPorts = [ @@ -98,6 +102,14 @@ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINGHadFhDCUU/ta3p1FQgpm7NExHkyHNrJbNJP6np5w9 kempinger@ins.jku.at" ]; }; + + users.users."stalwart-mail".extraGroups = [ + "acme" + ]; + + users.users."nginx".extraGroups = [ + "acme" + ]; users.users.immich.extraGroups = [ "video" @@ -143,7 +155,30 @@ security.acme = { acceptTerms = true; defaults.email = "mail@kempinger.xyz"; - certs."kempinger.at".domain = "*.kempinger.at"; + defaults.webroot = "/var/lib/acme/acme-challenge/"; + certs."kempinger.at" = { + domain = "kempinger.at"; + extraDomainNames = [ + "git.kempinger.at" + ]; + reloadServices = [ + "nginx" + ]; + }; + certs."webadmin.kempinger.at" = { + domain = "webadmin.kempinger.at"; + extraDomainNames = [ + "mta-sts.kempinger.at" + "autoconfig.kempinger.at" + "autodiscover.kempinger.at" + "mail.kempinger.at" + "imap.kempinger.at" + "mx1.kempinger.at" + ]; + }; + certs."bilder.kempinger.at" = { + domain = "bilder.kempinger.at"; + }; }; #services.resolved.enable = true; @@ -163,15 +198,30 @@ }; virtualHosts."kempinger.at" = { root = "/srv/website/public_html"; - locations."/" = { - index = "index.html"; - }; + locations."/".index = "index.html"; forceSSL = true; - enableACME = true; + useACMEHost = "kempinger.at"; + locations."/.well-known/".root = "/var/lib/acme/acme-challenge/"; + }; + virtualHosts."webadmin.kempinger.at" = { + forceSSL = true; + useACMEHost = "webadmin.kempinger.at"; + #acmeRoot = null; + serverAliases = [ + "mta-sts.kempinger.at" + "autoconfig.kempinger.at" + "autodiscover.kempinger.at" + "mail.kempinger.at" + "imap.kempinger.at" + "mx1.kempinger.at" + ]; + locations."/" = { + proxyPass = "http://127.0.0.1:8090"; + }; }; virtualHosts.${config.services.forgejo.settings.server.DOMAIN} = { forceSSL = true; - enableACME = true; + useACMEHost = "kempinger.at"; extraConfig = '' client_max_body_size 512M; ''; @@ -179,8 +229,8 @@ "http://localhost:${toString config.services.forgejo.settings.server.HTTP_PORT}"; }; virtualHosts."bilder.kempinger.at" = { - enableACME = true; forceSSL = true; + useACMEHost = "bilder.kempinger.at"; locations."/" = { proxyPass = "http://[::1]:${toString config.services.immich.port}"; proxyWebsockets = true; @@ -205,7 +255,7 @@ DOMAIN = "git.kempinger.at"; # You need to specify this to remove the port from URLs in the web UI. ROOT_URL = "https://${config.services.forgejo.settings.server.DOMAIN}/"; - HTTP_PORT = 8184; + HTTP_PORT = 8084; DISABLE_SSH = false; SSH_PORT = 2222; START_SSH_SERVER = true; @@ -347,8 +397,6 @@ }; }; - #services.matter-server.enable = true; - virtualisation.oci-containers = { backend = "podman"; containers.homeassistant = { @@ -440,8 +488,8 @@ "/var/run/podman/podman.sock:/var/run/docker.sock" ]; environment = { - WUD_SERVER_PORT = "8186"; - WUD_TRIGGER_COMMAND_LOCAL_CMD="echo \${display_name} can be updated to \${update_kind_remote_value}"; + WUD_SERVER_PORT = "8089"; + WUD_TRIGGER_COMMAND_LOCAL_CMD = "echo \${display_name} can be updated to \${update_kind_remote_value}"; }; extraOptions = [ "--network=host" @@ -451,7 +499,7 @@ services.ntopng = { enable = true; - httpPort = 8182; + httpPort = 8088; interfaces = [ "tcp://0.0.0.0:5556" ]; extraConfig = '' --dns-mode 1 @@ -460,6 +508,9 @@ services.influxdb2 = { enable = true; + settings = { + http-bind-address = ":8086"; + }; # provision = { # enable = true; @@ -490,7 +541,7 @@ services.scrutiny = { enable = true; - settings.web.listen.port = 8185; + settings.web.listen.port = 8085; influxdb.enable = true; collector.schedule = "hourly"; settings.web.influxdb = { @@ -504,14 +555,14 @@ enable = true; # You can select any ip and port, just make sure to open firewalls where needed host = "0.0.0.0"; - port = 8183; + port = 8083; }; - + services.paperless = { enable = true; consumptionDirIsPublic = true; address = "0.0.0.0"; - port = 8187; + port = 8087; settings = { PAPERLESS_CONSUMER_IGNORE_PATTERN = [ ".DS_STORE/*" @@ -525,7 +576,6 @@ }; }; - services.homepage-dashboard = { enable = true; listenPort = 8080; @@ -628,7 +678,7 @@ icon = "forgejo.png"; widget = { type = "gitea"; # Forgejo uses Gitea API - url = "http://192.168.69.69:8184"; + url = "http://192.168.69.69:8084"; key = "{{HOMEPAGE_VAR_FORGEJO_TOKEN}}"; # Create in Forgejo settings # Shows: repository count, issue count, pull requests }; @@ -640,12 +690,12 @@ "Network & Monitoring" = [ { "AdGuard Home" = { - href = "http://192.168.69.69:8183"; + href = "http://192.168.69.69:8083"; description = "DNS filtering & ad blocking"; icon = "adguard-home.png"; widget = { type = "adguard"; - url = "http://192.168.69.69:8183"; + url = "http://192.168.69.69:8083"; username = "{{HOMEPAGE_VAR_ADGUARD_USER}}"; password = "{{HOMEPAGE_VAR_ADGUARD_PASS}}"; # Shows: queries blocked, % blocked, queries processed @@ -667,29 +717,29 @@ } { "Scrutiny" = { - href = "http://192.168.69.69:8185"; + href = "http://192.168.69.69:8085"; description = "S.M.A.R.T Monitoring"; icon = "scrutiny.png"; widget = { type = "scrutiny"; - url = "http://192.168.69.69:8185"; + url = "http://192.168.69.69:8085"; }; }; } { "Whats Up Docker" = { - href = "http://192.168.69.69:8186"; + href = "http://192.168.69.69:8089"; description = "Docker Image Updates"; icon = "whats-up-docker.png"; widget = { type = "whatsupdocker"; - url = "http://192.168.69.69:8186"; + url = "http://192.168.69.69:8089"; }; }; } { "ntopng" = { - href = "http://192.168.69.69:8182"; + href = "http://192.168.69.69:8088"; description = "Network traffic analysis"; icon = "ntopng.png"; # No official widget, but could use iframe or custom API @@ -787,6 +837,69 @@ environmentFile = "/var/lib/homepage-dashboard/secrets.env"; }; + services.stalwart = { + enable = true; + openFirewall = true; + settings = { + server = { + hostname = "mx1.kempinger.at"; + tls = { + enable = true; + implicit = true; + }; + listener = { + smtp = { + protocol = "smtp"; + bind = "192.168.69.69:25"; + }; + submissions = { + bind = "192.168.69.69:587"; + protocol = "smtp"; + tls.implicit = true; + }; + imaps = { + bind = "[::]:993"; + protocol = "imap"; + tls.implicit = true; + }; + jmap = { + bind = "0.0.0.0:8091"; + url = "https://mail.kempinger.at"; + protocol = "http"; + }; + management = { + bind = [ "127.0.0.1:8090" ]; + protocol = "http"; + }; + }; + }; + resolver.type = "custom"; + resolver.custom = [ "udp://127.0.0.1:53" ]; + + certificate."default" = { + cert = "%{file:${config.security.acme.certs."webadmin.kempinger.at".directory}/fullchain.pem}%"; + private-key = "%{file:${config.security.acme.certs."webadmin.kempinger.at".directory}/key.pem}%"; + }; + + lookup.default = { + hostname = "mx1.kempinger.at"; + domain = "kempinger.at"; + }; + + session.rcpt.directory = "'internal'"; + directory."imap".lookup.domains = [ "kempinger.at" ]; + # authentication.fallback-admin = { + # user = "admin"; + # secret = "bcrypt-hash"; + # }; + }; + }; + + services.snowflake-proxy = { + enable = true; + capacity = 50; + }; + nixpkgs.config.allowUnfree = true; # nixpkgs.overlays = [