A selection of tutorials and whitepapers related to Mac OS X Server Mail and Web Services.

SpamAssassin Filter for New TLDs (.xyz .info .ninja etc)

Have you seen an increased spam from new TLDs (top level domains like these)?

.link, .xyz, .info, .ninja

This short tutorial demonstrates how to create a filter to add points for messages that are not from a list of preferred TLDs.

Important: This filter is not for everyone and you should adjust for best results considering your mail traffic and typical senders. You also should be familiar with editing plain text configuration files.1

Lets get started:

The local configuration for SpamAssassin is stored in this directory:

/Library/Server/Mail/Config/spamassassin

Within this directory, you can customize SpamAssassin with configuration files for filters, whitelists, blacklists, score overrides and more. These config files must end in .cf and are processed in alphabetical order. When the same setting is repeated, the last occurrence wins.

Your additions should load last, so we’ll call this new filter: z_tld.cf

Lets think about the goal.

We want to reduce spam, but still accept/deliver legitimate mail from these TLDs.
SpamAssassin runs hundreds of tests, and they all have a subtle effect on the final spam score.
We don’t want to be too heavy handed. For our example: we’re going to add 1.5 points to the final score.

Here’s our filter:

file: /Library/Server/Mail/Config/spamassassin/z_tld.cf

# add points if the From address is not a valid host in a listed TLD
header      LOCAL_FROM_TLD  From   !~ /@[a-z0-9\-\.]+\.(com|org|net|mil|edu)/i
describe    LOCAL_FROM_TLD         From address is not a valid host in a listed TLD
score       LOCAL_FROM_TLD  1.5

Lets break it down:

header:
This is the meat of the filter. We are searching the From header for mail not !~ matching the regex expression. The regex expression has two parts.

Part 1: /@[a-z0-9\-\.]+\. catches a legit hostname (mail.company) without the TLD (com, org, etc). spammer@spam!domain.com would be caught because ! is not allowed in a hostmame.

Part 2: (com|org|net|mil|edu) is the list of TLDs we do not penalize. Edit this list to include any TLD you typically receive mail from. Note: the filter ends in /i. A spamassassin expression begins with / ends with / and the i means case insensitive.

describe:
Description of the filter

score:
We are adding 1.5 points.
Remember, this is a negative match !~, so we add 1.5 points when the TLD is not com|org|net|mil|edu.

Shortcut

If you decide to implement this ‘as-is’, copy/paste the following in Terminal:

echo '# TLD Filter
# adds points if the From address is not a valid host in a listed TLD
header      LOCAL_FROM_TLD  From   !~ /@[a-z0-9\-\.]+\.(com|org|net|mil|edu)/i
describe    LOCAL_FROM_TLD         From address is not a valid host in a listed TLD
score       LOCAL_FROM_TLD  1.5' | sudo tee -a /Library/Server/Mail/Config/spamassassin/z_tld.cf

sudo launchctl stop org.amavis.amavisd
Test and Verify Results

Test your mail system, make sure you are able to send/receive.

Watch the amavis log located at /Library/Logs/Mail/amavis.log and you should see hits.

From your mail application, check for the x-spam-status header.

Check if syntax, typos or other errors in this filter have caused any errors:

sudo -u _amavisd -H spamassassin --lint -D 2>&1 | grep LOCAL_FROM_TLD

Reference

http://commons.oreilly.com/wiki/index.php/SpamAssassin/SpamAssassin_Rules

Document Version 1.0, 11.2.2016


  1. If you are unsure about how to edit a configuration file, have a look at our tutorial on how to edit text configuration files on OS X Server 

Setting Logging Levels for Mail Services on OS X Server 5

With OS X Server 5, Apple has further modified logging level and files for mail services. This setup is well thought out for occasional log peeking through Server.app, but can make it a bit cumbersome for troubleshooting since different log levels are written into separate log files, rather than a single one.

The most important logs for a mail server are:

/var/log/mail.log
/var/log/system.log
/Library/Logs/Mail/mail-info.log
/Library/Logs/Mail/mail-debug.log
/Library/Logs/Mail/amavis.log

These logs cover the SMTP, IMAP and SPAM Filter parts of mail services.

If you are curious, there are more logs here:

/Library/Logs/Mail/

