プロフィール

髭山髭人(ひげひと)

自分の書いた記事が、一人でも誰かの役に立てば...
活動信条の一つとして「貴方のメモは、誰かのヒント」というのがあります。

このサイトについて

本家HP packetroom.net から切り離した いわゆる技術メモ用のブログで、無料レンタルサーバーにて運用しています。広告表示はその義務なのでご容赦。
XREA さんには長年お世話になっています

XAMPPで立ち上げたローカルサーバーとSSL通信をしたい。オレオレ証明書で

意訳・概要

Windowsに入れたXAMPP内で立ち上げたApacheのローカルサーバーとhttps方式で通信したい。

その為には適切な形式のサーバー証明書 および そのペアとなる鍵ファイルを作成し、サーバー(XAMPP内のApache)に使わせ、尚且つ自分のPC(ブラウザ)に対して「この証明書は(ワイが作ったし、ワイしか使わんから)安心や^^」と認識させ、ブラウザから拒絶させないようにする必要があるので、その方法をまとめた。

と言う訳で、一応 Windows , XAMPP(+Apache) 的な環境が前提になっています。

仮想ホスト名

ローカルサーバーと言えば、 https://localhost/https://192.168.xx.xx/ あたりが代表格で思い浮かぶ方もいらっしゃると思いますが、この記事では 仮想ホスト での運用例として https://ore.domain/ に接続する前提で解説しています。 適宜、ご自身で運用される「オレオレドメイン」に置き換えて解釈してください。

すごく大事なこと (証明書のバージョンについて)

割と古い「OpenSSLを用いたオレオレ証明書発行の記事」だと、比較的簡単(?)に証明書を発行できるのですが、出力される証明書のバージョンが「v1」となってしまうケースも少なくありません。
この「v1」は古いバージョンとして、昨今のブラウザでは弾かれます。 現在(執筆時:2019年4月)だと「v3」の証明書を作らなければいけない様です。
もしもエラーなく証明書を発行・運用できたのに、httpsで接続したときにブラウザ(Chrome)から警告されて接続できない場合は「正しく v3 で発行されているか」を疑ってください。

※ 実際は「v3」に加え、「X509v3 extensions」と呼ばれる拡張情報が含まれている事も条件となっているようです。
裏を返せばプレーンな「ただの v3」だけでは、やはり昨今のブラウザに弾かれると言う事なのだと思います。

この記事では適応できる「v3 ( X509v3 extensions を含む)」での作成方法を書いています。

作業開始~https接続までの総合的な流れ

先に流れだけ書いておくと、以下の様になります。

  1. 「v3 / X509v3 extension」生成の為に必要な、設定拡張ファイルを用意する
  2. XAMPP内OpenSSLのコマンドと設定拡張ファイルを用いて、鍵ファイルや証明書を作成する
  3. 作成した鍵ファイルを証明書を、必要な個所に配置する
  4. 配置したファイル名と整合性を持たせる為に、Apacheの httpd-ssl.conf を編集する
  5. 発行した オレオレ証明書をインストール してブラウザで使えるようにする
  6. Apacheとブラウザを再起動してhttpsで接続を確認する

作成する証明書のバージョンが「v1」で問題なかった時代だと、確か 1とそれに準ずる 2の一部工程は不要だったと記憶しています。

当作業環境と、差異による注意事項

  • Windows10 x64
  • XAMPP / 3.2.3
  • (XAMPP内蔵の)Apache / 2.4.39
  • (Apache内蔵の)OpenSSL / 1.1.1b 26 Feb 2019

一応注意事項として、配布されているXAMPP(のApacheやOpenSSL)のバージョンによって、デフォルト設定ファイルの記載内容が変わっている可能性も考えられます。
自分は最近(2019年4月)入れなおしたXAMPPで検証し、比較的低コスト(←個人の感想)で「v3 + X509v3 extensions」のオレオレ証明書を発行・運用できましたが、古いバージョンのXAMPPを運用している方だと、もしかしたら設定ファイルも古く、この記事で示した方法だけでは足りず、結果的に狙った形式の証明書を書き出せない可能性があるかもしれない...という可能性を考慮しておいてください。

