from onlinepersona@programming.dev to selfhosted@lemmy.world on 18 Apr 18:41
https://programming.dev/post/49023431
cross-posted from: programming.dev/post/49000591
TL;DR fetchmail to move all emails from email provider to local mailbox that is then served via IMAP by dovecot
Hi, I like being able to switch between email providers easily without having to change my email address (related post). For example right now people have to go through the hassle of going from
mygreatusername@some.hosttoanotherusername@another.host. It’s a big barrier because you now have to update that email address everywhere. Imagine having everything on gmail and then moving to startmail, fastmail, posteo, or whatever else.A solution I was made aware of is to:
- pay for a domain e.g
mydomain.orgfor 10 years (can be cheap)- use their inbuilt email (sometimes free) or pick an email provider that allows custom domains
- pull all the email to server you host
- serve that email
That way, you will have your
myname@mydomain.organd switch email providers underneath while keeping all your emails.Example config
This config uses the module I wrote (maybe something else exists, but I couldn’t find it). It pulls emails of
myaccount@my.domainfrompop.remote.hosttomy.hostand exposes them via IMAPS asmyaccount@my.domainonmy.host.Notice that
my.domainneed not be the same asmy.host. This allows me to hide my IMAP server. Somebody looking at theMXrecord ofmy.domainwon’t immediately find the IMAP server.{ config, ... }: { /** configuration to for fetchmail to retrieve from the remote host emails will be moved into a the **local** mailbox of a user with the same email address */ environment.etc."mail/fetchmailrc" = { text = '' poll pop.remote.host protocol pop3 port 995: user "myaccount@my.domain" with password "passwordWithouQuotes" is vmail here options fetchall ssl mda "dovecot-deliver -d myaccount@my.domain" ''; user = config.services.email-fetch-serve.daemonUser; group = config.services.email-fetch-serve.daemonGroup; }; /** usernames and passwords used to log into the **self-hosted** IMAP service Uses same format as /etc/passwd https://doc.dovecot.org/2.4.3/core/config/auth/databases/passwd_file.html */ environment.etc."mail/imap.passwd" = { text = '' myAccount@my.domain:{plain}password ''; user = config.services.email-fetch-serve.daemonUser; group = config.services.email-fetch-serve.daemonGroup; }; services.email-fetch-serve = { enable = true; sslCertPath = "/var/acme/certs/mydomain.crt"; sslCertKey = "/var/acme/certs/mydomain.key"; fetchmailRcPath = "/etc/mail/fetchmailrc"; imap = { port = 993; openFirewall = true; passdb = "/etc/mail/imap.passwd"; }; }; }the module
nix { config, lib, pkgs, … }: let cfg = config.services.email-fetch-serve; daemonUserHome = “/var/spool/${cfg.daemonUser}”; sslEnabled = (cfg.sslCertPath != null) && (cfg.sslCertKey != null); /** Used by fetchmail to deliver mail to dovecot */ dovecot-deliver-wrapper = pkgs.writeShellScriptBin “dovecot-deliver” ‘’${pkgs.dovecot}/libexec/dovecot/deliver “‘’${@}”‘’; in { /** A self-hosted “email relay” that allows fetching emails from a server and then serving it via IMAP. Emails are retrieved with fetchmail and exposed via dovecot. By default, dovecot used IMAP which unencrypted, but with an ssl certificate and key, it can be encrypted and thus turned into IMAPS. To generate SSL certs, the `security.acme` option is powerful, but you can also use a self-signed certificate. To store secrets, do consider using - agenix: https://github.com/ryantm/agenix - sopsnix: https://github.com/Mic92/sops-nix */ options = with lib; { services.email-fetch-serve = { enable = mkEnableOption “emails from an email server and serve them via IMAP”; sslCertPath = mkOption { type = types.nullOr types.externalPath; description = “Giving a path to an SSL cert **and** key will enable IMAPS and disable IMAP”; default = null; }; sslCertKey = mkOption { type = types.nullOr types.externalPath; description = “Giving a path to an SSL key **and** cert will enable IMAPS and disable IMAP”; default = null; }; fetchmailRcPath = mkOption { type = types.externalPath; description = “Configuration for fetchmail”; example = ‘’ poll pop.remote.host protocol pop3 port 995: user “accountName@remote.host” with password “passwordWithouQuotes” is vmail here options fetchall ssl mda “dovecot-deliver -d accountName@remote.host” ‘’; }; imap = { port = mkOption { type = types.int; description = ‘’ Which port to host the IMAP service on. If sslCertPath is set this will be the port of othe IMAPS service’‘; default = 143; # Default IMAP port }; openFirewall = lib.mkOption { type = lib.types.bool; default = false; example = true; description = “Allow external traffic to reach the IMAP(S) port”; }; passdb = mkOption { type = types.externalPath; description = ‘’ Where passwords for IMAP are stored. Should be secret and accessible by vmail user https://doc.dovecot.org/2.4.3/core/config/auth/databases/passwd_file.html https://doc.dovecot.org/2.4.3/core/config/auth/passdb.html ‘’; }; }; daemonUser = mkOption { type = types.str; description = “Name of the user running the daemons”; default = “vmail”; }; daemonGroup = mkOption { type = types.str; description = “Name of the user’s group running the daemons”; default = “vmail”; }; }; }; config = lib.mkIf cfg.enable { assertions = [ { # Either both SSL vars are set or none are set assertion = (cfg.sslCertPath == null && cfg.sslCertKey == null) || (cfg.sslCertPath != null && cfg.sslCertKey != null); message = “email-fetch-serve service must have sslCertPath AND sslCertKey to have functional SSL”; } ]; # How electronic email works # https://tldp.org/HOWTO/Mail-Administrator-HOWTO-3.html # ${daemonUserHome} needs to be created and owned by vmail users.users.“${cfg.daemonUser}” = { createHome = true; home = daemonUserHome; group = cfg.daemonGroup; isSystemUser = true; }; users.groups.“${cfg.daemonGroup}” = { }; services.dovecot2 = lib.mkMerge [ ({ # Taken and adapted from https://wiki.nixos.org/wiki/Dovecot enable = cfg.enable; createMailUser = true; enableImap = true; mailUser = cfg.daemonUser; mailGroup = cfg.daemonGroup; # implement virtual users # https://doc.dovecot.org/2.3/configuration_manual/howto/simple_virtual_install/ # store virtual mail under # /var/spool/mail/vmail/<DOMAIN>/<USER>/Maildir/ mailLocation = “maildir:~/Maildir”; mailboxes = { # use rfc standard https://apple.stackexchange.com/a/201346 All = { auto = “create”; autoexpunge = null; specialUse = “All”; }; Archive = { auto = “create”; autoexpunge = null; specialUse = “Archive”; }; Drafts = { auto = “create”; autoexpunge = null; specialUse = “Drafts”; }; Flagged = { auto = “create”; autoexpunge = null; specialUse = “Flagged”; }; Junk = { auto = “create”; autoexpunge = “60d”; specialUse = “Junk”; }; Sent = { auto = “create”; autoexpunge = null; specialUse = “Sent”; }; Trash = { auto = “create”; autoexpunge = “60d”; specialUse = “Trash”; }; }; extraConfig = lib.concatStrings [ ‘’ # force to use full user name plus domain name # for disambiguation auth_username_format = %Lu # Authentication configuration: auth_mechanisms = plain passdb { driver = passwd-file args = ${cfg.imap.passdb} } userdb { driver = static # the full e-mail address inside passwd-file is the username (%u) # user@example.com # %d for domain_name %n for user_name args = uid=${cfg.daemonUser} gid=${cfg.daemonGroup} username_format=%u home=${daemonUserHome}/%d/%n } ‘’ (lib.optionalString (!sslEnabled) ‘’ service imap-login { inet_listener imap { port = ${builtins.toString cfg.imap.port} } inet_listener imaps { port = 0 } ‘’) (lib.optionalString (sslEnabled) ‘’ service imap-login { inet_listener imap { port = 0 } inet_listener imaps { port = ${builtins.toString cfg.imap.port} } }’') ]; }) (lib.mkIf sslEnabled { sslServerCert = cfg.sslCertPath; sslServerKey = cfg.sslCertKey; }) ]; # Open the firewall port to be able to be contacted networking.firewall.allowedTCPPorts = [ cfg.imap.port ]; networking.firewall.allowedUDPPorts = [ cfg.imap.port ]; ##################### # To fetch the emails systemd.services.fetchmail = { enable = cfg.enable; after = [ “dovecot2.service” ]; wantedBy = [ “dovecot2.service” ]; path = [ dovecot-deliver-wrapper ]; serviceConfig = { User = cfg.daemonUser; ExecStart = “${pkgs.fetchmail}/bin/fetchmail --fetchmailrc ${cfg.fetchmailRcPath} --daemon 60”; }; }; }; }
#selfhosted
threaded - newest
Sorry, not clear to me what this accomplishes. Yes you buy a domain and use it for your email, then if and when you switch, you also migrate imap-to-imap all your email… It’s a pretty easy thing to do and there are tools just for this purpose.
Is this a script to do the same?