When troubleshooting, most of the time we have to focus on SMTP and SPAM Filters. IMAP, which is provided by Dovecot, tends to give very few issues nowadays (while this wasn’t true in the pre 10.6 era where Cyrus was used).

So let’s focus on SMTP and SPAM Filters.

The SMTP logs are written into /var/log/mail.log while the SPAM Filter logs we usually need are written into /Library/Logs/Mail/amavis.log

The amount of information written into these logs depends on the logging level. The ones we care about are typically notice, info and debug

Most of the time you want your log levels to be at info. This gives you plenty of information for troubleshooting the most common issues. When running into real trouble, you might need even more detail which you get by setting the level to debug. Some object to keeping info on all the time as they claim that this generates lots of log entries and load on your server. Truth is, unless you are running mail services with hundreds of thousands of messages a day, this will never be an issue. Should you want to reduce the number of entries, you can set the log level to notice, but will have to compromise on the log detail you get.

Another factor is the time your log remains available before being rotated and archived or deleted. A good default setting is usually 1 day. However, most OS X Server mail servers aren’t so busy that you need to rotate daily, so setting it to 3-7 days gives you more detail to work with in the current log, rather than having to dig out archived logs. This is especially important if you suspect a breach and want to have a quick look at the past 48-72 hours.

Having said that, here is how to set what we discussed above:

sudo serveradmin settings mail:postfix:log_level = "info"
sudo serveradmin settings mail:postfix:spam_log_level = “info”
sudo serveradmin settings mail:imap:log_level = "info"
sudo serveradmin settings mail:postfix:log_rolling_days_enabled = yes 
sudo serveradmin settings mail:postfix:log_rolling_days = 3

To check your settings, you can for example issue:

sudo serveradmin settings mail:imap:log_level

Besides above log related commands, there are many more parameters that can be viewed or set via the command line. For an overview, issue:

sudo serveradmin settings mail

Be careful when unsure about changing a parameter and always make sure you have a working backup.

Another option is to merge SMTP and SPAM Filter information into one log. This of course comes down to personal preference. I like it, because I can follow the entire flow of an incoming or outgoing e-mail through SMTP and all connected filters, rather then having to peek into two separate log files.

To do so, edit1
/Library/Server/Mail/Config/amavisd/amavisd.conf

and make sure the necessary parameters are set as follows:

$log_level = 3;
$DO_SYSLOG = 1;              # log via syslogd (preferred)
$syslog_facility = 'mail';

From now on, all SPAM Filter log entries will be written into /var/log/mail.log rather than /Library/Logs/Mail/amavis.log for easy troubleshooting.


  1. If you are unsure about how to edit a configuration file, have a look at our tutorial on how to edit text configuration files on OS X Server 

How to Edit Text Configuration Files on OS X Server

Managing OS X Server, quite often requires one to manually edit text based configuration files. As do many of our tutorials and FAQs.

There are many ways of doing this. You can use a Terminal based editor or one with a fancy GUI. What is paramount though, is that you use a Plain Text Editor like TextWrangler, Textastic or BBEdit. Rich Text Editors like Microsoft Word or Pages can severely damage your configuration files. Keeping above in mind, the rest comes down to personal preference.

On OS X I prefer to either use PICO, a Terminal based editor or TextWrangler which has a simple but powerful GUI and good syntax highlighting.

On iOS, PICO – accessed through an SSH session with Prompt – or TextWrangler with its built in SFTP client are my tools of choice.

Whether I use a Terminal based editor or one with a GUI mainly depends on the task at hand. For quick edits of a few lines, PICO works well and is the fastest way to go. If I need to make lots of changes or need a good overview of the file I am editing, a GUI editor is way more comfortable.

Let’s have a quick look at how these work.

Assuming we want to modify Postfix’ main.cf, we would issue:

sudo pico /Library/Server/Mail/Config/postfix/main.cf

And be presented with a view like this:

Now we can use our cursor keys to move around, the backspace key to delete characters or simply type what we need. When we are done editing, we need to save and exit. The commands for this are at the bottom of the window.

In order to save and exit, we would hit CTRL-O (to write the file) and CTRL-X to exit PICO. Alternatively we can just hit CTRL-X and enter y when asked to save.

Have a good look at the available commands as there are more options like cutting text and page scrolling.

While it may need a bit of time to get adjusted to, mastering a Terminal based text editor can be a very useful item in your tool chest.

