Introduction
A “short” guide on Mail server setup. We’re going to rely on Postfix, Dovecot, MySQL and anti-spam including some details related to OpenDKIM/SPF/ReversePTR.
Install Packages For Mail Server Setup
First of all, we need to install required packages as a first step in mail server setup.
apt-get install postfix postfix-mysql dovecot-core dovecot-imapd dovecot-lmtpd dovecot-mysql
In postfix configuration, select Internet Site.
Create a MySQL Database, Virtual Domains, Users and Aliases
We’re going to create a MiSQL DB, containing 3 different tables:
- Domains
- Users
- Aliases
Login to MySQL and create servermail database:
mysql -u root -p CREATE DATABASE servermail;
First create a new user, specific for mail authentication:
mysql > GRANT SELECT ON servermail.* TO 'usermail'@'127.0.0.1' IDENTIFIED BY 'mailpassword'; mysql > FLUSH PRIVILEGES;
Use that DB to create tables and data:
mysql> USE servermail;
Create domains tables for domains recognized as authorized domains:
CREATE TABLE `virtual_domains` ( `id` INT NOT NULL AUTO_INCREMENT, `name` VARCHAR(50) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
User table, for email addresses and passwords, associating each user with a domain:
CREATE TABLE `virtual_users` ( `id` INT NOT NULL AUTO_INCREMENT, `domain_id` INT NOT NULL, `password` VARCHAR(106) NOT NULL, `email` VARCHAR(120) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `email` (`email`), FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Aliases table, for specifying emails that are going to be forward to another email:
CREATE TABLE `virtual_aliases` ( `id` INT NOT NULL AUTO_INCREMENT, `domain_id` INT NOT NULL, `source` varchar(100) NOT NULL, `destination` varchar(100) NOT NULL, PRIMARY KEY (`id`), FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
With structure set, moving to data segment.
Virtual Domains
Insert domain(s):
INSERT INTO `servermail`.`virtual_domains` (`id` ,`name`) VALUES ('1', 'cyberpunk.rs'), ('2', 'mail.cyberpunk.rs');
Virtual Emails
Create email address and passwords for each domain:
INSERT INTO `servermail`.`virtual_users` (`id`, `domain_id`, `password` , `email`) VALUES ('1', '1', ENCRYPT('firstpassword', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), 'email1@cyberpunk.rs'), ('2', '1', ENCRYPT('secondpassword', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), 'email2@cyberpunk.rs');
Virtual Aliases
Create alias that we are going to forward to some other emal address (destination):
INSERT INTO `servermail`.`virtual_aliases` (`id`, `domain_id`, `source`, `destination`) VALUES ('1', '1', 'alias@cyberpunk.rs', 'email1@cyberpunk.rs');
EncFS (optional)
As you can see in the picture above (a warning while installing), EncFS is not the ideal one. It has some known vulnerabilities, so maybe some other alternatives like CryFS might be better idea. For this example, we’ll stick to EncFS.
$ apt-get install encfs mkdir /encrypted-mail /decrypted-mail chgrp mail /decrypted-mail/ chmod -R g+rw /decrypted-mail/ gpasswd -a mail fuse chgrp fuse /dev/fuse; chmod g+rw /dev/fuse root@li212-205:~# encfs /encrypted-mail /decrypted-mail -o --public Creating new encrypted volume. Please choose from one of the following options: enter "x" for expert configuration mode, enter "p" for pre-configured paranoia mode, anything else, or an empty line will select standard mode. ?> p Paranoia configuration selected. Configuration finished. The filesystem to be created has the following properties: Filesystem cipher: "ssl/aes", version 3:0:2 Filename encoding: "nameio/block", version 3:0:1 Key Size: 256 bits Block Size: 1024 bytes, including 8 byte MAC header Each file contains 8 byte header with unique IV data. Filenames encoded using IV chaining mode. File data IV is chained to filename IV. File holes passed through to ciphertext. -------------------------- WARNING -------------------------- The external initialization-vector chaining option has been enabled. This option disables the use of hard links on the filesystem. Without hard links, some programs may not work. The programs 'mutt' and 'procmail' are known to fail. For more information, please see the encfs mailing list. If you would like to choose another configuration setting, please press CTRL-C now to abort and start over. Now you will need to enter a password for your filesystem. You will need to remember this password, as there is absolutely no recovery mechanism. However, the password can be changed later using encfsctl. New Encfs Password: Verify Encfs Password:
It’s that simple. /decrypted-mail
is now a regular directory. /encrypted-mail
is that same data, just encrypted.
Configure Postfix
What is Postfix? It is Wietse Venema’s mail server (an “MTA” in the email lingo), that started life at IBM research as an alternative to the widely-used Sendmail program. Essentially it runs SMTP, and delivers incoming mail to Dovecot. As a next step in mail server setup, we are going to configure Postfix to handle the SMTP connections and messages for each user introduced in the MySQL Database.
Just in case, create backup(s) for the config files we’re going to change. Open the main.cf
file to modify it:
nano /etc/postfix/main.cf
First we need to comment the TLS Parameters and append other parameters. You can use the Free SSL certificates and the paths that are suggested:
# TLS parameters #smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem #smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key #smtpd_use_tls=yes #smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache #smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache smtpd_tls_cert_file=/etc/ssl/certs/dovecot.pem smtpd_tls_key_file=/etc/ssl/private/dovecot.pem smtpd_use_tls=yes smtpd_tls_auth_only = yes
or you could modify depending on your personal configuration, for instance using Let’s encrypt.
# TLS parameters smtpd_tls_cert_file=/etc/letsencrypt/live/<DOMAIN.com>/fullchain.pem smtpd_tls_key_file=/etc/letsencrypt/live/<DOMAIN.com>/privkey.pem smtpd_tls_CAfile=/etc/letsencrypt/live/<DOMAIN.com>/chain.pem
Then we are going to append the following parameters below the TLS settings that we have changed in the previous step:
smtpd_sasl_type = dovecot smtpd_sasl_path = private/auth smtpd_sasl_auth_enable = yes smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination
We need to comment the mydestination default settings and replace it with localhost. This change allows your VPS to use the virtual domains inside the MySQL table.
#mydestination = cyberpunk.rs, mail.cyberpunk.rs, localhost.cyberpunk.rs, localhost mydestination = localhost
Verify that myhostname parameter is set with your FQDN.
myhostname = mail.cyberpunk.rs
Append the following line for local mail delivery to all virtual domains listed inside the MySQL table.
virtual_transport = lmtp:unix:private/dovecot-lmtp
Finally, we need to add these three parameters to tell Postfix to configure the virtual domains, users and aliases.
virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf virtual_alias_maps = mysql:/etc/postfix/mysql-virtual-alias-maps.cf
We are going to create the final three files that we append in the main.cf file to tell Postfix how to connect with MySQL.
First we need to create the mysql-virtual-mailbox-domains.cf
file. It’s necessary to change the values depending your personal configuration.
nano /etc/postfix/mysql-virtual-mailbox-domains.cf user = usermail password = mailpassword hosts = 127.0.0.1 dbname = servermail query = SELECT 1 FROM virtual_domains WHERE name='%s'
Then we need to restart Postfix.
service postfix restart
We need to ensure that Postfix finds your domain, so we need to test it with the following command. If successful, it should return 1:
postmap -q cyberpunk.rs mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
Then we need to create the mysql-virtual-mailbox-maps.cf
file.
nano /etc/postfix/mysql-virtual-mailbox-maps.cf user = usermail password = mailpassword hosts = 127.0.0.1 dbname = servermail query = SELECT 1 FROM virtual_users WHERE email='%s'
Restart Postfix again:
service postfix restart
At this moment we are going to ensure Postfix finds your first email address with the following command. It should return 1 if successful:
postmap -q email1@cyberpunk.rs mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
Finally, we are going to create the last file to configure the connection between Postfix and MySQL:
nano /etc/postfix/mysql-virtual-alias-maps.cf user = usermail password = mailpassword hosts = 127.0.0.1 dbname = servermail query = SELECT destination FROM virtual_aliases WHERE source='%s'
Restart Postfix again:
service postfix restart
We need to verify that Postfix can find your aliases. Enter the following command and it should return the mail that’s forwarded to the alias:
postmap -q alias@cyberpunk.rs mysql:/etc/postfix/mysql-virtual-alias-maps.cf
If you want to enable port 587
to connect securely with email clients, it is necessary to modify the /etc/postfix/master.cf
file
nano /etc/postfix/master.cf
We need to uncomment these lines and append other parameters:
submission inet n - - - - smtpd -o syslog_name=postfix/submission -o smtpd_tls_security_level=encrypt -o smtpd_sasl_auth_enable=yes -o smtpd_client_restrictions=permit_sasl_authenticated,reject
In some cases, we need to restart Postfix to ensure port 587 is open.
service postfix restart
Note: You can use “netstat -tulpn
” cmd to check if your system listens on specific ports, or you can use this tool to scan your domain ports and verify that port 25
and 587
are open.
Configure Dovecot
Dovecot, an “LDA” (Local Delivery Agent) in the email lingo, is an open source IMAP and POP3 email server for Linux/UNIX-like systems, written with security in mind. Essentially it runs IMAP.
Backup 7 files that are about to be modified, so that you could revert it to default if you needed to:
cp /etc/dovecot/dovecot.conf /etc/dovecot/dovecot.conf.orig cp /etc/dovecot/conf.d/10-mail.conf /etc/dovecot/conf.d/10-mail.conf.orig cp /etc/dovecot/conf.d/10-auth.conf /etc/dovecot/conf.d/10-auth.conf.orig cp /etc/dovecot/dovecot-sql.conf.ext /etc/dovecot/dovecot-sql.conf.ext.orig cp /etc/dovecot/conf.d/10-master.conf /etc/dovecot/conf.d/10-master.conf.orig cp /etc/dovecot/conf.d/10-ssl.conf /etc/dovecot/conf.d/10-ssl.conf.orig
Edit configuration file from Dovecot.
nano /etc/dovecot/dovecot.conf
Verify this option is uncommented.
!include conf.d/*.conf
We are going to enable protocols (add pop3 if you want to) below the !include_try /usr/share/dovecot/protocols.d/*.protocol line.
!include_try /usr/share/dovecot/protocols.d/*.protocol protocols = imap lmtp
Then we are going to edit the mail configuration file:
nano /etc/dovecot/conf.d/10-mail.conf
Find the mail_location line, uncomment it, and put the following parameter:
mail_location = maildir:/var/mail/vhosts/%d/%n
Find the mail_privileged_group line, uncomment it, and add the mail parameter like so:
mail_privileged_group = mail
Ensure permissions are 775 like this:
>drwxrwsr-x 3 root vmail 4096 Jan 24 21:23 /var/mail
We are going to create a folder for each domain that we register in the MySQL table:
mkdir -p /var/mail/vhosts/cyberpunk.rs
Create a vmail user and group with an id of 5000
groupadd -g 5000 vmail useradd -g vmail -u 5000 vmail -d /var/mail
We need to change the owner of the /var/mail
folder to the vmail user.
chown -R vmail:vmail /var/mail
Then we need to edit the /etc/dovecot/conf.d/10-auth.conf
file:
nano /etc/dovecot/conf.d/10-auth.conf
Uncomment and/or set following lines:
disable_plaintext_auth = yes auth_mechanisms = plain login #!include auth-system.conf.ext
We need to create the /etc/dovecot/dovecot-sql.conf.ext
file with your information for authentication:
nano /etc/dovecot/conf.d/auth-sql.conf.ext
Enter following code:
passdb { driver = sql args = /etc/dovecot/dovecot-sql.conf.ext } userdb { driver = static args = uid=vmail gid=vmail home=/var/mail/vhosts/%d/%n }
We need to modify the /etc/dovecot/dovecot-sql.conf.ext
file with our custom MySQL information:
nano /etc/dovecot/dovecot-sql.conf.ext
Uncomment the driver parameter and set mysql as parameter:
driver = mysql connect = host=127.0.0.1 dbname=servermail user=usermail password=mailpassword default_pass_scheme = SHA512-CRYPT password_query = SELECT email as user, password FROM virtual_users WHERE email='%u';
Change the owner and the group of the dovecot folder to vmail user:
chown -R vmail:dovecot /etc/dovecot chmod -R o-rwx /etc/dovecot
Open and modify the /etc/dovecot/conf.d/10-master.conf file (be careful because different parameters will be changed).
nano /etc/dovecot/conf.d/10-master.conf ##Uncomment inet_listener_imap and modify to port 0 service imap-login { inet_listener imap { port = 0 } #Create LMTP socket and this configurations service lmtp { unix_listener /var/spool/postfix/private/dovecot-lmtp { mode = 0600 user = postfix group = postfix } #inet_listener lmtp { # Avoid making LMTP visible for the entire internet #address = #port = #} }
Modify unix_listener parameter to service_auth like this:
service auth { unix_listener /var/spool/postfix/private/auth { mode = 0666 user = postfix group = postfix } unix_listener auth-userdb { mode = 0600 user = vmail #group = } #unix_listener /var/spool/postfix/private/auth { # mode = 0666 #} user = dovecot }
Also modify service auth-worker like this:
service auth-worker { # Auth worker process is run as root by default, so that it can access # /etc/shadow. If this isn't necessary, the user should be changed to # $default_internal_user. user = vmail }
Finally, we are going to modify the SSL configuration file from Dovecot (skip this step if you are going to use default configuration).
# nano /etc/dovecot/conf.d/10-ssl.conf ssl = required ssl_cert = </etc/ssl/certs/dovecot.pem ssl_key = </etc/ssl/private/dovecot.pem
or as we mentioned earlier, set Let’s encrypt keys:
ssl_cert = </etc/letsencrypt/live/<DOMAIN.com>/fullchain.pem ssl_key = </etc/letsencrypt/live/<DOMAIN.com>/privkey.pem
Generating SSL certs:
openssl req -new -x509 -days 1000 -nodes -out "/etc/ssl/certs/dovecot.pem" -keyout "/etc/ssl/private/dovecot.pem"
Furthermore, you should check that port 993
is open and working (in case you enable pop3; you should check also port 995
).
telnet cyberpunk.rs 993
Congratulations. You have successfully configured your mail server and you may test your account using an email client:
- Username: email1@cyberpunk.rs - Password: email1's password - IMAP: cyberpunk.rs - SMTP: cyberpunk.rs
Note: use port 993 for secure IMAP and port 587 or 25 for SMTP.
Avoiding SPAM filters (SPF, DKIM, DMARC)
We’re going to setup SPF, DKIM, DMARC and (maybe) PTR. Due to the size of this post/tutorial, we’re going to move these to individual posts:
SPF Setup
Check SPF Postfix Setup.
DKIM Setup
Check OpenDKIM Postfix Setup.
DMARC Setup
Check DMARC Postfix Setup.
Reverse PTR
The Reverse DNS is one of the basic requirements for running some Internet protocols. It is also often used as a spam filter to determine whether the IP address of the incoming message matches an authenticated domain name and to block the message if it doesn’t.
Anti-Spam
Spam can be annoying and dangerous, so its always a good idea to set some anti-spam services. We’ll include few: dspam and SpamAssasin. Postfix domain block is also usefull at times.
Postfix Block Domains
To block Emails to/from specific domains, start by creating the access list file (e.g. /etc/postfix/access):
$ nano /etc/postfix/access
In there, add domain names followed by the action (DISCARD or REJECT). We recommend DISCARD:
spamdomain01.com DISCARD spamdomain02.com REJECT
Tell postfix to use that file. Edit mail.cf
and add/update smtpd_sender_restrictions header:
$ nano /etc/postfix/main.cf smtpd_sender_restrictions = check_sender_access hash:/etc/postfix/access
After you finish, postmat the file to prepare postfix to use it (every time you modify the file).
$ postmap /etc/postfix/access
Restart Postfix.
DSpam
apt-get install dspam dovecot-antispam postfix-pcre dovecot-sieve
patch these in /etc/dspam/dspam.conf:
Home /decrypted-mail/dspam TrustedDeliveryAgent "/usr/sbin/sendmail" UntrustedDeliveryAgent "/usr/lib/dovecot/deliver -d %u" Tokenizer osb IgnoreHeader X-Spam-Status IgnoreHeader X-Spam-Scanned IgnoreHeader X-Virus-Scanner-Result IgnoreHeader X-Virus-Scanned IgnoreHeader X-DKIM IgnoreHeader DKIM-Signature IgnoreHeader DomainKey-Signature IgnoreHeader X-Google-Dkim-Signature ParseToHeaders on ChangeModeOnParse off ChangeUserOnParse full ServerPID /var/run/dspam/dspam.pid ServerDomainSocketPath "/var/run/dspam/dspam.sock" ClientHost /var/run/dspam/dspam.sock
Create the directory:
mkdir /decrypted-mail/dspam chown dspam:dspam /decrypted-mail/dspam
As best as I can tell, the preferences in /etc/dpsam/dspam.conf
are completely ignored. If you want to edit them, the right place is /etc/dspam/default.prefs. Totally logical, right? Anyway, patch these values:
spamAction=deliver # { quarantine | tag | deliver } -> default:quarantine signatureLocation=headers # { message | headers } -> default:message showFactors=on
Edit /etc/postfix/master.cf
:
dspam unix - n n - 10 pipe flags=Ru user=dspam argv=/usr/bin/dspam --deliver=innocent,spam --user $recipient -i -f $sender -- $recipient dovecot unix - n n - - pipe flags=DRhu user=mail:mail argv=/usr/lib/dovecot/deliver -f ${sender} -d ${recipient}
and
nano /etc/postfix/dspam_filter_access /./ FILTER dspam:unix:/run/dspam/dspam.sock
Patch the end of /etc/postfix/main.cf
# new settings for dspam dspam_destination_recipient_limit = 1 #only scan one mail at a time smtpd_client_restrictions = permit_sasl_authenticated #localhost doesn't get scanned check_client_access pcre:/etc/postfix/dspam_filter_access #run dspam on everything else
Integrating dspam with imap:
nano /etc/dovecot/conf.d/20-imap.conf mail_plugins = $mail_plugins antispam
Integrating dspam with lmtp:
protocol lmtp { # Space separated list of plugins to load (default is global mail_plugins). mail_plugins = $mail_plugins sieve }
Telling sieve to move spam into a Spam folder. Edit /decrypted-mail/mail.cyberpunk.rs/drew/.dovecot.sieve
(e.g. for your username and domain):
require ["regex", "fileinto", "imap4flags"]; # Catch mail tagged as Spam, except Spam retrained and delivered to the mailbox if allof (header :regex "X-DSPAM-Result" "^(Spam|Virus|Bl[ao]cklisted)$", not header :contains "X-DSPAM-Reclassified" "Innocent") { # Mark as read setflag "\\Seen"; # Move into the Junk folder fileinto "Spam"; # Stop processing here stop; }
And then we’ll configure /etc/dovecot/conf.d/90-plugin.conf
. Note that, there’s just one plugin {} dict, and this stuff goes inside it.
plugin { ... # Antispam (DSPAM) antispam_backend = dspam antispam_allow_append_to_spam = YES antispam_spam = Spam;Junk antispam_trash = trash;Trash antispam_signature = X-DSPAM-Signature antispam_signature_missing = error antispam_dspam_binary = /usr/bin/dspam antispam_dspam_args = --user;%u;--deliver=;--source=error antispam_dspam_spam = --class=spam antispam_dspam_notspam = --class=innocent antispam_dspam_result_header = X-DSPAM-Result }
Give postfix and dovecot a kick:
service postfix restart service dovecot restart
Incoming messages should have headers like:
X-Dspam-Result: Innocent X-Dspam-Processed: Wed Jun 12 21:46:08 2013 X-Dspam-Confidence: 0.9899 X-Dspam-Probability: 0.0000 X-Dspam-Signature: 51b9246071121935811689 X-Dspam-Factors: 27, Received*12+Jun, 0.01000, Received*12+Jun, 0.01000, Received*Postfix+with, 0.01000, Received*with+#+id, 0.01000, Received*mail.cyberpunk.rs+#+12, 0.01000, Content-Type*text+plain, 0.01000, Received*Postfix+#+ESMTP, 0.01000, Received*li212-205.members.linode.com+Postfix, 0.01000, Received*drew+#+#+#+Jun, 0.01000, Received*Wed+#+Jun, 0.01000, Received*Wed+#+Jun, 0.01000, Received*li212-205.members.linode.com+#+with, 0.01000, Received*Wed+#+#+2013, 0.01000, Received*Wed+#+#+2013, 0.01000, Received*Postfix+#+#+id, 0.01000, Received*li212-205.members.linode.com+#+#+#+id, 0.01000, Received*ESMTP+id, 0.01000, Date*12+Jun, 0.01000, Received*for+#+#+#+12, 0.01000, Date*Jun+2013, 0.01000, Received*by+#+Postfix, 0.01000, Received*by+#+with, 0.01000, Received*mail.cyberpunk.rs+#+#+Jun, 0.01000, Received*by+#+#+#+ESMTP, 0.01000, Date*Wed+#+#+2013, 0.01000, Received*drew+#+#+12, 0.01000, Received*for+#+mail.cyberpunk.rs, 0.01000
SpamAssassin
First we need to install SpamAssassin.
apt-get install spamassassin spamc
Then we also need to create a user for SpamAssassin.
adduser spamd --disabled-login
To successfully configure SpamAssassin, it’s necessary to open and modify the configuration settings.
nano /etc/default/spamassassin
Also, we need to change the ENABLED parameter to enable SpamAssassin daemon.
ENABLED=1
We need to configure the home and options parameters.
SPAMD_HOME="/home/spamd/" OPTIONS="--create-prefs --max-children 5 --username spamd --helper-home-dir ${SPAMD_HOME} -s ${SPAMD_HOME}spamd.log"
Then we need to specify the PID_File parameter like this:
PIDFILE="${SPAMD_HOME}spamd.pid"
Finally, we need to specify that SpamAssassin’s rules will be updated automatically.
CRON=1
We need to open /etc/spamassassin/local.cf
to set up the anti-spam rules. SpamAssassin will score each mail and if it determines this email is greater than 5.0 on its spam check, then it automatically will be considered spam. You could use the following parameters to configure the anti-spam rules:
nano /etc/spamassassin/local.cf rewrite_header Subject ***** SPAM _SCORE_ ***** report_safe 0 required_score 5.0 use_bayes 1 use_bayes_rules 1 bayes_auto_learn 1 skip_rbl_checks 0 use_razor2 0 use_dcc 0 use_pyzor 0
We need to change the Postfix /etc/postfix/master.cf
file to tell it that each email will be checked with SpamAssassin.
nano /etc/postfix/master.cf smtp inet n - - - - smtpd -o content_filter=spamassassin
Finally, it is finished. We need to append the following parameters:
spamassassin unix - n n - - pipe user=spamd argv=/usr/bin/spamc -f -e /usr/sbin/sendmail -oi -f ${sender} ${recipient}
It is also necessary to start SpamAssassin and restart Postfix to begin verifying spam from emails.
service spamassassin start service postfix restart
Done! Mail server with Postfix and Dovecot with MySQL authentication and spam filtering with either dpan or SpamAssassin is ready!
Things to work on:
- Push: an email system that provides an always-on capability, in which new email is actively transferred (pushed) as it arrives by the mail delivery agent (MDA) (commonly called mail server) to the mail user agent (MUA), also called the email client. Email clients include smartphones and, less strictly, IMAP personal computer mail applications.
- Full-text search: relying on Java, solr-tomcat & dovecot-solr
- Webmail: check next tutorial related to simple webmail control (Rainloop).
- Requiring TLS encryption: makes you non-RFC-compliant, but makse NSA life a bit more difficult
- Greylisting: This is a cool idea involving providing a “temporary failure” each time a new sender sends a message. Legitimate senders will keep retrying, and after a few minutes you add them to a “good” list. Spammers will give up, and furthermore, their mail messages will never even hit disk. It’s actually really easy configure, just apt-get install postgrey and then add check_policy_service inet:127.0.0.1:10023 under smtpd_client_restrictions in
/etc/postfix/main.cf
.