手順まとめ(シンプル版)

1. 設定拡張ファイルを用意

適当な(テキスト)ファイル ore_v3_ext.txt を用意し以下を記述。
ore.domain の箇所は適宜置き換えてください。
このファイルの位置は C:\XAMPP\ 直下に置くものと想定しています。

↓ 記載内容

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment

subjectAltName=@alt_names
[alt_names]
DNS.1 = ore.domain
DNS.2 = *.ore.domain

2. 証明書関連ファイル作成

XAMPPコントロールパネルから起動できる shell (コマンドプロンプト)を用い、上から順にやっていく感じで。
カレントディレクトリ位置は 手順1と同じ C:\XAMPP\ 上で作業するものと想定しています。

コマンド 概要
openssl genrsa -aes128 -out ore.key 2048 秘密鍵作成
openssl rsa -in ore.key -out ore_nopass.key 復号化で平文秘密鍵生成
openssl req -new -key ore_nopass.key -sha256 -out ore.csr 証明書署名要求ファイル作成
openssl x509 -req -in ore.csr -signkey ore_nopass.key -sha256 -out ore.crt -extfile ore_v3_ext.txt 証明書作成

証明書作成時、 -extfile オプションで先ほどの ore_v3_ext.txt を読ませているのがポイントです

3. ファイル配置

作成した4つのうち、3つを以下に配置

配置場所 配置するファイル
C:\xampp\apache\conf\ssl.key\ ore_nopass.key (平文鍵)
C:\xampp\apache\conf\ssl.csr\ ore.csr (※実は置かなくても機能する)
C:\xampp\apache\conf\ssl.crt\ ore.crt (発行した証明書)

4. httpd-ssl.conf に追記編集

Apache起動の際に、オレオレドメイン(仮想ホスト名)と紐づけつつ、先ほど作成した鍵と証明書を読み込ませるよう仕向けます。

C:\xampp\apache\conf\extra\httpd-ssl.conf を編集。
新しく <VirtualHost> セクションをファイル末尾に追記して増やすイメージ。
複数個所、適宜書き換えてください。 ( ホスト名2つ / .crt位置 / 平文.key位置)

# ▼ホスト名
<VirtualHost ore.domain:443>
    DocumentRoot "C:/xampp/htdocs/"
    # ▼ホスト名
    ServerName ore.domain:443
    ServerAdmin admin@example.com
    SSLEngine on
    # ▼証明書を配置した位置
    SSLCertificateFile "conf/ssl.crt/ore.crt"
    # ▼平文の秘密鍵を配置した位置
    SSLCertificateKeyFile "conf/ssl.key/ore_nopass.key"
    <FilesMatch "\.(cgi|shtml|phtml|php)$">
        SSLOptions +StdEnvVars
    </FilesMatch>
    <Directory "C:/xampp/apache/cgi-bin">
        SSLOptions +StdEnvVars
    </Directory>
    BrowserMatch "MSIE [2-5]" \
    nokeepalive ssl-unclean-shutdown \
    downgrade-1.0 force-response-1.0
</VirtualHost>

5. オレオレ証明書 .crt をインストール

手順2内 で作成した ore.crt をダブルクリックで開き、「全般」タブから証明書のインストール

  • 保存場所は現在のユーザーで良いかなと
  • 証明書をすべて次のストアへ配置する
  • 「参照」から「信頼されたルート証明機関」を選択
  • そのまま色々進めてインポート

6. システムファイルの hosts 書き換え

この記事を見ている時点で十中八九チェック済みの項目だとは思ますが、一応書いておきます
C:\Windows\System32\drivers\etc\hosts を編集して、以下を追記

127.0.0.1   ore.domain

7. Apache再起動 & httpsで接続

XAMPPのApacheと、ブラウザを 必ず再起動する事
【!】特に、ブラウザは再起動しないと証明書を正しく使ってくれないぽいので注意【!】

あとは https://ore.domain/ にアクセスして、ブラウザに弾かれることなく接続できれば完了



▼ここから下は、詳細・捕捉解説的な記事となります (やってることは上の記事と同じです)



一連の手順 (詳細解説版)

架空のドメイン(ホスト名)を決めておく

今回は https://ore.domain/ という「自分だけが認識する、仮想のホスト名」を作り出し、この仮想ホスト名をローカルサーバー(XAMPP内のApache)に割り当てて運用させていきます。

※ この記事で運用できる架空のホスト名は https:// 通信プロトコルのみで運用出来ます。 http:// で運用したい場合はまた別となりますので注意 ( http の方は本記事では触れません )

手順1. 設定拡張ファイルを用意

適当な(テキスト)ファイルを新規作成して編集します。 今回は ore_v3_ext.txt として用意しました。 証明書発行時に使います。これを使わないとブラウザに弾かれるので必須です (「v1」で済んでいた時は必要なかった)

shell の作業位置(カレントディレクトリ)が初期 C:\xampp となっているので、そこに置いておくと良いんじゃないかな、と思います。 ( この拡張ファイルの配置場所を変えた場合は、後々使うコマンドで参照先を変えてください )

ファイルの中身は全部でこの数行のみ。これらを記述します

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment

subjectAltName=@alt_names
[alt_names]
DNS.1 = ore.domain
DNS.2 = *.ore.domain

※ 下にある、各 DNS.n = の右辺値は、あなた独自の所謂「オレオレドメイン」に置き換えてください。 必要に応じて増やす事も出来るみたいですね。

このファイルは、証明書発行コマンドのオプション x509 -extfile で後々参照させます。

拡張設定ファイル運用についての捕捉

openssl.cnf を書き換えて、その設定で証明書を発行させる方法の解説記事もありますが、

  • オリジナルの設定ファイルを弄るのは気が引ける・面倒
  • コピーして編集したファイルを設定で使う場合、指定して読み込ませる処理が面倒

といった個人的な事情(私情)で、先に挙げた拡張設定ファイル方式を採用しています。「v3(と X509v3 extensions)」に対応した自己署名のTLS証明書を書き出すだけなら、自分はこれだけで事足りました。

Qiita - OpenSSLでX.509 v3の証明書を作成する

手順2. XAMPP内蔵のOpenSSLを使って秘密鍵や証明書等を作成

※ OpenSSLってソフトが使えれば何でもよいので、XAMPP内蔵にこだわる必要は無く、手持ちのLinux系サーバーに入っているものや、別途Windows用OpenSSLをDL&インストールしてきて、それらを使って作成しても構いません。( 当然、その場合は XAMPP\Apache\conf 内にあるファイルが読み込まれる訳ではないので、そこを意識する必要は出てきますが )

作成作業の流れ (2分くらいで終わる)

undefined.jpg

XAMPPを立ち上げ、コントロールパネルの右にあるボタンから Shell を起動させ、以下の流れで所定のコマンドを入力して、4つのファイルを作成します。

2-1. パスワードを用いて、.KEY(秘密鍵) を作成する
2-2. 秘密鍵 を復号化させて、サーバー内部から参照させる 秘密鍵(平文版) を作成する
2-3. .KEY(秘密鍵) を用いて、.CSR(証明書の基になる情報) を作成する
2-4. .KEY(秘密鍵).CSR(証明書の基) を用いて .CRT(証明書) を作成する

2-1. 秘密鍵の生成

openssl genrsa -aes128 -out ore.key 2048
>パスフレーズ入力
>パスフレーズ再入力(確認の為)

undefined.jpg

2-2. サーバー内部用の 復号化済み秘密鍵(.key) を作成

XAMPPのApacheでhttps通信をさせようとすると、↓ こんな副作用が出てきますので、その対応としてやっておく作業です。( 必須と言う訳ではないですが、一応 )

