TOP  >  なーお'nぶろぐ  >  なーお  >  PC,Linux,仮想化  >  [Linux] stone経由でSSL-IPベースVirtualホスト

なーお さんの日記

 
2007
11月 5
(月)
11:00
[Linux] stone経由でSSL-IPベースVirtualホスト
本文

用途

 1つのグローバルIPアドレスと1台のサーバーでApacheの「名前ベースVirtualホスト」で複数ドメインを運営している場合などで、SSLサイトをいくつか稼動させたいと思っても、簡単にはできませんでした。
 なぜなら、この場合のサイト証明書はIPアドレス別かポート別にしか有効に機能しないからで、その理由はHTTPSヘッダーに「どのサイトのサーバー証明書を要求するか」が含まれなかったためです。
 
 ところが、実は2003年に「Transport Layer Security (TLS) Extensions」として、これを拡張する規格が発表されていたのです。。 そしてようやく、FireFox2+、WindowsVista上のIE7やOPERA8+でブラウザ側の対応も徐々に進行している模様。

 で、サーバー側の状況はどうかというと、↓のサイト
名前ベースのVirtualHostでそれぞれのSSLサーバ証明書を使う  で書かれている3つの方法があるらしい。
 その中で一番スマートな、「Server Name Indication (SNI)を使う」方法にチャレンジしてみました。

参考サイト

A: url=http://seclan.dll.jp/dtdiary/2007/dt20071015.htm]OpenSSL 0.9.8f で tls extension の SNI (Server Name Indication、サーバ名指示) 拡張が利用可能に![/url] → 下のstoneのページではOPENSSL-0.9.9以上が必要と書かれていますが、これはまだ公開されていなくて諦めかけていたとき、この0.9.8f以降でOKという情報を知り再開しました。
B: stone に Server Name Indication (TLS 拡張) 機能を実装 → stoneの作者の方の、開発ブログです。全面的に参考になります。
C: simple repeater 'stone'

接続概念図

 stoneは、リバースプロクシとして物理マシン上で動かします。 ADSLモデムルーターのhttpsポートだけを物理マシン向けに変更し、そこで要求先URLに応じてDNSから得たIPアドレスに転送します。
 本当はstoneを使えばIPベースにする必要がないのですが、今回は勉強の意味もありそうしています。

t_00ea44e3ff7b3a2d22f155f290fd23c6da.gif

準備

1、Linuxマシン(自分は仮想マシンだけど)に、仮想NICを追加しておきます。 eth0:1、eth0:2 の2つ。。Webminで安直にやりましたんで、省略。

2、HTTPサーバーの各SSLサイトのディレクティブを、名前ベース→上記で作成したIPベースに変更。
 内部DNSの各SSLサイト用のレコードを上記IPアドレスに変更。

3、使用する各SSLサーバー証明書の作成。
 この辺を参考に→SSLでセキュアなWebサイト - 鍵の作成とサイト証明書 証明書ファイルと暗号化キーファイルを作成します。 今のところ「オレオレ証明書」でアラートが出ますが、指定認証局に認証してもらえば、正式な証明書として使えます。
 そして、/usr/local/ssl/certs/以下に 証明書ファイルを「ドメイン名-cert.pem」 キーファイルを「ドメイン名-key.pem」として保存しておきます。

インストール

1、OPENSSLの最新版をインストール
 (参考サイトA) 「SNI」を使えるOPENSSLライブラリが、OPENSSL-0.9.8f以降にバックポートされて公開されています。 そのインストール時に「enable-tlsext」オプションを指定します。
 また、私の場合(VineLinux-4.1)0.9.7-0vl2がインストールされていましたが、これはそのまま残しておいて別にインストールします。

1
2
3
4
5
6
7
8
(usr/src/)
# wget ftp://ftp.openssl.org/source/openssl-0.9.8g.tar.gz
# tar -xvzf openssl-0.9.8g.tar.gz
# cd openssl-0.9.8g
# ./config enable-tlsext
# make depend ##←ライブラリファイルの更新
# make
# make install

2、stoneのインストール
 (参考サイトB)
 上で作ったOPENSSLのライブラリをインクルードしてコンパイルします。

1
2
3
4
5
6
7
8
9
(usr/src/)
# wget http://cvs.sourceforge.jp/cgi-bin/viewcvs.cgi/*checkout*/stone/stone/stone.c?rev=2.3.2.4
# gcc -Wall -DCPP='"/usr/bin/cpp -traditional"'  
     -DPTHREAD -DUNIX_DAEMON -DPRCTL -DSO_ORIGINAL_DST=80 -DUSE_POP -DUSE_SSL 
     -I /usr/local/ssl-0.9.8g/include -L /usr/local/ssl-0.9.8g/lib 
     -o stone stone.c -lpthread -ldl -lssl -lcrypto 
stone.c: 関数 `mkStoneSSL' 内:
stone.c:7332: 警告: 引数 1 個の `SSL_CTX_new' を渡しますにより、ポインタの示す型からの修飾子が切り捨てられます
# mv stone /usr/local/sbin/

 (上のエラーを回避しようとしましたが、今のところそのままでも動いています。)

実行

1
2
3
4
5
# /usr/local/sbin/stone -z sni 
 -z certpat=/usr/local/ssl/certs/%n-cert.pem 
 -z keypat=/usr/local/ssl/certs/%n-key.pem 
 -z servername=aaa.bbb.cc aaa.bbb.cc:http 443/ssl -- 
 -z servername=ddd.eee.ff ddd.eee.ff:http 443/ssl &

これだけです。  :-D
実際は調査も含め、数日かかりましたが。  :hammer:

確認

1、まずはOPENSSLのクライアント機能を使い、サーバー上でコマンドで確認します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# openssl s_client -connect localhost:443 -servername aaa.bbb.cc 
 -CApath /usr/local/ssl/certs
depth=0 /C=JP/ST=Chiba-Pref/L=Katori-City/O=Motion Create Inc/CN=aaa.bbb.cc/emailAddress=xxx@bbb.cc
verify error:num=18:self signed certificate
verify return:1
depth=0 /C=JP/ST=Chiba-Pref/L=Katori-City/O=Motion Create Inc/CN=aaa.bbb.cc/emailAddress=xxx@bbb.cc
verify return:1
---
 : (省略)
  
# openssl s_client -connect localhost:443 -servername ddd.eee.ff 
 -CApath /usr/local/ssl/certs
depth=0 /C=JP/ST=Chiba-Pref/L=Katori-City/O=Motion Create Inc/CN=ddd.eee.ff/emailAddress=xxx@eee.ff
verify error:num=18:self signed certificate
verify return:1
depth=0 /C=JP/ST=Chiba-Pref/L=Katori-City/O=Motion Create Inc/CN=ddd.eee.ff/emailAddress=xxx@eee.ff
verify return:1
---
 : (省略)

 ↑のように、接続指定したドメイン毎に、夫々の証明書が返ってきたら成功です!

2、ブラウザから接続
 最後に外部からの接続確認です。
 繰り返しになりますが、ブラウザはFireFox2+、WindowsVista上のIE7やOPERA8+でしか対応されていません。 (XP上のIE7でもだめらしい・・)
 私は普段からFireFoxを使っていますので、そのまま確認できました!

**
 以上、だいぶ端折りましたけれども、今までなかなか出来なかったことができるようになると、嬉しいですね!

閲覧(5081)

新しくコメントをつける

題名
ゲスト名
投稿本文
より詳細なコメント入力フォームへ