This post is now out of date! Running your own mailserver is even easier these days thanks to rspamd. You literally plug rspamd into your mailserver using a milter, it’s a single line in postfix, and rspamd rolls up everything below in the smtpd_recipient_restrictions section and then some more, plus it’s got a nice webGUI.
Rspamd: Zero spam, Rapid delivery.
Running your own mailserver isn’t that hard. I always have a chuckle when I read people say “Why would you do it yourself, there’s so much management?” That’s crap, they just don’t know how to do it.
A mailserver basically runs itself, there’s plenty of online tools to verify that you’re not an open relay, that you’ve configured your TLS settings correctly etc. Plenty of configuration guides (another is included below) to show you how to lock it down so that it’s not a spam wind-up-and-go machine.
I run 3 mailservers (1 primary, 2 backup). They all talk a single Greylisting Daemon, set to allow mail through after 1 minute. Should the greylisting daemon not be available, the servers are set to accept the mail.
Before greylisting takes place however, the mail gets a bunch of checks. First of all, High Quality DNS Whitelists are checked, if a server is listed in here it can be Trusted to not be sending Spam. Then Blacklists are checked. Then remaining whitelists are checked, if a server is listed it is allowed to bypass Greylisting. NOTE: Don’t use SORBS! Their data is out of date and crap. Way too many false positives. Avoid at all costs. I made this mistake once.
Here’s the full logic that all my mail servers use. You have to ensure you share the greylisting database correctly, otherwise you’ll end up delaying mail much longer than necessary.
- REJECT anyone who doesn’t say HELO
- REJECT invalid Hostnames in HELO
- REJECT senders not using <user@domain.domain> correctly as per RFC821.
- REJECT Unknown Recipients
- ALLOW from a list of Known IPs (Backup MX hosts, other trusted devices)
- ALLOW from Authenticated Senders (To send mail from anywhere, using username/password)
- ALLOW from a set of DNS Whitelists that state an entry in their list can be considered “Non-Spam”
- REJECT from a list of DNS Blacklists
- ALLOW from a second set of DNS Whitelists that are verified to be SMTP servers (skips the need to greylist)
- Send to Greylisting Daemon to ACCEPT/DELAY
- ACCEPT
Step 7 could be amalgamated with step 9, but I prefer to “trust” the lists of known, trusted email senders before checking blacklists, as sometimes blacklists can be a bit “over zealous” in their flagging a server a spam, i.e. one that sends newsletters etc. This way I get check of this logic:
- Verified quality sender – ACCEPT.
- Check for blacklists – DENY.
- Verified RFC compliant SMTP server, skip greylisting (because we know it’ll just retry anyway, no point delaying) – ACCEPT.
- Send to Greylisting for DELAY/ACCEPT decision.
With these rules in place, I get almost zero spam making it through, probably 2-3 spams per week. However the amount of mail that is rejected via the Blacklists and the Greylisting is amazing, in the thousands per day.
Once I’ve finally accepted a mail, I send it to Spamassassin for checking, just to be sure.
The other thing that’s important that I’ve done fairly recently (in the last couple of years) is to ensure that Postfix is setup correctly to send and receive mail using encryption. SSLv2 and SSLv3 are disabled, weak ciphers are disabled, Perfect Forward Secrecy is enabled.
Here’s my main.cf for Postfix.
smtpd_banner = $myhostname ESMTP - SMTP BANNER GREETING biff = no # appending .domain is the MUA's job. append_dot_mydomain = no # Send a warning if mail is delayed after 1 hour delay_warning_time = 1h # If mail can't be delivered after 7 days, we give up maximal_queue_lifetime = 7d readme_directory = no inet_protocols = ipv4 # Incoming Mail smtpd_tls_cert_file=/etc/letsencrypt/live/<hostname>/fullchain.pem smtpd_tls_key_file=/etc/letsencrypt/live/<hostname>/privkey.pem smtpd_tls_CAfile = /etc/ssl/certs/ca-certificates.crt smtpd_tls_dh1024_param_file = ${config_directory}/dh2048.pem smtpd_tls_dh512_param_file = ${config_directory}/dh512.pem smtpd_use_tls=yes smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache smtpd_tls_session_cache_timeout = 604800 smtpd_tls_eecdh_grade = strong smtpd_tls_security_level = may smtpd_tls_ciphers = high smtpd_tls_protocols = !SSLv2, !SSLv3 smtpd_tls_exclude_ciphers = aNULL, eNULL, RC4 #Don't offer Auth until STARTTLS has setup smtpd_tls_auth_only = yes #Ask for a Client Cert smtpd_tls_ask_ccert = yes # Outgoing Mail smtp_tls_cert_file=/etc/letsencrypt/live/<hostname>/fullchain.pem smtp_tls_key_file=/etc/letsencrypt/live/<hostname>/privkey.pem smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt smtp_use_tls=yes smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache smtp_tls_session_cache_timeout = 604800 smtp_tls_security_level = may smtp_tls_ciphers = high smtp_tls_protocols = !SSLv2, !SSLv3 smtp_tls_exclude_ciphers = aNULL, eNULL, RC4 #TLS Params tls_preempt_cipherlist = yes myhostname = <my hostname> alias_maps = hash:/etc/aliases alias_database = hash:/etc/aliases myorigin = /etc/mailname mydestination = <hostnames I accept mail for> virtual_alias_domains = <other domains I host> virtual_alias_maps = hash:/etc/postfix/virtual relayhost = mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 <backup MX1> <backup MX2> mailbox_command = procmail -a "$EXTENSION" mailbox_size_limit = 0 recipient_delimiter = + inet_interfaces = all html_directory = no # Procmail to deliver mailbox_command = /usr/bin/procmail # sasl! You want to eat it! smtpd_sasl_auth_enable = yes smtpd_sasl_security_options = noanonymous smtpd_sasl_local_domain = $myhostname smtpd_sasl_authenticated_header = yes # Mailing Signing with OpenDKIM milter_protocol = 2 milter_default_action = accept smtpd_milters = inet:localhost:12301 # Don't copy unless you have setup DKIM non_smtpd_milters = inet:localhost:12301 # Don't copy unless you have setup DKIM # Proper Mail Protocol Please strict_rfc821_envelopes = yes # Verify? No thanks! disable_vrfy_command = yes # Demand a polite conversation! smtpd_helo_required = yes # Delay before reject smtpd_delay_reject = yes smtpd_helo_restrictions = permit_mynetworks, reject_non_fqdn_hostname, reject_invalid_hostname, permit smtpd_recipient_restrictions = reject_invalid_hostname, reject_unknown_recipient_domain, reject_unauth_pipelining, permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, check_client_access cidr:/etc/postfix/rbl_override, permit_dnswl_client iadb.isipp.com=127.0.1.255, permit_dnswl_client sa-trusted.bondedsender.org, permit_dnswl_client sa-accredit.habeas.com, permit_dnswl_client list.dnswl.org=127.0.[0..255].[2..3], permit_dnswl_client hostkarma.junkemailfilter.com=127.0.0.[1;5], reject_rhsbl_reverse_client dbl.spamhaus.org, reject_rhsbl_sender dbl.spamhaus.org, reject_rhsbl_client dbl.spamhaus.org, reject_rbl_client zen.spamhaus.org, reject_rbl_client dnsbl-1.uceprotect.net, reject_rbl_client psbl.surriel.com, reject_rbl_client hostkarma.junkemailfilter.com=127.0.0.2, reject_rbl_client bl.mailspike.net, reject_rbl_client b.barracudacentral.org, reject_rbl_client truncate.gbudb.net, permit_dnswl_client iadb.isipp.com=127.0.2.[1;2], permit_dnswl_client iadb.isipp.com=127.3.100.[5..100], permit_dnswl_client wl.mailspike.net, permit_dnswl_client list.dnswl.org, permit_dnswl_client hostkarma.junkemailfilter.com=127.0.0.3, check_policy_service inet:127.0.0.1:10060, message_size_limit = 81920000
Once configured like that, it’s set and forget pretty much. I occasionally check the logs to ensure that nothing is being greylisted due to the dumb policy some senders have of retrying each time from a DIFFERENT IP Address. When I do see such stupidity I usually just add the sending /24 network to the Greylist Whitelist.
The final thing to note is that you should run your own caching DNS server. If you’re using your ISPs, or a big public provider like Google etc, then the black/whitelists often won’t work as they implement rate-limiting against abuse, and the big public name-servers are almost always blocked. Running your own small caching DNS server is easy and will give you a working RBL setup.
Update: 11/4/2017 – Turns out Protected Sky are just a bunch of rip-off merchants. Removed them from my list of checked RBLs.