現象の詳細
昨今の事情に鑑み、内部専用サイトについて、外部からWAF経由でアクセスできるようにしました。ただ、そのまま無条件アクセスできるのはよろしくないので、関係者だけがアクセスできるようWAFでBasic認証をかけるようにしました。
アクセスは下記の流れで通信していきます。
- WAF (Apache HTTP Server + ModSecurity2)
- ロードバランサー (nginx)
- Webサーバー (nginx)
- アプリケーションサーバー (puma + 自作Webアプリ)
※ 3.と4.は一つのサーバーに同居して、サーバー自体は冗長化している。1.と2.はそれぞれ別サーバーでホットスタンバイの二重化。全てオンプレ。
WAFの所でAuthType Basic
等を設定して、普通のBasic認証を行っています。内部からは2.のロードバランサーに直接アクセスできるため、Basic認証はかかりません。
ほとんどの場合はうまくいくのですが、次のOSとブラウザでのみ、何度もBasic認証が聞かれます。
- iOS Safari
- iOS Crome
- iPadOS Safari
- iPadOS Chrome
- macOS Safari
次のOSとブラウザはBasic認証は一回のみです。
- Windows10 Edge/Chrome/Firfox
- macOS Chrome
- iOS Edge
同じ仕組みがもう一つ(対象のWeb画面はアプライアンス製品の組み込み)あるのですが、そちらは、駄目なSafariとかでも一回のみです。なぜかSafariだけ聞かれて、なぜか該当のWebアプリだけが発生する謎な現象が発生しました。
Webアプリの詳細
WebアプリはRuby制でHanamiフレームワークを使用した自家製の物です。少し他のWebアプリと変わったところと言えば<script type="module" src="...">
を使っていることぐらいです。複数のJavaScriptをモジュールベースで遅延読み込みし、その中でもimport
文でJavaScriptの読み込みをいくつか行っています。
動作の検証と推測
Basic認証は、一回成功すれば、それ以降の通信は毎回Authorization
ヘッダがついて、自動的に認証してくれるはずです。しかし、SafariではモジュールベースのJavaScript読み込みにバグがあり、Authorization
ヘッダを付けてくれないのでは無いかと推測しました。
実際に、macOSのSafariで検証したところ、モジュールベースのJavaScript読み込みについて、Authorization
ヘッダを付けずにアクセスしようとしているようでした。もう一回認証を通すと、その時読み込もうとしたJavaScriptは正常に読み込みますが、そのJavaScript内のimport
文でのJavaScript読み込みについてはAuthorization
ヘッダを付けてくれず、またまた再度認証が聞かれる状態でした。つまり、import
文のネストの数だけBasic認証が聞かれてしまうと言う状況です。
なお、これはSafariのみで発生しています。iOS/iPadOSのChromeでも起きるのは、内部でSafariのエンジンを用いているか、内部エンジンが古いからと言う可能性が考えられます。
Safariなんとかしたい
現在、iPhoneからアクセスしたいという要望があり、可能であれば対応したいと考えています。現象を回避する何かいい方法はありませんでしょうか?
Webアプリ本体は触らずに、WAFの部分を変えるだけでいけるのがベストです。
JavaScriptだけBasci認証を外すというのも考えられますが、本来は内部アクセス限定のサイトであるため、内部情報が含まれないはずのJavaScriptであっても、何も制限せずに外から見える形にしたくはありません。(その後の状況の追記にあるとおり、この方法で回避できることは確認しています)
なお、WebアプリでモジュールベースのJavaScriptを普通の読み込みに変えるというのは、webpackとかでimport
文をなくしていく仕組みを入れる所から始める必要があるため、工数的にちょっとすぐに対応できるものではありません。ひとまず、その方法は無しでお願いします。
その他の情報
- ModSecurity2の設定はrecommendedを使用し、細かいカスタマイズはありません。
- 通信はHTTPS化されています。
- Basic認証がない内部からの場合は、Safariであっても正常にアクセスでき、Webアプリを利用できます。
その後の状況(2020年7月11日追記)
しばらく回答もなく、良い解決策が見つからないため、JavaScriptが含まれるassets周りのみBasic認証から外すことで現在は回避できています。assetsにあるファイルは静的なコンテンツのみであり、第三者に閲覧されても問題ないという判断です。
ただ、やはり、妥協していることには変わりありません。引き続き、良い方法がないか、回答を募集します。
あなたの回答
tips
プレビュー