🔒

ローカル開発環境を独自ドメインでSSL化

2021/05/20に公開

改善前

私 (Technote) が先月から開発に携わっているオンライン家庭教師マナリンクの開発環境は Docker Compose で簡単に立ち上がるようになっています。
開発環境構築を行った当時の全体的な構成は以下のような感じでした。

構成

クライアントは Nuxt で http://localhost:8000
API は Laravel で https://localhost
です。

ログインできない問題

Docker Compose と Nuxt の立ち上げが完了し、トップページが表示されて一安心。

開発初日ということで全体感を把握するためいろいろなページを回遊していたところ README に書いてあるアカウントでログイン出来ないことに気づきました。

Chrome の DevTools で Console を見てみると net::ERR_CERT_INVALID というメッセージ
試しに直接ブラウザから https://localhost にアクセスしても NET::ERR_CERT_INVALID

NET::ERR_CERT_INVALID

APIサーバの https化に https-portal というhttpsサーバを使用していましたが、
ローカルではオレオレ証明書しか使用できないことが原因でした。

chrome://flags から無効な証明書を許可して対応しているとのことだったので設定を変更

invalid-cert

これでようやくログインできるようになりました。

ログインクッキーが保存されない

と思ったのも束の間、今度はリロードするとログアウトしてしまうことが判明

DevTools でログイン時のレスポンスを確認すると後ろの方に小さな警告マークが。

warning

マウスを合わせると原因が表示されました。

This Set-Cookie was blocked because it had the "SameSite=Lax" attribute but came from a cross-site response which was not the response to a top-level navigation.

  • Scheme と Port が異なるため CrossSite
  • Cookie の SameSite が Lax で Post 送信

が原因なようです。

SameSite by default cookiesDisabled にすることでようやくちゃんとログインできるようになりました。

SameSite

問題点

  • セキュリティ上の安全性が低くなる設定をしないと開発できないこと
  • 環境構築の手順に前述の設定変更方法も加える必要があり手順が割と増えること
  • フロントのURLとAPIのURLが本番環境のそれと大きく異なること

などが問題だと感じたので対応しました。

改善したこと

  • Nginx の手前にあった https-portal をやめ、mkcert で作った証明書を使用してNginxのSSLリバースプロキシを配置
    • 最初はもともとあった Nginx でSSL化しようと考えましたが、本番ですでに使っていたので触らないようにしました。
  • http://localhost:8000 で動いている Nuxt も host.docker.internal を使用してSSL化

変更後の構成は以下のような感じになりました。

変更後

クライアントは https://localhost-manalink.jp
API は https://api.localhost-manalink.jp

これは本番サイトに近いURLになりました。

https://manalink.jp
https://api.manalink.jp

他にも Makefile で諸々のコマンドを定義していたので

  • hosts への書き込み
  • mkcert のインストール
  • mkcert コマンドの実行

のSSLの設定用のコマンドをまとめて make ssl コマンドだけで完了するようにしました。

init:
	docker-compose up -d --build
	docker-compose exec php-fpm cp .env.local .env
	docker-compose exec php-fpm php artisan key:generate
	docker-compose exec php-fpm chmod -R 777 storage bootstrap/cache
	@make fresh
	@make ssl
ifeq ($(shell uname), Darwin)
ssl:
# 以下割愛

また、以上の設定により、新規の開発者は make init コマンドのみでSSL含めたDocker環境のセットアップが完了します。

躓いたこと

README をちゃんと読んでいなかっので、最初は mkcert で作成した鍵を共有してしまえばmkcertのインストール自体必要ないのではないかと思いました。
しかし mkcert はローカルに認証局を用意してローカル用の証明書を生成するため、それぞれのPCで mkcert をインストールし証明書を生成する必要があります。

https://github.com/FiloSottile/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.

マナリンク Tech Blog

Discussion