Apache 2.4系でHTTP/2サーバを構築してみるテスト。
マルチアルゴリズム証明書の使い方さて、当サイトでは前方秘匿性を確保するECDHE鍵交換と、サーバの負荷を下げられるECDSA鍵認証の組み合わせをご説明してきましたが、フィーチャーフォン用のサイトを含めて運用していると、フィーチャーフォンの多くがECDSAに対応していないため、証明書をRSAのものにしなければならなくなります。 つまり、RSAのサーバ証明書しか利用できないため、スマートフォン・PC向けにECDHE鍵交換-RSA鍵認証、フィーチャーフォン用にRSA-RSA(鍵交換・鍵認証ともにRSA)の組み合わせとなってしまい、ECDSAの恩恵を受けられません。
ところが、OpenSSL1.0.2では、一つのドメイン名(FQDN)に対して、複数の署名アルゴリズムを利用することもできます。 これをマルチアルゴリズム証明書と呼びます。 OpenSSL1.0.2とそれを使うApache Webサーバのインストール>>インストールするもの
この機能を使えば、RSAのサーバ証明書と、ECDSAのサーバ証明書を同時に利用することができます。 フィーチャーフォンには、Let's Encryptのルート証明書である、DST Root CA X3がインストールされている可能性は低いのですが、概念の説明と言うことで、Let's Encryptから、RSA対応サーバ証明書と、ECDSA対応サーバ証明書を取得して、同時にApache Webサーバで使用してみます。 異なる署名アルゴリズムのサーバ証明書の取得今回は、1つのFQDNに対して、2枚の異なる署名アルゴリズムのサーバ証明書を取ります。 Let's Encrypt(ACMEプロトコル)を利用する都合なのですが、多くのACMEエージェントは、1つのドメイン名(FQDN)に対して、1つのアルゴリズムのサーバ証明書を取ってくる前提で設計されています。 当然、取得したサーバ証明書を配置するディレクトリも異なっていなければなりません。 そのためには、異なる2つのACMEエージェントを使って、片方はRSA、もう片方は、ECDSAを取得するために使うと、簡単に異なるディレクトリにサーバ証明書を配置できそうです。 今回は、letsencrypt-autoを使って、RSA対応のサーバ証明書を取得し、dehydratedを使って、ECDSA対応のサーバ証明書を取得します。 それぞれのインストールと使い方は、 RSA対応の証明書を取ってくるletsencrypt-autoのインストール>>Let's Encrypt(無償の証明書発行機関)から取得
ECDSA対応の証明書を取ってくるdehydratedコマンドのインストール>>dehydratedスクリプトの使い方やオプション
をご覧ください。上記リンクを参考に、それぞれ、サーバ証明書を取ってくるところまで、済ませてください。 letsencrypt-autoなら、以下のコマンドが成功すればOK。 # cd /usr/local/letsencrypt # ./letsencrypt-auto certonly -t -d example.com -a webroot --webroot-path=/var/http/example.com/htdocs/ --rsa-key-size 2048 --server https://acme-v01.api.letsencrypt.org/directory …(省略)… ------------------------------------------------------------------------------- This is a PREVIEW RELEASE of a client application for the Let's Encrypt certificate authority and other services using the ACME protocol. The Let's Encrypt certificate authority is NOT YET ISSUING CERTIFICATES TO THE PUBLIC. Until publicly-trusted certificates can be issued by Let's Encrypt, this software CANNOT OBTAIN A PUBLICLY-TRUSTED CERTIFICATE FOR YOUR WEB SERVER. You should only use this program if you are a developer interested in experimenting with the ACME protocol or in helping to improve this software. If you want to configure your web site with HTTPS in the meantime, please obtain a certificate from a different authority. For updates on the status of Let's Encrypt, please visit the Let's Encrypt home page at https://letsencrypt.org/. ------------------------------------------------------------------------------- (A)gree/(C)ancel:A ←良ければA+[ENTER]を入力 Enter email address (used for urgent notices and lost key recovery) (Enter 'c'to cancel):webmaster@example.com ←メールアドレスを入力 …(省略)… IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at /etc/letsencrypt/live/example.com/fullchain.pem. Your cert will expire on 2016-XX-XX. To obtain a new version of the certificate in the future, simply run Let's Encrypt again. dehydratedコマンドは以下のコマンドが成功すればOKです。 # cd /usr/local/dehydrated # ./dehydrated -c -d example.com -a prime256v1 # INFO: Using main config file /usr/local/dehydrated/config.sh です。 続いて、この2つの証明書をApacheの設定ファイルに追加します。
サーバの設定さきほどの操作で、以下のファイルができていると思います。
RSAサーバ証明書ファイル(/etc/letsencrypt/live/example.com/cert.pem) RSA秘密鍵ファイル(/etc/letsencrypt/live/example.com/privkey.pem) RSA中間証明書ファイル(/etc/letsencrypt/live/example.com/chain.pem) ECDSAサーバ証明書ファイル( /usr/local/dehydrated/certs/example.com/cert.pem) ECDSAの中間証明書ファイル( /usr/local/dehydrated/certs/example.com/chain.pem) ECDSAの秘密鍵ファイル( /usr/local/dehydrated/certs/example.com/privkey.pem)
二組もサーバ証明書と秘密鍵を登録して大丈夫?と思われると思いますが、前述の通り、OpenSSL1.0.2は証明書の出し分けに対応しています。 設定と言うほどの設定でも無いのですが、これをそのまま設定ファイルに追加すればOKです。
クライアントからの接続時のメッセージ(ClientHello)に、TLS extensionのservername(DNSのFQDN名)とsigalgs(RSA-SHA256とか,ECDSA-SHA256といったサーバ証明書のアルゴリズム)が指定されている場合、サーバ証明書のアルゴリズム別の出し分けが行われます。 指定されていない場合は、2つの内、RSAサーバ証明書がセッション確立の際に利用されます。 これによって、TLS extensionに対応していないフィーチャーフォンも、問題なくRSAサーバ証明書を利用することができます。 この動作については、次の、動作確認で見てみます。
ということで、httpd-ssl-vhosts.confに設定を追加します。 # vi /usr/local/apache2/conf/extra/httpd-ssl-vhosts.conf /usr/local/apache2/conf/extra/httpd-ssl-vhosts.conf
<VirtualHost *:443> SSLEngine on SSLCertificateFile "/etc/letsencrypt/live/example.com/cert.pem" SSLCertificateKeyFile "/etc/letsencrypt/live/example.com/privkey.pem" SSLCertificateChainFile "/etc/letsencrypt/live/example.com/chain.pem" SSLCertificateFile "/usr/local/dehydrated/certs/example.com/cert.pem" SSLCertificateKeyFile "/usr/local/dehydrated/certs/example.com/privkey.pem" SSLCertificateChainFile "/usr/local/dehydrated/certs/example.com/chain.pem" DocumentRoot "/var/https/example.com/htdocs/" ServerName example.com:443 ServerAdmin webmaster@example.com <Directory /var/https/example.com/htdocs> Options -Indexes AllowOverride All Require all granted </Directory> <FilesMatch "\.(cgi|shtml|phtml|php)$"> SSLOptions +StdEnvVars </FilesMatch> ErrorLog "|/usr/local/apache2/bin/rotatelogs -l /var/log/https/example.com/error_log.%Y%m%d 86400" CustomLog "|/usr/local/apache2/bin/rotatelogs -l /var/log/https/example.com/access_log.%Y%m%d 86400" combined CustomLog "|/usr/local/apache2/bin/rotatelogs -l /var/log/https/example.com/ssl_request_log.%Y%m%d 86400" "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b" </VirtualHost> さらにフィーチャーフォン用の暗号スイートを追加します。 今回は、DHE-RSA-AES128-SHA256と、AES128-SHAをフィーチャーフォン用と想定して追加しています。 # vi /usr/local/apache2/conf/extra/httpd-ssl.conf
/usr/local/apache2/conf/extra/httpd-ssl.confの一部
…(省略)… SSLProtocol -All +TLSv1 +TLSv1.1 +TLSv1.2 SSLHonorCipherOrder on SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:ECDHE-ECDSA-AES128-SHA256:DHE-DSS-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-SHA256:DHE-RSA-AES128-SHA256:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK …(省略)… 設定の反映は、apachctl -tで、設定ファイルの間違いが無いこと(Syntax OKが表示されること)を確認の上、下記のように # /usr/local/apache2/bin/apachctl -t Syntax OK # /usr/local/apache2/bin/apachctl stop # /usr/local/apache2/bin/apachctl start とします。
動作確認証明書の署名アルゴリズムを選択する機能は、OpenSSL1.0.2以降が必要です。 インストールのところでも説明しましたが、自力でインストールしたOpenSSLを利用する場合、 $ source ~/.profile_ssl Add /usr/local/ssl/lib. として、OpenSSLのライブラリがインストールされている/usr/local/ssl/libを、ダイナミックリンクの対象とします。
まず、フィーチャーフォン(ガラケー)想定のコマンドから試します。 つまり、TLS extension無しで、接続します。 ガラケーが対応していると思われるTLSv1.0と、暗号スイート(ここではDHE-RSA-AES128-SHA)を指定してOpenSSLクライアントを動かします。 ターゲットの端末が、DHE-RSA-AES128-SHAに対応してねーよ、って場合は、たとえば、AES128-SHAをお使いください。 $ /usr/local/ssl/bin/openssl s_client -connect example.com:443 -tls1 -cipher DHE-RSA-AES128-SHA CONNECTED(00000004) depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X1 verify error:num=20:unable to get local issuer certificate --- Certificate chain 0 s:/CN=example.com i:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X1 1 s:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X1 i:/O=Digital Signature Trust Co./CN=DST Root CA X3 --- Server certificate -----BEGIN CERTIFICATE----- (…省略…) -----END CERTIFICATE----- subject=/CN=example.com issuer=/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X1 --- No client certificate CA names sent Peer signing digest: SHA256 Server Temp Key: DH, 2048 bits --- SSL handshake has read 3694 bytes and written 444 bytes --- New, TLSv1/SSLv3, Cipher is DHE-RSA-AES128-SHA Server public key is 2048 bit Secure Renegotiation IS supported Compression: NONE Expansion: NONE No ALPN negotiated SSL-Session: Protocol : TLSv1 Cipher : DHE-RSA-AES128-SHA (…省略…) Timeout : 300 (sec) Verify return code: 20 (unable to get local issuer certificate) --- Cipher is DHE-RSA-AES128-SHAと出れば、OKです。RSAの証明書が使われています。 続いて、TLS extensionのservername(DNSのFQDN名)とsigalgsを付けてみます。 sigalgs(署名アルゴリズム)には、 ECDSA+SHA256を、暗号スイートには、ECDHE-ECDSA-AES128-SHA256を設定します。 $ /usr/local/ssl/bin/openssl s_client -connect example.com:443 -servername example.com -tls1_2 -sigalgs ECDSA+SHA256 -cipher ECDHE-ECDSA-AES128-SHA256 CONNECTED(00000004) depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X1 verify error:num=20:unable to get local issuer certificate --- Certificate chain 0 s:/CN=example.com i:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X1 1 s:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X1 i:/O=Digital Signature Trust Co./CN=DST Root CA X3 --- Server certificate -----BEGIN CERTIFICATE----- (…省略…) -----END CERTIFICATE----- subject=/CN=example.com issuer=/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X1 --- No client certificate CA names sent Peer signing digest: SHA256 Server Temp Key: ECDH, P-256, 256 bits --- SSL handshake has read 2862 bytes and written 308 bytes --- New, TLSv1/SSLv3, Cipher is ECDHE-ECDSA-AES128-SHA256 Server public key is 256 bit Secure Renegotiation IS supported Compression: NONE Expansion: NONE No ALPN negotiated SSL-Session: Protocol : TLSv1.2 Cipher : ECDHE-ECDSA-AES128-SHA256 (…省略…) Timeout : 7200 (sec) Verify return code: 20 (unable to get local issuer certificate) --- Cipher is ECDHE-ECDSA-AES128-SHA256と出ていればOKです。ちゃんと出し分けできています。 ちなみに、ECDHE-RSAについても試してみます。 sigalgs(署名アルゴリズム)には、 RSA+SHA256を、暗号スイートには、ECDHE-RSA-AES128-SHA256を設定します。 $ /usr/local/ssl/bin/openssl s_client -connect example.com:443 -servername example.com -tls1_2 -sigalgs RSA+SHA256 -cipher ECDHE-RSA-AES128-SHA256 CONNECTED(00000004) depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X1 verify error:num=20:unable to get local issuer certificate --- Certificate chain 0 s:/CN=example.com i:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X1 1 s:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X1 i:/O=Digital Signature Trust Co./CN=DST Root CA X3 --- Server certificate -----BEGIN CERTIFICATE----- (…省略…) -----END CERTIFICATE----- subject=/CN=example.com issuer=/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X1 --- No client certificate CA names sent Peer signing digest: SHA256 Server Temp Key: ECDH, P-256, 256 bits --- SSL handshake has read 3268 bytes and written 308 bytes --- New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-SHA256 Server public key is 2048 bit Secure Renegotiation IS supported Compression: NONE Expansion: NONE No ALPN negotiated SSL-Session: Protocol : TLSv1.2 Cipher : ECDHE-RSA-AES128-SHA256 (…省略…) Timeout : 7200 (sec) Verify return code: 20 (unable to get local issuer certificate) --- Cipher is ECDHE-RSA-AES128-SHA256と出てますね。出し分けも問題なさそうです。 これで、フィーチャーフォン用のサーバ証明書と、スマートフォン・PC用の証明書を出し分けるマルチアルゴリズム証明書の運用ができます。
ちなみに、当サイトはECDSAとRSAの2種類の証明書に対応していますが、2016年度は以下のようなアクセスとなりました。
前述の通り、フィーチャーフォンには、Let's Encryptのルート証明書である、DST Root CA X3がインストールされている可能性は低いです。 そこで、スマートフォン・PC向けは、Let's Encryptから、ECDSAのサーバ証明書を取得して、フィーチャーフォン用のRSAのサーバ証明書は、有償の証明書発行機関から取得するというのが現実的です。
|