Apache HTTP Server の SSL/TLS サポートを有効化する

> [!NOTE]
> この記事は 2013/09/08 に [momoto.github.io](http://momoto.github.io) へ投稿した内容を Qiita へ移行してきたものです

　[mod_ssl](http://httpd.apache.org/docs/current/mod/mod_ssl.html) をつかって Apache HTTP Server の SSL/TLS サポートを有効化します。 SSL を有効にするために必要な RSA 秘密鍵と公開鍵証明書のうち、公開鍵証明書は第三者の認証局に署名してもらうのが通常ですが、この記事では検証のため自己発行証明書をつかいます。

　手順としては (1) RSA秘密鍵を生成、(2) 証明書署名要求（CSR）を作成、(3) 公開鍵証明書を発行、その後、ウェブサーバで SSL/TLS を設定します。(3) の「公開鍵証明書の発行」は本来、認証局で行う手順です。

## 1. OpenSSLをつかってRSA秘密鍵と証明書署名要求を用意する（申請者）

　RSA 秘密鍵の生成には `openssl genrsa -out <秘密鍵ファイル名> <鍵長>` のコマンドをつかいます。

```shell-session:openssl-genrsa
$ openssl genrsa -out localhost.key 2048
Generating RSA private key, 2048 bit long modulus
...................................................+++
...............+++
e is 65537 (0x10001)
```

　2013 年 9 月現在、1024 bit 鍵長の CSR の受付を停止した認証局もあるように、鍵長は 2048 bit 以上が一般的です。

（参考） [SSLにおけるRSA鍵1024bitの問題 | グローバルサイン](https://jp.globalsign.com/service/ssl/knowledge/1024bit.html)

　`openssl genrsa` のオプションによって、生成した RSA 秘密鍵を別の暗号方式で暗号化することや、乱数生成につかわれるシード値をファイルで指定することもできます。 RSA 秘密鍵を AES や DES などの共通鍵暗号方式で暗号化する場合は秘密鍵にパスフレーズを設定します。このパスフレーズはウェブサーバの起動時や証明書署名要求ファイル作成時に入力が必要になります。

　続いて、RSA 秘密鍵をもとに証明書署名要求ファイルを作成します。OpenSSL コマンドは`openssl req -new -key <秘密鍵ファイル名> -out <証明書署名要求ファイル名>` をつかいます。 CSR の作成にはディスティングイッシュネームの入力が必要です。

```shell-session:openssl-req
$ openssl req -new -key localhost.key -out localhost.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:JP
State or Province Name (full name) []:Tokyo
Locality Name (eg, city) [Default City]:Shinjuku
Organization Name (eg, company) [Default Company Ltd]:Localhost, Local Area Network
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:localhost
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
```

（参考）

- [「ディスティングイッシュネーム」とは何ですか | DigiCert](https://knowledge.digicert.com/ja/jp/solution/SO23079.html)
- [ディスティングイッシュネームとは何ですか | グローバルサイン](https://jp.globalsign.com/support/faq/74.html)
- [ディスティングイッシュネームとは何ですか？ | クロストラスト](https://crosstrust.co.jp/support/faq/faq08/a002)
- [ディスティングイッシュネームとは何ですか | CSPSSL](https://cspssl.jp/faq/ssl/1_20_ja.php)

## 2. 公開鍵証明書を発行する（認証局）

　証明書署名要求ファイルと認証局の私有鍵をもとに公開鍵証明書を発行します。 OpenSSL コマンドは `openssl ca -in <証明書署名要求ファイル名> -out <公開鍵証明書ファイル名>` をつかいます。

```shell-session:openssl-ca
$ openssl ca -in localhost.csr -out localhost.self-signed.crt
Using configuration from /etc/pki/tls/openssl.cnf
Enter pass phrase for /etc/pki/CA/private/cakey.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number:
            ec:65:47:48:ff:6d:ff:cc
        Validity
            Not Before: Sep  7 00:00:00 2013 GMT
            Not After : Sep  7 00:00:00 2014 GMT
        Subject:
            countryName               = JP
            stateOrProvinceName       = Tokyo
            organizationName          = Localhost, Local Area Network
            commonName                = localhost
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:TRUE
            Netscape Comment:
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier:
                02:B3:E2:99:8B:C9:E8:F2:33:A7:27:1B:FD:D6:9E:64:C9:12:D2:7E
            X509v3 Authority Key Identifier:
                keyid:15:F3:B6:82:FD:BB:41:AF:F2:AE:D9:BD:E1:C0:2E:B6:A5:23:C6:FA

Certificate is to be certified until Sep  7 00:00:00 2014 GMT (365 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
```

　認証局は発行した公開鍵証明書を申請者に渡して、申請者は公開鍵証明書をウェブサーバに移動します。

## 3. mod_ssl を設定する (Apache HTTP Server)

　www.modssl.org やディストリビューションから mod_ssl をインストールします。

```shell-session
$ sudo yum install mod_ssl
```

　上記の手順で用意した RSA 秘密鍵と公開鍵証明書を、Apache 実行ユーザが読み込めるファイルパスに設置します。同様にパーミッションも適宜、設定します。

```shell-session
$ sudo mv localhost.key /etc/pki/tls/private/
$ sudo mv localhost.self-signed.crt /etc/pki/tls/certs/
$ sudo chmod 0600 /etc/pki/tls/certs/localhost.self-signed.crt
$ sudo chmod 0600 /etc/pki/tls/private/localhost.key
```

　Apache の設定ファイル (<ServerRoot>/conf.d/ssl.conf など) を編集して、SSLCertificateFile ディレクティブと SSLCertificateKeyFile ディレクティブを設定します。

```conf:ssl.conf
SSLCertificateFile /etc/pki/tls/certs/localhost.self-signed.crt
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
```

　Apache を再起動します。RSA 秘密鍵を暗号化している場合はパスフレーズの入力が必要です。

```shell-session
$ sudo apachectl -t
Syntax OK
$ sudo /etc/init.d/httpd restart
Stopping httpd:                                            [  OK  ]
Starting httpd: Apache/2.2.15 mod_ssl/2.2.15 (Pass Phrase Dialog)
Some of your private key files are encrypted for security reasons.
In order to read them you have to provide the pass phrases.

Server localhost:443 (RSA)
Enter pass phrase:

OK: Pass Phrase Dialog successful.
                                                           [  OK  ]
```

　ウェブサーバにアクセスしてみると、発行者不明 (sec_error_unknown_issuer) のため接続を信頼されていませんが、接続は暗号化されているようです。

![01-untrusted-connection.png](https://qiita-image-store.s3.amazonaws.com/0/58/c79c0595-3d36-2f71-1287-8ef51c3781b1.png)

![02-connection-encrypted.png](https://qiita-image-store.s3.amazonaws.com/0/58/4b887e48-b40c-0f4b-e74d-a04ab156b78a.png)

　証明書情報を表示すると入力した ディスティングイッシュネーム を確認することができます。また、この記事の例では主体者と発行者が同一になっていることも確認できます。

![03-could-not-verify-this-certificate.png](https://qiita-image-store.s3.amazonaws.com/0/58/cf2186b0-79f7-e922-791d-1540bbbbb891.png)

## 参考

- [OpenSSL Documentation](https://www.openssl.org/docs/)
- [mod_ssl – Apache HTTP Server](http://httpd.apache.org/docs/current/mod/mod_ssl.html)
- [安全な接続ができませんでした | Firefox ヘルプ](https://support.mozilla.org/ja/kb/secure-connection-failed-error-message?redirectlocale=ja&redirectslug=Secure+Connection+Failed)
- [セキュアなWebサーバーの構築と運用 | ipa.go.jp](https://www.ipa.go.jp/security/awareness/administrator/secure-web/)
- [CA/Browser Forum](https://cabforum.org)
- [CA/ブラウザフォーラム パブリック証明書の発行および管理に関する基本要件v.1.0 | symantec.com](https://www.jp.websecurity.symantec.com/ssl/pdf/baseline_requirements1.0_jp.pdf)
- [CA/ブラウザフォーラム パブリック証明書発行及びマネジメントの基本要件 ver1.0 | globalsign.com](https://jp.globalsign.com/repository/baseline_requirements_ja.pdf)