CatoSASEクラウドと喧嘩しないバックエンドアプリ開発の進め方
初投稿のあいさつ
はじめまして、株式会社ジンズ(JINS Inc.)でバックエンドエンジニアを勤めています、中島です。
JINSには2024/2にジョインしたばかりで、前職では受託開発会社でデータ分析やAIシステムの開発を行っていました。
割と節操なく色々な技術に手を出してきたバックグラウンドを生かし、米国ECサイトの運用・保守・改善やデータ基盤の刷新プロジェクトなど、割と幅広めに参加しています。
国内トップクラスの眼鏡販売数を誇る企業のシステムを覗いては規模のデカさ、そしてベンチャー的な力強い開発の形跡を見て日々学んでいる最中です。
バックエンドアプリ開発の環境構築といえば
昨今のバックエンドアプリ開発において、Dockerによる仮想環境の構築から逃れることはできません。
クラウド上にサービスにデプロイするにも、Dockerコンテナを利用することで
- gitを用いた開発環境設定の履歴管理が可能に
- チーム間・メンバー間の環境差異を削減
- 機能毎に凝集した保守性の高いシステムの構築
- ローリングアップデート・ブルー/グリーンデプロイによる安全かつ可用性の高いサービスの実現
など、開発目線でも運用目線でも想定できるメリットの枚挙に暇がありません。
我々JINSでも主にAWS ECSを利用し、様々なサービスをコンテナとして運用・管理しています。
Windowsで、ローカルで、仮想環境構築 ⇒ WSL2+Docker
とはいえ、開発自体はローカルで行えるようにしたい…
EC2でコンテナを作るのもいいけどそれなりにお金かかるし、権限の設定面倒だし…
なにより社内のデータを分析したい場合も多く、ローカルにあるファイルをシームレスに取り扱える環境が欲しいのです。
私は普段Windows環境で開発を行っているので、お馴染みWSL2+Dockerを利用することでこのわがままを解消します!
Ubuntu22.04 on WSL2 のインストール方法(公式)
Docker on Ubuntu のインストール方法(公式)
Dockerインストール段階でのエラー
解消しません! 環境構築の段階でエラーが出ますね。よくある話です。
今回ぶつかった壁は、Dockerリポジトリのgpgキーを取得する際にエラーを吐く というものでした。
これ自体の原因は"WSLからcurlを叩いた際にgpgキーが置いてあるサーバーへのsslが弾かれること"、
柔らかく言うと"「よくわからんサーバーに接続?信用ならん!」とcurlが通信を拒否してしまう"ことです。何で?
社内セキュリティ(CatoSASEクラウド)の壁
ある程度ちゃんとした企業であれば社用PCにはセキュリティツールがインストールされており、当然JINSも例外ではありません。
我々の場合、CatoSASEクラウドというセキュリティツールを全社的に導入しています。
そのセキュリティツールの機能の一つに、 TLSインスペクション(SSLインスペクション) というものがあります。
これは"社内から外部へのSSL暗号化通信の中身を検閲する"という機能です。
この場合の通信フローは以下のような感じ
全ての通信は一度Catoさんの検閲所、セキュリティ用のサーバーを経由するんですね。
>apt-get update
のような、よく使われる外部サーバーへのアクセスはそのままトンネルしてくれたりするんですが、Dockerのgpgキーが置いてあるサーバーはその例外のようです。
そのため、WSLから「有名な信用できる」サーバーにアクセスする前に一度、セキュリティ用の「信用ならない」サーバーにアクセスしに行ってしまうわけです。
なぜ信用ならないと判じてしまうか、というと、WindowsにCatoクライアントを入れる際に一緒にインストールされる "サーバー証明書"をWSLは認識しないためです。
WSLはあくまでWindowsとは別のLinuxPCとしてふるまうため、そのあたり共有されていないのです。
対策(※社内セキュリティに仁義を通す)
上記までわかれば対策はシンプルで、Windows側にあるサーバー証明書をWSLに読み込ませます。
ここからは具体的な手順、まずはWindowsの方でサーバー証明書をエクスポートします。
-
証明書一覧にアクセスし、
-
セキュリティ用サーバーのサーバー証明書をexportします。
出力するときのフォーマットは"DER encoded binary X.509(.CER)"でOK。
続いてexportしたサーバー証明書をWSLに読み込ませます。
以下はすべてWSL内で実施します。
-
WSL内でOpenSSLをインストールして、
> sudo apt install openssl
-
サーバー証明書のフォーマットをDERからPEMに変換します。
> sudo openssl x509 -in <サーバー証明書>.cer -inform der -out <サーバー証明書>.pem -outform pem
-
変換したサーバー証明書は既定のディレクトリに配置します。
> sudo mv <サーバー証明書>.pem /usr/share/ca-certificates/
-
念のため権限と所有者を設定して(これは不要かもしれません)
> sudo chmod 644 /usr/share/ca-certificates/cato_networks_ca.pem > sudo chown root:root /usr/share/ca-certificates/cato_networks_ca.pem
-
サーバー証明書一覧に証明書名を追記します。
> sudo echo <サーバー証明書>.pem >> /etc/ca-certificates.conf
-
最後にサーバー証明書のアップデートを実行して設定変更完了です。
> sudo update-ca-certificates
これでdockerのインストールが公式の手順どおりに進められます。
あとはよくあるように、ユーザーにdocker権限を与えて、wslを再起動して、> docker run hello-world
で…
Hello!Docker!
追記
上記と同様、Dockerコンテナから外部へのアクセスもサーバー証明書不足で弾かれることがあります。
基本的にはホストPC(=WSL)のサーバー証明書がコンテナ内に引き継がれるので問題はないのですが、独自でサーバー証明書を管理しているソフトウェアでは同じエラーが起こりえます。node.jsとかnode.jsとか…
その場合も考え方は全く同じ、サーバー証明書を適切に読み込ませてやりましょう。
nodejsの場合は環境変数NODE_EXTRA_CA_CERTS
にサーバー証明書のパスを指定することで解消します。
Discussion