Using the GUI instead of Terminal

If you don’t like using Terminal, you can always use a Plain Text Editor like TextWrangler which would look something like this

and behave like any other GUI Plain Text Editor.
The choice is yours, just make sure you avoid Rich Text Editors like Microsoft Word or Pages. There are plenty to choose from, like TextWrangler, Textastic, BBEdit, SubEthaEdit, SublimeText and many more. The choice on iOS is equally large.

For this tutorial, let’s look at TextWrangler which is a powerful (yet free) plain text editor

TextWrangler allows you to navigate hidden directories (/etc /Library etc) and edit files even when they are owned by root.

IMPORTANT: Don’t use the App Store version
Due to app store rules, the version from the app store is not able to unlock/edit files.
Download the application directly from the publisher: http://www.barebones.com/products/textwrangler/

These steps walk you through editing a hidden/privileged (root) file. We’ll use /etc/php.ini as our example.

In TextWrangler, use the Open File by Name option in the File menu.
This allows you to simply paste the path/name: /etc/php.ini

OpenByName

Another way to open /etc/php.ini is with the more familiar Open Dialog from TextWrangler.
Be sure to choose the Show Hidden Files option.

open-dialog

ALWAYS backup a file before you make changes
Save a backup to your Desktop using the Save a Copy option from the File menu.
Because the file is owned by root, you’ll need to authenticate.

Screen Shot 2016-02-10 at 11.45.44 AM

We need to be careful editing this file, one out of place character could effect your system.
You did backup first, right ?

Let’s make a safe change.
In the php.ini file, comments start with a semi-colon.
Simply add a space at the end of one of the commented lines:

;;;;;;;;;;;;;;;;;;;
; About php.ini   ;  <<--- add a space at the end of this line
;;;;;;;;;;;;;;;;;;;

When you attempt to edit the file, you’ll be asked to authenticate again.
Once you authenticate, you can edit, then save the file.

That is all there is. Happy editing!

Implementing Postgrey on OS X 10.10.X Yosemite and OS X 10.11.X El Capitan With Server 5.X

1. Introduction
2. Requirements
3. Getting and installing the required components
4. Getting and installing Postgrey
5. Using Postgrey to greylist incoming messages
6. Caveats – READ this chapter!

DISCLAIMER: The author(s) claim(s) no responsibility for any damage that may occur from the use of any information found here or found on links followed from this document. Please make sure you have a backup before applying modifications to your server.

1. – Introduction

The purpose of this document is to provide instructions on how to implement Postgrey on OS X 10.10.x Yosemite and OS X 10.11.x El Capitan With Server 5.x.

While OS X Server 5.x. comes with a greylisting policy server, I find Postgrey to be better performing and easier to manage. Most importantly though, it will correctly log that it is greylisting rather than simply reject a message without clear indication to the sender.

You will not find many explanations as to why something is done one way or the other. Also, I will not discuss whether greylisting is useful or not. This is a decision you must make for yourself. There are plenty of discussions about this available on the internet.

Postgrey is a Postfix policy server implementing greylisting developed by David Schweikert. The official website can be found here: http://postgrey.schweikert.ch/

Postgrey functionality depends on several Perl modules and scripts to be installed.

Postgrey works as a policy server in conjunction with Postfix.

This document will require you to use the command line. If you do not feel comfortable with using the command line, you should look for a ready made installer package or for somebody to assist you.

This document is written for OS X 10.10.x Yosemite and OS X 10.11.x El Capitan With Server 5.x. It does not apply to earlier versions. Separate versions of this tutorial are available for earlier Mac OS X Server versions.

If you have used Mac OS X Server releases prior to OS X 10.10.x Yosemite and OS X 10.11.x El Capitan With Server 5.x, you are most likely used to a series of standard file paths. While some of them are still the same, many have changed in an attempt by Apple to better consolidate server related files and binaries. So always be very careful and double-check which file you are editing.

This tutorial has been tested on a standard OS X 10.10.x Yosemite and OS X 10.11.x El Capitan With Server 5.x. installation. If you have already tinkered with your system, be aware that things might differ. It is impossible for me to foresee all changes that one might have applied to a server.

This tutorial contains step-by-step instructions for terminal. Although you could just type them in line by line, it is recommended you have a basic understanding of the terminal.

