1.DomainKeys って何?

1-1. DomainKeys(ドメイン・キーズ)は認証鍵によるメール認証

 DomainKeys は迷惑メール(SPAM)対策の手法として Yahoo.com が提唱している対策法です。特徴としては既存のプロトコルを変更させるようなことはありません。公開鍵・秘密鍵を DNS レコードの一部として用います。送信側のメールサーバはメールヘッダ内にヘッダ情報の一部の署名を付与します。この署名を受信側のメールサーバが検証を行います。また、電子メールのフィッシング詐欺やダイレクトメールなど、正しいドメインから送信されたものかどうかの判定にも用いることができます。  以上の特徴から、主にドメイン偽装された迷惑メール(SPAM)や From アドレスを詐称するウイルスメールに対策を絞ったものとも考えられます。

1-2. DomainKeys の動作の流れ

  1. 公開鍵・秘密鍵を作成し、公開鍵を DNS レコードの TXT フィールドに書き込みます
  2. メールを送信する度に、メールには秘密鍵(rsa-sha1方式)が作成され、ヘッダの中に署名が埋め込まれます
  3. 送り先のメールサーバではメールを受信すると、ヘッダの中の署名と DNS 上の TXT レコードに組み込まれている情報を比較します(メールに添付されている署名が DNS 上の公開鍵によって作成されたものかどうか確認)。比較するドメインは SMTP プロトコル中の Sender: ヘッダです。
  4. 署名と秘密鍵の組み合わせが正しい場合にメッセージを受け取ります。正しくない場合はメールを受け取らず拒否します

1-2. DomainKeys に関する開発状況

 SourceForge(ソース・フォージ)で開発が進んでいます。

 http://domainkeys.sourceforge.net/

 ドキュメントの中には sendmail と qmail, Postfix に関するものも含まれています。

2. ライセンスは無料

Royalty-free, worldwide, non-exclusive licensing information for this project is available here:. 

http://domainkeys.sourceforge.net/license/softwarelicense1-1.html

3. DomainKeysに関する技術的な事

3-1. 公開鍵による署名の認証

 署名は RSA 暗号(SHA1)によるメールのダイジェスト化されたものが標準です。

 署名の例として、openssl の使用例を挙げます。768 bit の秘密鍵を生成する例をあげます。

$ openssl genrsa -out private.txt 512
warning, not much extra random data, consider using the -rand option
Generating RSA private key, 512 bit long modulus
..++++++++++++
..............++++++++++++

 コマンドを実行することで、 private.txt というファイルが作成されます。テキスト形式なので cat コマンドで参照可能です。

$ cat private.txt
-----BEGIN RSA PRIVATE KEY-----
MIIBOgIBAAJBANo5mJu+XfOJIJ65idRWQHQDSwKo1YV+2EiGIkx+E62eHGOrgbWn
Kdwdlcp6f5KBtH+rEePykgABfb19T8R2kFECAwEAAQJAIgYc3xt9Nn1I0raG4M5Z
2jyxM0bzk47FVflj251EoCre+HxFUE9kYjlO2cc/IJmAlvknetxvJxrJ8vtpZC+g
gQIhAO+IWb9fPKAqKrl9qKnXWIK3oHuzxfupDrAo0jt/6il5AiEA6To+BZFGZJMw
t3GYo61qZ6KeCsnOb0Ro+wi7zkcHP5kCIGPd+W0si95LNlz34yZMvn5hiOuKXHU8
Wv9fRafBASQhAiBVKsuTROWrvIRBuN3Ah4cfqSaFUgRsZVLguOO8A/wFoQIhAKTB
NYtK7KDGyf2U09OKXi+z8ZdQpyud3I3OvPQq63St
-----END RSA PRIVATE KEY-----

 このように秘密鍵(RSA PRIVATE KEY)を作成するように、メールに対しても同様に秘密鍵の作成が出来ます。opensslに引数としてファイルの情報を渡す事です。たとえばメールの本文が input.file とすると、

$ openssl dgst -sign ./private.txt -sha1 < ./input.file  > mime.file

 この手順で MIME-Base64 形式のファイルが mime.file に出力されます。このようにして署名を作成し、メールのヘッダ中に埋め込むことがメール送信側サーバで必要な事です。

 秘密鍵から公開鍵を抽出するには次のような openssl コマンドを用います。

