User Tools

Site Tools


computing:mailserver-trixie

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
computing:mailserver-trixie [2025/11/05 04:19] oemb1905computing:mailserver-trixie [2025/11/09 05:46] (current) oemb1905
Line 10: Line 10:
  
 ------------------------------------------- -------------------------------------------
 +
 +  * [[https://nextcloud.haacksnetworking.org/index.php/s/s6wAL5p7jKHc9Db|Slides]]
 +  * [[https://content.haacksnetworking.org/w/nsMwnJhLnfMrs17W5cAdWg|SeaGL Presentation]]
 +  * [[https://tech.haacksnetworking.org/2025/06/10/your-email-your-rules-self-hosting-simplified/|Blog Post]]
  
 ====== Introduction ====== ====== Introduction ======
 ~~NOTOC~~ ~~NOTOC~~
  
-Contrary to popular belief, it's entirely possible to self-host email servers. Like others, I listened to the propaganda that "it's no longer feasible to self-host email" or "it's too complex and servers won't respect your mail health anyway" or other such explanations. In 2014, while running workshops for students on security and networking, one of my student'parent (a Ruby dev) said he agreed with me and that as far as he knew, postfix was fairly straightforward. From that day forward, I decided to approach self-hosting email servers the same way as I approach self-hosting any instance (Nextcloud, Dokuwiki, Airsonic, Gitlab, etc.). I decided that it must be entirely possible and that it was merely a question of how. So, from 2014 - 2018, from Wheezy to Buster, I began using my spare hacking time to create my first smtp relay in 2015 and later setup my first proper email server in 2018. As it turns out, it is relatively straight forward to setup a functional base server. Getting the ecosystem to respect your email, however, takes a little tender care.+Contrary to popular belief, it's entirely possible to self-host email servers. Like others, I listened to the propaganda that "it's no longer feasible to self-host email" or "it's too complex and servers won't respect your mail health anyway" or other such explanations. In 2014, while running workshops for students on security and networking, one of my student'parents (a Ruby dev) said he agreed with me and that as far as he knew, postfix was fairly straightforward. From that day forward, I decided to approach self-hosting email servers the same way as I approach self-hosting any instance ([[https://nextcloud.haacksnetworking.org|Nextcloud]][[https://music.outsidebox.club|Airsonic]][[https://repo.haacksnetworking.org|Gitlab]], etc.). I decided that it must be entirely possible and that it was merely a question of how. So, from 2014 - 2018, from Wheezy to Buster, I began using my spare hacking time to create my first smtp relay in 2015 and later setup my first proper email server in 2018. As it turns out, it is relatively straight forward to setup a functional base server. Getting the ecosystem to respect your email, however, takes a little tender care. It's entirely doable though: [[https://mail.haacksnetworking.org|My Business Webmail]]. 
 + 
 +I did not migrate my personal emails and/or business infrastructure until 2021. During 2018 - 2021, I would intermittently test, identify and fix failures, breakages, and read up more on DNS records and worked to gain a deeper understanding of the ecosystem. I spent countless hobbyist hours reviewing forums, Stack Exchange, and, of course, Linux Babe. I also shared notes and perspectives with a local colleague and fellow IT/networking professional, [[http://schaeferconsulting.com|Schaefer Consulting]]. I was not in any rush to migrate, and I also wanted to develop a system that balanced complexity with reliability/convenience. After initially developing a [[https://wiki.haacksnetworking.org/doku.php?id=computing:exim4|mail relay recipe]] both under/alongside Schaefer and on my own, I ultimately decided to switch to postfix for incoming/outgoing, or what I call a proper email server (not merely a relay or send-only MTA). This was pure chance, namely, as the first server recipe I got working for IMAP/dovecot was on my postfix VPS not the exim4 VPS, so I simply got motivated to keep fixing it until it all worked. Until that time, circa 2018, I was tinkering back and forth on two different VPSs, one with exim4 and another with postfix, testing different strategies. To this day, I continue to use exim4 for relaying email from hosts behind NAT. For proper email servers, I currently use postfix. In getting everything to work, my goal was to only increase complexity if/when it was required for proper functioning. For this reason, I chose to use simple UNIX users.
  
-I did not migrate my personal emails and/or business infrastructure until 2021. During 2018 2021, I would intermittently test, identify and fix failures, breakages, and read up more on DNS records and worked to gain a deeper understanding of the ecosystem. I spent countless hobbyist hours reviewing forums, Stack Exchange, and, of course, Linux Babe. I also shared notes and perspectives with a local colleague and fellow IT/networking professional, Schaefer Consulting. I was not in any rush to migrate, and I also wanted to develop a system that balanced complexity with reliability/convenience. After initially developing a mail relay recipe both under/alongside Schaefer and on my own, I ultimately decided to switch to postfix for incoming/outgoing, or what I call a proper email server (not merely a relay or send-only MTA). This was pure chance, namely, as the first server recipe I got working for IMAP/dovecot was on my postfix VPS not the exim4 VPS, so I simply got motivated to keep fixing it until it all worked. Until that time, circa 2018, I was tinkering back and forth on two different VPSs, one with exim4 and another with postfix, testing different strategies. To this day, I continue to use exim4 for relaying email from hosts behind NAT. For proper email servers, I currently use postfix. In getting everything to work, my goal was to only increase complexity if/when it was required for proper functioning. For this reason, I chose to use simple UNIX users.+{{ :computing:screenshot_from_2025-11-04_20-48-13.png?direct&800 |}}
  
-{{ :computing:screenshot_from_2025-11-04_20-48-13.png?direct&600 |}}+Results[[https://www.mail-tester.com/test-8hia4koy2|Mail Tester Results]]
  
-In my case, the servers I built are on VMs that reside on a [[https://wiki.haacksnetworking.org/doku.php?id=computing:vmserver|custom virtualization stack stack]] that uses virsh and kvm/qemu on a Debian SuperMicro server (Xeon Silvers) that I co-locate at Brown Rice data center. My virtualization stack has roughly 30 VMs at present, with the host boasting over 500 virtual cores and 384GB of RAM. My primary business email server, for haacksnetworking.org, is an 8-core Virtual Machine with 8GB of RAM that resides on that same SuperMicro. Remember, though, as long as your VPS host provides PTR (reverse DNS) access, you can do this on a very basic ($5-$10 per month) VPS. My Taos server is also the proud host of the following services:+In my case, the servers I built are on VMs that reside on a [[https://wiki.haacksnetworking.org/doku.php?id=computing:vmserver|custom virtualization stack]] that uses virsh and kvm/qemu on a Debian SuperMicro server (Xeon Silvers) that I co-locate at Brown Rice data center. My virtualization stack has roughly 30 VMs at present, with the host boasting over 500 virtual cores and 384GB of RAM. My primary business email server, for haacksnetworking.org, is an 8-core Virtual Machine with 8GB of RAM that resides on that same SuperMicro. Remember, though, as long as your VPS host provides PTR (reverse DNS) access, you can do this on a very basic ($5-$10 per month) VPS. My Taos server is also the proud host of the following services:
  
-  * Mastodon: gnulinux.social +  * **Mastodon**: [[https://gnulinux.social|GNU/Linux Social]] 
-  * Matrix: gnulinux.club +  * **Matrix**: [[https://gnulinux.club|GNU/Linux Club]] 
-  * PeerTube: gnulinux.tube +  * **PeerTube**: [[https://gnulinux.tube|GNU/Linux Tube]] 
-  * Navidrome: gnulinux.studio +  * **Navidrome**: [[https://gnulinux.studio|GNU/Linux Studio]] 
-  * Pixelfed: (forthcoming)+  * **Pixelfed**: (forthcoming)
  
-My work on email servers and these public instances is all free of charge and shared under Creative Commons Attribution, Share-Alike, Non-Commercial. If you like the tutorials and/or services I provide, please consider giving back at Libera Pay. Alright, let's get this email server set up!+This particular tutorial is [[https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en|CC BY-NC-SA 4.0]] instead of FDL 1.3 (like the majority of posts on this Wiki). If you like the tutorials and/or services I provide, please consider giving back at [[https://liberapay.com/oemb1905/|Libera Pay]]. Alright, let's get this email server set up!
  
 ====== Part I - DNS Records ====== ====== Part I - DNS Records ======
Line 57: Line 63:
   SPF (mail.domain.tld): v=spf1 a mx ip4:8.28.86.125 ip6:2a10:e780:10:28::2 ~all   SPF (mail.domain.tld): v=spf1 a mx ip4:8.28.86.125 ip6:2a10:e780:10:28::2 ~all
  
-The SPF record, or sender policy framework, instructs mail servers about which IPs are permitted to send email from a given domain. I include the a flag for redundancy and or for safety. Allowing any A-record in the domain to send using this domain is very permissive and also helps in case you misconfigure an explicit record while testing. The mx flag ensures that email sent from my own MX servers is explicitly permitted. Although not essentially required to include a or mx if your server's IP is specified, I find it helpful to provide extra resilience for cases where you change or scale. For example, if I decide to add a backup mail server, the mx flag automatically approves it, i.e., I don't need to change the record each time. If I migrate to a different node and/or IP, the A specification allows sending immediately and I can edit the individual TXT records later. So, specifying all three together (A, MX, and IPs) is beneficial for updating, changing, or scaling up your email offering. Additionally, bounces are often sent from the mx server, not the outbound IP, which could potentially differ from the IP of the primary MTA. Some email servers, moreover, compare spf IP to sender domain, so including a and mx alongside the IPs provides full alignment and therefore better email health. As for the ~all, I use that because it specifies "soft fail" if an origin IP does not align. This is important because mistakes happen and sysadmins don't want phantom rejections. If you instead set this flag to -all (reject aka hard fail), then recipients won't receive emails if you configured an IP or DNS record in error. Conversely, setting the flag to +all defeats the purpose of the record by permitting everything. The soft fail flag ~all allows sysadmins to identify misconfigurations and fix them, while ensuring that no emails are auto-rejected by the recipient due to your own spf policy. Of course, after sufficient testing, you can optionally change this flag to hard fail, but proceed with caution. The pct flag controls what portion of emails should be evaluated by dmarc, which I keep at 100%. By specifying 100%, you are stating that all your emails should be checked. In thus testing the whole population (instead of a random sample) of your emails, you increase your own chances of failing merely by increasing the number of evaluated emails. However, it is important to remember that mail servers rarely reject incoming email due to dmarc failure alone (almost never), so just because you increase dmarc failures, those won't result in rejections per se. As long as all the other records are solid, I prefer to error on the side of getting more reports and every email evaluated, rather than permitting phantom allowances.+The SPF record, or sender policy framework, instructs mail servers about which IPs are permitted to send email from a given domain. I include the a flag for redundancy and or for safety. Allowing any ''A'' record in the domain to send using this domain is very permissive and also helps in case you misconfigure an explicit record while testing. The mx flag ensures that email sent from my own MX servers is explicitly permitted. Although not essentially required to include ''a'' or ''mx'' if your server's IP is specified, I find it helpful to provide extra resilience for cases where you change or scale. For example, if I decide to add a backup mail server, the mx flag automatically approves it, i.e., I don't need to change the record each time. If I migrate to a different node and/or IP, the A specification allows sending immediately and I can edit the individual TXT records later. So, specifying all three together (''A''''MX'', and IPs) is beneficial for updating, changing, or scaling up your email offering. Additionally, bounces are often sent from the ''mx'' server, not the outbound IP, which could potentially differ from the IP of the primary MTA. Some email servers, moreover, compare spf IP to sender domain, so including a and mx alongside the IPs provides full alignment and therefore better email health. As for the ''~all'', I use that because it specifies "soft fail" if an origin IP does not align. This is important because mistakes happen and sysadmins don't want phantom rejections. If you instead set this flag to ''-all'' (reject aka hard fail), then recipients won't receive emails if you configured an IP or DNS record in error. Conversely, setting the flag to ''+all'' defeats the purpose of the record by permitting everything. The soft fail flag ''~all'' allows sysadmins to identify misconfigurations and fix them, while ensuring that no emails are auto-rejected by the recipient due to your own spf policy. Of course, after sufficient testing, you can optionally change this flag to hard fail, but proceed with caution. The ''pct'' flag controls what portion of emails should be evaluated by ''dmarc'', which I keep at 100%. By specifying 100%, ''pct=100'', you are stating that all your emails should be checked. In thus testing the whole population (instead of a random sample) of your emails, you increase your own chances of failing merely by increasing the number of evaluated emails. However, it is important to remember that mail servers rarely reject incoming email due to dmarc failure alone (almost never), so just because you increase dmarc failures, those won't result in rejections per se. As long as all the other records are solid, I prefer to error on the side of getting more reports and every email evaluated, rather than permitting phantom allowances.
  
 ====== Part II - Installing Postfix+Dovecot, Setting up LAMP ====== ====== Part II - Installing Postfix+Dovecot, Setting up LAMP ======
Line 63: Line 69:
 The first part of the tutorial, i.e., setting up DNS records, is now complete. It's now time to address installation and setup of postfix+dovecot. Do not proceed to this part of the tutorial unless you completed the DNS steps above. Put simply, postfix+dovecot both require proper DNS resolution to work. The only exception to this rule is for our DKIM record, which requires us first configuring the server before we cut the keypair and create the associated TXT record. Other than that, make sure DNS is ready to go before proceeding. Okay, let's ssh into the VM/VPS and do the following: The first part of the tutorial, i.e., setting up DNS records, is now complete. It's now time to address installation and setup of postfix+dovecot. Do not proceed to this part of the tutorial unless you completed the DNS steps above. Put simply, postfix+dovecot both require proper DNS resolution to work. The only exception to this rule is for our DKIM record, which requires us first configuring the server before we cut the keypair and create the associated TXT record. Other than that, make sure DNS is ready to go before proceeding. Okay, let's ssh into the VM/VPS and do the following:
  
-  sudo apt update && sudo apt upgrade -y\+  sudo apt update && sudo apt upgrade -y
   sudo apt install mailutils postfix ufw fail2ban nginx apache2 php8.4-fpm php8.4-mysql php8.4-curl php8.4-gd php8.4-mbstring php8.4-xml php8.4-zip dovecot-core dovecot-imapd dovecot-lmtpd   sudo apt install mailutils postfix ufw fail2ban nginx apache2 php8.4-fpm php8.4-mysql php8.4-curl php8.4-gd php8.4-mbstring php8.4-xml php8.4-zip dovecot-core dovecot-imapd dovecot-lmtpd
  
Line 101: Line 107:
 {{ :computing:postfix7.png?direct&600 |}} {{ :computing:postfix7.png?direct&600 |}}
  
-For the mail name, put haacksnetworking.org or domain.com. Leave most fields at default values; make sure other destinations populated correctly. Do not select All unless you have properly configured records and interfaces for both. Only select and specify what you have records for, otherwise they will fail if they hop to the unsupported protocol. I speak from direct experience. +For the mail name, put ''haacksnetworking.org'' or ''domain.com''. Leave most fields at default values; make sure other destinations populated correctly. Do not select All unless you have properly configured records and interfaces for both. Only select and specify what you have records for, otherwise they will fail if they hop to the unsupported protocol. I speak from direct experience. Now that a basic postfix setup is in place, you can optionally install a firewall. If you choose to do this, I recommend the Uncomplicated Firewall, or ufw. Install it and open up all the ports required by postfix+dovecot and no others.
- +
-Now that a basic postfix setup is in place, you can optionally install a firewall. If you choose to do this, I recommend the Uncomplicated Firewall, or ufw. Install it and open up all the ports required by postfix+dovecot and no others.+
  
   sudo apt install ufw   sudo apt install ufw
Line 163: Line 167:
 #smtpd_tls_security_level=may #smtpd_tls_security_level=may
 #smtp_tls_CApath=/etc/ssl/certs #smtp_tls_CApath=/etc/ssl/certs
-smtp_tls_security_level=may+#smtp_tls_security_level=may
 #smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache #smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
  
Line 169: Line 173:
 smtpd_tls_cert_file=/etc/letsencrypt/live/mail.haacksnetworking.org/fullchain.pem smtpd_tls_cert_file=/etc/letsencrypt/live/mail.haacksnetworking.org/fullchain.pem
 smtpd_tls_key_file=/etc/letsencrypt/live/mail.haacksnetworking.org/privkey.pem smtpd_tls_key_file=/etc/letsencrypt/live/mail.haacksnetworking.org/privkey.pem
-smtpd_tls_security_level=may+smtpd_tls_security_level = may
 smtpd_tls_loglevel = 1 smtpd_tls_loglevel = 1
 smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
Line 958: Line 962:
 If your client does not honor autodiscovery and/or you choose to enter manually, use the port recommendations and protocols above. Other options also exist. If your client does not honor autodiscovery and/or you choose to enter manually, use the port recommendations and protocols above. Other options also exist.
  
-====== Part VII - Additional Options ======+====== Part VIII - Additional Options ======
  
 The options below are results of small things that came up while using my own server over the last 5 years or so. First, I noticed that clients would not set up the standard directories and it turns out you need to tell dovevot to do that over in ''/etc/dovecot/conf.d/15-mailboxes.conf'' by enabling the ''auto = create'' in the folder blocks for which you desire auto-population. The options below are results of small things that came up while using my own server over the last 5 years or so. First, I noticed that clients would not set up the standard directories and it turns out you need to tell dovevot to do that over in ''/etc/dovecot/conf.d/15-mailboxes.conf'' by enabling the ''auto = create'' in the folder blocks for which you desire auto-population.
Line 999: Line 1003:
 If other quirky issues come up, I'll besure to add them right here! If other quirky issues come up, I'll besure to add them right here!
  
-====== Part VIII - What's next? ======+====== Part IX - What's next? ======
  
 Next Steps Next Steps
Line 1011: Line 1015:
 I rewrote the mail server tutorial for the presentation [[https://tech.haacksnetworking.org/2025/06/10/your-email-your-rules-self-hosting-simplified/|Your Email, Your Rules: Self-Hosting Simplified]]. The SeaGL presentation can be found [[https://pretalx.seagl.org/2025/talk/VLM7AS/|on their calendar]]. I rewrote the mail server tutorial for the presentation [[https://tech.haacksnetworking.org/2025/06/10/your-email-your-rules-self-hosting-simplified/|Your Email, Your Rules: Self-Hosting Simplified]]. The SeaGL presentation can be found [[https://pretalx.seagl.org/2025/talk/VLM7AS/|on their calendar]].
  
- --- //[[alerts@haacksnetworking.org|oemb1905]] 2025/11/05 03:41//+ --- //[[alerts@haacksnetworking.org|oemb1905]] 2025/11/09 05:45//
computing/mailserver-trixie.1762316389.txt.gz · Last modified: by oemb1905