DISCLAIMER: Whatever you do based on this document, you do it at your own risk! Just in case you haven’t understood: Whatever you do based on this document, you do it at your own risk!

2. – Requirements

Before you get started, you need to make sure some basic requirements are met:

  • You have made a backup of your system.
  • You have the latest version of Apple’s Developer Tools (e.g. Xcode 7 or higher for 10.11.x including command line tools) installed. Dev Tools are available as a free download from the Mac App Store
  • You do have a backup or clone.
  • You are running OS X 10.10.x Yosemite or OS X 10.11.x El Capitan With Server 5.x.
  • Familiarity with a command line editor or alternatively a GUI plain text editor (do NOT use Word or similar)
  • While not a requirement, it is recommended you subscribe to our newsletter or follow us on Twitter to be informed when updated versions of this and other tutorials become available:
    Newsletter: https://topicdesk.com/newsletter/
    Twitter: @topicdesk
3. Getting and installing the required components

As mentioned, you will need a few perl modules to be able to use Postgrey. This chapter will guide you through getting and installing them.

So let’s get going:
Make sure you are logged in as root (or alternatively use sudo).

Install the required modules by issuing the following commands. Issue them one after the other making sure you do not miss any dots or slashes. Also note that the download URLs given may change in the future. In that case just replace the URLs in this document with the current ones.

NOTE: Lines wrapping without line spacing are a single command.

The easiest way to install them is by using CPAN. To do so issue:

sudo perl -MCPAN -e shell

If you have never used CPAN before you will be prompted to supply a few parameters. Just accept the default values. Once done, you should see the CPAN prompt (cpan >):

When at the CPAN prompt issue:

o conf prerequisites_policy ask

This will prompt you when a module relies on other pre-requisites that have to be installed first. You should allow it to go ahead if asked.

Now you are ready to install the missing modules. Actually, the missing module. Apple has caught up well with basic perl modules, so currently there is only one missing.

Just issue:

install IO::Multiplex

This will install the modules and bring you back to the CPAN prompt.

Now issue

exit

to exit CPAN.

NOTE: It is possible that some of the modules will not install. In that case use “force install” instead of “install” at the CPAN prompt.

NOTE: If you had previously tried to use CPAN without having the Developer Tools installed, you will need to make sure that Developer Tools are now correctly installed and you will also need to re-configure CPAN. To do so get to the CPAN prompt and issue:

o conf init

You will be prompted to supply a few parameters. Just accept the default values.

4. – Getting and installing Postgrey

This chapter will guide you through getting and installing Postgrey.

Postgrey is written and maintained by David Schweikert. The official website can be found here: http://postgrey.schweikert.ch/

There are other tools and combinations to implement greylisting available out there, but this one works best and makes most sense for OS X Server.

So let’s get going:
Make sure you are logged in as root (or alternatively use sudo).

Install the latest version of Postgrey by issuing the following commands. Issue them one after the other making sure you do not miss any dots or slashes. Also note that the download URLs given may change in the future. In that case just replace the URLs in this document with the current ones.

NOTE: Lines wrapping without line spacing are a single command.

mkdir -p /topicdesk/sources

cd /topicdesk/sources

sudo curl -O http://postgrey.schweikert.ch/pub/postgrey-1.36.tar.gz

sudo tar xzf postgrey-1.36.tar.gz

cd postgrey-1.36    

mkdir -p /usr/local/sbin

cp postgrey /usr/local/sbin

chmod -R 755 /usr/local/sbin/postgrey

mkdir -p /var/postgrey

NOTE: Instead of creating a new system user for Postgrey, we will use the existing user for other anti-spam measures. 10.10.x and 10.11.x use user _amavisd.

chown -R _amavisd:_amavisd /var/postgrey 

cp postgrey_whitelist_clients /Library/Server/Mail/Config/postfix/postgrey_whitelist_clients

cp postgrey_whitelist_recipients /Library/Server/Mail/Config/postfix/postgrey_whitelist_recipients

Next we need to set up a property list for launchd, so that Postgrey is started on system startup.

cd /Library/LaunchDaemons

sudo touch ch.schweikert.postgrey.plist

Above command created a new empty property list. Edit

/Library/LaunchDaemons/ch.schweikert.postgrey.plist

