SSLによるSecureWWWサーバの構築


WWWサーバのApache2.0系へのバージョンアップを機会に、SSL対応にしました。目的は、某所(分かりますよね)から自宅サーバにアクセスした時、パスワードロックしているページにアクセスしてパスワードを見られてしまうのを防止することです。

設定は、http(80)とhttps(443)の両方で同一コンテンツにアクセスできるようにしました。httpsは、バーチャルサーバで動かしています。
なお、Apache2.0でSSL対応すると、デフォルトのconfファイルの設定でhttpsでアクセスすると、接続はできるのですが大量にエラーログを吐くというバグがあり、2.0.43でも修正されていません。いろいろ調べた結果、Listenポートの80番と443番のconfへの記述を変更することで回避できるようなので、暫定的に設定変更しました。(2.0.45では問題ありません。)
何もしないと、アクセス時に毎回SSLの警告メッセージ(証明書が自己認証のため信頼されないとの警告)がでるので、クライアント側の設定を追加しました。

後半のクライアント認証は、認証局で署名されたクライアント用証明書を持たない端末(ブラウザ)からのアクセス制限をするためのものなので、特別にセキュリティを確保するとき以外は不要です。

■Apache (httpd.conf, ssl.conf) の設定

Apache2.0.46をこちらからダウンロードします。
インストールは、任意の場所にソースを展開してコンパイルします。ここでは、SSLとWeb/DAVが使えるようにインストールしておきました。アップグレードでしたので、バックアップを兼ねてあらかじめhttpd.confをリネームしておいてインストールし、新しいhttpd.confを作成しました。(httpd.confが既にあると上書きしないため。といっても、httpd-std.confができるのでここから新しいhttpd.confを作ればいいのですが)
RedHat系の場合、のopensslがKerberosサポートの状態でコンパイルされていて、また、kerberosのヘッダが何故か/usr/kerberos/includeにあるため make でエラーが発生します。下記の赤字のように、明示してあげて下さい。

 $ tar zxfv httpd-2.0.46.tar.gz
 $ cd httpd-2.0.46
 $ export CPPFLAGS=-I/usr/kerberos/include
 $ ./configure --enable-ssl --enable-dav
 $ make
 $ su
 # make install

◆httpd.confの設定

httpd.confの設定は SSLが無いときと全く同一ですので、こちらを参考にしてください。デフォルトで ssl.confが Includeされるようになっているはずですが、一応確認して置いてください。


◆ssl.confの設定

Apache2.0では、SSL関係の設定は全てhttp.confと同じディレクトリに作成されるssl.confで行います。設定を変更した項目は以下のとおりです。

 

■クライアント認証関係の設定

クライアント認証関係の設定は、単に通信を暗号化(httpsでのアクセス)するだけなら不要です。
このクライアント用証明書によるクライアント認証を導入すると、予め認証局で署名されたクライアント用証明書を持たない端末がアクセスしても、接続そのものが拒否されるのでセキュリティ的にかなり強固になります。反面、クライアント毎に証明書を発行することになるので、運用はかなり面倒になりますが、セキュリティとのバータなので止むを得ません。
このようなクライアント認証は、一般的に企業などで導入されており、具体例としてはwebを使用して外勤の営業マンが社外から社内システムにアクセスできるシステムや株取引のシステムなどに導入されています。このようなシステムの場合、不特定多数にアクセスされるとApacheの認証やアプリ認証だけではセキュリティが甘くなるため、アクセスレベルでセキュリティを強化するためにクライアント認証を導入します。
クライアント認証は、サーバ全体やバーチャルサーバ、ディレクトリ単位で行うことができますが、ここではバーチャルサーバで行うことを前提とします。従って、上記の ssl.conf に追加設定していきます。

◆ssl.conf の設定

  上記設定に、下記を追加設定します。特定ディレクトリだけを対象にするなら、下記の2項目の SSLVerifyClient/SSLVerifyDepth をディレクトリディレクティブ内に記述すればよい。

■logrotateの設定

loglotateは、/etc/logrotate.d配下にあるapacheを参考に作成していますが、おやじは、下記のようなワイルドカードでの設定なので今回は変更していません。(青字は削除、赤字は追加、緑字は変更したものです。行頭の数字は説明上、おやじが付加したものです。)

1.  /var/log/httpd/access_log /var/log/httpd/agent_log /var/log/httpd/error_log /var/log/httpd/referer_log {
2.  missingok
3.  sharedscripts
4.  postrotate
5.  /bin/kill -HUP `cat /var/run/httpd.pid 2>/dev/null` 2> /dev/null || true
6.  endscript
7.  }

              ↓削除、追加

