DKIM signing possible from within phpList

There have been much written about DKIM signing for phpList and I just wanted to tell everyone that it is in fact possible to sign messages from within phpList. The reason why this is possible is that phpList relies on PHPMailer and this library actually supports DKIM.

First the disclamers

  • I know that its possible and probably better to setup your own mail server with DKIM signing and route all messages though this. But as One.com customer I did not have that luxury, so I decided to have a look into the code and see what was needed to implement a php dkim solution into the code.
  • This example and code have not been tested extensively yet, but I have successfully signed messages to be properly approved by multiple large mail vendors.
  • I know that a proper solution will include config file options, and admin panels, but that is outside the scope for this post.
  • I will not try to teach you how DKIM works in this post, search google. There are many sources out there much more capable than me
  • I am not affiliated with phpList or One.com

So the steps required (domain example.com used):

Step 1:
Create DKIM private and public keys. I used openssl, but there are also web sites that can do this if you trust them. I chose to call the key s1, you can call it whatever you like.
$ openssl genrsa -out s1.example.com.pem 1024
$ openssl rsa -in s1.example.com.pem -pubout > s1.example.com.pub

For my test I did not create a passkey for the private certificate.

Step 2:
Open file s1.example.com.pub and remove first and last lines (the ones starting with “—”), and remove all linefeeds so that you have one long line without spaces etc.

Step 3:
I used One.com DNS panel to create one TXT record called s1._domainkey.example.com with TTL 900 and value :
v=DKIM1; k=rsa; s=email; p=<paste in long key from step 2 here>

Although unrelated to DKIM , if you are also using One.com you should probably also create an DNS record named .example.com of type TXT with TTL 3600 and value :
v=spf1 include:_custspf.one.com ~all
This will ensure that you also get spf=pass in Step 8.

Step 4:
Upload private key to web server. I used the phpList config directory for my test but I also changed .htaccess to disallow access to pem files.
copy s1.example.com.pem -> //lists/config/s1.example.com.pem

Step 5:
Modify first line of lists/config/.htaccess
<FilesMatch "\.(php|inc|pem)$">

Step 6:
Modify file lists/admin/class.phplistmailer.php
In public function __construct add the following lines after $this->addCustomHeader

 	// Test of DKIM
        $this->DKIM_domain = 'example.com';
        $this->DKIM_selector = 's1';
        $this->DKIM_private = '/customers/8/d/3/example.com/httpd.www/lists/config/s1.example.com.pem';
        $this->DKIM_passphrase = '';
        $this->DKIM_identity = 'newsletter@example.com';

For One.com the full file system path is available under Advanced in the Control Panel.

Step 7:
Send a test mail to mail provider that will verify DKIM and check the raw email source

Step 8:
Look for a block like this:

DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; l=10578; s=s1;
	t=1497644660; c=relaxed/simple;
	h=From:To:Date:Subject;
	.
	.

This proves that the email was signed by phpList with key s1.

Then look for a block that looks like this (format might vary between providers) :

Authentication-Results: spf=pass (sender IP is xx.xx.xx.xx)
 smtp.mailfrom=example.com; vendor.com; dkim=pass (signature was verified)
 header.d=example.com;vendor.com; dmarc=bestguesspass action=none
 header.from=example.com;

This message should contain dkim=pass which proves that this email vendor verified the signed mail to our public key in DNS.

Regards Kjetil

2 Likes

Hi Kjetil,

Thanks for posting this!

Regards,
Dan

Hi,
I did everything you wrote and domain validated successfully, but in mail header there aren’t DKIM block.I use cloudflare, SPF and DKIM records are there. Can you give me an advice, what to do?

try these test /validators.

http://www.appmaildev.com/en/dkim/

http://dkimvalidator.com/

When you create the keys can you do this on your local computer or do you need to ssh into the server that phplist is installed on?

Is example.com the domain of the website the phplist is installed on or the domain that appears as the sender which might be different?

@kjens Belatedly many thanks for writing up and sharing this. Very useful!

It does not matter where you create the keys. It can be your server, your PC or anything else able to run openssl
example.com is the domain where mail appares to come from yes !

You are welcome ! Still signing without a problem for me.

Unfortunately not, I am not familiar with cloudflare. But ensure that the webserver have access to read the pem file. Did you btw use your own path to the files in Step6 for the pem file ?

Hi.
Thank you very much for this process.
If I have successfully activated the DKIM for other software, I cannot activate it for phplist: already the test email is failing and does not leave. So I can’t verify if the header is correct.

I added the following code to the file “lists/admin/class.phplistmailer.php” on line 40, after the condition “GOOGLE_SENDERID” on line 36 :

// Test of DKIM
$this->DKIM_domain = ‘mydomain.ch’;
$this->DKIM_selector = ‘s1’;
$this->DKIM_private = ‘/home/clients/mix_numbers_and_letters/mydomain.ch/s1.mydomain.ch.pem’;
$this->DKIM_passphrase = ‘’;
$this->DKIM_identity = ‘postmaster@mydomain.ch’;

https://dkimcore.org/c/keycheck tells me that my DKIM is OK

Thank you very much for the help.
Best regards,
AlainR

Hi.
Is the possibility to parameter DKIM always possible in phplist v3.5.3 ?
Many thanks in advance for any answer.
Regards.