ブラウザがSNIをサポートする場合にのみSSLにリダイレクトする


20

mod_sslを備えたApache 2.2と、VirtualHostingを備えた同じIP /ポート上にあるHTTPS内の多数のサイトがあるため、クライアントはこれらの仮想ホストに接続するためにSNIをサポートする必要があります。

サーバーを次のように構成したいと思います。

ユーザーがwww.dummysite.comと入力し、ブラウザー SNI(サーバー名表示)をサポートしている場合、HTTP要求はhttps://HSTSヘッダーの送信先にリダイレクトされます。ただし、ブラウザ SNIをサポートしていない場合、リクエストはHTTPによって処理されます。

上記の規則は、MozillaとChromeにはこの問題がないため、これらのユーザーをサイトから外さないようにするために、実際には古いブラウザーを実行しているユーザーのフォールバック規則です。

おそらくユーザーエージェントのフィルターを使用して、Apache構成レベルでこのリダイレクトを実行したいと思います。直接のhttp://参照が存在しないことを確認する以外は、実行中のアプリケーションに触れたくない(そうでない場合はセキュリティ警告を意味する)

[編集](質問の編集中に質問を忘れまし):リダイレクトするSNI対応ユーザーエージェントのリストは何ですか?

回答:


20

SNIはSSL / TLSハンドシェイク中に発生するため、クライアントがHTTPに接続するときにブラウザーサポートを検出することはできません。

だから、あなたは正しい。これを行う唯一の方法は、ユーザーエージェントフィルターです。

大きな問題は、SNIをリッスンしないことがわかっているブラウザーに対してブラックリストに基づいて行動するか、それをサポートすることが知られているブラウザーのホワイトリストに基づいて行動するかです。このサイトを使用できない不明瞭なデバイスや新しいデバイスは、契約違反のように思えるので、ホワイトリストの方が良い選択肢だと思います。

HTTPで<VirtualHost>

# Internet Explorer 7, 8, 9, on Vista or newer
RewriteCond %{HTTP_USER_AGENT} MSIE\s7.*Windows\sNT\s6 [OR]
RewriteCond %{HTTP_USER_AGENT} MSIE\s8.*Windows\sNT\s6 [OR]
RewriteCond %{HTTP_USER_AGENT} MSIE\s9.*Windows\sNT\s6 [OR]
# Chrome on Windows, Mac, Linux
RewriteCond %{HTTP_USER_AGENT} Windows\sNT\s6.*Chrome [OR]
RewriteCond %{HTTP_USER_AGENT} Macintosh.*Chrome [OR]
RewriteCond %{HTTP_USER_AGENT} Linux.*Chrome [OR]
# Firefox - we'll just make the assumption that all versions in the wild support:
RewriteCond %{HTTP_USER_AGENT} Gecko.*Firefox
RewriteRule ^/(.*)$ https://ssl.hostname/$1 [R=301]

ブラックリストのオプションもあります-これは、SNIを使用しないクライアントをSNIが必要なサイトに送信するリスクを負いますが、一方で、IE 10のような新しいユーザーを右側に送信することに注意してください場所:

# IE 6
RewriteCond %{HTTP_USER_AGENT} !MSIE\s6
# Windows XP/2003
RewriteCond %{HTTP_USER_AGENT} !Windows\sNT\s5
# etc etc
RewriteRule ^/(.*)$ https://ssl.hostname/$1 [R=301]

そこには多くのブラウザがあります。私は表現にかなりゆるんでいて、多くのブラウザをカバーしていません-これは維持するのに非常に悪夢に変わる可能性があります。

どちらのオプションを選択しても..幸運を祈ります!


1
すばらしいです!Opera Mobile(SNIに準拠していますが、リストには含まれていません)でテストしましたが、リダイレクトしません。私のFirefoxでは、リダイレクトします!
USR-ローカルΕΨΗΕΛΩΝ

6
mod_setenvif httpd.apache.org/docs/2.2/mod/mod_setenvif.htmlの BrowserMatchディレクティブでこのソリューションをモジュール化することをお勧めします。BrowserMatchを使用して環境変数supports_sni = yを設定し、RewriteCond%{ENV:supports_sni} = yと記述します。そうすれば、SNI検出ロジックを他のRewriteRulesに再利用できます。
200_success

@ 200_successいいね!
シェーンマッデン

8

私の解決策はこれです:

  # Test if SNI will work and if not redirect to too old browser page
  RewriteCond %{HTTPS} on
  RewriteCond %{SSL:SSL_TLS_SNI} =""
  RewriteRule ^ http://www.example.com/too-old-browser [L,R=307]

SNIのない古いブラウザーがhttps://www.example.com/ * にアクセスしようとすると、最初にブラウザーでエラーがスローされますこれは、Apacheが非SNIブラウザーに応答するまでわからないため回避できません。それが求めているサイト。次に、ブラウザが古すぎることをユーザーに知らせるページにリダイレクトします(ユーザーがクリックしてWebサイトにアクセスする限り)。

そして、私が持っている新しいブラウザを持つユーザーのために

  #Test if new browser and if so redirect to https
  #new browser is not MSIE 5-8, not Android 0-3
  RewriteCond %{HTTPS} off
  RewriteCond %{HTTP_USER_AGENT} !MSIE\ [5-8]
  RewriteCond %{HTTP_USER_AGENT} !Android.*(Mobile)?\ [0-3]
  RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

