1
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?

Markdown AIチャレンジ!効率化と個性を活かした活用術!

ActionController::Redirecting::UnsafeRedirectError: Unsafe redirect to "http:///〇〇", pass allow_other_host: true to redirect anyway.

Last updated at Posted at 2025-01-01

概要

ECSにおいて、サイドカーコンテナ構成を使用してRailsNginxを組み合わせてシステムを構築しました。その際、Railsのリダイレクト処理においてActionController::Redirecting::UnsafeRedirectErrorと言うエラーが発生し、動作が停止する問題に直面しました。このエラーを解決するまでに多くの時間を要した為、本記事ではエラーの原因ならびに解決方法を詳細に解説します。

エラー内容

detadog.log
"ActionController::Redirecting::UnsafeRedirectError",
					"Unsafe redirect to \"http:///〇〇\", pass allow_other_host: true to redirect anyway."
				]
			},
			"duration": 380000,
			"view": 0,
			"exception_backtrace": [
				# 省略
			],
			"service": "test",
			"action": "index",
			"http": {
				"url_details": {
					"path": "/"
				},
				"status_code": 500,
				"method": "GET"
			},
			"db": 0,
			"timestamp": 1732793088746
		}
	}
}
rails.log
ActionController::Redirecting::UnsafeRedirectError: Unsafe redirect to "http:///login", pass allow_other_host: true to redirect anyway.
/usr/local/bundle/gems/actionpack-7.0.4.3/lib/action_controller/metal/redirecting.rb:193:in `_enforce_open_redirect_protection': Unsafe redirect to "http:///login", pass allow_other_host: true to redirect anyway. (ActionController::Redirecting::UnsafeRedirectError)

以下省略

原因

  • Application Load Balancer(ALB)NginxRails間の通信で、リダイレクト先のURLを生成する為に必要なホストとスキーム情報が正しく伝達されなかった為に発生
  • Railsの設定にconfig.force_ssltureする事で、Railsが全ての通信をHTTPSに統一し、リダイレクト先のURLを正しく作成出来る様になり、エラーが解消される

補足

ホスト(Host)

  • Webのリクエストがどのサーバー(ドメイン名やIPアドレス)に向かっているかを示す情報
  • リクエストヘッダーのHostフィールドで指定する
Host: example.com

スキーム(Scheme)

  • リクエストがどの通信プロトコル(httpまたはhttps)を使っているかを示す情報
  • NginxALBで設定されるX-Forwarded-Protoヘッダーに含まれている
X-Forwarded-Proto: https

解決方法

  • NginxRailsに対して下記の設定を行う

Nginxの修正

  • Nginxdefault.confまたは任意のconfファイル内に修正を行う
  • 修正箇所は、リバースプロシキの設定内に行う
server {
  # 省略

  # リバースプロキシの設定
  location / {

    proxy_pass http://web;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Proto https;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
  }
  # 省略
}

リバースプロキシ内で使用しているメソッドと説明

メソッド 説明
proxy_pass リバースプロキシとしての転送先を指定する。指定したURL(例: http://web)にリクエストを転送する。UnixソケットやIPアドレスも指定が可能。URLの末尾にスラッシュを付けるかどうかで転送先パスの挙動が変わる為、設定に注意が必要
proxy_set_header X-Real-IP クライアントの実際のIPアドレスをバックエンドに送信する。通常、バックエンド側でクライアントのIPアドレスを取得する為に必要
proxy_set_header X-Forwarded-Proto クライアントが使用しているプロトコル(httpまたはhttps)をバックエンドに通知する。この情報により、Rails等が正しいスキームを認識できる
proxy_set_header X-Forwarded-For クライアントIPアドレスのチェーンをバックエンドに送信する。プロキシを通過した全てのIPアドレス情報を保持し、クライアントの追跡を可能にする。$proxy_add_x_forwarded_forがデフォルト設定。独自のカスタム値も指定が可能
proxy_set_header Host 元のリクエストに含まれるHostヘッダーをバックエンドにそのまま送信する。バックエンドでリクエストのホスト情報を正しく認識する為に必要。$hostを使用すると、Nginxの解決したホスト名を送信可能。$http_hostは元のリクエストをそのまま使用する
proxy_redirect バックエンドからのリダイレクトレスポンスをクライアント向けに書き換える。offを指定すると、リダイレクトレスポンスはそのままクライアントに送信される。リダイレクトURLをカスタマイズする場合、正規表現を使って書き換え規則を設定可能(例: proxy_redirect /old /new

Railsの修正

  • config/environments/production.rbを下記の設定にする
  • クラウドのサーバで動作するstagingや検証、テスト等の環境がある場合も、ECSで尚且つサイドカーコンテナー仕様のRailsNginxで動作している場合は、必要に応じて下記の記述を追加する

公式の説明

3.2.35 config.force_ssl
すべてのリクエストをHTTPSプロトコル下で実行するよう強制し、URL生成でも"https://"をデフォルトのプロトコルに設定します。HTTPSの強制はActionDispatch::SSLミドルウェアによって行われ、config.ssl_optionsで設定できます。詳しくはAPIドキュメントActionDispatch::SSLを参照してください。

require "active_support/core_ext/integer/time"

Rails.application.configure do
  # Settings specified here will take precedence over those in config/application.rb.

  # 省略 

  # コメントアウトを外す
  config.force_ssl = true

  # 省略

end  

注意事項

注意 : ローカル環境では、config.force_sslの設定を適用しない

HTTPSが必須になる

  • config.force_ssl = trueを設定すると、すべてのHTTPリクエストがHTTPSにリダイレクトされる
  • ローカル環境でSSL証明書を設定していない場合、HTTPリクエストが失敗する為、動作確認が出来なくなる

HSTSの影響

  • HSTSが有効な場合、一度でもHTTPSでアクセスしたドメインはブラウザ側で「HTTPSでしか通信しない」という状態がキャッシュされる
  • ローカル環境でHSTSが設定されると、仮に後でforce_sslを無効にしてもブラウザがHTTPでの接続を許さなくなり、リセットが必要になる

ローカル環境にHSTSの設定を行ってしまった場合の対処方法

Chromeの場合

  • 手順1: chrome://net-internals/#hsts にアクセス
  • 手順2: Delete domain security policiesに対象のドメインを入力して削除
  • 手順3: ブラウザを再起動

参考資料

参考資料

まとめ

表題のエラーに関しては、通信経路やヘッダーの仕組みについての理解が不足していた為、問題解決に多大な時間を費やしました。この経験を通して、ネットワークやプロトコルに関する知識の重要性を改めて痛感しました。今後は、ネットワークやHTTPヘッダー、リバースプロキシ等の基礎から応用までの知識を深め、より効率的にトラブルシューティングが出来る様にする為、本やネットを利用して知識を深めていきたいと思いました。

1
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
1
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?