with your favorite editor (pico, vi, etc.) and add the following content:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>ch.schweikert.postgrey</string>
    <key>OnDemand</key>
    <false/>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/local/sbin/postgrey</string>
        <string>--inet=127.0.0.1:10029</string>
        <string>--dbdir=/var/postgrey</string>
        <string>--user=_amavisd</string>
        <string>--group=_amavisd</string>
        <string>--whitelist-clients=/Library/Server/Mail/Config/postfix/postgrey_whitelist_clients</string>
        <string>--whitelist-recipients=/Library/Server/Mail/Config/postfix/postgrey_whitelist_recipients</string>
    </array>
    <key>ServiceIPC</key>
    <false/>
    <key>UserName</key>
    <string>root</string>
</dict>
</plist>

(NOTE: is a single line.)

The last step is to start Postgrey by issuing:

sudo /bin/launchctl load -w /Library/LaunchDaemons/ch.schweikert.postgrey.plist

You are now all set and should have Postgrey installed and running.

To check if it runs, issue:

sudo ps U _amavisd

Among other processes, you should see postgrey as well. Something like:

68   ??  Ss     0:01.70 /usr/local/sbin/postgrey --inet=127.0.0.1:10029

The next step is to configure Postfix to use Postgrey for greylisting of incoming messages.

5. – Using Postgrey to greylist incoming messages

As mentioned, we will use Postgrey in combination with Postfix to implement greylisting of incoming messages.

Note: OS X 10.8.x Mountain Lion with Server 2.x and OS X 10.9.x Mavericks with Server 3.x. come with its own greylisting policy server. Unless you have already done so, it needs to be disabled first.

To disable OS X Server’s stock greylisting policy server issue:

sudo serveradmin settings mail:postfix:greylist_enabled = no

Now let’s modify a parameter in your Postfix configuration so that Postgrey is used instead.

Edit:

/Library/Server/Mail/Config/postfix/main.cf

and look for:

smtpd_recipient_restrictions = ...

remove:

permit

at the end and instead add:

check_policy_service inet:127.0.0.1:10029

make sure:

smtpd_recipient_restrictions = ...

contains:

reject_unauth_destination

BEFORE:

check_policy_service

The result should look something like:

smtpd_recipient_restrictions = ..., reject_unauth_destination, ..., check_policy_service inet:127.0.0.1:10029

When done, reload Postfix by issuing:

sudo /Applications/Server.app/Contents/ServerRoot/usr/sbin/postfix reload

You are now all set and should have greylisting in place.

If you would like to exclude certain senders and/or recipients from greylisting, you can edit the following files:

/Library/Server/Mail/Config/postfix/postgrey_whitelist_clients
/Library/Server/Mail/Config/postfix/postgrey_whitelist_recipients
6. – Caveats

The most frequent issues to watch out for are:

a) Incompatible perl modules
b) Typos made when applying this tutorial
c) Long lines seen as multiple lines. Watch for incorrect line breaks

Also, if you have modified any paths and or environment variables, make sure you check them against above instructions.

Hope this helps.


Document Version 1.3, 1.2.2016

Implementing DomainKeys-DKIM on OS X 10.10.X Yosemite and OS X 10.11.X El Capitan With Server 5.X

1. Introduction
2. Requirements
3. Using Mail::DKIM to verify incoming messages
4. Using amavisd-net to sign outgoing messages
5. Advanced configuration options
6. Caveats – READ this chapter!

DISCLAIMER: The author(s) claim(s) no responsibility for any damage that may occur from the use of any information found here or found on links followed from this document. Please make sure you have a backup before applying modifications to your server.

1. Introduction

The purpose of this document is to provide instructions on how to implement DomainKeys/DKIM on OS X 10.10.x Yosemite and OS X 10.11.x El Capitan With Server 5.x.

You will not find many explanations as to why something is done one way or the other. Neither will I discuss whether DomainKeys/DKIM are useful or not. This is a decision you must make for yourself. There are plenty of discussions about this available on the internet.

DomainKeys/DKIM functionality has two sides to it. First, it is used to verify if a sender domain is using DomainKeys/DKIM signatures and if the incoming mail was correctly signed. Second, it allows you to sign outgoing messages with a digital signature for recipients to verify your mail server.

