2026年6月12日

2026年6月12日

DANE を導入してセキュリティを強化する設定:受信メールサーバーに TLSA を公開し、証明書の更新で止めない運用まで

DANE を導入すると、あなたのドメイン宛てにメールを送るサーバーが、DNSSEC で署名された TLSA レコードを使って受信サーバーの証明書を確かめるようになり、STARTTLS を外させる攻撃や偽の証明書による盗み見を防げます。導入の要点は、MX ホストのゾーンを DNSSEC で署名すること、TLSA は 3 1 1 で公開すること、そして証明書を更新しても鍵が変わらないか、変わる前に TLSA を追加しておく運用にすることです。この記事では、Postfix で受信している自前のメールサーバーを例に、前提の確認から公開、確認、日々の監視までを説明します。

DANE で守れるもの

メールサーバー同士の通信は、STARTTLS で暗号化されるのが一般的です。ただし STARTTLS は「使えれば暗号化する」という仕組みのため、経路上の攻撃者が STARTTLS の案内を消せば平文に戻され、偽の証明書を出されても送信側は多くの場合そのまま送ってしまいます。

DANE for SMTP(RFC 7672)は、受信側が「このサーバーはこの鍵の証明書を出す」という情報を TLSA レコードとして DNS に公開し、送信側がそれを DNSSEC で検証してから照合する仕組みです。TLSA が見つかった相手には暗号化と証明書の一致が求められるため、上の2つの攻撃が成り立ちにくくなります。

似た目的の仕組みに MTA-STS があります。MTA-STS は HTTPS でポリシーを配る方式で DNSSEC を必要としません。両方を併用することもでき、送信側がどちらに対応しているかで効く仕組みが変わります。なお、ブラウザでの HTTPS に DANE を使う方式は主要なブラウザで採用されていないため(2026年10月現在)、この記事ではメール(SMTP)に絞ります。

前提を確かめる

DANE を導入できるかどうかは、次の3点で決まります。

  • MX ホスト名のゾーンが DNSSEC で署名され、親ゾーンに DS が登録されている。メールのドメインと MX ホストのドメインが違う場合は、MX ホスト側のゾーンが対象
  • その MX ホストを自分で運用している。Google Workspace や Microsoft 365 などのメールサービスを使っている場合、TLSA を公開するのはサービス事業者の役割で、利用者側では設定できない
  • 受信サーバーで STARTTLS が動いていて、MX ホスト名の証明書を出している
# MX ホストのゾーンが検証できるか(ad が付くか)
dig mx1.example.com A +dnssec

# 受信サーバーが STARTTLS で証明書を出しているか
openssl s_client -starttls smtp -connect mx1.example.com:25 -servername mx1.example.com </dev/null

1つ目で ad が付かない場合は、先に DNSSEC の設定を整えます。2つ目で証明書が表示されない場合は、Postfix の TLS 設定から見直します。

TLSA の形式を選ぶ

TLSA レコードは「使用法・選択子・照合方式」の3つの数字とデータで構成されます。SMTP で推奨されるのは 3 1 1 です。

  • 3(DANE-EE):サーバー証明書そのものを指定する。認証局の検証は使わない
  • 1(SPKI):証明書全体ではなく公開鍵だけを対象にする。証明書を更新しても鍵が同じなら値は変わらない
  • 1(SHA-256):公開鍵の SHA-256 ハッシュを載せる

中間証明書の鍵を指定する 2 1 1 もありますが、認証局が中間証明書を切り替えると TLSA と合わなくなります。Let's Encrypt のように中間証明書が定期的に変わる認証局では、3 1 1 のほうが扱いやすくなります。使用法 0 と 1 は SMTP の DANE では使わない前提になっているため、選ばないでください。

手順1:証明書の鍵を固定する

3 1 1 は公開鍵のハッシュなので、証明書を更新しても鍵が同じなら TLSA を変える必要はありません。逆に、更新のたびに鍵が変わると、そのたびに TLSA が合わなくなります。

certbot は既定では更新のたびに新しい鍵を作るため、受信サーバー用の証明書は鍵を再利用する設定にします。

# 既存の証明書を、更新時に鍵を再利用する設定にする例
sudo certbot reconfigure --cert-name mx1.example.com --reuse-key

reconfigure サブコマンドが使えない古い版では、certbot renew --reuse-key のように更新時に指定するか、更新設定ファイル(/etc/letsencrypt/renewal/ 内)で鍵の再利用を有効にします。オプションの扱いは版によって違うため、certbot --help all で確認してください。レンタルサーバーやコントロールパネルが自動で証明書を更新している場合は、鍵が再利用されるかどうかを先に確かめます。

手順2:TLSA の値を作る

サーバー証明書から公開鍵を取り出し、SHA-256 のハッシュを計算します。

openssl x509 -in /etc/letsencrypt/live/mx1.example.com/cert.pem -noout -pubkey \
  | openssl pkey -pubin -outform DER | openssl dgst -sha256 -hex