$ openssl rsa -in ./private.txt -out public.txt -pubout -outform PEM
read RSA key
writing RSA key

 作成された公開鍵は cat で確認できます。

$ cat public.txt
-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANo5mJu+XfOJIJ65idRWQHQDSwKo1YV+
2EiGIkx+E62eHGOrgbWnKdwdlcp6f5KBtH+rEePykgABfb19T8R2kFECAwEAAQ==
-----END PUBLIC KEY-----

 この作成された公開鍵の情報を DNS に TXT レコードとして登録します。

 なお、署名の正当性を確認するには、openssl では次のコマンドを用います。

$ openssl dgst -verify ./public.txt -sha1 -signature ./mime.file < ./input.file
Verified OK

 このように "Verified OK"=認証 OK と表示されました。

3-2. DNS 上の TXT レコードとはどんなものか?

 まず、認証を行う件ですが、必ず 512, 768, 1024, 1536, 2048 ビットのいずれかでなくてはいけません。

 テキストレコードは次のような形式です。

brisbane._domainkey IN TXT "g=; k=rsa; p=MHww ... IDAQAB"

 "(ダブルコーテーション)の中の記号(タグ)には、次のような意味があります。

  • g = キーの暗号強度です。記述は任意であり省略してもありません。0 以外の値を入力します。空白でも鍵の長さから、自動で鍵の暗号強度が判明します。
  • k = キーの種類です。RSA 認証が標準です。署名は 'rsa'鍵でなくてはいけません。この項目は省略できます。
  • n = メモ欄です。人間が読むことができます。この項目は省略できます。
  • p = Base64 文字列としてエンコードされた公開鍵データです。この項目指定は必須です。公開鍵がないものは無効として判断されます。
  • t = フラグ(boolean)属性のセットができます。有効な属性は「y」です。「y」はテストモードです。DomainKeys をテストしているときに用いると、メールサーバ側で設定が適切でなくてもメールを通過させることができる場合もあるでしょう(設定次第)。この項目も省略できます。

 なお、TXT レコードは 2048 bit までの暗号強度の鍵を用いることが可能です。

3-3. 鍵の暗号強度

 どのレベルの暗号強度を用いるかは安全度の高さとコストパフォーマンスに反比例します。暗号強度が高いほど、パフォーマンスが悪くなります。いくつかの判断材料としては、

  • DNS が通信する時に用いる UDP パケットでは、2048 ビットのキーが、UDP パケットの上限(512バイト)に収まる長さ
  • 鍵が大きくなればなるほど、署名の確認に CPU の処理負担となる
  • 鍵を頻繁におきかえると、それはそれで面倒になる
  • 目的は公開鍵認証方式を用いて正しい送信者か確認ができれば良い

結局の所ドキュメントでは 1024 ビットの暗号鍵を推奨してます。

3-4. 署名とメールヘッダの関係

 これら署名の情報はメールヘッダ中の【 DomainKey-Signature: 】に含まれます。この中に署名やドメインなど全ての情報を含んでいます。

 また、【 DomainKey-Signature: 】はその他のヘッダよりも優先し、一番前に出てきている必要があります。これは【 DomainKey-Signature: 】ヘッダ自体が署名が適切かどうかの判断材料に含まれないからです。

 DomainKey-Signature のサンプルはこんな感じです。

DomainKey-Signature: a=rsa-sha1; s=brisbane; d=example.net; q=dns; c=simple

 もう少し具体的にしてみると、

DomainKey-Signature: a=rsa-sha1 s=brisbane; d=example.net;
c=simple; q=dns;
b=dzdVyOfAKCdLXdJOc9G2q8LoXSlEniSbav+yuU4zGeeruD00lszZ
      VoG4ZHRNiYzR;

 Gmail.com では次のようなヘッダを返しています。