Unlike previous versions of this tutorial which were based on dkimproxy and amavisd, this tutorial relies only on amavisd. dkimproxy is still a valid solution, but it hasn’t been maintained much in the past couple of years. On the other hand, Apple is now including an updated version of amavisd-new with its Server OS, so why rely on extra components when all we need is already available.

Verification of signatures is done through amavisd-new/SpamAssassin. This allows to integrate as closely as possible with the existing components on OS X 10.10.x Yosemite and OS X 10.11.x El Capitan With Server 5.x.

Signing is handled by amavisd-new and Postfix.

This document will require you to use the command line. If you do not feel comfortable with using the command line, you should look for a ready made installer package or for somebody to assist you.

This document is written for OS X 10.10.x Yosemite and OS X 10.11.x El Capitan With Server 5.x. It does not apply to earlier versions. Separate versions of this tutorial are available for earlier Mac OS X Server versions.

If you have used Mac OS X Server releases prior to OS X 10.10.x Yosemite and OS X 10.11.x El Capitan With Server 5.x, you are most likely used to a series of standard file paths. While some of them are still the same, many have changed in an attempt by Apple to better consolidate server related files and binaries. So always be very careful and double-check which file you are editing.

This tutorial has been tested on a standard OS X 10.10.x Yosemite and OS X 10.11.x El Capitan With Server 5.x installation. If you have already tinkered with your system, be aware that things might differ. It is impossible for me to foresee all changes that one might have applied to a server.

This tutorial contains step-by-step instructions for the terminal. Although you could just type them in line by line, it is recommended you have a basic understanding of the terminal.

DISCLAIMER: Whatever you do based on this document, you do it at your own risk! Just in case you haven’t understood: Whatever you do based on this document, you do it at your own risk!

2. Requirements

Before you get started, you need to make sure some basic requirements are met:

  • You have made a backup of your system.
  • You are running OS X 10.10.x Yosemite or OS X 10.11.x El Capitan With Server 5.x
  • You do have a backup
  • Familiarity with a command line editor or alternatively a GUI plain text editor (do NOT use Word or similar)
  • While not a requirement, it is recommended you subscribe to our newsletter or follow us on Twitter be informed when updated versions of this and other tutorials become available:
    Newsletter: http://topicdesk.com/newsletter/
    Twitter: @topicdesk
3. Using Mail::DKIM to verify incoming messages

As mentioned, we will use Mail::DKIM together with SpamAssassin to verify incoming messages.

Nothing needs to be done in OS X 10.10.x Yosemite and OS X 10.11.x El Capitan With Server 5.x. Everything is already correctly configured.

Send yourself an e-mail from a domain that uses DomainKeys/DKIM (e.g. yahoo.com, gmail) and check the headers. You should see something along the lines of:

DKIM_SIGNED=0.001  
DKIM_VALID=-0.1  

in the X-Spam-Status Tests.

The scores are low on purpose by default. It is up to you to change them if you would like action to be taken based on this information. Simply edit:

/Library/Server/Mail/Config/spamassassin/local.cf  

(or wherever you keep your score adjustments) and add:

score DKIM_SIGNED 0.001
score DKIM_VALID -0.001
score DKIM_VALID_AU -0.001

(replace 0.001 with the score you want)

Remember to restart amavisd-new after score changes.

Note: If you don’t see any X-Spam-Status in your e-mail’s headers, you need to edit:

/Library/Server/Mail/Config/amavisd/amavisd.conf  

and make sure the following parameter is set (by default it is set to 2.0 which will not tag low scoring mails):

$sa_tag_level_deflt  = -999.0;  

Remember to restart amavisd-new after changes to amavisd.conf.

4. Using amavisd-new to sign outgoing messages

As mentioned, we will use amavisd-new together with Postfix to sign outgoing messages.

4.1. The first step is to generate a set of keys to be used for our signature.

To do so issue:

sudo mkdir -p /var/db/dkim

sudo chown _amavisd /var/db/dkim

sudo -u _amavisd -H amavisd genrsa /var/db/dkim/mydomain.tld.default.pem

sudo chown root:_amavisd /var/db/dkim/mydomain.tld.default.pem

sudo chmod 640 /var/db/dkim/mydomain.tld.default.pem

The following file:

/var/db/dkim/mydomain.tld.default.pem

now contains the private key used for DKIM signing.

4.2. The next step is to modify the configuration files for amavisd-new and Postfix.

