ローカル HTTPS 開発専用ツール SPTTH を公開した
Intro
http://localhost:3000 での開発には限界がある。
しかし、本番と同じように https://example.com でアクセスできる環境をローカルに作るには、ドメインの解決、証明書の発行、443 での起動など、少し手間がかかる。
そこで、必要な全てを 1 つのツールで行い、様々な開発環境を再現するためのツールを開発したので、紹介する。
- Jxck/sptth: reverse https proxy (https - sptth) for local development
localhost の罠
localhost はあまりにも特別なホストであるため、権限などの挙動は、本番ドメインにデプロイすると変わる。
また、本番ドメインとは Origin が異なるため、連携のためのあらゆるセキュリティ境界も変わる。
もし、複数のサービスの中で、1 サービスだけ手元で動かし、他は本番を参照したいような開発があっても、localhost ではうまく再現できない場合が多い。
つまり、ある程度複雑なサービスを開発していれば、http://localhost:3000 での開発など、早々に限界を迎えるのだ。
もし本番が https://example.com ならば、ローカルでも同じく https://example.com で開発したい。
しかも、自己署名証明書で起動し、ブラウザが出す証明書エラーを無視しながら開発するのもやめたい。
どうしたら良いだろうか?
3 つの sudo
手法自体は知られている。以下の 3 つを行えば、ローカルで起動したサーバに https://example.com でアクセスできるようになる。
/etc/hostsを修正し、example.com を 127.0.0.1 にする- mkcert でローカル CA を立て、example.com の証明書を発行する
- 443 でサーバを起動する
そして、この 3 つのステップ全てに sudo が必要だ。
なぜならどれも、システムにとって重要な操作をしているからだ。
これらを手順書だけでやり遂げるのは、開発慣れしていない人には難しい場合もある。
ここまでやっても、アプリサーバ自体が証明書を使って HTTPS を受けるようになっている必要があるが、通常サーバが直接 HTTPS を喋るようには作らないだろう。基本的に TLS の終端は LB や CDN などで行い、アプリサーバは平文で受け付ける構成が一般的だからだ。
筆者はずっと、この 3 つを 1 つのツールで 1 回の sudo で実行できないか、と考えていた。
Requirement
要件はこうだ。
- ローカル DNS を立ち上げ、名前解決を 127.0.0.1 にする。
- ローカルに CA を立ち上げ、動的に証明書を発行する。
- プロキシを 443 で立ち上げ、ローカルサーバには平文で転送する。
全てを 1 つのコマンドにし、一回の sudo で起動できれば、認証も一回で済みローカルへの影響も最小限にできる。
と、頭では思いついていたが、手を動かすとなると相応の時間がかかる。
しかも、DNS と CA と Reverse Proxy を実装するとなると、それなりに面倒だ。
しかし時代が変わり一晩で動くところまでいけたため、公開することにした。
それが sptth だ。
SPTTH
以下のような設定を TOML に記述する。
[dns]
listen = "127.0.0.1:53"
upstream = ["1.1.1.1:53", "8.8.8.8:53"]
[[record]]
domain = "example.com"
A = ["127.0.0.1"]
AAAA = ["::1"]
[[record]]
domain = "example.net"
A = ["127.0.0.1"]
AAAA = ["::1"]
[tls]
ca_dir = "~/.config/sptth/ca"
cert_dir = "~/.config/sptth/certs"
[[proxy]]
domain = "example.com"
listen = "127.0.0.1:443"
upstream = "localhost:3000"
[[proxy]]
domain = "example.net"
listen = "127.0.0.1:443"
upstream = "localhost:4000"
そして、以下のように実行する。
$ sudo sptth config.toml
初回起動時にローカル CA を立ち上げるので、それを許可する。
あとは、OS の DNS 設定を 127.0.0.1 に変えるだけだ。
ブラウザから https://example.com にアクセスすれば http://localhost:3000 に、https://example.net にアクセスすれば http://localhost:4000 にアクセスできる。ローカル CA で署名した正しい証明書なので、URL バーも赤くならない。
sudo が一個になり、設定も一箇所にまとめて、複数のサービスを デプロイしたときと同じブラウザの状態 で操作することができるようになる。ブラウザが持つ Permission も Origin も Security Surface も、本番と同じ条件で開発できるのだ。
Architecture
基本的には、DNS、CA、LB を 1 つのツールに詰め込んだだけだ。
DNS は 53 (sudo) で起動し、toml に書いたドメインだけ、指定した A/AAAA レコードを返し、それ以外は upstream に移譲するようになる。
CA は、初回起動時にルート証明書を OS の証明書ストアに入れる(sudo)。その上で、毎回 toml に書かれたドメインの証明書を発行する。
LB は、443 (sudo) で起動し、リクエストを受けたら upstream のローカルサーバに転送する。したがって、ローカルで開発しているサーバは今まで通り localhost:3000 などで開発すれば良い。
以上を 1 つのコマンドにしているため、sudo が一回で済み、toml を変えるまでは起動しっぱなしでよくなる。
必要な設定は、OS の DNS 設定の変更だけだ。
Install
現在、ビルドを GitHub で配布している状態なので、それをダウンロードして実行して欲しい。
https://github.com/Jxck/sptth/releases
ツールの性質上、悪意があれば DNS クエリをすべて抜き取ったり、任意の証明書を発行して Person in the Middle 攻撃が可能だ。そこで、署名などはきちんと付けるようにしている。必要に応じて検証して欲しい。
一応 Linux / Windows にも対応してはいるが、環境がないので試していない。
ちなみに、ローカル環境を壊しても責任は取れないので AT YOUR OWN RISK で使用することを前提に公開している。
心配であれば、最初に書いた旧来の環境構築を自分で行うことをおすすめする。
Implementation
プロトタイプはすべて Codex App の音声入力だけで開発した。
コードは一行も書かず、読んでない。
とはいえ、プランの段階でだいぶ脱線する場面もあるので、任せきりにはしていない。こちらには、かなり明確に方針とアーキテクチャが浮かんでいるため、そのキャリブレーションには相応の時間をかけている。
今後の開発はこうなると思うので、そのうえでクオリティを担保するような方法を探る意味でも、様々な取り組みを試す場としている。
特に Codex と Claude の相互レビューや、クオリティ担保系の Skill はある程度ワークしているように思う。
Claude Code Security も解放されたら試したいが、それ相当のものを自分で Skill として組み、コマンドとしても使えるようにしている。
引き続き、「書いてない読んでないコードのクオリティをどう担保できるか」を試す場にしたい。
Contribution
各地で見られるように、AI による PR も増えてきたが、レビューする気はない。
代わりに、Issue template にプロンプトを書けるようにした。
AI で実装するためのプロンプトをもらい、そのプロンプトをこちらで兼用しながら、こちらのガバナンスの元で実行して開発し、チェックしてリリースする方針だ。
もちろん、プロンプト無しで、単に困った部分を Issue にファイルしてくれても構わない。
Outro
頭に描いたものを、可処分時間を過度に浪費せずに実現できるようになったのは、非常にありがたい。
そして、長年なんとかしたかった問題も解決できたので、非常に満足度が高い。
あと 10 年早く欲しかった。