DomainKey-Signature: a=rsa-sha1; c=nofws;
s=beta; d=gmail.com;
h=received:message-id:date:from:reply-to:to:subject:
mime-version:content-type:content-transfer-encoding;
b=UHWIvAn9.....jw5mJ7H+A
  • a = 署名生成時の暗号方式です。暗号方式は "rsa-sha1" でなくてはいけません(必須)
  • b = Base64 エンコードされた署名データです。この項目も必須です。
  • c = 署名アルゴリズム(正規化)の指定です。"simple" もしくは "nofws" の指定が必須です。
  • d = メール送信ホストのドメイン名です。この項目も必須です。このドメインは公開鍵の照会にも用います。
  • h = 適切な署名かどうか比較するときアルゴリズムが用いるメールのヘッダ情報。message-id, from, subject など。フィールドは : 区切りで用います。なお、ドメイン名を識別するために "From:" と "Sender:" ヘッダは必須です。この h の項目が無ければ、全メールヘッダが照会に必要なものと見なされます。
  • q = 公開鍵を探すための方法(DNS 検索)を指定しなくてはいけません。通常は dns です。
  • s = DNS に問い合わせる TXT レコードのタイプです

 結局の所、サーバ管理者としては DNS レコードの作成と、DomainKey-Signature: ヘッダの発行・照会を MTA で行わせる必要があります。

 なお、データ正規化に用いるアルゴリズムには simple と nofws があります。詳しくはドキュメント 3.4.2参照

3-5. DNS 情報の追加を行うには?

 実際の DNS(bind) のゾーン情報ファイルには以下のような記述を行います。

_domainkey   IN TXT "t=y; o=-; n=notes; r=emailAddress"

 項目はそれぞれ ; セミコロンで区切られます。

 タグの意味は次の通りです

  • n = 人間が読むことができるメモ欄です。プログラムは無視します。
  • o = メール送信時のポリシー定義です。 '-' は送信する全メールに対して署名しているという意味です。省略時は '-' が指定されているものとして認識されます。
  • r = レポート(報告)用メールアドレスです。もし送信時のメールが無効であれば通知されるべきメールアドレスです。
  • t = boolean フラグです。y はテスト用のフラグです。本物の署名済み送信メールと区別します。だからといって、実際にメールがどう扱われるかはメールの送り先サーバのポリシーによって処理されます。このオプションは省略可能です。

 なお、認証が失敗したときは "Authenticated-Results:" ヘッダが作成されます。

4 実践、DomainKeys DNS 情報の追加

4-1. DNS 上に設定が必要なもの

 DNS に設定が必要なのは「【任意の文字(sタグで定義)】._domainkey.ドメイン名」という TXT 形式のレコードです。

 たとえば s タグが betatest の場合、ドメインは example.jp とすると、必要な TXT レコードは 「betatest._domainkey.example.jp」となります。

 実際 gmail の例では dig コマンドは次のような応答を返します。

$ dig beta._domainkey.gmail.com txt
(中略)
;; ANSWER SECTION:
beta._domainkey.gmail.com. 300  IN      TXT     "t=y\; k=rsa\;  
p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC69TURXN3oNfz+G/m3g5rt4P6nsKmVgU1D6cw2
X6BnxKJNlQKm10f8tMx6P6bN7juTR1BeD8ubaGqtzm2rWK4LiMJqhoQcwQziGbK1zp/MkdXZEWMCfl
LY6oUITrivK7JNOLXtZbdxJG2y/RAHGswKKyVhSP9niRsZF/IBr5p8uQIDAQAB"

4-2. DomainKeys 対応 TXT レコードの作成

 DomainKeys 対応の TXT レコードを作るためには公開鍵の作成が必要です(TXTレコード中に公開鍵の情報が含まれるためです)。ドキュメントを参考にし、1024 bit の暗号強度を持つ公開鍵を作成することにします。

4-2-1. 秘密鍵の作成

 サーバ内に OpenSSL がセットアップされている事が必須です。もし OpenSSL がサーバ内になければ、別の OpenSSL が導入されているサーバで作成しても構いません。

 署名は RSA暗号(SHA1) による 1024 bit の鍵を作成することにします。

$ mkdir ssl
$ cd ssl

 まず作業用にディレクトリを作成します。名前は適当でも良いのですが、後から必要になったときあわてないような名前にしておくことをお勧めします。  手始めに openssl で用いるためのランダムファイルを準備します。

$ openssl md5 ~/* > random.txt

 これで random.txt の中にホームディレクトリに含まれるファイルのハッシュ値(MD5)が取り込まれます。

 次に openssl に genrsa オプションをつけ、RSA鍵を作成します。

$ openssl genrsa -rand random.txt -out private.key 1024
8705 semi-random bytes loaded
Generating RSA private key, 1024 bit long modulus
..................++++++
...............................++++++
e is 65537 (0x10001)

 cat で内容を確認します。

$ cat private.key
-----BEGIN RSA PRIVATE KEY-----
MIICXwIBAAKBgQDnvGryYF051/F6PKSgOnfy8nDJc9Jav1bDW7ACQdliEN/lCTqn
/2396aeoNk4OpU+yK7kuN4infoT2pn6kGVI6IhoCDmqI42e8R96A3xggctEu6ftP
iv+kd9gPJUOtID8XyCfoErSwtY3e1vYNMjeCmOKL3bbddO2xLdfi7JLFywIDAQAB
(中略)
74OxW3taChgtQkm5cGvGMAiTIoWWAsGOaTsXJ+32hJco+iu3FuLpZpECP0d9UhYs
MYF+YrjNuwXRAJdy8wshtwJBAORa8K6OrC/gKA0nrtY2dRWP9y1/qGWfb9jRfEah
w0Mjuede7rg9bDfVo93woFAmSWJklpQy5p39BH1MxbSr41M=
-----END RSA PRIVATE KEY-----

 "RSA PRIVATE KEY"(RSA秘密鍵)と書かれたファイル内容が表示されます。

4-2-2. 公開鍵の作成

 公開鍵は次の openssl コマンドを用いて作成します。

$ openssl rsa -in ./private.key -out public.key -pubout -outform PEM
read RSA key
writing RSA key

 作成された公開鍵は cat で確認できます。

$ cat public.key
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDnvGryYF051/F6PKSgOnfy8nDJ
c9Jav1bDW7ACQdliEN/lCTqn/2396aeoNk4OpU+yK7kuN4infoT2pn6kGVI6IhoC
DmqI42e8R96A3xggctEu6ftPiv+kd9gPJUOtID8XyCfoErSwtY3e1vYNMjeCmOKL
3bbddO2xLdfi7JLFywIDAQAB
-----END PUBLIC KEY-----

 ここで表示されたデータを TXT レコードに追加します。

4-2-3. DNS(bind)のゾーン情報ファイルに TXT レコード追加

 ここでは3-2項を参考に、TXT レコードをゾーンファイルに記述します。


変なところがあればご指摘下さい……

  • 秘密鍵を添付するのではなくて、署名をヘッダに加えるのですよ。鍵と署名がごっちゃになってる -- 通りすがりの学生さん 2005-07-11 16:40:03 (月)
  • ご指摘ありがとうございます、なおします -- 前佛 2005-07-11 17:23:50 (月)
  • どのゾーンにTXTレコードを追加するかわかりません.また,結局どれをTXTレコードに追加すればよいか,サンプルのソースがあればわかるのですが、教えてください -- 教えて 2005-12-14 19:43:47 (水)
  • 私が実際に使っているZONE情報ファイルをアップしました。<a href=http://pocketstudio.jp/~zem/sample/pocketstudio.jp.zone.txt>こちらをご覧下さい。</a> -- zem? 2005-12-14 20:32:58 (水)
  • こちらの通り設定しているのですが、どうにも自分の方の署名がされません。ログにも残っていませんし・・・何から疑ってかかればよいでしょう? -- koko? 2006-06-07 23:43:28 (水)
  • お騒がせしました。結局のところmaster.cfの書き方が悪かったようです。 -- koko? 2006-06-09 21:20:58 (金)

##comment


5 実際の所 DomainKeys を使うには

  • SENDMAIL.NET で配布されている sendmail 用 milter フィルタ "dk-milter" が実装に必要となります。

http://sendmail.net/dk-milter/

情報元(リソース)

Yahoo! Anti-Spam Resource Center - DomainKeys
http://antispam.yahoo.com/domainkeys
Domain-based Email Authentication Using Public-Keys Advertised in the DNS (DomainKeys)
http://www.ietf.org/internet-drafts/draft-delany-domainkeys-base-02.txt
Preventing SPAM
http://www.poornam.com/articles_spam.php#SECTION00043000000000000000

トップ   編集 凍結解除 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: Thu, 23 Sep 2010 13:53:45 JST (4957d)