Gmailにセキュアなメールサーバと認識されるために必要な設定
以前の投稿で紹介しましたが、当ブログも利用しているGMO系列のWebサーバでGmailへのメール送信ができなくなるという障害が発生しました。(現在は復旧済み)
今回の原因はGMOのサーバ利用者がスパムメールを大量に送信したため、GMOに割り振られたIPが範囲ごとブロックされるというものでした。
GMO VPSには障害情報を通知する仕組みがありません。そのため一利用者の私としては原因探しに奔走することになりました。
その奔走の中で「Gmail でメールがブロックされる理由」というページを発見しました。
今回の件とは関係がなかったものの、メールサーバのセキュリティを向上させるには大切な内容だったので、皆様と共有したいと思います。
目次
- GoogleのPostmaster Toolsを利用する
- SPF(Sender Policy Framework)を利用する
- DKIM(Domainkeys Identified Mail)を利用する
- DKIMとpostfixとの連携
- DMARC (Domain-based Message Authentication, Reporting, and Conformance)を利用する
- Let’s Encryptを利用してオレオレ証明書からの脱却
- cronで証明書の自動更新とサービスの再起動を設定
GoogleのPostmaster Toolsを利用する
上で紹介した「Gmail でメールがブロックされる理由」というページでも触れられていますが、Gmailには「Postmaster Tools」というツールが存在します。
Postmaster Toolsとは大量のメールを送受信するユーザーが利用するメール版のAnalyticsのようなサービスです。
具体的には以下の項目を調べることができます。
- ●迷惑メール率
- ●IPレピュテーション
- ●ドメインレピュテーション
- ●フィードバックループ
- ●認証
- ●暗号化
- ●配信エラー
これらの指標を利用して迷惑メールに登録された原因や問題点を洗い出すのに利用します。
設定するにはまずはPostmaster Toolsにアクセスします。
するとスタートガイドが始まるので手順通りに進めます。
メールの認証に使用するドメインの入力
まずは「メールの認証に使用するドメイン」を入力します。いわゆるGmailへ接続するメールサーバのドメイン(例えばexample.com)です。入力したら「次へ」をクリック。
DNSへのTXTレコードの追加
続いてドメインの確認の為のTXTレコードをコピーして、DNSへ追加します。
BINDを利用したDNSの設定については詳しくは以前の投稿を見てもらうとして、私の場合は以下のように設定しました。
example.comは環境に合わせて適宜読み替えてください。
# vi /var/named/example.com.hosts
$ttl 38400 example.com. IN SOA ns.example.com. info.example.com. ( 1347519085 ; シリアル番号 10800 ; リフレッシュ間隔 3600 ; リトライ間隔 604800 ; ゾーンの有効期 38400 ) ; ネガティブキャッシュ有効期間 example.com. IN NS ns.example.com. ; このゾーンのプライマリマスタ example.com. IN NS ns3.maihama-net.com. ; マイハマnetのセカンダリマスタ example.com. IN MX 10 mail.example.com. ; メール用 example.com. IN TXT "google-site-verification=E16-8F4wgoV1575-b6CU1556515693uHsTIoU2fdbmy6M" ; メールの認証 (省略)
最終行のTXTレコードが認証用のコードです。ダブルコーテーションで囲むのを忘れないようにしてください。
設定ができたらシリアル番号を一つ進めて念のためにBINDを再起動します。
# /etc/init.d/named restart
あとは内容が伝播するのを待ちます。(伝播って言うな問題はry)
すぐに確認ボタンをクリックしても、以下のような表示になると思います。
確認が取れると、以下のように表示されます。
これで一応Postmaster Toolsの下準備が完了しました。
なぜ下準備かと言うと、これから下記で解説するSPFやDKIMといった認証技術を導入しないと正確にカウントされないためです。
また、Postmaster Toolsは大量にメールを送受信するサーバで有効なサービスです。月に数十通程度では統計は表示されません。そのため、一般のメールサーバではドメインの正当性と、正しい認証技術を利用していることをGoogleへ通知するのが目的です。いわゆるGoogleへの点数稼ぎです。
SPF(Sender Policy Framework)を利用する
Sender Policy Framework(センダー・ポリシー・フレームワーク)とはメールを送信するIPを限定する認証方法です。
DNSのTXTレコードへメール送信者のIPを記述することで設定します。受信側はDNSへ記述されたIPと実際にメールを送信してきた相手のIPを照合することで、なりすましを防ぎます。
更に詳しい仕組みを知りたい方は「なりすましメール撲滅に向けたSPF(Sender Policy Framework)導入の手引き:IPA 独立行政法人 情報処理推進機構」をご覧ください。
考えてみればSPF認証のないメールは手紙の差出人を無条件で本人と認定しているようなものです。物騒な世の中で、これはいただけません。
余談ですがSPFを提唱したSender Policy Frameworkの公式Webページは資金不足で閉鎖しています。なんとも世知辛い話ですね。
では設定を行います。
仕組みが簡単なら、設定も簡単です。先程GoogleのPostmaster Toolsを設定したときと同じようにDNSへSPF用のTXTレコードを追加するだけです。
私はわかりやすいようにPostmaster Tools用のコードの次の行に追加しました。
oxynotes.com. IN TXT "google-site-verification=E16-8F4wgoVuvLh-b6CUks6515061auHsTIoU2fdbmy6M" ; メールの認証 oxynotes.com. IN TXT "v=spf1 +ip4:153.122.40.105 -all" ; SPFレコード
特に解説する要素もないですが、v=spf1はSPFのVersion 1という意味のようです。
「+ip4:153.122.40.105」の部分にメールサーバのIPを記述します。この例ではIPが一つだけですが、複数のIPがある場合はスペース区切りで「+ip4:153.122.40.105 +ip4:153.122.40.106」といった具合に追記します。
最後の「-all」は全てのメールで指定したIPを利用するということのようです。
通常であれば定型文のようにallを追記しますが、リダイレクトする場合などは記述しないようです。
例えばhoge.example.comのメールはexample.comで送受信を行うといった場合は以下のように記述します。
hoge.example.com. TXT "v=spf1 redirect=_spf.example.com" _spf.example.com. TXT "v=spf1 mx:example.com -all"
その他にもたくさんの応用例があるので、複雑なメールサーバを運用している方は公式のドキュメントをご覧ください。
正しく設定できたかどうかはSUPERTOOL!というサイトで確認することができます。
ドメインを入力して、プルダウンメニューから「SPF Record Lookup」を選択して実行してください。
正しく設定できていれば以下のような表示になります。(この画像の場合は複数のIPを指定した例です)
DKIM(Domainkeys Identified Mail)を利用する
続いてDomainkeys Identified Mail(ドメインキー・アイデンティファイド・メール)という認証技術を導入します。
簡単に言えば電子署名を利用して送信ドメインを認証する技術です。
具体的にはメールの送信元が電子署名で暗号化を行い、DNSへ公開鍵の情報を公開します。受信側はDNSに記述された公開鍵情報を元に検証し、暗号化されたメールの復号化を行います。つまりメール版の公開鍵認証です。
仕組みがわかったところで、早速設定してみます。
DKIMに利用する秘密鍵と公開鍵を作成するにはOpenDKIMを利用します。
EPELリポジトリを利用してインストールしてください。
# yum install opendkim --enablerepo=epel (省略) Dependencies Resolved ================================================================================ Package Arch Version Repository Size ================================================================================ Installing: opendkim x86_64 2.11.0-0.1.el6 epel 215 k Installing for dependencies: libbsd x86_64 0.8.3-2.el6 epel 83 k libopendkim x86_64 2.11.0-0.1.el6 epel 71 k opendbx x86_64 1.4.6-6.el6 epel 45 k sendmail-milter x86_64 8.14.4-9.el6_8.1 base 57 k Transaction Summary ================================================================================ Install 5 Package(s) Total download size: 472 k Installed size: 1.1 M Is this ok [y/N]: y ←YESの「y」と入力してエンター
OpenDKIMの使い方は「OpenDKIM – ArchWiki」で詳しく解説されています。
今回はマルチドメイン(同一サーバで複数のサイトを運営)の場合を想定して解説を進めます。
まずは鍵を保存するディレクトリを作成します。マルチドメインということで「/etc/opendkim/keys/」の中にドメイン名のサブディレクトリを作成し、その中にそれぞれのサイト用の鍵を生成します。
# mkdir /etc/opendkim/keys/example.com
続いてopendkim-genkeyで鍵を作成します。
# opendkim-genkey --directory=/etc/opendkim/keys/example.com --domain=example.com --bits=2048 --selector=example
それぞれのオプションの意味は以下のようになります。
--directory | 鍵を作成するディレクトリの指定 |
---|---|
--domain | 作成するドメインの指定 |
--bits=2048 | 鍵長 |
--selector | 鍵の参照に利用するセレクタ(後にDNSに記述する) |
他のドメインがある場合は、それぞれディレクトリを作成し、対応する鍵を作成してください。
鍵ができたらディレクトリの所有権を変更しておきます。
# chown -R opendkim:opendkim /etc/opendkim/*
DNSへADSPレコードの追加
DNSへ公開鍵の設定をする前にADSPレコードを追加します。
ADSPレコードとは公開鍵認証をした結果、どのようにメールを扱うかを指定するものです。
# vi /var/named/example.com.hosts
_adsp._domainkey.example.com. IN TXT "dkim=unknown"
私の場合は上で設定したSPFレコードの直下に追記しました。
追記が完了したらシリアル番号を進めて保存します。
ADSPレコード値の意味は以下のとおりです。
dkim=unknown | DKIM署名していないメールも送信している |
---|---|
dkim=all | 送信するメールはすべてDKIM署名している |
dkim=discardable | DKIM署名されていないメールまたは不正な内容のDKIM署名がされているメールが届いた場合は、すべて破棄してよい。 |
普通に考えれば「all」が一番セキュリティ上安全ですが、配送経路で再署名された際などに厳格すぎると弾かれる可能性があります。今回の目的はセキュリティに配慮してメールを正しく届けることなので「unknown」にします。
ドメインキーが正しく設定できているかどうかは以下のコマンドで確認できます。
$ host -t txt _adsp._domainkey.example.com
_adsp._domainkey.example.com descriptive text "dkim=unknown"
上記のように出力されれば正しく設定できています。
DNSへ公開鍵の追加
それではOpenDKIMで作成した公開鍵をDNSへ記述します。
とりあえず作成された公開鍵を開きます。
# vi /etc/opendkim/keys/example.com/example.txt
すると以下のような形式になっています。
example._domainkey IN TXT ( "v=DKIM1; k=rsa; " "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmySj0PzDNa4TpTOCfcmXk67QfjqO+7e8Z1bd9MgZeWUwdLPBICQbdzwxg921QmFx9I3eCmY1T7iYZHDU/q6F4shSwJkowHbQowVtgXyjlIHW7YUxqcVFaMavcMjilOgItRuyuWVNa/c4KuzLaoKWe0+sRJYwzdq2hnz0bAnlbzF70odk1scu561513O44ESigr0Ddzp1ss7rHu5" "yPqDkXD4UFTz/CcSqjK50le/c+/zkoDiiy3CkYfKODql556527Zo/xvoKr26E+XmpMoExypNq07rVL6/87qrLMgCd82IAszadHo+6iHSnysKefRg/TATbQV8/hMbG5064wtrwQIDAQAB" ) ; ----- DKIM key example for example.com
まずTXTレコード全体が()で囲まれています。これはDNSの書式で、()内を一行とみなしています。
なぜ()で囲んで改行されているかというと、DNSのTXTレコードは一行の文字数が256文字で制限されているためです。
つまり、長い鍵長の場合はTXTレコードへコピペしやすいように分割してくれているというわけです。
ただし注意点として、INやTXT等はあくまでサンプルで、区切り文字などは既存の書式に合わせる必要があります。
私の場合はspfレコード直下に以下のように追記しました。
example._domainkey.example.com. IN TXT ( "v=DKIM1; k=rsa; " "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmySj0PzDNa4TpTOCfcmXk67QfjqO+7e8Z1bd9MgZeWUwdLPBICQbdzwxg921QmFx9I3eCmY1T7iYZHDU/q6F4shSwJkowHbQowVtgXyjlIHW7YUxqcVFaMavcMjilOgItRuyuWVNa/c4KuzLaoKWe0+sRJYwzdq2hnz0bAnlbzF70odk1scuSWmlcO44ESigr0Ddzp1ss7rHu5" "yPqDkXD4UFTz/CcSqjK50le/c+/zkoDiiy3CkYfKODqli0j527Zo/xvoKr26E+XmpMoExypNq07rVL6/87qrLMgCd82IAszadHo+6iHSnysKefRg/TATbQV8/hMbG7E9xlfwtrwQIDAQAB" ) ; ----- DKIM key example for example.com
シリアル番号を進めて保存します。
必要なら他のドメイン分も同じように追加してください。
設定が完了したら念の為BINDを再起動します。
# /etc/init.d/named restart
では正しく設定できているか調べます。
$ dig txt example._domainkey.example.com
; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.62.rc1.el6_9.2 <<>> txt example._domainkey.example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 13876
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;example._domainkey.example.com. IN TXT
;; ANSWER SECTION:
oxynotes._domainkey.example.com. 38400 IN TXT "v=DKIM1\; k=rsa\; " "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmySj0PzDNa4TpTOCfcmXk67QfjqO+7e8Z680465654BICQbdzwxg921QmFx9I3eCmY1T7iYZHDU/q6F4shSwJkowHbQowVtgXyjlIHW7YUxqcVFaMavcMjilOgItRuyuWVNa/c4KuzLaoKWe0+sRJYwzdq2hnz0bAnlbzF70odk150646532ESigr0Ddzp1ss7rHu5" "yPqDkXD4UFTz/CcSqjK50le/c+/zkoDiiy3CkYfKODqli0j527Zo/xvoKr26E+XmpMoExypNq07rVL6/87qrLMgCd451656565+6iHSnysKefRg/TATbQV8/hMbG7E9xlfwtrwQIDAQAB"
;; Query time: 106 msec
;; SERVER: 180.222.191.15#53(180.222.191.15)
;; WHEN: Sun May 5 20:46:11 2019
;; MSG SIZE rcvd: 475
このように表示されれば、正しく設定できています。
SPFの時に利用したSUPERTOOL!でも調べることができます。
今度は「DKIM Lookup」を選んで実行してください。(実際に送信するメールが暗号化されるのは下記の設定を完了してからです)
それぞれ「v, k, p」の値が正しく連動していることを確認してください。
OpenDKIMのKeyTableを更新
OpenDKIMのKeyTableを更新します。
KeyTableとは鍵とドメインを関連付ける設定ファイルです。
KeyTableは以下の書式で行います。
DKIMレコード名 ドメイン名:セレクタ名:秘密鍵ファイル
では早速編集をします。
# vi /etc/opendkim/KeyTable
# OPENDKIM KEY TABLE # To use this file, uncomment the #KeyTable option in /etc/opendkim.conf, # then uncomment the following line and replace example.com with your domain # name, then restart OpenDKIM. Additional keys may be added on separate lines. #default._domainkey.example.com example.com:default:/etc/opendkim/keys/default.private example._domainkey.example.com example.com:example:/etc/opendkim/keys/example.com/example.private
複数のドメインがある場合は改行して複数記述してください。
コメントにありますが「/etc/opendkim.conf」の「KeyTable」を有効にする必要があります。
「/etc/opendkim.conf」の以下の項目が対応しています。(設定は後ほど行います)
KeyTable refile:/etc/opendkim/KeyTable
OpenDKIMのSigningTable更新
つづいてSigningTableを更新します。SigningTableとは許可するユーザーをドメインごとに関連付けるファイルです。
書式は以下の通り。
対象のメールアカウント DKIMレコード名
ユーザーを追加するごとにユーザー名を指定するのは面倒という場合はワイルドカードが使用可能です。
ただし、ワイルドカードで全てのユーザーを許可してしまうと、SigningTableの意味が無くなってしまいます。ユーザーが決まっているなら限定したほうがセキュリティは高まります。
最後の行に以下のように追記します。
*@example.com example._domainkey.example.com
複数ユーザーを追加する場合や、複数ドメインがある場合は、複数行で追記してください。
「/etc/opendkim.conf」の以下の項目が対応しています。
SigningTable refile:/etc/opendkim/SigningTable
OpenDKIMのTrustedHosts設定
TrustedHostsで信頼できるホストを設定します。
ここに追加したホストの場合に署名を行います。
# vi /etc/opendkim/TrustedHosts
デフォルトで追加されている以下のものは必須と言えます。(自分のサーバー内のため)
127.0.0.1 ::1
これ以外に追記するとなると、中継サーバを利用している場合などです。同一サーバ内でメールサーバが完結している場合は特に追記する必要はありません。
ちなみにCIDRやホスト名の追加にも対応しています。
「/etc/opendkim.conf」の以下の項目が対応しています。
ExternalIgnoreList refile:/etc/opendkim/TrustedHosts
opendkim.confの設定
いよいよOpenDKIM本体の設定ファイルです。
公式の解説があるので詳しくはそちらをご覧ください。
一応バックアップを取ります。
# cp /etc/opendkim.conf /etc/opendkim.conf.org # vi /etc/opendkim.conf
以下のサイトに設定例が書いてありますが、今回はマルチドメインを想定しているので設定方法が異なります。
OpenDKIM - ArchWik
具体的にはDomainはSigningTableを利用する場合は無視されます。KeyFileもKeyTableが有効な場合は無視される、といった具合です。
基本的には無視されるオプションを変更する意味はないですが、マルチドメインであることをわかりやすくするために、シングルドメイン用の設定をあえてコメントアウトします。
KeyFile /etc/opendkim/keys/default.private ↓ # KeyFile /etc/opendkim/keys/default.private Selector default ↓ # Selector default
ちなみにDomainはデフォルトではコメントアウトされています。
そしてマルチドメイン用の設定をします。
# KeyFile /etc/opendkim/keys/default.private ↓ KeyTable /etc/opendkim/KeyTable # SigningTable refile:/etc/opendkim/SigningTable ↓ SigningTable /etc/opendkim/SigningTable # ExternalIgnoreList refile:/etc/opendkim/TrustedHosts ↓ ExternalIgnoreList /etc/opendkim/TrustedHosts # InternalHosts refile:/etc/opendkim/TrustedHosts ↓ InternalHosts /etc/opendkim/TrustedHosts
「refile:」という記述ですが、解説によってはそのまま記述していますが、私の環境では以下のエラーが出て使えませんでした。公式の解説によると「refile:」は正規表現を利用した指定方法とのこと。
以下はデフォルトで設定されいますが、大切な項目なので一応確認しておいてください。
Socket inet:8891@localhost UserID opendkim
これでopendkimの設定は完了です。
早速起動してみます。
# /etc/init.d/opendkim start
opendkimの自動起動を確認、自動起動を有効にする。
# chkconfig --list opendkim # chkconfig opendkim on
DKIMとpostfixとの連携
OpenDKIMの設定が完了したのでpostfixと連携します。
メールフィルターでOpenDKIMのソケットを経由するように設定します。
具体的にはUnixソケットをlistenします。
# vi /etc/postfix/main.cf
記述する場所はどこでもいいですが、ファイルの最後に追記しました。
# OpenDKIM用 smtpd_milters = unix:/run/opendkim/opendkim.sock non_smtpd_milters = unix:/run/opendkim/opendkim.sock smtpd_milters = inet:localhost:8891 non_smtpd_milters = inet:localhost:8891
これでメールはOpenDKIMのソケットを経由するようになります。
設定が完了したらpostfixを再起動します。
# /etc/init.d/postfix restart
以上でDKIMの設定が完了しました。
試しにGmailのアカウントにメールを送信したところ、ヘッダーの情報に以下のように記述されていました。
DKIM-Filter: OpenDKIM Filter v2.11.0 mail.example.com 6AB4AAAD7D9
OpenDKIMが有効になっています。
DMARC (Domain-based Message Authentication, Reporting, and Conformance)を利用する
DMARCとはDomain-based Message Authentication, Reporting, and Conformanceの略です。なんのことやらわかりませんねw
簡単に言えば上で設定したSPFとDKIMを組み合わせて補強した技術です。具体的にはSPFとDKIMで認証が失敗した際の扱いを決めたり、認証の成否をレポートメールで受け取ることが可能になります。レポートを見ればメールの利用状況を簡単に把握することができます。
Gmailが導入を推奨している技術です。
Googleの以下のページで丁寧にまとまっています。
DMARC について - G Suite 管理者 ヘルプ
DMARC を有効にする - G Suite 管理者 ヘルプ
では実際に設定をしていきます。
DMARCもDNSへ記述することで設定を行います。
Googleの解説を拝借すると以下のようになります。
DMARC TXT レコード
v=DMARC1(必須)
プロトコルのバージョン
p=reject(必須)
ドメインでの不審なメールの処理方法
none | メールに対して何もせずに、日次レポートに不審なメールを記録する。 |
---|---|
quarantine | 迷惑メールに分類して保持し、処理する。 |
reject | 受信者に送信されないようにメールをキャンセルする。 |
pct=20
DMARC ポリシーを適用する不審なメールの割合を設定します。不審なメールとは、DMARC 認証が通らなかったメールのことです。デフォルト値は100です。
rua=mailto:aggrep@example.com
集計レポートの報告先 URI(Uniform Resource Identifier)。ドメインの DMARC アクティビティに関するレポートを受け取るには、このオプションを使用して独自のメールアドレスを指定します。
sp=reject
メインドメインのサブドメインからのメールに関するポリシーを設定します。サブドメインに別の DMARC ポリシーを適用する場合はこのオプションを使用します。使用できる値は p タグと同じです。
aspf=r
SPF(ASPF)の調整モードを設定して、メールの情報が SPF 署名とどの程度一致する必要があるかを定義します。デフォルトは relaxed です。
r | relaxed は部分一致(ドメイン内のサブドメインなど)を許可します。 |
---|---|
s | strict の場合は完全に一致する必要があります。 |
reject | 受信者に送信されないようにメールをキャンセルする。 |
では実際に設定します。
私の場合はDKIMの設定の直下に追加しました。
# vi /var/named/example.com.hosts
_dmarc.example.com. IN TXT "v=DMARC1; p=quarantine; pct=100; rua=mailto:info@example"
シリアル番号を進めて再起動します。
# /etc/init.d/named restart
チェックします。
$ dig txt _dmarc.example.com
以下のように応答があれば正しく設定できています。
;; ANSWER SECTION: _dmarc.example.com. 38400 IN TXT "v=DMARC1\; p=quarantine\; pct=100\; rua=mailto:info@example.com"
DMARCのレポートは送信したドメインごとにzip形式で送られてきます。
以下のものはGmailのレポート例です。
<?xml version="1.0" encoding="UTF-8" ?> <feedback> <report_metadata> <org_name>google.com</org_name> <email>noreply-dmarc-support@google.com</email> <extra_contact_info>https://support.google.com/a/answer/2466580</extra_contact_info> <report_id>12647404983077268418</report_id> <date_range> <begin>1557014400</begin> <end>1557100799</end> </date_range> </report_metadata> <policy_published> <domain>oxynotes.com</domain> <adkim>r</adkim> <aspf>r</aspf> <p>quarantine</p> <sp>quarantine</sp> <pct>100</pct> </policy_published> <record> <row> <source_ip>153.122.40.105</source_ip> <count>4</count> <policy_evaluated> <disposition>none</disposition> <dkim>pass</dkim> <spf>pass</spf> </policy_evaluated> </row> <identifiers> <header_from>oxynotes.com</header_from> </identifiers> <auth_results> <dkim> <domain>oxynotes.com</domain> <result>pass</result> <selector>oxynotes</selector> </dkim> <dkim> <domain>oxynotes.com</domain> <result>pass</result> <selector>oxynotes</selector> </dkim> <spf> <domain>oxynotes.com</domain> <result>pass</result> </spf> </auth_results> </record> </feedback>
auth_resultsのdkimとspfの項目がpassとなっています。失敗した場合はfailと表示されます。
今回はレポートを受け取る側ですが、自分のメールサーバがメールを受信した際に送信サーバへレポートを送ることもできます。それをサポートしているのがOpenDMARCというパッケージです。送信時には関係ないのでこのページでは解説しませんが、設定する場合は以下のページを参照してください。
Let's Encryptを利用してオレオレ証明書からの脱却
以前投稿したメールサーバを構築する方法でオレオレ証明書を利用したSSL通信の方法を解説しました。
しかし今やLet’s Encryptを利用すれば、無料でSSL証明書を利用できます。独自で有料のSSL証明書を用意できないのであれば、利用しない理由はありません。
Let’s Encryptについては過去の投稿で詳しくまとめたのでそちらをご覧ください。
では早速設定を開始します。
# ./certbot-auto certonly --webroot -w /var/www/html/example -d mail.example.com -m info@example.com --agree-tos -n
webサーバも運用している設定で「--webroot -w /var/www/html/example」とweb用の公開フォルダのルートディレクトリを指定。
「-d」でドメインの指定。
「-m」でトラブル時の通知用アドレスを指定。
「--agree-tos -n」で証明書の利用規約への署名を省略。
これでmail.example.comに接続し、確認用のファイルを作成し、外部から確認が取れればめでたく証明書の発行となるわけです。
ちなみに、このオプションを利用するにはポート80とポート443が空いている必要があります。また、nginxでリバースプロキシを設定している場合はそちらも忘れずに設定してください。
# vi /etc/nginx/nginx.conf
SSL用の設定
listen 443 ssl; server_name example.net mail.example.com;
リバースプロキシ用の設定
listen 8080; server_name example.net mail.example.com;
リダイレクト用の設定
listen 80; server_name example.net mail.example.com;
# /etc/init.d/nginx restart
この例はあくまでサンプルです。port 443しか利用してなければ、そのserver_nameだけでも構いません。
その他にもよくある失敗例がiptablesによるパケットフィルタリングです。普通にWebサーバとして運用しているならポートは空いていると思いますが、失敗する場合は再度設定を見直してください。
どうしてもうまくいかない場合は以下のように検証時に作られるディレクトリにファイルを作成して外部からアクセスできるか調べてみてください。
# vi /var/www/html/example/.well-known/acme-challenge/index.html
ファイルへは「Let's Encrypt Test」とでも入力してアクセスしてみてください。
postfixの設定
作成した鍵をpostfixに設定します。
# vi /etc/postfix/main.cf
smtpd_tls_cert_file = /etc/pki/postfix/postfix.pem smtpd_tls_key_file = /etc/pki/postfix/postfix_noenc.key ↓ smtpd_tls_cert_file = /etc/letsencrypt/live/mail.example.com/fullchain.pem smtpd_tls_key_file = /etc/letsencrypt/live/mail.example.com/privkey.pem
以下追加
# postfix 2.3移行より必要になった smtp_tls_CAfile = /etc/letsencrypt/live/mail.example.com/fullchain.pem smtp_tls_security_level = may
設定が完了したら再起動して反映させます。
# /etc/init.d/postfix restart
このページではマルチドメイン用の設定を解説していましたがpostfixではsni対応していないので複数証明書を設定する必要はありません。
dovecotの設定
せっかくSSL証明書を取得したので、メールサーバへのログイン時にも利用します。
# vi /etc/dovecot/conf.d/10-ssl.conf
# sukegra用 ssl_cert = </etc/pki/postfix/postfix.pem ssl_key = </etc/pki/postfix/postfix_noenc.key ↓ # sukegra用 ssl_cert = </etc/letsencrypt/live/mail.example.com/fullchain.pem ssl_key = </etc/letsencrypt/live/mail.example.com/privkey.pem
以下は追記。
# POODLE SSL 3.0 脆弱性問題 (CVE-2014-3566) 対策 # https://access.redhat.com/ja/solutions/1379503対策 ssl_protocols = !SSLv2 !SSLv3
設定が完了したらDovecotを再起動します。
# /etc/init.d/dovecot restart
ちなみにCentos6系ではTLS通信サポートしてないっぽいです。
よって以下の設定はコメントアウトしてSSLで通信にしました。
# ssl_protocols = !SSLv2 !SSLv3
以上で無事にLet's Encryptを利用したSSL通信が可能になりました。
cronで証明書の自動更新とサービスの再起動を設定
crontabで自動更新を行います。今回の例ではhttpサーバとメールサーバの両方でLet's Encryptの証明書を利用していることを想定しています。
# vi /etc/crontab
0 5 * * * root /root/certbot-auto renew --post-hook "service nginx restart;service postfix restart;service dovecot restart" >/dev/null 2>&1
毎朝五時頃に実行。出力はいらないよという設定です。
オプションのpost-hookは証明書が更新された際に一度だけ実行されるコマンドを記述します。例のように;で区切れば複数のサービスを再起動することができます。
今回は使いませんが、更新作業の前に実行されるpre-hook、個々の証明書が更新されるごとに実行されるdeploy-hookといったオプションの存在します。証明書の更新日時をフラグに対応するサービスだけを再起動したり、更新された証明書の情報をメールで通知したりといったスクリプトと組み合わせることもできます。
以上でメールサーバのセキュリティを向上させる方法について解説しました。
Gmailが推奨するこれらの認証技術ですが、導入すればメールサーバのセキュリティは確実に向上します。
ただし、導入には一定の知識が必要で、ユーザー管理にも手間がかかります。
GMOのメール障害の例にもあるように、とばっちりでメールが届かなくなることもありえます。
さまざまな状況を考慮すると、セキュリティに配慮したメールサーバを維持することの難しさを感じます。
解説しておいてなんですが、これだけの労力を払うならG Suite等のサービスを利用したほうが現実的です。
ただし、最近あったoffice 365の障害のようなこともあるので、悩ましい限りです。