Record of some of the computer tech I deal with so that it's documented at least somewhere.

Friday 30 September 2011

DKIM signing with Postfix

Scenario

You use SMTP-AUTH (hopefully over TLS) on your phone to connect to a Postfix server which then sends your email over the public internet. You want to add some authority to the message somehow.

Enter OpenDKIM - look there for ./make install etc.

A DKIM Signature

DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=maht0x0r.net; s=blogger; t=1317392525; 
        bh=AKfekrfl5wnhOUH0Zy1ZDQuS/dTepAwDyGPkx1cTdLk=;
        h=Content-Type:To:Subject:MIME-Version:Content-Transfer-Encoding: From:Date:Message-ID; 
        b=pJL4iPtbmXl2G+58UrJR6SeKbcoWx4sYwqUXitFs/tKvolBnSiy53D3+Mf79pYZ2L   
        5q35MwZcWEx94s4bFb88AYC44TdAhZx9hZuo/NbOvKRdUjDv028XRLJ0mOAgVR0jle  
        bCXqykNnCdduIgyO3xKyEaw+xRhwxPf74g9P2mdY=
Before signing the values of d=maht0x0r.net (domain) s=blogger (section) and the private key chosen are under your control based on the sender's email address.

I've got OpenDKIM running as a service under daemontools which is what I use for long running servers - anyway you need it listening on it's socket

% cat /etc/opendkim.conf # the important bits Canonicalization relaxed/simple KeyTable file:/etc/postfix/ssl/opendkim/KeyTable SigningTable refile:/etc/postfix/ssl/opendkim/SigningTable ExternalIgnoreList refile:/etc/postfix/ssl/opendkim/trusted-hosts InternalHosts refile:/etc/postfix/ssl/opendkim/trusted-hosts Socket inet:8891@localhost Make some keys % opendkim-genkey -d maht0x0r.net -s blogger % ls -l --rw------- M 0 root root 887 Sep 30 13:26 blogger.private --rw------- M 0 root root 320 Sep 30 13:26 blogger.txt % cat blogger.private # used to sign outgoing email -----BEGIN RSA PRIVATE KEY----- MIICXQIBAAKBgQDEfFH3nxvFnwck2oJCq7JojSPsfAvr93+N+M5cykwFruPgJXsW EIcNymwKyEABwS7kL78eg1SYggh/8RI1jZiXfLW+PQFZLrwqE9/L0ZzZhjrjYQjK WM182/Uaj6GWtOhariSLKmR6JYtRPFh/fiOr6YDDAt/puFSLCnUi3Ppj8QIDAQAB AoGBAKj/BMEmaIyhK1PXXRJa+yhRvQQ57UcXqO5DgbrthFWfBwBTPHrN3FtQL31W nzbjIaHCL2/fJXPG4+inQDIvh33BJZa7I2h7ZDMIzEiYJ/3Y0VEPpW+3W4GTMj2I JgJWJokpCuJGqBcujhVPW2xmKAFtd27+Y+urxgt+gCrj+KrBAkEA8iNseAFbKBoN Df2krnH8rEyfRMWaLqI6hP8AtAYfVBiNW/2P0+6bBWoZ6YV/iDQwubtQsCkW3jrp FNZW6CVSPwJBAM+72SRKdTPYnplTEYkdPzyKmNV094AUw9XRVDvM1MVEgXXQBctn kPrms/TKvDq6w66INK0rVUmiNeKsohUUXc8CQQCuaUGqNx/YBNu+ZiMG3GgqG47l VIg4avZH8f4prfdG9eBskHnXKBlVjxVXFafFDgLC5d+64/3q2Pgm4DT9RlS1AkBi 7hgkY11bup8Vb+0a+pXCFFNi3Nh94+W773wJGqx94fkxjUclLoZqJvKu8tofshA9 D1re2ZM9hQXalNJ/7XobAkArHhx9+quDr6/jj/lDb8vbrcpEne2+8FivmpHmeEHJ roIJtX5TyD4gfPxC45qQEL1/q88w2OhYCP915fMBtS+X -----END RSA PRIVATE KEY----- % cat blogger.txt # used by receivers to check your signate blogger._domainkey IN TXT "v=DKIM1; r=postmaster; g=*; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDEfFH3nxvFnwck2oJCq7JojSPsfAvr93+N +M5cykwFruPgJXsWEIcNymwKyEABwS7kL78eg1SYggh/8RI1jZiXfLW+PQFZLrwqE9/L0ZzZhjrjYQjKWM182 /Uaj6GWtOhariSLKmR6JYtRPFh/fiOr6YDDAt/puFSLCnUi3Ppj8QIDAQAB" ; ----- DKIM blogger for maht0x0r.net r=postmaster (DKIM errors to $r@$domain) # something like that :) Then tell opendkim about your keys, here you name them : This is where keyname is used to determine d, s and the private key % cat /etc/postfix/ssl/opendkim/KeyTable # keyname d s keyfile maht maht0x0r.net:blogger:/etc/postfix/ssl/opendkim/blogger.private maht0x0r maht0x0r.net:blogger:/etc/postfix/ssl/opendkim/maht0x0r.net.private default example.com:flex:/etc/postfix/ssl/opendkim/smtp.private And in here you match email addresses to named keys % cat /etc/postfix/ssl/opendkim/SigningTable maht@maht0x0r.net maht *@maht0x0r.net maht0x0r * default First match wins in the SigningTable, which took me a while to realise when I had * as the first entry. OpenDKIM by default will only sign mails posted from inside the network. But we can control this # ExternalIgnoreList refile:/etc/postfix/ssl/opendkim/trusted-hosts # InternalHosts refile:/etc/postfix/ssl/opendkim/trusted-hosts % echo '*' > /etc/postfix/ssl/opendkim/trusted-hosts That's right, we just sign for anyone but only SASL-Authed clients can be sending so that means only SASL-Auth'd clients get a signature. OK, then you need a DKIM entry in your DNS % host -t txt blogger._domainkey.maht0x0r.net blogger._domainkey.maht0x0r.net descriptive text "v=DKIM1\; r=maht-dkim\; g=*\; k=rsa\; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDEfFH3nxvFnwck2oJCq7JojSPsfAvr93+N+ M5cykwFruPgJXsWEIcNymwKyEABwS7kL78eg1SYggh/8RI1jZiXfLW+PQFZLrwqE9/L0ZzZhjrjYQjKWM182 /Uaj6GWtOhariSLKmR6JYtRPFh/fiOr6YDDAt/puFSLCnUi3Ppj8QIDAQAB" I tried to verify it with a few online DKIM testing suites, all failed. This is a header when I send it to google : Authentication-Results: mx.google.com; spf=pass (google.com: domain of maht@maht0x0r.net designates x.x.x.x as permitted sender) smtp.mail=maht@maht0x0r.net; dkim=pass header.i=@maht0x0r.net I didn't use the keys above, obviously, so my DNS /public key is different, which you can verify : host -t txt flex._domainkey.maht0x0r.net flex._domainkey.maht0x0r.net descriptive text "v=DKIM1\; r=maht-dkim\; g=*\; k=rsa\; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDeQqlOKodABflhh076+6yueVDiQAm5koXBEg QG31F04Al01HeyYxM7HllBjvrDfuQei102SyZH298QDDXmk/4Wtb8zh2SZ5xammqSR89HkKmbqFaSHD 2iEAgiEeWGf7nL/lK2NM0QljP5aOUpjOW1SGfRiB1AtipAcKNPLm1NRIQIDAQAB" Next job is to find out how to sign it manually without using an OpenDKIM process forever listening. Then I can add my own headers *before* signing it.

No comments: