自己署名した証明書について、オレオレ証明書と揶揄する呼び方が浸透して、自己署名のリスクという側面はおおいに宣伝されている。一方で、ではどのような手順を踏めば証明書に署名し、発行できるのか、という実態について、知る機会を持つことはなかった。
それはひとえに自分で手を動かして実装したことがないからに他ならない。証明書自体は Let’s Encrypt なり AWS Certificate Manager なりで簡単に発行できるし、一度有効化さえしてしまえばあとはほとんど気にすることもなくなる。開発者を含めたユーザーがまったく意識せずに堅牢な暗号通信をできるというのは強力な仕組みである。門外漢からすると、あまりに完成されすぎていて近寄りがたい印象すら持つ。しかし職業としてウェブシステムを扱う者のはしくれとして、そう甘えた態度を撮り続けるわけにもいかないのも事実だ。そこで自己署名証明書、通称オレオレ証明書である。
この記事ではコマンドラインツールの openssl を使ってふたつの証明書、つまり
- 自己署名したルート認証局の証明書
- このルート認証局により認証したサーバー証明書
を発行し、後者を利用したウェブサーバーを立ち上げ、 TLS 通信することを目標とする。
一通りの実行可能なコードスイートは以下のレポジトリに置く。なお、含まれるソースコードの一部は、Real World HTTP 第2版――歴史とコードに学ぶインターネットとウェブ技術 1 から借用させていただいた。
sato11/go-tls-demo (https://github.com/sato11/go-tls-demo)
細かい動作についてはレポジトリに譲るとして、やっていることとしては次の通りである。
- Dockerfile 内で openssl を利用して秘密鍵の作成、署名リクエストの作成、自己署名による証明書の作成を行う。イメージに証明書が含まれてしまうことになるが、デモ用と割り切って記述を近くにまとめることを優先した。
docker-compose up
により、サーバーが起動して、 curl と go のクライアントからの TLS によるリクエストが行われる。docker-compose up
によりサーバーを起動すると docker ボリュームを介して./certs/
以下にルート証明書がコピーされる。これを macOS の keychain にインポートして信頼させるなど設定すればローカルでの通信も TLS 化できる。
こうしてひとまず、自己署名による認証局とサーバー証明書を発行し、それを利用して TLS 通信するところまでを、手を動かして体験できたことになる。もっとも、このレポジトリ単体ではなんの機能も持たないし、学んだといってもごく基本の部分を参考書通りになぞったに過ぎないとも言える。今後もこれらの作業を自分でなぞることはないはずだし、むしろ手動で行うリスクの方が怖いのでできれば願い下げなのは変わらない。
HTTP/3 では常時 TLS 化が原則となるという。そうなるころには TLS は、今よりもよりいっそう、だれもその存在を意識しない「透明な技術」となるはずだ。人はそれを知らずに利用できるし、それでいてそれを知るには難儀すぎるということになる。ではそれでも学ぶ意義とはなにか、と問うならば、それはきっと倫理や良心の話になるだろう。つまり、ユーザーをいたずらにリスクに晒すような実装をしないこと、また、悪意のある実装をそうと見破り、告発することができる目を持つこと。こういったものは、これら技術を生業とする市民に要請される良識としてあるべきで、そしてまたその要請に応えるべく、われわれ技術者はこういったごく基本的な事項について、少しずつであっても正しく理解するステップを踏んでいくべきなのだろう。
-
渋川よしき. Real World HTTP 第2版――歴史とコードに学ぶインターネットとウェブ技術. O’Reilly Japan. ISBN978-4-87311-903-8. ↩