0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ECSからFirebase Authにアクセスできない理由を特定する方法(Redisの仕様に注意)

0
Posted at

はじめに

本記事では、AWS ECS をプライベートサブネットで運用している際に Firebase Authentication がタイムアウトする問題について、
原因を切り分け、最終的に Redis Serverless(Valkey)の仕様に行き着いた過程と解決策を解説します。
Firebase 側の問題に見えて、実際は Redis の接続仕様が原因というケースは非常にハマりやすいため、同様の構成で困っている方の参考になれば幸いです。

この記事でわかる・できること

  • ECS(プライベートサブネット)から Firebase Auth に接続できない原因の切り分け方法
  • 「ECS Exec は成功するのにアプリは通信できない」理由
  • ElastiCache Redis Serverless(Valkey)の罠仕様
  • 問題を確実に解消するための実践的な解決策

この記事の対象者

  • ECS + Rails API を使っている人
  • Firebase Authentication をバックエンドで検証している人
  • ElastiCache(特に Serverless / Valkey)を初めて使う人
  • 「ネットワークは通っているはずなのに Timeout する」問題で詰まっている人

動作環境・使用するツールや言語

  • OS:Amazon Linux(ECS Fargate)
  • AWS:ECS Fargate(Private Subnet), ElastiCache
  • 言語:Ruby 3.4.4
  • フレームワーク:Rails 8.0.2
    Firebase Authentication
    redis / firebase_id_token gem

1. 発生した問題の概要

ECS(プライベートサブネット)上で稼働する Rails API において、
Firebase Authentication を使ったリクエストが常にタイムアウトしてしまいました。

ログ上では以下のようなエラーが出力されていました。

証明書の取得に失敗しました: Connection timed out

一見すると、

  • Firebase 側の障害
  • ECS からインターネットに出られない
  • DNS / NAT / VPC Endpoint の設定ミス

などが疑われます。

2. ECS Exec は成功するのに、なぜアプリは通信できないのか

まず混乱しやすいポイントとして、ECS Exec は問題なく成功していました。

ECS Exec ✅ 成功
コンテナ内で curl htps://www.googleapis.com/...(Firebaseのドメイン) ✅ 成功

ここで多くの人がこう考えます。

「Firebase へは到達できている。じゃあ、どこのネットワークが悪い?」

しかし、これが 落とし穴でした。

3. Firebase Auth は「直接通信」だけでは完結しない

Rails で Firebase Authentication を扱う際、多くの場合、

  • firebase_id_token gem

を利用します。

この gem で取得した公開鍵(証明書)をRedisにキャッシュする設計としていました。
処理は以下の流れになっています。

  1. Google から公開鍵(証明書)を取得
  2. Redis にキャッシュ
  3. 次回以降は Redis から読み込み

firebase_id_token gemを使った場合のplantUML図
image.png
つまり、
Redis に接続できないと Firebase Auth も失敗する
という構造です。

4. 真犯人は Redis Serverless(Valkey)の仕様

今回使用していた Redis は以下でした。

  • ElastiCache Serverless
  • エンジン:Valkey 8.x
  • 転送中の暗号化:有効(必須)

Redis Serverless の重要な仕様

項目 Redis Serverless
ポート 6379
TLS 必須
平文接続 ❌不可
対応クライアント TLS 対応必須

Rails 側では以下のように初期化していました。

Redis.new(url: ENV["REDIS_URL"])

これは TLS 非対応(平文)接続です。

何が起きていたか

  • TCP 接続は成立
  • Redis 側は TLS を待つ
  • クライアントは平文を送信
  • お互いに一切応答せず timeout

結果として、以下の状態となっていました。

  • redis.ping → Redis::TimeoutError
  • Firebase 証明書キャッシュ失敗
  • 認証エラー

5. なぜ気づきにくいのか(ハマりポイント)

この問題が厄介な理由は以下です。

  • セキュリティグループ ✅ 正しい
  • DNS ✅ 正常
  • Google への curl ✅ 成功
  • ECS Exec ✅ 成功

👉 「ネットワークは全部 OK」に見えます。
しかし実際は、

Redis Serverless の TLS 強制仕様

という サービス固有の制約が原因でした。

6. 解決策(確実に直す方法)

解決策は大きく分けて 2 つあります。

方法① Redis OSS(非Serverless)に切り替える(おすすめ)

MVP・個人開発ではこれが最短・最安定です。

ElastiCacheからRedis OSS キャッシュに移行します。

  • 転送中の暗号化:OFF
  • REDIS_URL だけで接続可能
Redis.new(url: ENV["REDIS_URL"])

設定がシンプルで移行コストも最小化できます。

方法② Redis Serverless を使い続ける場合

TLS を明示的に指定する必要があります。

Redis.new(
  url: ENV["REDIS_URL"],   # 接続先RedisのURL(環境変数REDIS_URLから取得)
  ssl: true,               # SSL(暗号化通信)を有効化
  ssl_params: {            # SSLの詳細パラメータ指定
    verify_mode: OpenSSL::SSL::VERIFY_PEER
  })

※ 本番では CA 証明書を使った検証が推奨です。

まとめ

今回の問題は、Firebase の障害でも、ECS のネットワーク設定でもなく、Rails の実装ミスでもありませんでした。

原因は 「Redis Serverless(Valkey)は TLS 必須」 という仕様です。

本記事のポイント

Redis Serverless は平文接続できない
MVP では Redis OSS の方が圧倒的に楽
「Timeout」はネットワーク以外が原因のことも多い

同じ構成で悩んでいる方の助けになれば幸いです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?