Amazon LinuxのApache 2.4にSSL証明書を設定してみた

Apache

はじめに

清水です。 先日、Amazon Linux上のApache 2.4にSSL証明書を設定する機会がありました。 これまでCloudFrontやELBなどへの証明書設定(インストール)は行ったことがありましたが、Apacheにきちんと証明書を設定したことはなかったな、、ということで、今回はその手順をまとめてみました。

ApacheへのSSL証明書の設定については数多くの情報がありますが、Amazon LinuxのApache 2.4の場合、mod_sslがmod24_sslというパッケージ名でのインストールが必要なこと、また中間CA証明書の扱いだけ注意が必要となります。 他は秘密鍵、証明書をそれぞれ適切に配置して設定すれば、すんなり導入できた、という印象です。

設定する環境

証明書の設定方法に入る前に、まずは設定してみたサーバ環境と証明書についての情報をまとめてみます。

サーバ環境

今回設定した環境は以下になります。

  • Amazon Linux (2016.09.0)
  • Apache 2.4 + mod_ssl

まずはAmazon Linuxのインスタンスを作成します。Security GroupについてはHTTPS 443も開放するようにします。

そして独自ドメインでアクセスできるように設定します。今回は起動後のPublic DNSをRoute53で管理しているドメインのCNAMEレコードに登録しました。

続いて、Amazon LinuxインスタンスにSSHで接続して、Apache 2.4をインストールします。

 $ sudo yum install httpd24

またApacheのSSL対応に必要なmod_sslもインストールします。 Apacheが2.4の場合、このmod_sslについてはmod24_sslというパッケージをインストールする必要があります。

 $ sudo yum install mod24_ssl

mod24_sslではなく、mod_sslをインストールしようとすると、以下のようなエラーが発生してインストールできません。

 $ sudo yum install mod_ssl
Loaded plugins: priorities, update-motd, upgrade-helper
Resolving Dependencies
--> Running transaction check
---> Package mod_ssl.x86_64 1:2.2.31-1.8.amzn1 will be installed
--> Processing Dependency: httpd = 2.2.31-1.8.amzn1 for package: 1:mod_ssl-2.2.31-1.8.amzn1.x86_64
--> Processing Dependency: httpd-mmn = 20051115 for package: 1:mod_ssl-2.2.31-1.8.amzn1.x86_64
--> Running transaction check
---> Package httpd.x86_64 0:2.2.31-1.8.amzn1 will be installed
--> Processing Dependency: httpd-tools = 2.2.31-1.8.amzn1 for package: httpd-2.2.31-1.8.amzn1.x86_64
--> Processing Dependency: apr-util-ldap for package: httpd-2.2.31-1.8.amzn1.x86_64
--> Running transaction check
---> Package apr-util-ldap.x86_64 0:1.4.1-4.17.amzn1 will be installed
---> Package httpd-tools.x86_64 0:2.2.31-1.8.amzn1 will be installed
--> Processing Conflict: httpd24-2.4.23-1.66.amzn1.x86_64 conflicts httpd < 2.4.23
--> Processing Conflict: httpd24-tools-2.4.23-1.66.amzn1.x86_64 conflicts httpd-tools < 2.4.23
--> Finished Dependency Resolution
Error: httpd24-tools conflicts with httpd-tools-2.2.31-1.8.amzn1.x86_64
Error: httpd24 conflicts with httpd-2.2.31-1.8.amzn1.x86_64
 You could try using --skip-broken to work around the problem
 You could try running: rpm -Va --nofiles --nodigest

これで証明書設定前のサーバ側の準備は完了です。 ドキュメントルートにindex.htmlとして何かしらのファイルを作成し、Apacheを起動、http接続で問題ないか確認しておきます。

ドメイン名を記載したindex.htmlファイルを作成します。

  $ sudo sh -c "echo '<html><head><title>apache-ssl-testdomain.mydomain.net</title></head><body>apache-ssl-testdomain.mydomain.net</body></html>' > /var/www/html/index.html"

Apacheを起動します。

 
 $ sudo service httpd start
Starting httpd:                                            [  OK  ]

http接続ができるか確認します。先ほど作成したhtmlファイルが返ってくることを確認できました。

 $ curl http://apache-ssl-testdomain.mydomain.net/
<html><head><title>apache-ssl-testdomain.mydomain.net</title></head><body>apache-ssl-testdomain.mydomain.net</body></html>

証明書

設定した証明書についてもまとめてみます。

秘密鍵ならびにCSRは手元のMac OS X(El Capitan)上のOpenssl(0.9.8)で作成しました。ローカルに以下2つのファイルを保存します。

  • 秘密鍵: apache-ssl-testdomain.mydomain.net.key
  • CSR: apache-ssl-testdomain.mydomain.net.csr

証明書ですが、今回は検証目的ということもあり、無償で利用できるSSL証明書発行サービスLet's Encryptを利用しました。 Let's Encryptからの証明書発行については、下記のこやまさんのエントリを参考にZeroSSLを使用しています。

今回はCSRまで手元のMacで作成していたので、CSRを貼り付けてWizardを進めます。Vertification画面で得られる情報を、Route53の該当ドメインにTXTレコードとして追加します。この承認を経て証明書を取得し、以下のファイル名でローカルに保存しておきます。

  • 証明書: apache-ssl-testdomain.mydomain.net.crt

実際にサーバにコピーして使用するのは、以下2つのファイルになります。

  • 秘密鍵: apache-ssl-testdomain.mydomain.net.key
  • 証明書: apache-ssl-testdomain.mydomain.net.crt

中間CA証明書について

