Corredor

ウェブ、プログラミングの勉強メモ。

Node.js でオレオレ証明書を利用した簡易 HTTPS サーバを立てる

Real World HTTP ―歴史とコードに学ぶインターネットとウェブ技術

Real World HTTP ―歴史とコードに学ぶインターネットとウェブ技術


※2018年1月29日の記事の改善版 (というかソチラの記事が下書き版だったのに間違えてアップしていた) です。

neos21.hatenablog.com


テストのために自己署名証明書を使用するサーバを立てることになった。

そこで、MacOS に標準で入っている openssl コマンドを利用して自己署名証明書を用意し、Node.js で簡易的な HTTPS サーバを立ててみる。

オレオレ証明書を作る

まずは自己署名証明書を作る。自己署名証明書とは要するに「認証局のお墨付きがない証明書」のことで、データが改竄されていないことの証明には使えない。今回はあくまで開発用に作るが、本来オレオレ証明書は使うべきでないシロモノなので、お忘れなきよう。

MacOS は最初から openssl コマンドが使用できたが、Linux などで openssl コマンドがない場合は別途インストールする。

# yum を使っている場合は以下で
$ yum install openssl

# apt の場合は以下で
$ apt-get install openssl

Windows の場合は「Win32 OpenSSL」というツールをインストールすれば良いようだ (未検証)。

openssl コマンドを使って、秘密鍵 → 公開鍵 → デジタル証明書、の順に作る。

# 秘密鍵を作る → key.pem ができる
$ openssl genrsa -out key.pem 1024

# 公開鍵を作る : key.pem を指定する。csr.pem ができる
$ openssl req -new -key key.pem -out csr.pem
  # 対話式で国だのなんだの聞かれるので、適当に入力したり、空欄で飛ばしたり

# デジタル証明書 : key.pem と csr.pem を指定する。cert.pem ができる
$ openssl x509 -req -in csr.pem -signkey key.pem -out cert.pem

これで key.pemcsr.pemcert.pem という3つのファイルができる。

Node.js で簡易 HTTPS サーバを立てる

次に、Node.js に組み込みの https モジュールを使って、簡易 HTTPS サーバを作る。今回は Node.js v6.11.0 にて検証。

作業ディレクトリに my-server.js (名前は任意) という空ファイルを作成し、同じディレクトリに key.pemcert.pem を格納しておく (csr.pem は今回使わない)。

my-server.js を開き、以下のように実装する。

const fs    = require('fs');
const https = require('https');

// 秘密鍵とデジタル証明書ファイルを指定する
const options = { 
  key : fs.readFileSync('key.pem'),
  cert: fs.readFileSync('cert.pem')
};

// サーバを起動する
https.createServer(options, (req, res) => {
  console.log('リクエストを受信');
  // レスポンスの設定
  res.writeHead(200);
  res.end('Hello World');
}).listen(8443);  // ポートを指定して待受スタート

console.log('自己署名証明書サーバを起動');

https.createServer() の第2引数が、リクエストを受け取った時に実行される関数となる。今回は HTTP ステータスコード 200 を返し、画面に Hello World とだけ表示させることにする。ポートは .listen(8443) 部分で指定しているとおり、8443 となる。

my-server.js が実装できたら、Node.js でファイルを実行する。すると HTTPS サーバが起動する。

$ node my-server.js

自己署名証明書サーバを起動

ターミナルはこのまま待機状態になるので放置。

ブラウザを開き、https://localhost:8443/ にアクセスすると、自己署名証明書を使用している旨の警告が表示されるかと思う。警告を無視してページを開くようにすると、画面に「Hello World」と表示されるはずだ。この際、ターミナルには「リクエストを受信」のログが出ているはず。

終わり

コレにて完了。今回はとりあえず https://localhost:8443/ にアクセスするとオレオレ証明書を利用したページが開ける、というだけの簡素なサーバを立ててみた。ベースは http モジュールと同様なようなので、カスタマイズも可能だ。