Apache君「https通信させるのは良いけど、その.keyファイル、暗号化させたままワイに使わせるん?」
Apache君「起動のたびに『パスフレーズ何ですか~?』ってお宅に訊くハメになるで?それでもええんか?」
あなた「それは面倒くさいな...訊かれずに済む様に復号させた平文版も用意しておこう」
あなた「どうせサーバー内部の公開されないところに置くしな..」

openssl rsa -in ore.key -out ore_nopass.key
>最初に入力したパスフレーズを入力

undefined.jpg

2-3. CSR(証明書の基になる情報)の作成

openssl req -new -key ore.key -sha256 -out ore.csr
>以下必要な情報を入力

※ 鍵ファイル指定の引数に ore_nopass.key ではなく ore.key を指定しても構いません。その場合は、コマンド中に「パスフレーズ教えて?」と、一度入力が促されます。

undefined.jpg

補足:req -new コマンドで、CSRを作成するときに促される入力対応表

先に書いておきますが「v3」での運用を前提とするなら、極論(Common Nameも含めて)すべて空白でも構いません。 ですが、一応 Common Name の箇所だけは、「オレオレドメイン」を入れたほうが、後々判りやすくて良い気がします。

表記 入力例 対応
Country Name (2 letter code) [AU]: JP 2文字表記の国コード
State or Province Name (full name) [Some-State] Saitama 都道府県的なやつ
Locality Name (eg, city) [] OreTown 市町村的なやつ
Organization Name (eg, company) [Internet Widgits Pty Ltd] ore.Inc 会社名や組織名
Organizational Unit Name (eg, section) [] oren-toko 部署など
Common Name (eg, YOUR name) [] ore.domain ホスト名。いわゆるドメイン / IPアドレスでもOKぽい?
Email Address [] oreore.example.com メールアドレス
A challenge password [] 空白で良い
An optional company name [] 空白で良い

Common Name も空白入力にした場合、証明書の発行先名称が「Internet Widgits Pty Ltd」となります。 これは、XAMPPのApache内openssl.conf に記述されているデフォルトの値である 0.organizationName_default = Internet Widgits Pty Ltd が適用されている為だと思われます。

2-4. 証明書 の作成 (自己署名)

openssl x509 -req -in ore.csr -signkey ore_nopass.key -sha256 -out ore.crt -extfile ore_v3_ext.txt
>最初に入力したパスフレーズを入力

※ -extfile オプションで、拡張設定を記載したファイルを読ませて書き出さないと、必要な情報が含まれた「v3 / X509v3 extensions」とならず、発行しても結果的にブラウザで弾かれるので注意してください。

※ 鍵ファイル指定の引数に ore_nopass.key ではなく ore.key を指定しても構いません。その場合は、コマンド中に「パスフレーズ教えて?」と、一度入力が促されます。

undefined.jpg

出揃った4つのファイル

