Pocket

こんにちは。根本です。
今日はメールのセキュリティについて。

みなさんは、メールのセキュリティ被害というと何を思い浮かべるでしょう?

  • 不正利用
  • 盗聴
  • 改ざん
  • なりすまし

などが思い浮かびますか?

一般的にメールはSMTPというプロトコルによって送信します。
このプロトコルは平文で行われる為、悪意のある人が容易に盗聴することが可能です。
また認証もされないため、誰でも利用しメールを送信することが可能です。

不正利用の対応

そこでメールサーバでは、25番ポート(SMTPは25番ポート使って通信します)は自ドメイン向けのメールのみ受信し、それ以外は転送しないようにしたりします。
しかし、それでは自サーバから他のドメインへメールを送信出来なくなるため、
587番(サブミッションポート)をユーザーに提供しています。
サブミッションポートでは、ユーザー認証(SMTP-AUTH)も行うため、そこで不正ユーザーの利用を防ぐこととな ります。

盗聴・改ざんの対応

しかし587番ポートでは通信自体は平文で行われるため、盗聴の危険性が考えられます。
そこでメールサーバによっては、465番(SMTPS)を使うことで認証+暗号化を行い、
クライアントとサーバ間を暗号化する場合もあります。

自身の会社で使っているメールアドレスの送信サーバ等を、
メーラに設定した方ならお分かりになると思いますが、
指定するポートは25番ポートではないと思います。
465番ポートや587番ポートではありませんか?

なりすましは意外に簡単

さて、認証・暗号化をすることは、クライアントのメールサーバ間の話です。

仮にメールサーバ同士の通信にこの手法を使う場合、
ドメインによって、転送するメールサーバごとにポートを変えたり、
認証が必要な場合、世界中のメールサーバがそのメールサーバの認証情報を保持しなくては、
メールを届けることが出来ません。

そのため、メールサーバ間の通信は25番ポートを利用する必要があり、
クライアント以外からのメールを転送する必要があるメールサーバでは、
どうしてもセキュリティの面が弱くなってしまいます。

認証が機能していないメールサーバでは、なにを以って正規のメールなのか?
を判別するのは難しくなります。
このような状態で懸念する必要があるのが「なりすまし」です。

「なりすまし」とは、
AさんがBさんに送るメールを、偽AさんがAさんの振りをしてBさんにメールを送ることです。

「なりすまし」の対策の前に、SMTPの通信手順を見てみましょう。
以下はtelnetで某プロバイダの587番ポートに接続しメール送信した例です。

telnet [メールサーバ] 587
 # 220 [メールサーバ] ESMTP Postfix
ehlo [ドメイン]
 # 250-[メールサーバ]
 # 250-SIZE 10485760
 # 250-AUTH LOGIN PLAIN CRAM-MD5
 # 250 AUTH=LOGIN PLAIN CRAM-MD5
auth login
 # 334 VXNlcm5hbWU6
[ID]
 # 334 UGFzc3dvcmQ6
[Password]
 # 235 Authentication successful
mail from: [送信元]
 # 250 Ok
rcpt to: [宛先]
 # 250 Ok
data
 # 354 End data with .
[mail本文]
.
 # 250 2.0.0 Ok: queued as BD1622042E8
quit
 # 221 Bye

ポイントは [mail本文] の箇所です。

Date: Sat,  2 Nov 2013 09:00:00 +0900 (JST)
From: xxxxx@oioioioio.com
To: ooooo@uiuiuiuiu.com

test-mail

このようなメールでは、このメールがどう送られてくるか?
メーラで開くと
送信元が「xxxxx@oioioioio.com」。
宛先が「ooooo@uiuiuiuiu.com」。
で届きます。
もちろん、届いたメールは rcpt to で指定したアドレスです。

つまり。メーラに表示される内容は、
data コマンドの後のメールヘッダーの内容が表示されているだけなのです。

ということは、ここを偽装すれば他人になりすますことなどは容易。

さて、そのようななりすましメールをメールサーバではどう防ぐのか?
その手法として、SPF認証やDKIM認証を行っているサーバも珍しくはありません。

SPFとは

SPF(Sender Policy Framework)とは、
正しい送信元から送信されたメールかをチェックする仕組みです。

具体的には、
受信したメールサーバは、受信したメールのFromヘッダーのドメインをDNSに問合せます。
SPFレコードが登録されていると、DNSはそのSPFレコードを返します。
SPFレコードには、そのドメインが送信されるべきサーバのIPアドレス等が記載されており、
そのレコードを受け取ったメールサーバは、
その送信元が正しいサーバであるかを確認します。

DKIMとは

DKIM(DomainKeys Identified Mail)とは、
SPFと同様に、正しい送信元から送信されたメールかをチェックする以外に、
改ざんされたメールかどうかについてもチェックする仕組みです。

具体的には、
受信したメールサーバは、送られてきたメールのDKIM-Signatureヘッダーから、DNSに公開鍵を問合せます。
次に受信したメールからハッシュを生成し、電子署名を作成。
DNSから取得した公開鍵で、電子署名からハッシュを取得。
そのハッシュと、受信したメールから生成したハッシュを比較し、認証する仕組みです。
その為、SPFのSPFレコードの様に、DKIMでもDNSサーバに公開鍵を登録しておく必要があります。

次に、SPF認証およびDKIM認証にいついての設定してみましょう。
Server側(SMTP Server)については、CentOS×Postfixを利用しています。

設定(SPF)

まずは、SPF認証を送信側が利用する場合の設定です。

  1. DNSにSPFレコードを登録