出力の = より後ろにある 64 文字の 16 進数が TLSA のデータです。あわせて、次の鍵の値も作っておきます。鍵の入れ替えのときに、新しい鍵の TLSA を先に公開しておくためです。

# 次に使う鍵を作り、その TLSA の値を計算する
sudo openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out /etc/ssl/private/mx1-next.key
sudo chmod 600 /etc/ssl/private/mx1-next.key
sudo openssl pkey -in /etc/ssl/private/mx1-next.key -pubout -outform DER | openssl dgst -sha256 -hex

手順3:TLSA を公開する

MX ホストごとに、ポート 25 の TLSA を公開します。ゾーンファイルで書く場合の例です。マネージド DNS では、管理画面やAPIで TLSA 型のレコードとして登録します(TLSA に対応していない事業者もあります)。

; いまの鍵と次の鍵の2件を公開する
_25._tcp.mx1.example.com. 3600 IN TLSA 3 1 1 <いまの鍵のハッシュ>
_25._tcp.mx1.example.com. 3600 IN TLSA 3 1 1 <次の鍵のハッシュ>

MX が複数ある場合は、すべての MX ホストに TLSA を置くのが基本です。一部の MX にだけ TLSA がある状態でも動作はしますが、どの経路でも同じ保護を受けられるよう揃えておくと運用が分かりやすくなります。TTL は、入れ替えのときに古い値が残る時間に直結するため、極端に長くしないでおきます。

手順4:外から確かめる

公開した TLSA が検証済みで返るか、実際の証明書と一致するかを確かめます。

# 検証するリゾルバ経由で、TLSA に ad が付くか
dig @1.1.1.1 _25._tcp.mx1.example.com TLSA +dnssec

# Postfix 付属の posttls-finger で、DANE として照合できるか
posttls-finger -c -l dane "[mx1.example.com]"

posttls-finger は、検証するリゾルバを使えるサーバー上で実行します。照合に成功すると、TLS 接続が検証済み(Verified)である旨が表示されます。internet.nl のメールのテストのような外部の診断サービスでも、DANE の結果を確かめられます(提供内容は変わることがあります)。

あわせて、TLS-RPT(RFC 8460)のレコードを公開しておくと、対応している送信側から TLS の失敗についての集計レポートを受け取れます。

_smtp._tls.example.com. 3600 IN TXT "v=TLSRPTv1; rua=mailto:tlsrpt@example.com"

手順5:TLSA と証明書のずれを毎日見張る

DANE の運用で最も多い失敗は、証明書の更新で鍵が変わったのに TLSA を直していない状態です。送信側はメールを保留し、数日後にエラーとして差出人に戻すため、気づいたときには多くのメールが遅れていることがあります。cron などで毎日、証明書と DNS を比べる小さなスクリプトを動かしておくと早く気づけます。

#!/bin/sh
# TLSA と実際の証明書の公開鍵ハッシュが一致するかを確かめる
host=mx1.example.com
cert=/etc/letsencrypt/live/$host/cert.pem
want=$(openssl x509 -in "$cert" -noout -pubkey | openssl pkey -pubin -outform DER \
  | openssl dgst -sha256 -hex | awk '{print $NF}')
dig +short "_25._tcp.$host" TLSA | tr -d ' ' | tr 'A-F' 'a-f' | grep -q "^311$want\$" \
  || echo "TLSA mismatch: $host"

一致しなかったときだけ出力されるので、cron の出力をメールで受け取る設定と組み合わせられます。

鍵を入れ替えるときは、次の鍵の TLSA がすでに公開され、TTL の2倍以上の時間が過ぎていることを確かめてから、Postfix の証明書を差し替えます。差し替えて問題がないと確かめたら、古い鍵の TLSA を消し、その次の鍵の TLSA を追加します。作業前には Postfix の設定とゾーンのバックアップを取ってください。

送信側でも DANE を使う場合

自分のサーバーから送るメールでも相手の TLSA を検証したい場合は、Postfix の smtp_dns_support_level = dnssec と smtp_tls_security_level = dane を設定し、同じサーバー上に DNSSEC を検証するリゾルバを置きます。受信側の TLSA 公開とは別の作業で、リゾルバの設定や AD フラグの扱いを含めて準備が必要になるため、受信側が安定してから取りかかるのが無理のない順番です。

まとめ

  • DANE は、DNSSEC で署名した TLSA で受信サーバーの証明書を指定し、STARTTLS の格下げや偽の証明書を防ぐ
  • 前提は MX ホストのゾーンの DNSSEC 署名と、自分で運用している MX ホスト
  • TLSA は 3 1 1 を使い、証明書の更新で鍵が変わらないよう certbot などを設定する
  • いまの鍵と次の鍵の2件を公開しておき、入れ替えは TLSA を先に、証明書を後に行う
  • posttls-finger や外部の診断で確かめ、TLSA と証明書のずれを毎日見張る

お気軽にご相談ください

お見積りへ お問い合わせへ
▲