上記(手順2)の操作で https://ore.domain/ を架空運用させる為に必要な 4つのファイルが作成されました。 それぞれの用途をざっくり書き記したので、確認してみてください。
※ 初期状態だと C:\xampp 直下にこれらのファイルが存在しているはず。

  • ore.key (KEY:秘密鍵 / 暗号化済)
    あなただけが管理し、持っていなければならないファイルです。外部に晒すような真似は絶対にしないでください。
    ※今回のシーンに於いては、テストみたいなものなのでそこまで気を張らなくても良いですが、実運用に於いては慎重に扱われるファイルです。 一応、あなただけが知るパスフレーズによって暗号化はされていますが。

  • ore_nopass.key (KEY:秘密鍵 / 一度復号化して平文にしたもの )
    暗号化されていない分、上のファイルより一層気を付けて管理しなければなりません。
    ローカルサーバーとして立ち上げる際、暗号化したままのファイルを使わせると、起動の度にパスフレーズを入力しないといけなくなります。この操作が億劫な管理者が、横着するために使用・作成するファイルです。(←言い方) 「利便性とセキュリティの等価交換」を体現するような立ち位置ですね...

  • ore.csr (CSR:証明書を発行するための署名ファイル)
    本来は、存在するドメインを https(SSLもといTLS)で運用する時、トップレベルの偉い機関(ルート認証局 または 中間認証局)に提出するファイルです。 この提出された .csr に対して認証局が署名を加えて発行した証明書ファイル .crt を世間に向けて使わせる感じとなります。 ただし、今回はローカル環境で自分さえ使えれば良いので、この .csr(署名ファイル)は、自分自身の秘密鍵で署名したのち、証明書を発行する為だけに使います (後述)

  • ore.crt (CRT:発行された証明書ファイル)
    先述の通り、本来は社会的,世界的に信用のある偉い機関(認証局)が発行するファイルです。信用出来る所なので、皆が安心して使っています。 ですが今回は本物の認証局の力は借りず、OpenSSL標準の機能を用いて 「俺の身元保証人?俺だよ!」というギャグのようなノリで証明書を発行します。 尚、ここで発行させた証明書は、後程ブラウザに「俺が安全って言ってるんだから安全なんだよ^^」と強制認識させます。

手順3. 秘密鍵・署名・証明書 の配置

必ずここに置かなければならない..と言う訳ではないですが、XAMPPのテンプレとして記述、用意されている OpenSSL 関連の証明書などのファイルが以下の場所に置かれているので、それに準じています。

※ XAMPP内のApacheで使う前提です

配置場所 配置するファイル
C:\xampp\apache\conf\ssl.key\ ore_nopass.key ※平文の.keyファイルを配置
C:\xampp\apache\conf\ssl.csr\ ore.csr (証明書用の署名) ※実は置かなくても機能する
C:\xampp\apache\conf\ssl.crt\ ore.crt (自分で発行した証明書)

面倒くさいので調べてない ですが、ore_nopass.key の代わりに ore.key を配置(&指定) して運用させる場合、Apacheさんに「あ~~この秘密鍵のパスわかんねえな~~教えてくれないと俺起動できねえな~~~」ってボヤかれると記憶しています。

手順4. httpd-ssl.conf の編集

C:\xampp\apache\conf\extra\httpd-ssl.conf を開くと

<VirtualHost _default_:443>
    ~~(中略)~~
</VirtualHost>

...というオリジナルの長~い項目があるので、その下に新しく<VirtualHost> セクションを追記して増やす 形をとります。

作成した証明書(.CRT)と鍵ファイル(.KEY)のファイル名や配置場所に応じて、一部記述パラメータが異なりますが、おおむね以下のような感じ。

↓書き足すのはこちら

# ▼ ホスト名を入力
<VirtualHost ore.domain:443>
    # ▼ ルートディレクトリ
    DocumentRoot "C:/xampp/htdocs/"
    # ▼ ホスト名を入力
    ServerName ore.domain:443
    ServerAdmin admin@example.com
    SSLEngine on
    # ▼ 証明書.crtの位置
    SSLCertificateFile "conf/ssl.crt/ore.crt"
    # ▼ 秘密鍵(平文版).key の位置
    SSLCertificateKeyFile "conf/ssl.key/ore_nopass.key"
    <FilesMatch "\.(cgi|shtml|phtml|php)$">
        SSLOptions +StdEnvVars
    </FilesMatch>
    <Directory "C:/xampp/apache/cgi-bin">
        SSLOptions +StdEnvVars
    </Directory>
    BrowserMatch "MSIE [2-5]" \
    nokeepalive ssl-unclean-shutdown \
    downgrade-1.0 force-response-1.0
</VirtualHost>

あなた「ore.domain に https:// (ポート443)でアクセスされたら、ここをルートディレクトリにしてサーバー側で対応してね」
あなた「あ、TLS通信するのに必要な証明書ファイルは、あそこに置いてあるから、それ使ってね」