Edit:

/Library/Server/Mail/Config/amavisd/amavisd.conf  

and make sure the following 2 settings are enabled as shown:

$enable_dkim_verification = 1;
$enable_dkim_signing = 1;

next , right below

$enable_dkim_signing  

add:

dkim_key('mydomain.tld', 'default', '/var/db/dkim/mydomain.tld.default.pem');

@dkim_signature_options_bysender_maps = (
{ '.' => { ttl => 21*24*3600, c => 'relaxed/simple' } } );

Note: you need to replace mydomain.tld with your actual domain.

So far so good. Now all we need to do is to add the keys to our DNS and we are all set.

To display the key(s), issue:

sudo -u _amavisd -H amavisd -c /Library/Server/Mail/Config/amavisd/amavisd.conf showkeys 

You should see something along the lines of:

; key#1, domain mydomain.tld, /var/db/dkim/mydomain.tld.default.pem
default._domainkey.mydomain.tld.    3600 TXT ( 
"v=DKIM1; p=MIGfCSXUZqGSIb7DKIBQLOQA6GNAMNWiQKBgQCdtxXkwuk2d8ZUeq5W0gy3l39M9trMfI+1ieMshy4DaIF6pFrGqmo7aNFZqcjFBoKdziEarHvcoY9IyaAFH5L6FOxZsvyjniJW3Z76GWMH6JvQsl8vfn7FxM19YqNchBn/lU60V/A7R0IDFgyk53Y4sPj4sEoTFtR0FkUN+43bMQIDAQAB")

This is your public key inside a DNS TXT record.

4.3. The next step is to prepare your DNS records.

This procedure can differ based on what DNS software/provider you use. Many providers use different control panels, so you may have to adjust as needed. If you manage your own DNS, you’ll know what to do.

In essence you need to create the following 2 TXT records for each domain you handle and want to sign. One for the DomainKeys policy record and one for the DomainKeys selector record.

_domainkey.mydomain.tld  TXT  "o=~"

default._domainkey.mydomain.tld TXT "v=DKIM1; p=MIGfCSXUZqGSIb7DKIBQLOQA6GNAMNWiQKBgQCdtxXkwuk2d8ZUeq5W0gy3l39M9trMfI+1ieMshy4DaIF6pFrGqmo7aNFZqcjFBoKdziEarHvcoY9IyaAFH5L6FOxZsvyjniJW3Z76GWMH6JvQsl8vfn7FxM19YqNchBn/lU60V/A7R0IDFgyk53Y4sPj4sEoTFtR0FkUN+43bMQIDAQAB"

The long string looking like gibberish (after p=) is your public key and should be replaced with the key shown above when issuing:

sudo -u _amavisd -H amavisd -c /Library/Server/Mail/Config/amavisd/amavisd.conf showkeys 

Note that it is a single long line.

Also you should replace mydomain.tld with your actual domain name.

When done and after you are sure your new DNS records have propagated, issue:

sudo -u _amavisd -H amavisd -c /Library/Server/Mail/Config/amavisd/amavisd.conf testkeys

If all is well, you’ll see something like:

TESTING#1: default._domainkey.mydomain.tld => pass

To verify your policy record go here:
http://domainkeys.sourceforge.net/cgi-bin/check_policy?domain=mydomain.tld&Submit=Submit

To verify your DomainKeys Selector record go here:
http://domainkeys.sourceforge.net/cgi-bin/check_selector?selector=default._domainkey.mydomain.tld&Submit=Submit

Note: you need to replace mydomain.tld with your actual domain.

If all checks out, you are set and from now on your outgoing e-mail will be signed with your DKIM key and amavisd-new/spamassassin will check incoming mails for valid DKIM keys.

Try and send an e-mail using your server. If all went well, you should see your signature in the full/raw headers of your message.

Something along these lines:

DomainKey-Signature: a=rsa-sha1; c=simple; d=mydomain.tld; q=dns; s=default; MIGfCSXUZqGSIb7DKIBQLOQA6GNAMNWiQKBgQCdtxXkwuk2d8ZUeq5W0gy3l39M9trMfI+1ieMshy4DaIF6pFrGqmo7aNFZqcjFBoKdziEarHvcoY9IyaAFH5L6FOxZsvyjniJW3Z76GWMH6JvQsl8vfn7FxM19YqNchBn/lU60V/A7R0IDFgyk53Y4sPj4sEoTFtR0FkUN+43bMQIDAQAB
5. Advanced configuration options

