DKIMの導入手順

公開鍵と秘密鍵を作成

DKIMで使用する公開鍵と秘密鍵は、OpenDKIMというツールを使って作成します。
debianでは、以下の様なコマンドでOpenDKIMをインストール。

$ sudo apt-get install opendkim

OpenDKIMをインストールすると、dkim-genkeyというコマンドが使えるようになります。
このコマンドは、秘密鍵とDNSサーバに設定する公開鍵を作成します。

dkim-genkeyコマンドの以下の様なオプションを指定して、鍵をそれぞれ作成します。

$ dkim-genkey -d example.com -s dkimtest


上記のコマンドを実行すると、「dkimtest.txt」と「dkimtest.private」というファイルが作成されます。
dkimtest.txtには、DNSサーバ用の設定が記述されているので、認証に使うDNSサーバの設定ファイルにコピペします。
dkimtest.privateは、秘密鍵なのでメール送信時に使用します。

Mail::DKIMの使用

perlには、DKIMを行うためのcpanモジュールがあります。
Mail::DKIMは、DKIMの署名処理や認証処理を行ってくれるモジュールです。
インストールは通常のcpanモジュールと同じくcpanmコマンドなどでできます。

$ cpanm Mail::DKIM

Mail::DKIM::Signer

Mail::DKIM::Signerは、メールのヘッダや本文からハッシュを作成し、
「DKIM-Signature」ヘッダを出力するモジュールです。
以下、使用例。

use strict;
use warnings;
use utf8;
use Encode;
use Email::MIME;
use Mail::DKIM::Signer;
use Mail::DKIM::TextWrap;
use Net::SMTP;                                                                                                     

# FromとToの設定                                                                                                   
my $from = 'foo@example.com';
my $to   = 'memememomo@gmail.com';

# MIME作成                                                                                                         
my $mime = Email::MIME->create(
    header => [
        From => $from,
        To   => $to,
        Subject => encode('MIME-Header-ISO_2022_JP' => 'タイトル'),
    ],
    attributes => {
        content_type => 'text/plain',
        charset      => 'ISO-2022-JP',
        encoding     => '7bit',
    },
    body => encode('iso-2022-jp' => 'テスト本文'),
);
my $mailtext = $mime->as_string;
$mailtext =~ s/\r\n/\n/g;

# 署名モジュール生成                                                                                               
my $signer = Mail::DKIM::Signer->new(
    Algorithm => 'rsa-sha256',
    Method    => 'relaxed/relaxed',
    Domain    => 'example.com',
    Selector  => 'dkimtest',
    KeyFile   => 'dkimtest.private', # 作成した秘密鍵のファイルを指定                                              
);

# パースするため一行ずつ読みこませる                                                                               
my $newtext = '';
my @lines = split /\n/, $mailtext;
for my $line ( @lines ) {
    $newtext .= $line . "\r\n";
    $signer->PRINT($line."\r\n");
}
$signer->CLOSE;                                                                                                    

# DKIM-Signatureヘッダを追加する                                                                                   
my $signheader = $signer->signature->as_string;
$newtext =~ s/\r\n\r\n/\r\n$signheader\r\n\r\n/;


# メールの内容を標準出力                                                                                           
print $newtext;

__END__


# SMTPで送信                                                                                                       
my $smtp = Net::SMTP->new(Host => '127.0.0.1', Port => '25', Hello => '[127.0.0.1]');                              
$smtp->mail($from);
$smtp->to($to);
$smtp->data();
$smtp->datasend($newtext);
$smtp->quit();

Mail::DKIM::Verifier

Mail::DKIM::Verifierは、メールのDKIM-Signatureヘッダを読み込んで、認証処理を行ったりしてくれるモジュールです。
Mail::DKIMをインストールすると、「dkimverify.pl」というプログラムが同封されています。
このプログラムを使って、上記で作ったメールが認証可能かどうかをチェックすることができます。
メールは、標準入力を使ってこのプログラムに渡します。

$ perl dkimverify.pl < signed_mail.txt
originator address: foo@example.com
signature identity: @example.com
verify result: pass
sender policy result: accept
author policy result: accept
ADSP policy result: accept