前回は各サーバに散らばっていたメールを dhcp さんに集約するところまで行いました。今回は、ネットワーク上を流れるメールを暗号化して盗聴からデータを守ります。メールサービスの証明書の用途は大きく2つあり、データの暗号化とサーバの識別に使用されます。暗号化に関しては証明書を持っているだけで暗号化を行うことができます。対外的なサーバーの識別は正規の認証局から証明書を発行してもらう必要がありますが、組織内や家庭内で使用する分には自作のなんちゃって証明書で十分機能します。そこで自作の認証局を作って、そのなんちゃって認証局を使ってジャンジャンバリバリなんちゃって証明書を発行してメールの暗号化に使用してみましょう。前回に引き続き、メールフローの絵です。
パート1 復習
メールを dhcp さんに集約したので、何度も登場した FreeBSD さんからのメールが dhcp さんでまとめてみることができます。これであちこちに ssh しなくて済みます 🙂
tls encryption / certificate
メールのログを見てみると、いくつかエラーが見て取れます。まず、dh.param ファイルが無いと怒られています。このファイルは Diffie-Helman 鍵交換アルゴリズムで使用される素数が入っているそうです。セキュリティの専門家ではありませんので深入りせずに置きますが、無いと怒られているので、作りましょう。もう一つのエラーはサーバーの識別ができなかったと怒られています。
メールの証明書関係が保存されるディレクトリは /etc/mail/certs で、証明書はこのディレクトリに OS が一番最初の起動された時に作られます。そのスクリプトが /etc/rc.d/sendmail ファイルです。このファイルを見てみると、/etc/mail/certs 内にあるべきファイルが見つからないと、openssl.cnf ファイルを仮のディレクトリに作って、openssl コマンドでなんちゃって認証局を作ってからそれらのファイルを作って、必要なものだけ取り出して仮のディレクトリごと削除するということをしています。このスクリプトをちょっと改造して仮のディレクトリを削除しないようにして /etc/mail/certs ディレクトリを削除して OS を再起動するか、/etc/rc.d/sendmail を実行することで、仮のディレクトリの中身を見ることができます。その中の openssl.cnf ファイルを拝借して作業を行いましょう。
仮のディレクトリは mktemp コマンドでディレクトリ名を決めているので、/tmp ディレクトリに tmp.xxxxx というディレクトリができます。xxxxx の部分はサーバ毎に、あるいは mktemp コマンド実行毎に異なりますので、改造したスクリプトを実行するまでわかりません。が、起動直後なので1つしかないと思います。
これで openssl.cnf ファイルは入手できました。次は各サーバー共通のなんちゃって認証局を作る準備を行います。ディレクトリはどこでも構わないのですが、メール関係なので /etc/mail/CA を使用したいと思います。ディレクトリ構造はこのようにします。
このディレクトリにファイルを3つ作ります。
- serial: 証明書のシリアル番号が記憶されます。初期値は 01 を入れておきます。
- index.txt: 証明書の内容が記録されます。初期値は空で OK です。
- openssl.cnf: 改造版 /etc/rc.d/sendmail ファイルを実行して得られた仮のディレクトリからコピーします。どの FreeBSD で作っても全く同じ内容で、異なるのはマシン名を指定する CN の部分だけです。
では、これらのファイルを使用してなんちゃって認証局を作ります。このコマンドラインも /etc/rc.d/sendmail ファイルから作ることができます。このコマンドは一瞬で終了します。
続いて、krb5 さんで使用する証明書を作成します。これも一瞬で終了します。openssl.cnf ファイルの CN に krb5.home.jf3vqb.net と指定されているので、krb5 さん用となります。
続いて今作った証明書を先ほど作成したなんちゃって認証局で署名します。これには認証局作成時に登録したパスワードの入力が求められます。
パスワードが通れば、このデータで作成するよと確認を求められます。問題なければ ‘y’ を入力して続きを行います。ご覧のように国記号が XX であったり、組織名が Some-org であったりと本当にナンチャッテ認証局なので、もう少しまともな値を openssl.cnf に書き直してもよいかもしれません。
これで、証明書に署名したことが記録に残ります。次の署名のためにシリアル番号は 02 に、index.txt に署名した証明書の内容が記録されます。もし同じ証明書を作ろうとすると、重複していると怒られます。
/etc/mail/certs
今出来立ての host.key と host.cert、そして認証局の root 証明書の cacert.pem を /etc/mail/certs にコピーします。そして、root 証明書のハッシュ値をファイル名に持ったシンボリックリンクを作成します。そして、古いリンクファイルを消しておきます。
続いて、ファイルのパーミッションを確認します。host.key ファイルはプライベートキーが格納されるので、root 以外は読めないようにしておきます。最後に host.key を編集します。
このファイルにはプライベートキーの他に証明書も入っています。
証明書の部分は不要なので、証明書の部分を削除しておきます。
間違いがなければ保存します。
/etc/mail/certs ディレクトリの中身はこのような感じになります。
続いてなんちゃって認証局で dhcp さんの証明書を作成して署名します。
openssl.cnf ファイルを編集して CN を書き換えます。
krb5 さんと同様に証明書を作成して、なんちゃって認証局で署名します。
CN が正しいことを確認して、’y’ で継続します。
一時的に使用した tmp.pem は不要なので消しておきます。
今回はリモートホストの証明書なので、安全な方法で移動させます。
リモート側で sftp でコピーします。伝送路が暗号化されていることが重要です。
ここからの手順は krb5 さんと全く同じです。
最後に dh.param ファイルを作成します。素数を見つけるために大量の計算を行いますので、時間がかかります。比較的新しい windows PC で動いている krb5 さんで2,3分かかったと思います。32ビットマシンの dhcp さんでは数時間かかりました 🙂
最終的に /etc/mail/certs ディレクトリはこんな感じになります。
最後に sendmail を再起動して完了です。ログにエラーが無いことを確認します。
お試して krb5 で root 宛にメールを送ってみます。前回の設定で、dhcp さんの pokemon 宛に届くはずです。
verify=OK
ログを見てみると、前回は verify=FAIL であったものが OK に変わっています。なんちゃって証明書でお互いの識別を確認できたことになります。
これで、dhcp さんと krb5 さんの証明書が同じ認証局で署名されたことになります。同じことを他の pokemon さんや package さんなどにも行って自己証明書による暗号化と認証ができるようになりました。
では、本当の証明書を購入した場合はどうするでしょう? インストールしたパッケージを確認してみてください。ca_root_nss というパッケージが入っていますでしょうか?有名どころの root 証明書が入っていますので、これを cacert.pem の代わりに使用します。
証明書のファイルには今の段階で 143 の正規の認証局が登録されています。cacert.pem ファイルをこの証明書ファイルへのシンボリックリンクにして、ハッシュ値を計算しなおしたファイル名を作れば OK です。
最後に /etc/mail/CA ディレクトリにはあまり公にしないほうがよいファイルばかりが置かれています。誰もアクセスできないようにしておきましょう。
因みにこのメールサーバはとりあえず送受信できるように完成させますが、あくまで実験システムですので、証明書関係は完成後破棄されます。次回はメールに DKIM による署名を付けてみます。
以下広告
コメント