According to Yahoo best e-mail sending practices, it helps if your e-mails have a DKIM signature. On a separate issue, I was having problems with checking e-mail addresses on Yahoo domain (from home on comcast network), so I thought I may as well add a DKIM signature header and see if it improves anything.
Well I did that, and the 1st signed e-mail I sent to my Yahoo e-mail immediately landed in the SPAM folder. So much for signing the e-mail. Anyhow, here are the steps that I needed to complete to add this capability to out-going e-mails from my application. Hopefully over time, the DKIM signing will help with e-mail delivery.
Create a private key:
openssl genrsa -out rsa.private 1024
Create a public key:
openssl rsa -in rsa.private -out rsa.public -pubout -outform PEM
Create A DNS record for your DKIM mail signature, e.g. (base64 public key truncated to display well in the blog)
YOUR-SELECTOR._domainkey.YOUR-DOMAIN IN TXT "v=DKIM1; p=MIGfMA0GCSqGSIb3DQEBAQUAA4G...; s=email"
Use this wizard to create the TXT record.
You must add this DNS TXT record to your domain DNS entry. Contact your hosting service or your DNS provider. I contacted my hosting company bluehost.com and within an hour the DNS records were updated.
Install the dnspython and pydkim Python modules.
Wait for a while and use dig to check if your DNS record has been updated:
$ dig YOUR-SELECTOR._domainkey.YOUR-DOMAIN TXT ; <<>> DiG 9.6.0-APPLE-P2 <<>> YOUR-SELECTOR._domainkey.YOUR-DOMAIN TXT ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 50920 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;YOUR-SELECTOR._domainkey.YOUR-DOMAIN. IN TXT ;; ANSWER SECTION: YOUR_SELECTOR._domainkey.YOUR-DOMAIN. 11678 IN TXT "v=DKIM1\; p=MIGfMA0GCSqGSIb3DQEBAQUAA4G...; s=email" ;; Query time: 8 msec ;; SERVER: 10.0.1.1#53(10.0.1.1) ;; WHEN: Sun Nov 15 11:26:50 2009 ;; MSG SIZE rcvd: 298
Add the sign/verify option to your e-mail sending program:
import dkim
def dkim_sign_message(self, msg):
try:
sign = dkim.sign(msg, "YOUR-SELECTOR", "YOUR-DOMAIN", open(self._dkim_private_key, "r").read())
message = "%s%s" % (sign, msg)
if not dkim.verify(message):
print "DKIM verify failed"
message = msg
return message
except Exception as e:
print "EXCEPTION ... %s" % e
return msg
Where self._dkim_private_key is the path to the private key file that was created initially.
After you send an e-mail, you can view the e-mail headers from your e-mail client. You should see the Dkim-Signature header. Something like this:
Dkim-Signature: v=1; a=rsa-sha256; c=simple/simple; d=aquacue.org; i=@aquacue.org; q=dns/txt; s=accounts; t=1258312155; h=Content-Type : MIME-Version : Subject : From : To : X-Mailer : X-Organization : X-Abuse : X-Sender : X-Originating-IP; bh=JbJO60n6bvNZzyZilOW/hGrD2w5G6cR6o1YHimiwBbU=; b=iy8yt/YQlbhLUt2BpCWmKJ...
