web-dev-qa-db-ja.com

Apacheは、1つを除くすべてのサブドメインをwww以外のhttpsに書き換えます

サーバー上の301リダイレクトチェーンの量を削減しようとしています。サブドメインをwww以外のリダイレクト(サブドメインがdevの場合を除く)にHTTPからHTTPSへのリダイレクト( %{HTTP:X-Forwarded-Proto})インスタンスがロードバランサーの背後にあるため。

これが.htaccessにこれまでにあるものです。

# move http to https 
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule .* https://%{HTTP:Host}%{REQUEST_URI} [L,R=301]

# Remove leading www 
RewriteCond %{HTTP_Host} ^www.example.net [NC]
RewriteRule ^(.*)$ https://example.net/$1 [R=301,L]

現在の実装には3つの問題があります。

  1. http://www.example.netへのリクエストには2つのリダイレクトがあります。

  2. このサイトのほとんどのwwwからwww以外へのリダイレクトの例と同様に、ww.またはwwww.はリダイレクトされません。そのため、私の分析には、リダイレクトされていない多くの誤って入力されたサブドメインがあります。

  3. 私はdev.サブドメインをリダイレクトから除外したいので、http://dev.example.netとそのhttps兄弟です。開発とリリースのステージングにdev.を使用しているためです。

これを組み合わせるにはどうすればよいですか?

1
Matt Parkins

1)_http://www.example.net_へのリクエストには2つのリダイレクトがあります。

これは、2つのルールを逆にするだけで解決できます。次に、_www.example.net_が最初のリダイレクトでHTTPSにリダイレクトされるため、HTTPからHTTPSへのリダイレクトはトリガーする必要がありません。

(ただし、これは [〜#〜] hsts [〜#〜] を実装する意図がないことを前提としています。この場合、2つのリダイレクトとして保持する必要があります。同じホスト名firstが要件です。)

2)このサイトのほとんどのwwwからwww以外へのリダイレクトの例と同様に、_ww._または_wwww._はリダイレクトされないため、分析にはリダイレクトされていない多くの誤って入力されたサブドメインがあります。

通常、_ww._または_wwww._サブドメインへのリクエストは単に解決されないため、通常これは問題になりません。これが機能するには、DNSでwildcardサブドメインを構成し、そのような要求を受け入れるようにサーバーを構成する必要があります。

しかし、これは正規表現(スニペット)を_^www\._から_^w{2,4}\._に変更することで説明できます。

3)_dev._サブドメインをリダイレクトから除外したいので、開発とリリースのステージングに_http://dev.example.net_を使用しているため、_dev._とそのhttps兄弟です。

これはHTTPからHTTPSへのルールにのみ適用されるため、ここで追加の条件を適用して、_dev._で始まるホスト名を除外できます。

上記の点をまとめて、以下を試してください:

_# Remove leading ww, www or wwww (and redirect to HTTPS)
RewriteCond %{HTTP_Host} ^w{2,4}\.example\.net [NC]
RewriteRule (.*) https://example.net/$1 [R=301,L]

# Move http to https (except dev subdomain)
RewriteCond %{HTTP:Host} !^dev\. [NC]
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule ^ https://%{HTTP:Host}%{REQUEST_URI} [R=301,L]
_

これがロードバランサーの要件である場合に備えて、_HTTP:Host_の使用を同じにしました(Host HTTPリクエストヘッダーにアクセスするため)。それ以外の場合は、ここで_HTTP_Host_サーバー変数を使用する方が一般的です。

CondPatternの_!_接頭辞(つまり、_!^dev\._)は正規表現を否定するため、Hostは_dev._で始まりませんではありません。 (私は_www.dev._は事ではないと思いますか?)

_(.*)_は、デフォルトでは正規表現が貪欲であるため、^(.*)$と同じです。

テストする前に、ブラウザのキャッシュをクリアする必要があります。キャッシュの問題を回避するために、最初に302(一時)リダイレクトでテストすることをお勧めします。

1
MrWhite
# Remove leading www, always using https regardless of the current URL scheme
RewriteCond %{HTTP_Host} ^w{2,4}.example.net(?::|$) [NC,NV]
RewriteRule .* https://example.net%{REQUEST_URI} [L,R=301]

# move http to https, except for dev.example.net
RewriteCond %{HTTP:X-Forwarded-Proto} =http [NC,NV]
RewriteCond %{HTTP_Host} !^dev.example.net(?::|$) [NC,NV]
RewriteRule .* https://%{HTTP_Host}%{REQUEST_URI} [L,R=301]
  1. X-Forwarded-Proto条件にNCnocase)フラグを追加しました。これは、値が大文字と小文字を区別しないように見えるためです(つまり、HTTP = Http = hTTp = http)。これは自由に削除できます。
  2. X-Forwarded-Proto条件にNVnovary)フラグを追加して、Vary応答ヘッダーから非表示にしました。繰り返しますが、これが当てはまらない場合(特にリバースプロキシがクライアントに送信する前に自動的にフィルタリングする)、または正しいキャッシュ動作に必要な場合(キャッシュはhttphttpsのコンテンツを区別しません)であれば、これを自由に削除できます。 。
  3. NVヘッダー条件にnovaryHost)フラグを追加して、Vary応答ヘッダーからそれを非表示にしました。キャッシュサーバーが壊れている場合は、これを削除することもできます。
  4. RewriteRuleフラグの順序に一貫性を持たせました(L,R=301R=301,Lは基本的に同じです)。
  5. www.example.net.but.not.actually.yours.comが認識されないようにしましたが、たとえばwww.example.net:443
  6. 一貫して%{REQUEST_URI}を置換として使用します。
  7. wwおよびwwwwも認識します。
2
Jin-oh Kang