CrossRoad

XRを中心とした技術ブログ。 Check also "English" category.

expressを使ってLAN環境向けhttpsサーバを構築する方法

npmで提供されているexpressを使うと、簡単なコードでWebサーバを作ることができます。

expressでWebサーバを作るためのサンプルコードを使うと、大抵はhttp://localhost:8080のURLで実行できるサーバになります。しかし、検証したいサービスによっては、httpsが必要な場合があります。

もちろん、サーバ構築に必要なコードをGithubに置いて Github Pagesを使えばhttpsに対応したサイトを作ることはできます。

しかし、Github PagesでサーバにするにはPublicリポジトリにする必要があり、ちょっと試すだけで外に公開するのはちょっと、、というときにはあまり向いていません。

そこで、今回はexpressを使ってhttpsサーバを立ててローカル環境で動かすための方法をまとめました。また、httpsに関する技術用語で理解が曖昧な箇所があったので、それらの用語補足もいれました。

動作環境
・MacOSX 10.15.3
・LibreSSL 2.8.3

1. https対応に必要な証明書を作成する

以下のサイトを参考にさせていただきました。

weblabo.oscasierra.net

https対応するには、まず対象となるサイトに秘密鍵 (拡張子:.key)と、認証局によって認証された証明書(拡張子:.crt) を格納しておく必要があります。

秘密鍵は、opensslコマンドを使用します。Macの場合、opensslコマンドがすでにあるので、以下のように実行します。

$ openssl genrsa 2024 > cert_server.key

これで秘密鍵「cert_server.key」が生成されます。

httpsで使う証明書は、本来は認証局が作成しますが、今回は自分で作成します。

蛇足ですが、本来認証局が証明書を発行するためには、Webサイトの製作者や組織の所在を確認するようです。
たとえば、日本の認証局であるサイバートラスト株式会社では、証明書を発行したい企業については以下を確認すると書かれていました。

登記簿謄本など公的機関が発行する書類
社会的に信頼された第三者機関が管理するデータベースの登録情報
企業の代表電話番号から申請責任者(SSL/TLS サーバー証明書申請の責任者)を辿り本人の在籍と申請意思などを確認する
上記の1つでも確認が取れない場合は、証明書を発行しません。

引用:企業の実在証明 「実在証明」はなぜ必要なのか?

今回は、認証局を自分が担当して証明書を作ります。自己証明証明書、いわゆる「オレオレ証明書」です。 まずは秘密鍵を指定する形で、証明局への要求書を作ります。

$ openssl req -new -key cert_server.key > cert_server.csr

このとき、制作した組織の所在地、サイトURLを順番に入力していきます。サイトURLの箇所では自宅LAN環境でのサーバ役PCのIPアドレスを入力しました。自宅でDNSを動かせば、https://testsite.com のような表記ができるのですが、そこまでは不要だったのでIPアドレスにしています。

Common Name (eg, your name or your server's hostname) []:192.168.0.5  

これで、証明局への要求書「cert_server.csr」が生成されます。

最後に、自分が証明局となって、サーバの証明書を発行します。以下のコマンドを実行します。

$ openssl x509 -req -days 365 -signkey cert_server.key < cert_server.csr > cert_server.crt

なお、x509は、X.509 という国際標準規格に準拠するオプションです。

電子証明書のデータフォーマットは X.509 という国際標準規格に準拠しています。

引用元:SSL/TLS サーバー証明書の基礎知識|BLOG|サイバートラスト株式会社

これで、cert_server.crtという証明書ファイルが生成されます。

2. Expressを使ってhttpsサーバを構築する

次に、作成した秘密鍵、証明書を指定するコードを記述します。

gist12e4cf873c6231077053325aaa65d5cf

この書き方の場合、./certkeysとserver.jsは同じ階層に配置されている必要があります。

あとは、npmを使って以下のように進めます。

$ npm init --y  
$ npm install express
$ node server.js

Self certified https site on Safari

これでサイトが表示されます。あとは、index.htmlなど必要なページを入れればWebサイトになります。

3. httpsの警告について

ここまでの手順でhttps対応にはなったのですが、証明書が登録された認証局から発行のものではないことから、ブラウザで警告が出ます。

Safariの場合、「危険性を理解している場合はこのWebサイトを閲覧できます」と表示され、閲覧しようとするとPCの管理パスワード (あるいはTouchID) を求められます。

Firefoxの場合、自己署名のため信頼できないと示され、「危険性を承知で実行」を選ぶとサイト閲覧ができます。

No certified https site on Firefox

Edge (Chronium版) の場合、以下の警告が出てサイトの表示ができませんでした。方法があるのかもしれませんが、他のブラウザと異なり表示するボタンが見つかりませんでした。

No certified https site on Edge

これらの警告が出る原因は、閲覧したWebサイト (今回はhttps:192.168.0.5) に含まれる証明書がどこから発行されたか不明のためです。
以下に書かれているように、Webブラウザには世界的に大手の認証局が発行した証明書 (ルート証明書) が組み込まれています。閲覧したサイトの証明書が、Webブラウザの持つ認証局発行ではない場合、今回のような警告が出ます。

Webブラウザなど公開鍵暗号を利用するソフトウェアの開発者は、世界的に有力な大手の商用認証局や政府機関の認証局など、信頼するに足ると思う機関が自ら発行する証明書を事前に入手して組み込んでおき、証明書を上位にたどっていった結果その機関の証明書に行き当たったら正しく検証されたと判断するようにしている。

引用元:ルート証明書とは - IT用語辞典 e-Words

ルート証明書を発行する認証局をルートCAと呼びます。下記のように、ブラウザによってルートCAは少し異なる場合があるため、自分でルートCAを追加することが可能なブラウザが多いようです。

世界にあまたある認証局のうちどの機関をルートCAとみなすかはそれぞれのソフトウェアの開発者が決めるため、ソフトウェアによってルートCAは異なることがある。
また、多くのソフトウェアには利用者がルートCAとみなす認証局の証明書を追加する仕組みが備わっており、例えば、利用者の居住地の政府機関の発行したルート証明書などを後から組み込むことができるようになっている。

引用元:ルートCA(ルート認証局)とは - IT用語辞典 e-Words

今回はサイト構築とアクセスができたので実施しませんでしたが、ルート証明書を作ってブラウザに登録すると、今回のエラーは消えます。
たとえば、以下のサイトには自己署名のルートCA証明書を作る方法が書かれています(日本語です)。

F-Secure User Guides

4. おわりに

個別の情報は見つかるのですが、一貫して作るための方法や用語解説がうまく見つけられなかったので書いてみました。