Above configuration will make sure that all outgoing mail for a configured domain will be signed as well as scanned for spam and viruses.

Sometimes it is preferable to offer multiple paths through the content filter. For example you might want to sign all of your outgoing mail, but at the same time would prefer if mail from your authenticated users is not scanned for spam or maybe assigned more lenient scores (this can be important when trying to send through your server from a dynamic IP).

I prefer having a setup where the content filter treats incoming and outgoing mail differently and thus will show you how to differentiate it through Postfix checks and separate amavisd-new policy banks. There are several advantages to this. First you will be able to send mail through your server without the risk of any false positives. Second, you keep CPU load down by signing only outgoing messages from your legit users.

This requires editing of

/Library/Server/Mail/Config/postfix/master.cf
/Library/Server/Mail/Config/postfix/main.cf
/Library/Server/Mail/Config/amavisd/amavisd.conf

Now on to editing:

/Library/Server/Mail/Config/postfix/main.cf

At the end of the file, add:

smtpd_sender_restrictions = check_sender_access regexp:/Library/Server/Mail/Config/postfix/tag_for_signing permit_mynetworks, permit_sasl_authenticated, reject_non_fqdn_sender, check_sender_access regexp:/Library/Server/Mail/Config/postfix/tag_for_scanning permit

Save main.cf and create a new file called tag_for_signing:

sudo touch /Library/Server/Mail/Config/postfix/tag_for_signing

Edit it and add:

/^/  FILTER smtp-amavis:[127.0.0.1]:10026

Save it and create a new file called tag_for_scanning:

sudo touch /Library/Server/Mail/Config/postfix/tag_for_scanning

Edit it and add:

/^/  FILTER smtp-amavis:[127.0.0.1]:10024

Save and next edit

/Library/Server/Mail/Config/postfix/master.cf

add a new block:

127.0.0.1:10027 inet n  -       y       -       -       smtpd
   -o content_filter=
   -o smtpd_tls_security_level=none
   -o smtpd_delay_reject=no
   -o smtpd_client_restrictions=permit_mynetworks,reject
   -o smtpd_helo_restrictions=
   -o smtpd_sender_restrictions=
   -o smtpd_recipient_restrictions=permit_mynetworks,reject
   -o smtpd_data_restrictions=reject_unauth_pipelining
   -o smtpd_end_of_data_restrictions=
   -o smtpd_restriction_classes=
   -o mynetworks=127.0.0.0/8
   -o smtpd_error_sleep_time=0
   -o smtpd_soft_error_limit=1001
   -o smtpd_hard_error_limit=1000
   -o smtpd_client_connection_count_limit=0
   -o smtpd_client_connection_rate_limit=0
   -o receive_override_options=no_header_body_checks,no_unknown_recipient_checks,no_milters
   -o local_header_rewrite_clients=
   -o smtpd_milters=
   -o local_recipient_maps=
   -o relay_recipient_maps=

Save it and now edit:

/Library/Server/Mail/Config/amavisd/amavisd.conf

Look for $policy_bank{'ORIGINATING'} 

inside the policy bank block, add:

bypass_spam_checks_maps   => [1],

Save and issue:

sudo postfix reload

sudo -u _amavisd -H amavisd -c /Library/Server/Mail/Config/amavisd/amavisd.conf reload

Now try sending mail from and to your server. Outgoing mail from authenticated users of yours should now be signed, but not scanned. Incoming mail from outside senders will be scanned but not signed.

The command we entered into the policy bank above prevents mail for outgoing mail from being scanned. You can of course add anything you like to the policy bank. For example instead of not scanning you could assign lower spam scores if mail is coming from your users. The amavisd-new documentation is a good starting point for this.

NOTE: The settings chosen are based on my personal preference and experience. You may want to change them as you deem fit.

6. Caveats

The most frequent issues to watch out for are:

a) Incompatible perl modules
b) Typos made when applying this tutorial
c) Long lines seen as multiple lines. Watch for incorrect line breaks

Also, if you have modified any paths and or environment variables, make sure you check them against above instructions.

Hope this helps.


Document Version 1.3, 1.2.2016