...と、上で示した <VirtualHost> セクション例から、そんな感じの雰囲気が読み取れるんじゃないかなーと思います。

httpd-ssl.conf オリジナルの記載から、使われているところはそのまま抜粋し、変更が必要なところだけ書き換えています。

ルートディレクトリ(DocumentRoot) の項目は、人によってはそのままの記述でも良いのですが、 仮想ホスト名を増やして複数運用させたい場合は、ここにサブディレクトリを作って指定してあげる事で、

  • C:/xampp/htdocs/ore/ を ore.domain として運用
  • C:/xampp/htdocs/hoge/ を hogehoge.hoge として運用

...といった風に、増やして遊ぶ事も出来ます。 便利。
( 増やすごとに、この <VirtualHost> セクションも追記させる必要は出てきますが )

さらに言えば、C:/oredomain/ のような、XAMPPフォルダの垣根を超えたルートディレクトリ運用も可能なようです。

手順5. オレオレ証明書をインポート(インストール)

証明書の自己署名処理により独自発行しておいた.CRTファイル(証明書)をPC , ブラウザに認識させます。 この作業を行わないと、 架空のドメイン https://ore.domain/ でローカルサーバーにつなげたとき 「https:// で接続可能なサイトだけど、このサーバー、ドメインの身元が不透明なため信用できない(証明書が怪しすぎる)」 として、ブラウザが接続してくれません。

undefined.jpg

以下の手順で、この証明書を「信頼するもの」として ブラウザに扱わせます。

  • 書き出した証明書(CRT)をダブルクリックで開く
  • 「証明書のインストール」を実行
  • 保存場所は「現在のユーザー」でよいと思います。そのまま次へ。
  • 「証明書をすべて次のストアに配置する」を選び「参照」を押す
  • 上から二番目 「信頼されたルート証明機関」 を選んでOK → 次へ
  • 最後に「完了」を押して、インポート完了

undefined.jpg

一度信頼済みとして認識させたオレオレ証明書を、後で取り除く(削除)事も可能ですが、ここでは特に触れません。まぁ普通にブラウザ設定の証明書あたりから消せますので...

手順6. システムファイルの hosts 書き換え

仮想ホスト名 (ここで言う ore.domain) をPC自体に認識させるため、以下の処理を行います。
C:\Windows\System32\drivers\etc\hosts を編集して、

127.0.0.1   ore.domain

をファイル末尾に追記。
以前のOSではどうだったか覚えてないですが、Windows10では再起動させなくても仮想ホスト名が反映されました。

手順7. Apache & ブラウザ再起動 および httpsで接続

XAMPPのApacheとブラウザを立ち上げなおしてください。
( 特に、ブラウザは再起動しないと証明書を正しく使ってくれないぽいので注意)

あとは https://ore.domain/ にアクセスして、ブラウザに弾かれることなく接続できれば、SSL(TLS)通信および、オレオレ証明書の運用が正しくできている事になります。



各種ファイルの形式について

(本当は最初に書いたほうが良かった気もするのですが)

本記事では、各種ファイルの拡張子に .key / .csr / crt といった独自のものを割り振っていますが、実の所、これらの「秘密鍵」「証明書署名要求」「証明書」は、本来拡張子を付けるとすれば .pem のほうが正しいです。

フォーマット的には .pem なのですが、役割毎ごとに拡張子を変えたほうが分かりやすいので、敢えて変更したまま扱っていた、と言う訳です。 同じテキスト形式のファイル同士でも、.txt / .ini / .conf 等と割り振られているのと似たような感じですね。

この辺りに関しては、この記事がメチャメチャ分かりやすい😋 ので、気になったら一度目を通してみてください

Qiita - RSA鍵、証明書のファイルフォーマットについて

ファイル名 概要 エンコーディング内容
ore.key 秘密鍵なので .key とした pem
ore_nopass.key 同上 pem
ore.csr 証明書署名要求 .csr は
Certificate Signing Request の略称
pem
ore.crt 証明書 .crt は
Certificateの略称
pem