1.  /usr/local/apache2/logs/*_log {
2.  missingok
3.  sharedscripts
4.  postrotate
5.  /bin/kill -HUP `cat /usr/local/apache2/logs/httpd.pid 2>/dev/null` 2> /dev/null || true
6.  endscript
7.  }

1行目: logrotateしたいlogファイル名を*_logでワイルドカード指定。
2行目: ログファイルが無くとも、処理を正常終了させる。
3行目: 1行目で複数指定されたlogファイルに対し、postrotate以降設定されたコマンドを実行する。
4行目: このコマンドの後に、logファイルのローテーション後に実行するコマンドを記述する。
5行目: logファイルのローテーション後、apacheサーバにハングアップシグナル(HUP)を送り、再起動
           させるためのもの。これにより、apacheが新たなlogファイルにログを出力するようになる。
6行目: postrotateの終端を示す。  

■ルータの設定

これは、単にhttps(ポート番号:443番)を他のプロトコルと同様に、スタティックNATとフィタリングの設定を追加するだけです。変更例は、こちらを参考にしてください。

■Apacheの起動設定

自動起動は、rc.localで行う場合は、/usr/local/apache2/bin/apachectl startssl としてください。

おやじはSSL化を機会に、/etc/rc.d/init.d/配下に起動スクリプトを置いて、自動起動できるようにしました。起動スクリプトは、下記内容をhttpd2として記述し、/etc/rc.d/init.d/配下に置きます。

apachectlで起動すると起動はするがエラーが出るので、RedHatの起動スクリプト(/etc/rc.d/init.d/httpd)をベースに修正し、/etc/rc.d/init.d/httpd2として置きました。
#!/bin/sh
#
# Startup script for the Apache Web Server
#
# chkconfig: - 85 15
# description: Apache is a World Wide Web server. It is used to serve \
# HTML files and CGI.
# processname: httpd
# pidfile:
/usr/local/apache2/logs/httpd.pid
# config:
/usr/local/apache2/conf/httpd.conf

# Source function library.
. /etc/rc.d/init.d/functions

if [ -f /etc/sysconfig/httpd ]; then
        . /etc/sysconfig/httpd
fi

# This will prevent initlog from swallowing up a pass-phrase prompt if
# mod_ssl needs a pass-phrase from the user.
INITLOG_ARGS=""

# Path to the apachectl script, server binary, and short-form for messages.
apachectl=
/usr/local/apache2/bin/apachectl
httpd=
/usr/local/apache2/bin/httpd
prog=httpd
RETVAL=0

# check for 1.3 configuration
check13 () {
        CONFFILE=/etc/httpd/conf/httpd.conf
        GONE="(ServerType|BindAddress|Port|AddModule|ClearModuleList|"
        GONE="${GONE}AgentLog|RefererLog|RefererIgnore|FancyIndexing|"
        GONE="${GONE}AccessConfig|ResourceConfig)"
        if grep -Eiq "^[[:space:]]*($GONE)" $CONFFILE; then
                echo
                echo 1>&2 " Apache 1.3 configuration directives found"
                echo 1>&2 " please read /usr/share/doc/httpd-2.0.40/migration.html"
                failure "Apache 1.3 config directives test"
                echo
                exit 1
        fi
}

# The semantics of these two functions differ from the way apachectl does
# things -- attempting to start while running is a failure, and shutdown
# when not running is also a failure. So we just do it the way init scripts
# are expected to behave here.
start() {
        echo -n $"Starting $prog: "
        check13 || exit 1
        daemon $httpd
-D SSL $OPTIONS
        RETVAL=$?
        echo
        [ $RETVAL = 0 ] && touch
/usr/local/apache2/logs/accept.lock
        return $RETVAL
}
stop() {
        echo -n $"Stopping $prog: "
        killproc $httpd
        RETVAL=$?
        echo
        [ $RETVAL = 0 ] && rm -f
/usr/local/apache2/logs/accept.lock /usr/local/apache2/logs/httpd.pid
}
reload() {
        echo -n $"Reloading $prog: "
        check13 || exit 1
        killproc $httpd -HUP
        RETVAL=$?
        echo
}

# See how we were called.
case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  status)
        status $httpd
        RETVAL=$?
        ;;
  restart)
        stop
        start
        ;;
  condrestart)
        if [ -f
/usr/local/apache2/logs/httpd.pid ] ; then
                stop
                start
        fi
        ;;
  reload)
        reload
        ;;
  graceful|help|configtest|fullstatus)
        $apachectl $@
        RETVAL=$?
        ;;
  *)
        echo $"Usage: $prog {start|stop|restart|condrestart|reload|status|fullstatus|graceful|help|configtest}"
        exit 1
esac

exit $RETVAL
作成したhttpdファイルに実行権限を付加し、ランレベルを設定した後、ランレベルが設定されたことを確認します。

 # cd /etc/rc.d/init.d/
 # chmod 755 httpd2
 # /sbin/chkconfig --add httpd2
 # /sbin/chkconfig --list httpd2
 httpd    0:オフ 1:オフ 2:オフ 3:オン 4:オン 5:オン 6:オフ
これで、システム起動時に自動的にApacheが起動されるようになります。rc.localに書いた起動スクリプト(/usr/local/apache2/bin/apachectl startssl)を消去するのを忘れないように。

以上で、https://www.aconus.com/~oyaji/ とSSLでのアクセスが可能となります。アクセス時にSSLのalertが出るのは、他の自己認証サイトをアクセスした時と同じです。
クライアント側のこの警告に対する対策については、Internet ExplolerとNetscape Navigatorで異なります。こちらを参照願います。


Top Pageへ   サーバの構築へ戻る