2019-03-30

local開発環境でhttpsの動作検証時にlocal-web-serverとmkcertが便利

何を解決するのか

mkcert

FiloSottile/mkcert: A simple zero-config tool to make locally trusted development certificates with any names you'd like.

  • CAと証明書を作成できる
  • CAを開発マシン上にインストールできるので、開発マシン上の https サーバを正しくユーザーに検証してもらえる

開発環境を https にしておく必要がある場合に CA と証明書を管理するために openssl コマンドを覚えてくださいと言わなくて済む。

local-web-server

lwsjs/local-web-server: The modular HTTP2 web server for productive full-stack development

開発環境で便利に使えるサーバで

  • https / http2 対応
  • reverse proxy になるのでどんな開発環境とも組み合わせることができる
  • 単体でも static assets の serve はできる

ということでいくつかの環境1で開発を行う機会がある場合はそれらの https 接続を全部まかなうことができて便利。

実際に https reverse proxy として動かす際には上の mkcert で作成した cert と key をコマンドラインオプションや設定ファイルなどで与えてあげるとよい。

どのようなシチュエーションで必要になるか

HTML5 の JavaScript API は、以前はいつでも利用できたが、最近ではプライバシーの観点から https 接続を必須にする方向に変わってきている。ただし、localhost は特別扱いしてくれるため http でも利用できる。したがってサーバを動かしている PC 上ではいつでも API を利用することができるので、PC 上では動作、デバッグが可能である。

しかしモバイルデバイスでこれらの API を利用する場合、モバイルデバイス上では開発サーバが動いていないので、モバイルデバイスからは localhost でアクセスすることができない。つまり、モバイルデバイス実機での API の利用のためには開発サーバが https を喋っている必要がある。

使い方

  1. まず mkcert -install して rootCA を開発サーバ上のシステム全体(あるいは Firefox)が認識できるようにする
  2. mkcert <hostname and/or IP> で接続するアドレスに対応する証明書を作成する

2 の際はサーバへ接続する際に利用する名前、IPアドレスを列挙する必要があることに注意。例えば

  • localhost
  • 192.168.0.1

で接続するのであれば

mkcert localhost 192.168.0.1

で生成する。すると localhost+1-key.pem と localhost+1.pem ができる。

勘のいい方はお気づきだと思うが、つまり、 IP アドレスが変われば証明書も作成し直しである2

で、証明書ができたら以下のように local-web-server を起動する。

ws --cert <cert file> --key <key file> --rewrite '/* -> http://localhost:3000/$1'

これで例えば rails server への接続を https にすることができる。ws は local-web-server のコマンドの名前。デフォルトでは 8000 で立ち上がるので

https://localhost:8000

に接続すると https で rails server に繋がるということになる。

※ すべて reverse proxy 経由でのアクセスになるので、開発サーバが Host ヘッダを見ていない場合はリンクを辿った際に思ったように動作しなくなってしまう。まぁそんな環境をそのままイマドキの https 環境に持っていこうというのはそもそも無理がある。

モバイルデバイスへのCAの転送

実機から開発サーバへ https 接続するには、どうにかして rootCA.pem をモバイルデバイスへ転送してインストールする必要がある。手段は

  • mail
  • Dropbox
  • BitTorrent Sync
  • AirDrop

なんかもあるけど、

claudiodangelis/qr-filetransfer: Transfer files over wifi from your computer to your mobile device by scanning a QR code without leaving the terminal.

こういうの一つ用意しておくといいかも。

terminal 上で QRCode を表示する系のやつは設定によってはちゃんと読み取れるコードを描画できないので、デフォルトのターミナルとかじゃないとダメです。

自分で試した限りでは

svenkatreddy/qr-filetransfer: Transfer files over wifi (or) internet from your computer to your mobile device by scanning a QR code without leaving the terminal. とデフォルトの Terminal.app で転送できました。他のツールは mime/type が設定できずにテキストファイルが表示されるだけになる可能性があります。

考えなきゃいけないこと

手元の環境用の証明書の管理およびそれを .gitignore すること

mkcertは共有には使えない

Installation Warning: the rootCA-key.pem file that mkcert automatically generates gives complete power to intercept secure requests from your machine. Do not share it.

と書かれている。

共有の際は ngrok などを利用するのがよいのかもしれない。

逆に、頑張って我慢すれば ngrok だけで開発できなくはないけど、当たり前だけどかなり遅いし制限もあるので、素直に手元で https サーバ、証明書の管理ができるようになりましょう。

参考

  1. 例えば Rack / PHP / Node.js 

  2. もともとSSLが分かってる人には当たり前ですが 

About

例によって個人のなんちゃらです