XAMPP for WindowsでSSLを有効にする

# 目標
1. XAMPPで「**https**://localhost」を表示可能にします。
2. 自作の証明書を認証して、警告を表示させないようにします。  
  未認証: ![not-secure.png](https://qiita-image-store.s3.amazonaws.com/0/27816/738a122d-bc68-d88f-7ff0-f69a46625ddd.png)  
  認証済: ![secure.png](https://qiita-image-store.s3.amazonaws.com/0/27816/46160398-cd37-7c45-1e5d-4619f58fea0a.png)


# 環境
- Windows 10
- XAMPP 7.2.2

# XAMPPの設定
## PHPでOpenSSLを有効にする
通常は有効になっているはずです。
`C:\xampp\php\php.ini`の下記の行がコメントアウトされていないことを確認してください。

```diff:php.ini
- ;extension=php_openssl.dll
+ extension=php_openssl.dll
```

## ApacheのSSL関連の設定を追加する
`C:\xampp\apache\conf\extra\httpd-ssl.conf`の末尾に下記を追加します。

```apache:httpd-ssl.conf
<VirtualHost *:443>
    DocumentRoot "C:/xampp/htdocs"
    ServerName localhost
    SSLEngine on
    SSLCertificateFile "conf/ssl.crt/my-server.crt"
    SSLCertificateKeyFile "conf/ssl.key/my-server.key"
</VirtualHost>
```

`my-server.crt`、`my-server.key`は後で作成します。
`DocumentRoot`,`ServerName`は適宜読み替えてください。
なお、ServerNameを`localhost`以外、例えば`www.example.com`などにしたい場合は、別途バーチャルホストの設定と`hosts`ファイルの修正が必要です。
:link: [windows7のXAMPPでバーチャルホストの設定をする &#8211; YATのBLOG](http://wp.yat-net.com/?p=2400)

## 動作確認
**Apache**を再起動して、`https://localhost`へアクセスしてください。
下記のような警告が出るものの、強引に表示させることはできます。
次章では、この警告を表示させないようにします。

![alert.png](https://qiita-image-store.s3.amazonaws.com/0/27816/2b259908-ed83-68b3-0488-e299f9ec61d7.png)


# 証明書
(修正: 2017-05-02)
Chrome58以降は、以前の方法では認証できません。
非推奨とされてきた「Common Name (CN)」への対応がついに廃止されたので、「Subject Alternative Name (SAN)」という拡張領域が必要です。

:link: [Chromeがコモンネームの設定を非推奨化、そのエラー対策としての自己署名証明書のCSRの作り方](https://rms-digicert.ne.jp/digital-certificate-news/chrome-deprecates_subject-cn-matching)
:link: [Support for commonName matching in Certificates - Chrome Platform Status](https://www.chromestatus.com/feature/4981025180483584)

以降の手順は下記の記事に従っています。
:link: [Fixing Chrome 58 &#8211; NET::ERR_CERT_AUTHORITY_INVALID error &#8211; Dev Notes](http://michaelthessel.com/fixing-chrome-58-neterr_cert_authority_invalid-error/)

## 古い証明書を削除する
認証されなくなった古い証明書がある場合は削除します。

1. Chromeの設定を開き、「証明書の管理」を検索してクリックします。
2. 信頼されたルート証明機関からlocalhostを削除します。  
  ![003.png](https://qiita-image-store.s3.amazonaws.com/0/27816/384ac4e9-995f-6f2b-47de-f02d21479d4a.png)

## OpenSSL設定ファイルを編集する
1. `C:\xampp\apache\conf\openssl.cnf`をコピーして、ファイル名を`openssl-san.cnf`に変更します。
2. 以下を末尾に追記します。  

```txt:openssl-san.cnf
[ SAN ]
subjectAltName = @alt_names

[ alt_names ]
DNS.1 = localhost
DNS.2 = <他に認証したいドメインがあれば>
DNS.3 = <他に認証したいドメインがあれば>
```

## SSLサーバ証明書を作成する
Windowsのコマンドプロンプトで`openssl`コマンドを実行するには、下記のように追加でインストール作業が必要です。
:link: [Tech TIPS：WindowsにOpenSSLをインストールして証明書を取り扱う（基本編） - ＠IT](http://www.atmarkit.co.jp/ait/articles/1601/29/news043.html)

[Git Bash](https://git-scm.com/)ならばそのままopensslコマンドを使えるので、お使いのPCにすでにGitをインストールしているのならGitBashを使うことをお勧めします。

```bash:GitBash
# C:\xampp\apache\conf へ移動
$ cd /c/xampp/apache/conf

# my-server.crt, my-server.key の2つのファイルを生成
$ openssl req \
    -newkey     rsa:4096 \
    -keyout     my-server.key \
    -x509 \
    -nodes \
    -out        my-server.crt \
    -subj       "//CN=localhost" \
    -reqexts    SAN \
    -extensions SAN \
    -config     openssl-san.cnf \
    -days       3650
```

`-subj`オプションでの書き方はGitBashのみで有効です。
GitBash以外の端末を使っている場合は`-subj       "/CN=localhost" \`と、スラッシュをひとつ減らしてください。
:link: [string - Running Openssl from a bash script on windows - Subject does not start with &#39;/&#39; - Stack Overflow](http://stackoverflow.com/questions/31506158/running-openssl-from-a-bash-script-on-windows-subject-does-not-start-with)

opensslコマンドのオプションについては下記をご覧ください。
:link: (日本語)[OpenSSL Manual Translation - req(1)](http://home.att.ne.jp/theta/diatom/req%281%29.html)
:link: (英語)[/docs/manmaster/man1/req.html](https://www.openssl.org/docs/manmaster/man1/req.html)

## 証明書を設置する
上のコマンドを実行して生成した`my-server.crt`と`my-server.key`を、それぞれ下記の場所に移動します。

|ファイル|設置場所|
|:--|:--|
|`my-server.crt`|`C:\xampp\apache\conf\ssl.crt`|
|`my-server.key`|`C:\xampp\apache\conf\ssl.key`|

## 証明書を認証する
`my-server.crt`をダブルクリックします。

![001.png](https://qiita-image-store.s3.amazonaws.com/0/27816/c519077c-5861-b8eb-d5ba-a746bf491dd7.png)

![002.png](https://qiita-image-store.s3.amazonaws.com/0/27816/7e3f921a-b5fb-85a4-ed25-1cf767e61e6d.png)

「証明書ストア」は、必ず「**信頼されたルート証明機関**」を選んでください。

![003.png](https://qiita-image-store.s3.amazonaws.com/0/27816/c0382865-80c1-e29a-8410-cf501bbc6de6.png)

![004.png](https://qiita-image-store.s3.amazonaws.com/0/27816/8dac48ab-78f2-81ea-c84e-e6924fcf88a3.png)

「はい」を選んでインストールします。

![005.png](https://qiita-image-store.s3.amazonaws.com/0/27816/b530a498-21a8-564a-865b-86304646a631.png)

## 動作確認
**Apache**と**ブラウザ**を再起動して、`https://localhost`へアクセスしてください。
一般的なHTTPSのサイトと同じように問題なく表示されるはずです。
ChromeだけでなくIEやEdgeでも同様です。ただしFirefoxだけは違います。

未認証: ![not-secure.png](https://qiita-image-store.s3.amazonaws.com/0/27816/738a122d-bc68-d88f-7ff0-f69a46625ddd.png)
認証済: ![secure.png](https://qiita-image-store.s3.amazonaws.com/0/27816/46160398-cd37-7c45-1e5d-4619f58fea0a.png)

# Firefoxでは
Firefoxではどんな自己署名証明書も認証されないようです。
よって、「例外」という形にするほかありません。
:link: [安全なウェブサイトでのエラーコード &#34;SEC_ERROR_UNKNOWN_ISSUER&#34; の問題解決 | Firefox ヘルプ](https://support.mozilla.org/ja/kb/troubleshoot-SEC_ERROR_UNKNOWN_ISSUER#w_ieiglhau)

## 例外に追加する
![001.png](https://qiita-image-store.s3.amazonaws.com/0/27816/0ef334f9-16a1-661e-ca8a-7ac44852fffc.png)

![004.png](https://qiita-image-store.s3.amazonaws.com/0/27816/fc4893c0-38ab-52e0-9dcf-a8ac38b0a8a8.png)

## 例外から削除する
逆に、もう例外扱いする必要がなくなった場合は、下記のように解除します。

![005.png](https://qiita-image-store.s3.amazonaws.com/0/27816/42512275-c8d3-3fc0-8fbe-84d4d42056a5.png)

![006.png](https://qiita-image-store.s3.amazonaws.com/0/27816/674ddf47-037d-019f-660e-fb93c073bdda.png)

# HTTPSを強制する
(コメント欄で @oliverusselldev さんから助言をいただきました。)
`http://`へアクセスされても`https://`へ自動でリダイレクトするように設定できます。
`.htaccess`に下記を追加してください。

```apache:.htaccess
# Redirect HTTP to HTTPS
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
```

:link: https://www.cloudways.com/blog/add-ssl-certificates-to-custom-php-sites/

# 参考記事
XAMPPの設定

- [Xamppローカル環境にSSLを有効にする設定手順まとめ | affiliate.ks-product](http://affiliate.ks-product.com/xampp-ssl/)
- [Enabling SSL (https protocol) with xampp in a local PHP project  | Our Code World ](http://ourcodeworld.com/articles/read/198/enabling-ssl-https-protocol-with-xampp-in-a-local-php-project)

証明書

- [Apache+OpenSSLで簡単に自己認証したい - Qiita](http://qiita.com/cs_sonar/items/81b30c7a1d86d729c7fc)
- [自己証明書のhttpsサイトで証明書エラーを非表示にする手順 - Qiita](http://qiita.com/tukiyo3/items/f6592f9f99e363ed14bb)
- [xampp + ssl + vhosts + windows オレオレ証明書のインストール - Qiita](http://qiita.com/teddy/items/4660fbdf42a4ffb68b8d)
- [オレオレ証明書をopensslで作る（詳細版） - ろば電子が詰まっている](http://d.hatena.ne.jp/ozuma/20130511/1368284304)