Apache 2.4 で https なサイトを複数運用する

本記事は最終更新日より 1 年以上経過しております。
スポンサーリンク

 昔は SSL を使ったサイトは 1 つの IP に対して 1 つ迄だったけど、Apache 2.2 から SNI (Server Name Indication) に対応しているから証明書さえ用意できるなら VirtualHost と同じ要領でセキュアなサイトを複数動かすことも簡単になってきた。
 SNI というのは、ホスト名を伝える部分だけを暗号化しないので、Apache が「どのホストの動作をするか判別できる」というような事になる。SNI に対応する前はホスト名も暗号化されていたので、VirtualHost ディレクティブでホスト名に紐付いた動作は不可能であった。


 Apache の設定でキモとなる設定は一つ。

SSLStrictSNIVHostCheck off

 これを記述すること。

 SSLStrictSNIVHostCheck を踏まえつつ ssl.conf を記述すると次の様になる。必要な数だけ virtualhost ディレクティブを用いてホストに関する記述を増やしていけば良い。

Listen 443 https

SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog
SSLSessionCache  shmcb:/run/httpd/sslcache(512000)
SSLSessionCacheTimeout  300

SSLRandomSeed startup file:/dev/urandom  256
SSLRandomSeed connect builtin
#SSLRandomSeed startup file:/dev/random  512
#SSLRandomSeed connect file:/dev/random  512
#SSLRandomSeed connect file:/dev/urandom 512

SSLCryptoDevice builtin
SSLStrictSNIVHostCheck off

## SSL Virtual Host Context
<VirtualHost 192.168.xx.xx:443>
        ServerAdmin foo@example.com
        ServerName ssl1.example.com
        DocumentRoot /var/www/html/ssl1

        # Logging.
        ErrorLog logs/ssl1.example.com/error_log
        CustomLog "| /usr/sbin/rotatelogs logs/ssl1.example.com/access_log.%\Y%m%d 86400 +540" combined

        # php-fpm using proxy_fcgi_module.
        <FilesMatch \.php$>
          SetHandler "proxy:unix:/var/run/php-fpm/php-fpm.sock|fcgi://localhost"
        </FilesMatch>

        SSLEngine on
        SSLProtocol ALL -SSLv2 -SSLv3
        SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
        SSLCertificateFile /etc/httpd/conf.d/keys/ssl1.example.com/server.crt
        SSLCertificateKeyFile /etc/httpd/conf.d/keys/ssl1.example.com/server.key
    <IfModule mod_headers.c>
      Header always set Strict-Transport-Security "max-age=15768000; includeSubDomains; preload"
    </IfModule>
</VirtualHost>

<VirtualHost 192.168.xx.xx:443>
        ServerAdmin foo@example.com
        ServerName ssl2.example.com
        DocumentRoot /var/www/html/ssl2

        # Logging.
        ErrorLog logs/ssl2.example.com/error_log
        CustomLog "| /usr/sbin/rotatelogs logs/ssl2.example.com/access_log.%\Y%m%d 86400 +540" combined

        # php-fpm using proxy_fcgi_module.
        <FilesMatch \.php$>
          SetHandler "proxy:unix:/var/run/php-fpm/php-fpm.sock|fcgi://localhost"
        </FilesMatch>

        SSLEngine on
        SSLProtocol ALL -SSLv2 -SSLv3
        SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
        SSLCertificateFile /etc/httpd/conf.d/keys/ssl2.example.com/server.crt
        SSLCertificateKeyFile /etc/httpd/conf.d/keys/ssl2.example.com/server.key
    <IfModule mod_headers.c>
      Header always set Strict-Transport-Security "max-age=15768000; includeSubDomains; preload"
    </IfModule>
</VirtualHost>

 SSL の証明書に関しては StartCom. で無料のものを取得してもいいし、内部的に扱うのであればオレオレ証明書で充分。
 オレオレ証明書に関しては次のサイトに詳しく載っていた物を参考にさせて頂いた。
オレオレ証明書をopensslで作る(詳細版) – ろば電子が詰まっている

 そのまま証明書の作成方法を引用すると 3 行でおわる。OpenSSL 周りは難しいので苦手であり、頭に入ってこないから識者の情報に頼っている。軽く概要だけ頭に入れつつコピペでも問題無い。出来上がった .key, .csr ファイルはパーミッションを 400 まで落としておこう。

openssl genrsa 2048 > server.key
openssl req -new -key server.key > server.csr
openssl x509 -req -days 3650 -signkey server.key < server.csr > server.crt

 x509 で署名要求証明 (CSR) に署名をする時は -sha256 を付け加えると良い。

openssl x509 -req -days 3650 -sha256 -signkey server.key < server.csr > server.crt

 今後はだんだん SHA2 のアルゴリズムで署名するのが主流になってくる。SHA1 だと Chrome では古いタイプの署名と注意書きがでる。
 実際に SNI を用いて動作させた https を喋るサイトを動かしたが、IE11 や Cyberfox (Firefox)、Chrome で閲覧出来る事を確認した。
22_cyberfox_ssl

スポンサーリンク