🚘

【MacOS】Nginx+オレオレ証明書の手動信頼でローカル開発環境を任意ドメイン+SSL化する

2023/12/18に公開

まえがき

株式会社エアークローゼット 新卒3年目の小林です。
この記事はエアークローゼット Advent Calendar 2023 18日目の記事です。

先日、弊社からDisney FASHION CLOSET というディズニーキャラクターをモチーフとしたバウンドコーデを借りられるサービスがリリースされ、私はそのフロントエンド全体の設計・開発と、認証周りの開発を担当していました。
https://disney.air-closet.com/

今回は認証周りの基盤づくりの話。
ローカル開発環境をブラウザに怒られないやり方でSSL化し、HttpOnly SecureなCookieを使って開発できるようにした話です。

背景 - HTTP Cookieを使った認証

今回のサービスではブラウザ-API間で認証情報を取り回すために、Http Cookieを使っています。
具体的には、ログインAPIからのレスポンスにSet-Cookieヘッダを付与し、以後の認証が必要なAPIのやりとりではwithCredentialなリクエストとして送ることで、改ざんが難しく、かつ取り回しやすい認証情報のやりとりを実現しました。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie

今回採用した認証構成がどのようにして外部攻撃を防いでくれるのか、という面に関してはまた追って記事を書いたり追記していくとして、今回は手短に任意ドメイン + SSL化の手法だけ共有します。

やり方

ざっくり言うと

  1. ローカルマシンのhostを書き換え、localhostを任意のドメインから見れるようにする
  2. Dockerにプロキシ(Nginx)を立て、任意のドメインからのリクエストを任意のポートに飛ばせるようにする
  3. 自己証明書を作り、Nginxのssl設定に自己証明書をセットする
  4. 自己証明書をローカルマシンに取り込み、信頼するよう設定する

です。

今回は、hoge.local-dev.comfuga.local-dev.com で、ローカルに立てた2つの開発環境にアクセスしてみます。

今回使ったDockerのコード置いときます
https://github.com/Helicoir/localhost-ssl-proxy

1. ローカルマシンのhostを書き換え、localhostを任意のドメインから見れるようにする

Linux系OSにおけるホスト名とIPアドレスを対応させるためのファイルに、使いたいドメインを書きます

$ vim /private/etc/hosts
127.0.0.1 hoge.local-dev.com
127.0.0.1 fuga.local-dev.com

2. Dockerにプロキシ(Nginx)を立て、任意のドメインからのリクエストを任意のポートに飛ばせるようにする

先ほど設定した各ドメインと、ローカルマシンの任意のポートを、プロキシサーバー経由でつなぎます。

server {
    listen 443 ssl;
    server_name hoge.local-dev.com;
 
    location / {
      proxy_pass http://host.docker.internal:3000;
    }
}

server {
    listen 443 ssl;
    server_name fuga.local-dev.com;
 
    location / {
      proxy_pass http://host.docker.internal:4566;
    }
}

特に重要なのが proxy_pass http://host.docker.internal:4566;の部分で、host.docker.internal:{port}を使うことで、ローカルマシンの任意のポートへアクセスを振り向けることができます。

今回の例でいうと、

  • localhost:3000 - hoge.local-dev.com
  • localhost:4566 - fuga.local-dev.com

というふうな接続が確保されました。

ここまでで、任意のドメインでローカル開発環境にアクセスする ことができます。

3. 自己証明書を作り、Nginxのssl設定に自己証明書をセットする

ここからは自己証明書を作り、ブラウザに怒られない信頼状態になるまで設定していきます。

自己証明書の作り方は巷にあふれており、そちらの詳しい解説を見てもらったほうがわかりやすいので割愛します。
MacOS標準 & 各種パッケージ管理ツールでインストールしやすいOpenSSLを使うのが一番楽そう、かつ明確にSANの設定を入れられるのでブラウザ上でも怒られることなく動くのでおすすめ。
こちらの記事が詳しいです。

https://pvision.jp/tech/2023/04/importing-self-signed-certificate-as-root-certificate

証明書の作成が完了したら、以下のようにnginx.conf を設定していきましょう。

server {
    listen 443 ssl;
    server_name disney.ac-local.com;

    ssl on;
    ssl_certificate /etc/nginx/certs/ac-local.com/server.crt;
    ssl_certificate_key /etc/nginx/certs/ac-local.com/server.key;
 
    location / {
      proxy_pass http://host.docker.internal:19834;
    }
}

証明書の配置について、サンプルリポジトリではdocker-compose.ymlにてvolumeの設定をしているため、ローカルにこのように配置するときれいに入ります

ここまで対応すると、さきほど設定したドメイン + httpsでアクセスすること自体は可能になりますが、公開認証局からの信頼がないためブラウザから警告が出ます。
(警告を無視してサイトにアクセスしてもhttps扱いとしてhttpOnly Cookieが使えるかは要検証。全体的な振る舞いはhttps扱いになっているようなのでできそうですが……)

4. 自己証明書をローカルマシンに取り込み、信頼するよう設定する

ブラウザからの警告を出さない方法として、ローカルマシンの設定でこの証明書を信頼する方法があります。
MacOSのキーチェーンアクセスにて、.crt拡張子がついた証明書を取り込み、信頼状態に変更します。

具体的には以下↓ (都合により *.ac-local.com になっていますが、他ドメインでも同様です)



これにより、ブラウザ上の警告が消え、ストレスなくアクセスすることが可能になります。

おわりに

最後までご覧いただきありがとうございました!

エアークローゼット Advent Calendar 2023はまだまだ続きますので、ぜひ他のエンジニア、デザイナー、PMの記事もご覧いただければと思います。

また、エアークローゼットはエンジニア採用活動も行っておりますので、興味のある方はぜひご覧ください!

https://corp.air-closet.com/recruiting/developers/
https://www.wantedly.com/companies/airCloset/projects

Discussion