apacheのSNI対応を行った場合のメリット・デメリットとapacheからのサーバ証明書切り替え処理

apache2.2.12以降で利用できるようになったSNI。

弊社サービスでも採用すれば、標準提供のワイルドカードSSL証明書と、オプションによる顧客個別のSSLサーバ証明書がうまく共存できるのではないかと考えた。

つまり、標準用とオプション用のサーバ証明書と秘密鍵を設定しておき、名前ベースのアクセスのみでサーバ証明書を切り替えられれば、標準SSL←→オプションSSLをいちいち証明書を切り替えてapacheをリロードする必要が無い。

しかし、いかんせんSNIはほぼすべてのフィーチャーフォンに未対応である。

2015年12月現在、スマホ時代が到来してフィーチャーフォンのシェアはもっぱら減少傾向にある。

運用上単純にフィーチャーフォンを排除もしくはフィーチャーフォン専用のホストを用意する場合は問題ないが、弊社のサービスはメールであり、かつ1顧客1ホストである。

特にフォームからの読者登録などの処理について、フィーチャーフォンの前提をまだ排除するわけにはいかない。

SNIを採用した場合、フィーチャーフォンのアクセス時に自動的に平文通信に切り替えてくれればまだいいのだが、SSLネゴシエーションをする段階での問題なので、無理である。

従って、フィーチャーフォンでアクセスした場合は、SNIの仕様として、デフォルトの証明書であるワイルドカードSSLの証明書が採用される。つまりフィーチャーフォンはワイルドカードにも対応していないので、結果として認証不可警告画面が出る。

これらの問題点ならびに、現在のプラットフォームはCentOS5.5+apache2.2.3なので、これらやOpenSSLをリビルドしてSNIに対応させなければならないことのリスクを考えれば、やはり標準SSL←→オプションSSLは証明書を切り替えてapacheをリロードするのが現実的であると考えた。

実現するにあたって、特に難しいことは無いが、既存のホストへのパッチ処理は最低限必要になる。

具体的には下記のような感じ。

1.ワイルドカード用のサーバ証明書・秘密鍵・ルート証明書をSCPなどで転送してapacheの設定ディレクトリ配下にコピー。

2.上記の証明書を利用するように設定したコンフィグファイル(例:ssl_wc.conf)を作成。

3.既存のssl.confをリネームして無効にする。

4.CGIが実行できる場所に、証明書の切り替えやapacheのリロードを実行するための処理を書いたshellスクリプトを追加

5.sudoユーザ設定ファイルにおいて、apacheに上記shellスクリプト(コマンド)の実行を許可する

ここまで準備を行ったら、アプリ側に、shellファイルを起動する処理を書き、GUIでサーバ証明書の切り替えを行えるようにコーディングし、これらが有効になるようにシステムファイルをバージョンアップしてもらう。

※当たり前だが、くれぐれも任意のパラメタをコマンドとして実行できてしまうような危険なshellにはしないこと。

またフォームの入力画面は、オプションSSLなしの場合は原則平文で出力し、formのaction属性(POST先)を動的に出力する。

フィーチャーフォン以外からのアクセスであれば https://+”ワイルドカードSSL用のドメイン”を出力し、フィーチャーフォンからのアクセスであれば http://+”デフォルトのドメイン”を出力する。

なお、shellの例。
————————————————————-
#!/bin/bash

# Subroutines

use_ssl_origin() {

# Checking config files…

local chg_ssl=’1′
local chg_ssl_wc=’1′

if [ ! -f “$SSL_CONF_DIR/ssl.conf.bak” ]; then
if [ ! -f “$SSL_CONF_DIR/ssl.conf” ]; then
retval=”Both ssl.conf.bak and ssl.conf are not exsist.”
return 1
else
chg_ssl=’0′
fi
fi
if [ ! -f “$SSL_CONF_DIR/ssl_wc.conf” ]; then
if [ ! -f “$SSL_CONF_DIR/ssl_wc.conf.bak” ]; then
$retval=”Both ssl_wc.conf and ssl_wc.conf.bak are not exsist.”
return 1
else
chg_ssl_wc=’0′
fi
fi
if [ $chg_ssl -eq 1 ]; then
# Updating config file…(ssl.conf.bak -> ssl.conf)
mv $SSL_CONF_DIR/ssl.conf.bak $SSL_CONF_DIR/ssl.conf || { retval=”Rename failed.(ssl.conf.bak -> ssl.conf)”; return 1; }
fi
if [ $chg_ssl_wc -eq 1 ]; then
# Updating config file…(ssl_wc.conf -> ssl_wc.conf.bak)
mv $SSL_CONF_DIR/ssl_wc.conf $SSL_CONF_DIR/ssl_wc.conf.bak || { retval=”Rename failed.(ssl_wc.conf -> ssl_wc.conf.bak)”; return 1; }
fi

# On bash, Success statsu -> 0
return 0
}

use_ssl_wc() {

# Checking config files…

local chg_ssl=’1′
local chg_ssl_wc=’1′

if [ ! -f “$SSL_CONF_DIR/ssl.conf” ]; then
if [ ! -f “$SSL_CONF_DIR/ssl.conf.bak” ]; then
retval=”Both ssl.conf and ssl.conf.bak are not exsists”
return 1
else
chg_ssl=’0′
fi
fi
if [ ! -f “$SSL_CONF_DIR/ssl_wc.conf.bak” ]; then
if [ ! -f “$SSL_CONF_DIR/ssl_wc.conf” ]; then
retval=”Both ssl_wc.conf.bak and ssl_wc.conf are not exsist.”
return 1
else
chg_ssl_wc=’0′
fi
fi
if [ $chg_ssl -eq 1 ]; then
# Updating config files…(ssl.conf -> ssl.conf.bak)
mv $SSL_CONF_DIR/ssl.conf $SSL_CONF_DIR/ssl.conf.bak || { retval=”Rename failed.(ssl.conf -> ssl.conf.bak)”; return 1; }
fi
if [ $chg_ssl_wc -eq 1 ]; then
# Updating config files…(ssl_wc.conf.bak -> ssl_wc.conf)
mv $SSL_CONF_DIR/ssl_wc.conf.bak $SSL_CONF_DIR/ssl_wc.conf || { retval=”Rename failed.(ssl.conf.bak -> ssl.conf)”; return 1; }
fi

# On bash, Success statsu -> 0
return 0
}

httpd_reload() {

/etc/rc.d/init.d/httpd reload

}

# Define values
SSL_CONF_DIR=’/etc/httpd/conf.d’

# Main
retval=”0″
if   [ “$1” = “use_ssl_origin”  ]; then
use_ssl_origin || { echo $retval; exit 1; }
elif [ “$1” = “use_ssl_wc” ];      then
use_ssl_wc     || { echo $retval; exit 1; }
elif [ “$1” = “httpd_reload” ];     then
httpd_reload
fi

exit
————————————————————-

参考リンク)
http://builder.japan.zdnet.com/etc/20402262/
http://hoge001.exblog.jp/13982612
http://another.rocomotion.jp/14140508324311.html
http://blogs.yahoo.co.jp/xkrdy982/12244910.html
http://okwave.jp/qa/q8172686.html
http://webcache.googleusercontent.com/search?q=cache:eKZwQAKc3pAJ:www.hutcraft.jp/%3FD%252F2013-08-03+&cd=3&hl=ja&ct=clnk&gl=jp
http://centos.it-study.info/web/apache2225.html
http://www.atmarkit.co.jp/ait/articles/1108/05/news122.html