今回のLet's Encryptでの証明書発行では中間CA証明書は使用しませんでしたが、Apache 2.4 (正確には2.4.8)以降で中間CA証明書を使用するときは、これまで(Apache 2.2等)のSSLCertificateChainFileディレクティブで指定せずに、1つの証明書ファイルとしてまとめて、SSLCertificateFileディレクトティブで指定する必要があります。

このとき、SSLCertificateFileディレクトティブで指定するファイルは、以下の中身となります。

-----BEGIN CERTIFICATE-----
    サーバ証明書
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
    中間CA証明書
-----END CERTIFICATE-----

さらに別途クロスルート証明書が必要な場合は、その下に続けます。

-----BEGIN CERTIFICATE-----
    サーバ証明書
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
    中間CA証明書
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
    クロスルート設定用証明書
-----END CERTIFICATE-----

Apacheへの設定手順

サーバと証明書の環境ができたので、実際にApache 2.4にSSL証明書を設定してみます。

手順としては以下となります。

  1. 証明書ファイルをAmazon Linux上に配置
  2. 設定ファイル(/etc/httpd/conf.d/ssl.conf)の編集
  3. 設定ファイルの文法確認
  4. Apacheサービスの再起動

1. 証明書ファイルをAmazon Linux上に配置

まずローカルにある秘密鍵と証明書を、設定するAmazo Linuxにscpでコピーします。 そしてそれぞれ以下の場所に配置します。配置したディレクトリ/etc/pki/tls/は設定ファイルssl.confで記載されていた場所を使用しています。

  • 証明書
    • /etc/pki/tls/certs/apache-ssl-testdomain.mydomain.net.crt
  • 秘密鍵
    • /etc/pki/tls/private/apache-ssl-testdomain.mydomain.net.key

また、ファイルの所有者とグループをroot、アクセス権限を所有者のみ読み込み可能としておきます。

2. 設定ファイル(/etc/httpd/conf.d/ssl.conf)の編集

続いてApacheの設定ファイルを書き換えて、先に配備した証明書ファイルを使用するようにします。編集するフファイルは/etc/httpd/conf.d/ssl.confで、 編集箇所は、証明書へのパス、秘密鍵へのパスの2箇所です。

証明書ファイルのパスの変更

以下のSSLCertificateFileディレクトティブの部分を探します。

#   Server Certificate:
# Point SSLCertificateFile at a PEM encoded certificate.  If
# the certificate is encrypted, then you will be prompted for a
# pass phrase.  Note that a kill -HUP will prompt again.  A new
# certificate can be generated using the genkey(1) command.
SSLCertificateFile /etc/pki/tls/certs/localhost.crt

コメントアウトされていない最終行、SSLCertificateFileディレクティブの値を以下のように書き換えます。

SSLCertificateFile /etc/pki/tls/certs/apache-ssl-testdomain.mydomain.net.crt

秘密鍵ファイルのパス変更

証明書ファイルのパス部分のすぐ後に、以下の記載があるSSLCertificateKeyFileディレクトティブが見つかります。

#   Server Private Key:
#   If the key is not combined with the certificate, use this
#   directive to point at the key file.  Keep in mind that if
#   you've both a RSA and a DSA private key you can configure
#   both in parallel (to also allow the use of DSA ciphers, etc.)
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key

こちらも同じく、コメントアウトされていない最終行、SSLCertificateKeyFileディレクティブの値を以下のように書き換えます。

SSLCertificateKeyFile /etc/pki/tls/private/apache-ssl-testdomain.mydomain.net.key

3. 設定ファイルの文法確認

設定ファイルを書き換えたら、Apacheに反映させる前にファイルの文法間違い等がないか、httpd -tコマンドで確認しておきます。

問題がなければ、以下のようにSyntax OKが返ってきます。

$ httpd -t
Syntax OK

文法や、設定ファイル記載内容にミスがあると、以下のようにエラーメッセージが返ってきます。内容を確認して修正しましょう。

$ sudo httpd -t
AH00526: Syntax error on line 98 of /etc/httpd/conf.d/ssl.conf:
SSLCertificateFile: file '/etc/pki/tls/certs/apache-ssl-testdomain.mydomain.crt' does not exist or is empty

こちらは、ファイルの拡張子を間違えてしまったパターンです。 設定ファイルの文法的には問題ありませんが、実在していないファイルを設定してしまったことでエラーとなっています。

4. Apacheサービスの再起動

設定ファイルに問題がないことが確認できたら、Apacheのサービスを再起動させて、設定を反映させます。

$ sudo service httpd restart
Stopping httpd:                                            [  OK  ]
Starting httpd:                                            [  OK  ]

動作確認

設定ができたら、ブラウザからhttpsでアクセスしてみます。アクセス後、ブラウザから証明書が有効であるかも確認してみます。

apache-ssl-001

有効な証明書として設定されていることが確認できました!

まとめ

Amazon LinuxのApache 2.4にSSL証明書を設定する手順をまとめてみました。 Apacheについては2.4とバージョンを明記していますが、大まかな導入方法については2.2についても変わらないのではないでしょうか。前述の通りmod_sslインストールの際のパッケージ名と、中間CA証明書の扱いについてはご注意ください。

ApacheにSSL証明書を設定するにあたりハマったところは(本エントリでは記載していませんが)、中間CA証明書とサーバ証明書を1つのファイルにまとめるときにcatコマンドで連結したら、改行コードが混ざってしまったところです(汗)。こちらもエントリ本文には記載していませんが、ファイルの中身をみることも大事なと実感しました。。

なお、AWS環境でSSL接続をする場合には、ELBやCloudFrontに証明書を設定することができます。また証明書とその管理機能としてACM(AWS Certificate Manager)を使用することもできますので、状況に応じて使い分けてみてはいかがでしょうか。

AWS Cloud Roadshow 2017 福岡