This is the first step - a server that accepts and sends mail. After installing, you’ll be able to check messages at the console. Remote client access (such as with Thunderbird) comes later.
- Linux Server
- Firewall Port-Forward
- Public DNS
We use Debian Bookworm (12) in this example but any derivative will be similar. At large scale you’d setup virtual users, but we’ll stick with the default setup and use your system account. Budget about 10M per 100 emails stored.
Mail protocol uses port 25. Simply forward that to your internal mail server and you’re done.
You need an entry for your server so mail sent directly to it ([email protected]) will arrive. You should also create a special entry for your domain root. That way, mail sent to [email protected] will get routed to it as well. Take advantage of dynamic DNS when possible.
Some configuration is done at install time by the package so you must make sure your hostname is correct. We use the hostname ‘mail’ in this example.
# Correct internal hostnames as needed. 'mail' and 'mail.home.lan' are good suggestions. cat /etc/hostname /etc/hosts # Set the external host name and run the package installer. If postfix is already installed, apt remove it first EXTERNAL="mail.your.org" sudo debconf-set-selections <<< "postfix postfix/mailname string $EXTERNAL" sudo debconf-set-selections <<< "postfix postfix/main_mailer_type string 'Internet Site'" sudo apt install --assume-yes postfix # Add the main domain to the destinations as well DOMAIN="your.org" sudo sed -i "s/^mydestination = \(.*\)/mydestination = $DOMAIN, \1/" /etc/postfix/main.cf sudo systemctl reload postfix.service
Test with telnet - use your unix system ID for the rcpt address below.
telnet localhost 25
ehlo localhost mail from: <[email protected]> rcpt to: <[email protected]> data Subject: Wish List Red Ryder BB Gun . quit
Assuming that ‘you’ matches your shell account, Postfix will have accepted the message and used it’s Local Delivery Agent to store it in the local message store. That’s in
Postfix will use the untrusted “snakeoil” that comes with debian to opportunistically encrypt communication between it and other mail servers. Surprisingly, most other servers will accept this cert (or fall back to non-encrypted), so lets proceed for now. We’ll generate a trusted one later.
sudo tee -a /etc/postfix/main.cf << EOF # Tighten up formatting smtpd_helo_required = yes disable_vrfy_command = yes strict_rfc821_envelopes = yes # Error codes instead of bounces invalid_hostname_reject_code = 554 multi_recipient_bounce_reject_code = 554 non_fqdn_reject_code = 554 relay_domains_reject_code = 554 unknown_address_reject_code = 554 unknown_client_reject_code = 554 unknown_hostname_reject_code = 554 unknown_local_recipient_reject_code = 554 unknown_relay_recipient_reject_code = 554 unknown_virtual_alias_reject_code = 554 unknown_virtual_mailbox_reject_code = 554 unverified_recipient_reject_code = 554 unverified_sender_reject_code = 554 EOF sudo systemctl reload postfix.service
PostFix has some recommendations as well.
sudo tee -a /etc/postfix/main.cf << EOF # PostFix Suggestions smtpd_helo_restrictions = reject_unknown_helo_hostname smtpd_sender_restrictions = reject_unknown_sender_domain smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, reject_rbl_client zen.spamhaus.org, reject_rhsbl_reverse_client dbl.spamhaus.org, reject_rhsbl_helo dbl.spamhaus.org, reject_rhsbl_sender dbl.spamhaus.org smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination smtpd_data_restrictions = reject_unauth_pipelining EOF sudo systemctl reload postfix.service
If you test a message from Santa now, Postfix will do some checks and realize it’s bogus.
550 5.7.27 [email protected]: Sender address rejected: Domain northpole.org does not accept mail (nullMX)
Postfix will attach a Received: header to outgoing emails that has details of your internal network and mail client. That’s information you don’t need to broadcast. You can remove that with a “cleanup” step as the message is sent.
# Insert a header check after the 'cleanup' line in the smtp section of the master file and create a header_checks file sudo sed -i '/^cleanup.*/a\\t-o header_checks=regexp:/etc/postfix/header_checks' /etc/postfix/master.cf echo "/^Received:/ IGNORE" | sudo tee -a /etc/postfix/header_checks
Note - there is some debate on if this triggers a higher spam score. You may want to replace instead.
You usually can’t send mail. Many ISPs block outgoing port 25 to keep a lid on spam bots. This prevents you from sending any messages. You can test that by trying to connect to gmail on port 25 from your server.
nc -zv gmail-smtp-in.l.google.com 25
Also, many mail servers will reverse-lookup your IP to see who it belongs to. That request will go to your ISP (who owns the IPs) and show their DNS name instead of yours. You’re often blocked at this step, though some providers will work with you. Put in a ticket to find out.
Even if you’re not blocked and your ISP has given you a static IP with a matching reverse-lookup, you will suffer from a lower reputation score as you’re not a well-known email provider. This can cause your sent messages to be delayed while being considered for spam.
To solve these issues, relay your email though a email provider. This will improve your reputation score (used to judge spam), ease the additional security layers such as SPF, DKIM, DMARC, and is usually free at small volume.
Postfix even calls this using a ‘Smarthost’
Now that you can get email, let’s make it so you can also send it.
- Set up a Relay
When adding Postfix’s anti-spam suggestions, we left off the smtpd_client_restrictions and smtpd_end_of_data_restrictions as they created problems during testing.
You may get a warning from Postfix that one of the settings you’ve added is overriding one of the earlier settings. Simply delete the first instance. These are usually default settings that we’re overriding.
Postfix only accepts messages for users in the “local recipient table” which is built from the unix password file and the aliases file1. You can add aliases for other addresses that will deliver to your shell account, but only shell users can receive mail right now. See virtual mailboxes to add users without shell accounts.
In the alias file, you’ll see “Postmaster” (and possibly others) are aliased to root. Add root as an alias to you at the bottom so that mail gets to your mailbox.
echo "root: $USER" | sudo tee -a /etc/aliases sudo newaliases
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.