試運転ブログ

技術的なあれこれ

ローカルでhttpsサーバの立て方

コールバックなどの関係で今使っているドメインをそのまま使って、手元の変更をすぐに確認したい場合などに、ローカルでhttpsサーバをたてて静的なサイトを用意したいことがありました。Mac OSGoogle Chromeでの確認の仕方を備忘録として必要なコマンドを残しておきます。

今回は https://my.example.com/ に手元の環境のファイルをホスティングする方法を記載します。

主に参考にした以下のサイトと実行しているコマンドはほぼ同じです。大事なことも多く書かれているので一度読んでみることをお勧めします。

web.dev

mkcertのインストール

mkcert はローカルでの開発用に証明書の発行できるツールです。

brew install mkcert
mkcert -install 

証明書の発行

$ mkcert my.example.com

Created a new certificate valid for the following names 📜
 - "my.example.com"
The certificate is at "./my.example.com.pem" and the key at "./my.example.com-key.pem" ✅
It will expire on 25 August 2023 🗓

$ ls
my.example.com-key.pem  my.example.com.pem

注意: ここで生成されたmy.example.com-key.pem と my.example.com.pemは他人には共有しないようにしてください。

http-serverのインストール

npm install -g http-server

http-serverの起動

$ mkdir src
$ cd src
$ echo "<h1>Hello World!</h1>" > index.html
$ http-server --ssl --port 443 --cert ../my.example.com.pem --key ../my.example.com-key.pem
Starting up http-server, serving ./ through https
Available on:
  https://127.0.0.1:443
  https://192.168.11.2:443
Hit CTRL-C to stop the server

/etc/hostsの更新

my.example.comのアクセスを127.0.0.1に向けるために、お好きなエディタで/etc/hostsに以下の1行を追加(sudo vim /etc/hostsなど)。root権限は必要です。

127.0.0.1 my.example.com

注意: 作業がおわったら削除かコメントアウトしてください。消し忘れると、本当のIPの方にアクセスできなくなり、いろいろ事故るので気をつけてください。

ブラウザでアクセス

ブラウザで https://my.example.com/ にアクセスすることでファイルにアクセスできます。

f:id:otameshi61:20210525233324p:plain

以上!

とりあえずファイルにアクセスしたいだけなら、以上です。

その他

その他いくつかためしたことなどのメモです。

ルーティングしたい場合

SPAなどで基本的に特定のファイルを返したいけど、/static配下は静的なファイルを返したいみたいなときはこんな感じのコードを書けばいけます。

const express = require('express');
const path = require('path');
const port = 443;
var app = express();

var fs = require('fs');
var https = require('https');
var options = {
  key: fs.readFileSync('../my.example.com-key.pem'),
  cert: fs.readFileSync('../my.example.com.pem')
};
var server = https.createServer(options, app);

app.use('/static', express.static(path.join(__dirname, 'static')))

app.get('*', function (request, response) {
  response.sendFile(path.resolve(__dirname, 'index.html'));
});

server.listen(port);
console.log("server started on port " + port);

コードは以下のサイトを参考にしています。

Node.js Express で HTTPSを利用するパターン - Qiita

mkcertの証明書について

mkcert -installコマンドでは、ローカルのsystem trust storeに登録されたというログが出力されます。

$ mkcert -install
Created a new local CA 💥
Sudo password:
The local CA is now installed in the system trust store! ⚡️

キーチェインで確認すると以下のルート証明書が有効にされていることが確認できます。

f:id:otameshi61:20210526001237p:plain

以下のコマンドで生成した証明書はブラウザの証明書の確認のところから、ルート証明書とチェーンになっていることがわかります。

$ mkcert my.example.com

Created a new certificate valid for the following names 📜
 - "my.example.com"
The certificate is at "./my.example.com.pem" and the key at "./my.example.com-key.pem" ✅
It will expire on 25 August 2023 🗓

f:id:otameshi61:20210526003055p:plain

Chromeの--host-rules

以下のブログでも紹介されている--host-rulesを使うとhostsファイルのようにドメインとIPのマッピングを更新できるとのこと。実際に試してみたのですが、確かに宛先は変わったのですが証明書のエラーが出てしまって、今回のケースでは使えないようでした。あまりちゃんと原因を追っていないので詳しい人がいたら知りたいです。

blog.jxck.io

こんな感じのコマンで試してました。

/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --host-rules="MAP my.example.com 127.0.0.1" --user-data-dir="/tmp/aaa" https://my.example.com

感想

opensslのコマンドを調べて証明書を用意して、次に必要になった時には記憶からなくなっているのでもう一度調べるみたいなことを繰り返していましたが、今は調べてみたらいろいろ便利なツールが出ていて驚きました。

途中でリンクを貼ったmaudnalsさんとjxckさんのブログはlocalhostというドメイン名の特異性などに触れられていたとても勉強になりました。

誰かのお役に立てたら幸いです。