ここでは設定の詳細内容について触れませんが、

v=spf1 +mx -all

このようなSPFレコードを登録すると、メールサーバ側では、mxレコードのIPアドレスが有効なIPアドレスとな ります。

dig mail.nemoxxxx.com txt
 # ...
     # ;; ANSWER SECTION:
 # mail.nemoxxxx.com.      3600    IN      TXT     "v=spf1 +mx -all"
 # ...

SPF認証で送信した場合には、このようにDNSにSPFレコードを登録するだけです。

設定(DKIM)

次に、DKIM認証で送信したい場合の設定をします。

OpenDKIMのインストール

sudo yum install --enablerepo=epel opendkim

ドメイン用の鍵を生成

# ドメイン毎にディレクトリを作成
sudo mkdir /etc/opendkim/keys/mail.nemoxxxx.com

# 鍵生成
sudo opendkim-genkey -D /etc/opendkim/keys/mail.nemoxxxx.com/ -d mail.nemoxxxx.com -s default

# 確認
sudo ls -l /etc/opendkim/keys/mail.nemoxxxx.com
 # total 8
 # -rw------- 1 root root 891 May 1 13:53 default.private
 # -rw------- 1 root root 321 May 1 13:53 default.txt

# パーミッション変更
sudo chown -R opendkim:opendkim /etc/opendkim/keys

DNSレコードを登録

dig default._domainkey.mail.nemoxxxx.com txt
 # ...
 # ;; ANSWER SECTION:
 # default._domainkey.mail.nemoxxxx.com. 3600 IN TXT "v=DKIM1\; k=rsa\; p=MIGfM...(略)...JQIDAQAB"
 # ...

OpenDKIM設定ファイル編集(/etc/opendkim.conf)

# s = 送信時の署名
# v = 受信時の確認
Mode    sv

# 秘密鍵の場所をコメントアウト
#KeyFile /etc/opendkim/keys/default.private

# TXT フィールドとシグニチャをつけるドメイン、セレクタ、対応する秘密鍵を指定するファイルのパス
KeyTable        refile:/etc/opendkim/KeyTable

# どのメールアドレスに対してはどの TXT フィールドを参照するかを指定するファイルのパス
SigningTable    refile:/etc/opendkim/SigningTable

# DKIM シグニチャをつけるべきメールサーバを設定するファイルのパス
ExternalIgnoreList      refile:/etc/opendkim/TrustedHosts
InternalHosts   refile:/etc/opendkim/TrustedHosts

KeyTableの設定(/etc/opendkim/KeyTable)

default._domainkey.mail.nemoxxxx.com
mail.nemoxxxx.com:default:/etc/opendkim/keys/mail.nemoxxxx.com/default.private

SigningTableの設定(/etc/opendkim/SigningTable)

*@mail.nemoxxxx.com default._domainkey.mail.nemoxxxx.com

OpenDKIMの起動

sudo /etc/init.d/opendkim start
 # Generating default DKIM keys:                              [  OK  ]
 # Default DKIM keys for nemoxxxx.com created in /etc/opendkim/keys.
 # Starting OpenDKIM Milter:                                  [  OK  ]

Postfix設定ファイル(main.cf)の編集

# 設定を追加
smtpd_milters = inet:127.0.0.1:8891

Postfixの再起動

sudo /etc/init.d/postfix restart

DKIM認証の場合は、DNSに公開鍵を登録するのと、
メールを送信する際に、ヘッダーにDKIM-Signatureを付与する必要があるため、このような設定が必要になります。

確認

それでは、
実際にこのサーバで送信したメールを受け取ってみます。
今回はGmailに送信してみました。

結果は以下です。

Received-SPF: pass (google.com: domain of nemoto@mail.nemoxxxx.com designates 49.212.xxx.xxx as permitted sender) client-ip=49.212.xxx.xxx;
Authentication-Results: mx.google.com;
       spf=pass (google.com: domain of nemoto@mail.nemoxxxx.com designates 49.212.xxx.xxx as permitted sender) smtp.mail=nemoto@mail.nemoxxxx.com;
       dkim=pass header.i=@mail.nemoxxxx.com

このように Gmail のメールサーバ側で、送ったメールがSPFとdkimがpassしていることがヘッダーに追加されています。
また、以下のように、

DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mail.nemoxxxx.com;
    s=default; t=1383919154;
    bh=JHJNgFNBisi6qhXiMGkdSSTI1Yajl+VjjlFd06xgsv8=;
    h=Date:From:To:Subject;
    b=I1Tw41wwwX10svpI8gblrtwpyAlDJI2TBKrt+RjMOlpsmCX7FZy1R4ofHD3OA/IVi
     ZSWiUweo3wJVClzeXxN4LZ8iU4x6k7WlgJye/eOMQxHOfU/9RyxXnAt64dTg1he3+A
     Q+Fyd8YxxhtxuBAIYM1bdX61y5O0B7gtFKfli1tw=

DKIM-Signatureヘッダーが送信元サーバで付与されていることがわかります。

最後に

このようにメールサーバ間での「なりすまし」を防ぐことができます。
今はDKIMなどの設定がなくても送信できないことは少ないかもしれませんが、
DKIMは今年、インターネット標準としてIETFに認められています。
今後、さらに普及することで、DKIM認証は常識となることでしょう。
そうなると、DKIM認証できないメールは受け取らないよ。という日が来るかもしれません。
ご自身でメールサーバを管理されている方で、しらんかったーって方は、是非導入を検討してみては?