httpからhttpsへのリダイレクトを削減するためのnginxの設定。

By | 2020年2月4日

はじめに

本WebサイトのWebサーバを2020年1月末よりnginxに切り替えました。本Webサイトとは別のWebサーバで事前に切り替えの練習を行っていたこともあってか、作業自体は順調かつ短時間で終了できました。

練習大事です。🐼

Apache httpdを使っていたときと比べて少しページの表示に要する時間が短くなったような気がします。

表示速度が速くなったっぽいことが確認できたところで、ついでにWebサーバの設定についても見直し、できるだけサーバへの負荷がかからないようにするために、HTTP接続からHTTPS接続へのリダイレクトを行うリクエストを制限するための設定を追加してみました。

スポンサーリンク

なぜリダイレクトを制限するのか?

Webサイトの常時HTTPS化を行う際に、HTTP接続によるリクエストに対してHTTPステータスコード301をレスポンスとして返すことで、HTTPS接続によるリダイレクトをさせることがよく行われます。例えば、http://pandanote.info/?p=5948 へのリクエストがあった場合に、HTTPステータスコード301をクライアントに返し、かつそれと同時に、リダイレクト先として先頭の “http://” の部分を “https://” に置き換えた
https://pandanote.info/?p=5948 もクライアントに返すことでクライアントをリダイレクト先である https://pandanote.info/?p=5948 にアクセスするように誘導することができます。

しかし、HTTP接続によるリクエストの中には、Webサーバに存在しないURLが指定されているものがあります。HTTP接続でアクセスしてきたリクエストをすべてHTTPS接続へリダイレクトしてしまうと、存在しないURLのためにTLSのハンドシェイクやリクエスト及びレスポンス(存在しないURLがリクエストされた場合のステータスコードはかの有名な404です。)に対する暗号化の処理が行われてしまいます。

TLSにおける署名及び暗号化の処理はHTTP/2の登場等により、以前ほど重い処理であるとは認識されなくなってはきていますが、TLS自体のバージョンが上がれば上がるほど、TLSで使用できる暗号化や署名のアルゴリズムが複雑かつ計算量を要するものになることはあっても簡単なものになるとは考えにくいです。

また、存在しないURLへのアクセスはWebサーバに脆弱性が存在するかどうかを調べるために行われることもありますので、HTTPSで直接接続してきた場合はそのままTLSの処理を行うのは止むを得ないにしても、HTTPで接続してきたリクエストで不審なものについてはHTTPS接続はさせない方が良いケースも考えられます。

リダイレクトを制限するための設定

設定にあたっての考え方

そこで、HTTP接続時に指定されたURLの文字列が、リダイレクトによるHTTPS接続時に有効なURLに変換されるようなもののみをリダイレクトし、それ以外のURLが指定された場合にはHTTPS接続へのリダイレクトは行わず、その代わりにHTTPステータスコード404をレスポンスとして返すような設定を行い、Webサーバの負荷を削減することを考えます。

本Webサイトでの設定では、以下のURLが指定された場合のみHTTPS接続へのリダイレクトを行う設定としてみました。

  1. http://pandanote.info/
  2. http://pandanote.info/index.php
  3. http://pandanote.info/catchphrase
  4. 上記のいずれかのURLに変数名p及び対応する値(数字に限る。)がパラメータとして付加されているURL

設定例

nginx.confのうち、HTTP接続の設定がされているserverブロックにおいて、以下の設定を追加します。

location ~ ^/?$ {
if ($arg_p ~ “\d+”) {
return 301 https://$host$request_uri;
}
if ($args) {
return 404;
}
return 301 https://$host$request_uri;
}

location ~ ^/(index\.php|catchphrase)$ {
if ($arg_p ~ “\d+”) {
return 301 https://$host$request_uri;
}
if ($args) {
return 404;
}
return 301 https://$host$request_uri;
}

 
設定のポイントは以下の通りです。

  1. $arg_ の直後にURLで使用されているパラメータ名を付加すると、そのパラメータ名に対応する値を参照することができます。上記の例では $arg_p でURL中で指定されたパラメータpに対応する値を参照しています。
  2. URL中で指定されたパラメータpに対応する値でかつそれが数字のみからなる文字列である場合にはHTTPステータスコード301を返してリダイレクトさせています。それ以外の場合で、URL中にパラメータがある場合にはリダイレクトが行われず、HTTPステータスコード404が返されます。
  3. URL中にパラメータがない場合についても、HTTPステータスコード301を返してリダイレクトさせています。

思わぬご利益

https://pandanote.info/?attachment_id= のような(無効な)URLがなぜかGoogle先生にインデックスされていたのですが、これはもともと http://pandanote.info/?attachment_id= としてアクセスされたものが https://pandanote.info/?attachment_id= にリダイレクトされたものがGoogle先生に有効なURLであると判断されてしまったことが原因だったようです。

HTTPS接続へのリダイレクトの対象が前節で示したURL例のみに限定されれば、このようなインデクシングは行われにくくなるものと予想されます。

まとめ

本Webサイトは稼働開始当初より常時HTTPS化されていますので、どこまて効果がでるかについては試してみないとわからない部分もありますので、しばらく様子を見たいと思います。

この記事は以上です。

References / 参考文献