From 99394cb573dd1e7a55197399deb63f719cc6e3ec Mon Sep 17 00:00:00 2001 From: Till Date: Sat, 3 May 2025 20:24:51 +0200 Subject: [PATCH] mail working --- home/default.nix | 1 - system/web-server/default.nix | 39 +++++++++ system/web-server/fundkorb-button.nix | 10 ++- system/web-server/ksh-map.nix | 2 +- system/web-server/mail.nix | 95 ++++++++++++---------- system/web-server/mail/default.nix | 9 +++ system/web-server/outline.nix | 111 +++++++++++++++++++++----- system/web-server/radicale.nix | 10 ++- 8 files changed, 204 insertions(+), 73 deletions(-) create mode 100644 system/web-server/mail/default.nix diff --git a/home/default.nix b/home/default.nix index 5db21a5..0c610dc 100644 --- a/home/default.nix +++ b/home/default.nix @@ -51,6 +51,5 @@ programs.obs-studio.enable = true; programs.kitty.enable = true; - } diff --git a/system/web-server/default.nix b/system/web-server/default.nix index 3b4530d..eaac8ed 100644 --- a/system/web-server/default.nix +++ b/system/web-server/default.nix @@ -9,10 +9,49 @@ enable = true; recommendedProxySettings = true; recommendedTlsSettings = true; + + virtualHosts = { + "${config.networking.domain}" = { + onlySSL = true; + useACMEHost = config.networking.domain; + locations."/" = { + return = "200 'This domain used for e-mail hosting only.'"; + extraConfig = '' + add_header Content-Type text/plain; + ''; + }; + }; + "${config.networking.fqdn}-80" = { + serverAliases = [ "*.ktiu.net" ]; + locations."/.well-known/acme-challenge" = { + root = "/var/lib/acme/.challenges"; + }; + locations."/" = { + return = "301 https://$host$request_uri"; + }; + }; + "${config.networking.fqdn}" = { + onlySSL = true; + useACMEHost = config.networking.domain; + locations."/" = { + return = "404"; + }; + }; + }; + }; security.acme = { + acceptTerms = true; defaults.email = "till@ktiu.net"; + + certs."${config.networking.domain}" = { + domain = config.networking.domain; + webroot = "/var/lib/acme/.challenges"; + group = config.services.nginx.group; + extraDomainNames = [ config.networking.fqdn ]; + }; }; + } diff --git a/system/web-server/fundkorb-button.nix b/system/web-server/fundkorb-button.nix index 42c96ec..bcb6e4a 100644 --- a/system/web-server/fundkorb-button.nix +++ b/system/web-server/fundkorb-button.nix @@ -1,11 +1,15 @@ { config, pkgs, ... }: { + security.acme.certs."${config.networking.domain}".extraDomainNames = [ + "fundkorb.ktiu.net" + ]; + services.nginx.virtualHosts."fundkorb.ktiu.net" = { - addSSL = true; - enableACME = true; + onlySSL = true; + useACMEHost = config.networking.domain; root = "/var/www/fundkorb-button/html"; - location."/" = { + locations."/" = { basicAuth = "Fundkorb build trigger"; basicAuthFile = "/var/www/fundkorb-button/.htpasswd"; }; diff --git a/system/web-server/ksh-map.nix b/system/web-server/ksh-map.nix index 834ef23..1377262 100644 --- a/system/web-server/ksh-map.nix +++ b/system/web-server/ksh-map.nix @@ -2,7 +2,7 @@ { services.nginx.virtualHosts."karte.nichtzudritt.de" = { - addSSL = true; + forceSSL = true; enableACME = true; root = "/var/www/ksh-map/dist"; }; diff --git a/system/web-server/mail.nix b/system/web-server/mail.nix index 2a195dd..51f82b7 100644 --- a/system/web-server/mail.nix +++ b/system/web-server/mail.nix @@ -27,34 +27,6 @@ in { }; users.users.postfix.extraGroups = [ "opendkim" ]; - - services.nginx = { - enable = true; - virtualHosts = { - "ktiu.net" = { - forceSSL = true; - enableACME = true; - locations."/" = { - return = "200 'This domain used for e-mail hosting only.'"; - extraConfig = '' - add_header Content-Type text/plain; - ''; - }; - }; - "${config.networking.fqdn}" = { - addSSL = true; - enableACME = true; - locations."/.well-known/acme-challenge" = { - root = "/var/lib/acme/.challenges"; - }; - locations."/" = { - # return = "301 http://${config.networking.domain}"; - return = "404"; - }; - }; - }; - }; - security.acme.certs."${config.networking.fqdn}-postfix" = { domain = config.networking.fqdn; webroot = "/var/lib/acme/.challenges"; @@ -63,28 +35,35 @@ in { services.postfix = { enable = true; - domain = "ktiu.net"; - origin = "ktiu.net"; - hostname = "arielle.ktiu.net"; - destination = [ - "ktiu.net" - "mail.ktiu.net" - "t9e.me" - "localhost" - "localhost.localdomain" - ]; + domain = config.networking.domain; + hostname = config.networking.fqdn; virtual = '' - @ktiu.net till - @t9e.me till - till till + @ktiu.net till@t9e.me + @t9e.me till@t9e.me ''; - networks = [ "127.0.0.0/8" "[::ffff:127.0.0.0]/104" "[::1]/128" ]; - sslKey = config.security.acme.certs."${config.networking.fqdn}-postfix".directory + "/key.pem"; - sslCert = config.security.acme.certs."${config.networking.fqdn}-postfix".directory + "/cert.pem"; + + mapFiles.virtual-mailboxes = pkgs.writeText "postfix-virtual-mailboxes" '' + @ktiu.net anything + @t9e.me anything + ''; + config = { + virtual_mailbox_domains = [ "t9e.me" "ktiu.net" ]; + virtual_mailbox_maps = "hash:/etc/postfix/virtual-mailboxes"; + virtual_transport = "lmtp:unix:/var/run/dovecot2/lmtp"; smtpd_tls_security_level = "may"; smtpd_milters = [ "unix:/run/opendkim/opendkim.sock" ]; }; + + networks = [ + "127.0.0.0/8" + "[::ffff:127.0.0.0]/104" + "[::1]/128" + ]; + + sslKey = config.security.acme.certs."${config.networking.fqdn}-postfix".directory + "/key.pem"; + sslCert = config.security.acme.certs."${config.networking.fqdn}-postfix".directory + "/cert.pem"; + enableSubmission = true; submissionOptions = { milter_macro_daemon_name = "ORIGINATING"; @@ -97,6 +76,7 @@ in { smtpd_client_restrictions = "permit_mynetworks,permit_sasl_authenticated,reject"; smtpd_recipient_restrictions = "reject_non_fqdn_recipient,reject_unknown_recipient_domain,permit_sasl_authenticated,reject"; }; + masterConfig = { "submission-header-cleanup" = { type = "unix"; @@ -115,6 +95,12 @@ in { group = config.services.dovecot2.group; }; + users.groups."vmail" = {}; + users.users."vmail" = { + group = "vmail"; + isSystemUser = true; + }; + services.dovecot2 = { enable = true; sslServerKey = config.security.acme.certs."${config.networking.fqdn}-dovecot".directory + "/key.pem"; @@ -126,6 +112,11 @@ in { Trash = { specialUse = "Trash"; auto = "subscribe"; }; Archive = { specialUse = "Archive"; auto = "subscribe"; }; }; + mailUser = "vmail"; + mailGroup = "vmail"; + enablePAM = false; + enableLmtp = true; + mailLocation = "maildir:/var/spool/mail/vmail/mailboxes/%u"; extraConfig = '' ssl = required service auth { @@ -135,6 +126,22 @@ in { group = postfix } } + passdb { + driver = passwd-file + args = /var/custom-access/dovecot.passwd + } + userdb { + driver = passwd-file + args = /var/custom-access/dovecot.passwd + default_fields = uid=vmail gid=vmail home=/var/spool/mail/vmail/users/%u + } + service lmtp { + unix_listener lmtp { + group = postfix + mode = 0600 + user = postfix + } + } ''; }; diff --git a/system/web-server/mail/default.nix b/system/web-server/mail/default.nix new file mode 100644 index 0000000..fe3d548 --- /dev/null +++ b/system/web-server/mail/default.nix @@ -0,0 +1,9 @@ +{ config, pkgs, ... }: + +{ + imports = [ + ./postfix.nix + ./dovecot.nix + ./roundcube.nix + ]; +} diff --git a/system/web-server/outline.nix b/system/web-server/outline.nix index 8d96afa..80e2635 100644 --- a/system/web-server/outline.nix +++ b/system/web-server/outline.nix @@ -1,31 +1,102 @@ { config, pkgs, ... }: -{ +let + + outline = { + hostname = "outline.${config.networking.domain}"; + mail = "outline@${config.networking.domain}"; + }; + + # bootstrapping only + # dex = { + # hostname = "dex.${config.networking.domain}"; + # }; + +in { services.outline = { enable = true; + publicUrl = "https://${outline.hostname}"; storage.storageType = "local"; - # smtp = { - # host = "localhost"; + + smtp = { + username = "outline"; + passwordFile = "/var/custom-access/outline-smtp-password.txt"; + fromEmail = outline.mail; + replyEmail = outline.mail; + # host = "arielle.ktiu.net"; + host = "localhost"; + secure = false; + # port = 587; + port = 25; + }; + + # oidcAuthentication = { + # authUrl = "https://${dex.hostname}/auth"; + # tokenUrl = "https://${dex.hostname}/token"; + # userinfoUrl = "https://${dex.hostname}/userinfo"; + # clientId = "outline"; + # clientSecretFile = (builtins.elemAt config.services.dex.settings.staticClients 0).secretFile; + # scopes = [ "openid" "email" "profile" ]; + # usernameClaim = "preferred_username"; + # displayName = "Dex"; # }; }; - services.nginx.virtualHosts."outline.ktiu.net" = { - addSSL = true; - enableACME = true; - locations."/" = { - proxyPass = "http://127.0.0.1:3000"; - extraConfig = - "proxy_set_header Upgrade $http_upgrade;" + - "proxy_set_header Connection \"Upgrade\";" + - "proxy_set_header Host $host;" + - "proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header Host $host;" + - "proxy_set_header X-Real-IP $remote_addr;" + - "proxy_set_header X-Scheme $scheme;" + - "proxy_set_header X-Forwarded-Proto $scheme;" + - "proxy_redirect off;" - ; - }; - }; + # services.dex = { + # enable = true; + # environmentFile = "/var/custom-access/dex-environemnt"; + # settings = { + # issuer = "https://${dex.hostname}"; + # storage.type = "sqlite3"; + # web.http = "127.0.0.1:5556"; + # staticClients = [ + # { + # id = "outline"; + # name = "Outline Client"; + # redirectURIs = [ "https://${outline.hostname}/auth/oidc.callback" ]; + # secretFile = "/var/custom-access/outline-oidc-secret.txt"; + # } + # ]; + # enablePasswordDB = true; + # staticPasswords = [ + # { + # email = "till@ktiu.net"; + # # gen hash with $ htpasswd -nBC 10 "" | tr -d ':\n' + # hash = ""; + # username = "bootstrap-admin"; + # # $ uuidgen + # userID = ""; + # } + # ]; + # }; + # }; + security.acme.certs."${config.networking.domain}".extraDomainNames = [ + "outline.${config.networking.domain}" + # "dex.${config.networking.domain}" + ]; + + services.nginx.virtualHosts = { + "outline.${config.networking.domain}" = { + onlySSL = true; + useACMEHost = config.networking.domain; + locations."/" = { + proxyPass = "http://127.0.0.1:${toString config.services.outline.port}"; + proxyWebsockets = true; + extraConfig = '' + proxy_set_header X-Scheme $scheme; + ''; + }; + }; + + # "dex.${config.networking.domain}" = { + # onlySSL = true; + # useACMEHost = config.networking.domain; + # locations."/" = { + # proxyPass = "http://${config.services.dex.settings.web.http}"; + # proxyWebsockets = true; + # }; + # }; + }; } diff --git a/system/web-server/radicale.nix b/system/web-server/radicale.nix index a176c12..2794491 100644 --- a/system/web-server/radicale.nix +++ b/system/web-server/radicale.nix @@ -1,9 +1,11 @@ { config, pkgs, ... }: { + security.acme.certs."${config.networking.domain}".extraDomainNames = [ "kalender.ktiu.net" ]; + services.nginx.virtualHosts."kalender.ktiu.net" = { - forceSSL = true; - enableACME = true; + onlySSL = true; + useACMEHost = config.networking.domain; locations."/" = { proxyPass = "http://127.0.0.1:5232/"; extraConfig = '' @@ -22,8 +24,8 @@ }; auth = { type = "htpasswd"; - htpasswd_filename = "/etc/radicale/users"; - htpasswd_encryption = "bcrypt"; + htpasswd_filename = "/var/custom-access/radicale.htpasswd"; + # htpasswd_encryption = "bcrypt"; }; storage = { filesystem_folder = "/var/lib/radicale/collections";