これは、Vista上のMSIE 5-8など(9+はVista / 7のみであるためSNIをサポートします)を含む、ほとんどの古いブラウザを除外します。100%ではありません(symbianは無視されますなど)が、大部分は動作するはずです。少数派は依然として証明書エラーを受け入れることを選択できます。


3

私が知る限り、これを行うには本当に良い方法はありません- ヘッダーに基づいてmod_rewriteルールまたは同様の条件を使用できますUser-agentが、NON-SSL仮想ホスト上にある必要があります:ブラウザがそうでない場合SNIをサポートすると、セキュアな(https://)サイトに移動し、「これがそのIPアドレスに関連付けられた最初のSSL証明書です。これがあなたの望んでいることを願っています!」という昔ながらのApacheの動作を取得します。-それが証明書ではない場合、ブラウザはホスト名の不一致に関するエラーメッセージを表示します。

これは基本的に、ユーザーがリダイレクトする非SSLインタースティシャルページにアクセスする必要があることを意味します。リクエストで送信しているデータを公開する可能性があります。これは取引ブレーカーである場合とそうでない場合があります(SNIをサポートしていない場合は、とにかく非SSLサイトに送信することになるので、セキュリティについてはあまり気にしないと思います。暗号化層または認証層としてSSLを必要とするシステムを設計しましたが、それについてもう少し固執します...)

ただし、誰かが安全なサイトをブックマークすることを止めることはありません-共有ブックマークサービスを使用するか、WebブラウザがSNIをサポートしていないマシンにブックマークを復元すると、潜在的なSSLエラーのケースに戻ります。


1

次の3つの方法のいずれかを解決したいと思います。

  1. RewriteRuleUser-Agentヘッダーに基づきます。
  2. <SCRIPT>デフォルト以外のVHostのタグにhttps:// URIをロードします。ロードが成功した場合、HTTPSの下でページ全体をリロードするのは少しのJSです。
  3. HTTPS Everywhereのようなものを使用するように訪問者に指示します。これが彼らにとって優先事項である場合、必要なページにHTTPSを強制し、すべてがうまくいくことを望みます。

これらのうち、個人的には2番が一番好きですが、それにはサイトのコードの変更が伴います。


0

必要な人だけに。

複数のホストがあり、それらすべてをVirtualHostingでSSL対応にしたい場合(およびそれぞれの証明書を購入した場合)、新しいホストを試してください mod_djechelon_ssl

$ cat /etc/apache2/mod_djechelon_ssl.conf 
RewriteEngine on
# Internet Explorer 7, 8, 9, on Vista or newer
RewriteCond %{HTTP_USER_AGENT} MSIE\s7.*Windows\sNT\s6 [OR]
RewriteCond %{HTTP_USER_AGENT} MSIE\s8.*Windows\sNT\s6 [OR]
RewriteCond %{HTTP_USER_AGENT} MSIE\s9.*Windows\sNT\s6 [OR]
# Chrome on Windows, Mac, Linux
RewriteCond %{HTTP_USER_AGENT} Windows\sNT\s6.*Chrome [OR]
RewriteCond %{HTTP_USER_AGENT} Macintosh.*Chrome [OR]
RewriteCond %{HTTP_USER_AGENT} Linux.*Chrome [OR]
# Firefox - we'll just make the assumption that all versions in the wild support:
RewriteCond %{HTTP_USER_AGENT} Gecko.*Firefox [OR]
#Safari iThing
RewriteCond %{HTTP_USER_AGENT} Mozilla.*iPhone.*Safari [OR]
RewriteCond %{HTTP_USER_AGENT} Mozilla.*iPod.*Safari [OR]
RewriteCond %{HTTP_USER_AGENT} Mozilla.*iPad.*Safari [OR]
RewriteRule ^/(.*)$ https://%{HTTP_HOST}/$1 [R=permanent,L]

使用法:

<VirtualHost ip:80>
ServerName www.yourhost.com

Include /path/to/mod_djechelon_ssl.conf

[plain old Apache directives]
</VirtualHost>

<VirtualHost ip:443>
ServerName www.yourhost.com

[SSL-related directives]

[Copy and paste directives from above host]
</VirtualHost>

0

私がここに投稿したように、あなたはそれを要求するにのみSNIサポートをテストできます。つまり、ユーザーにSNI HTTPSを強制し、サポートしない場合はフォールバックすることはできません。ユーザーはこのようなエラー(Windows XPのChromeから)を受信し、続行する方法がありません。

そのため、(残念ながら)ユーザーは実際には安全でないHTTP接続で開始し、SNIをサポートしている場合にのみアップグレードする必要があります。

次の方法でSNIサポートを検出できます。

  1. リモートスクリプト
    プレーンHTTPページ<script>から、宛先SNI HTTPSサーバーからをロードします。スクリプトが正しくロードおよび実行される場合、ブラウザーがSNIをサポートしていることがわかります。

  2. クロスドメインAJAX(CORS)
    オプション1と同様に、HTTPページからHTTPSへのクロスドメインAJAXリクエストを実行できますが、CORSのブラウザーサポートは限られていることに注意してください。

  3. ユーザーエージェントのスニッフィング
    これはおそらく最も信頼性の低い方法であり、サポートしていないことがわかっているブラウザー(およびオペレーティングシステム)のブラックリスト、またはサポートしている既知のシステムのホワイトリストを選択する必要があります。

    Windows XP以前のIE、Chrome、OperaのすべてのバージョンがSNIをサポートしていないことがわかっています。サポートされているブラウザの完全なリストについては、CanIUse.comを参照してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.