Nginx地域ターゲティング、特別な場合

ニュースサイトでロシアの地域向けにジオターゲティングを行うタスクがありました。 メインページに入ると、次の形式のアドレスを持つサイトのリージョナルページへのリダイレクトが必要です:region / [region number]、およびクライアントはApacheにデータを転送せずにnginxにリダイレクトされる必要があります。



1日あたりの平均リソーストラフィック40トン。 Drupal、nginxが発行する静的ページを作成するキャッシングブーストモジュール。



Googleでソリューションを見つけると、クライアント側のリダイレクト、またはApacheにデータを転送するためのjsオプションが提供され、目的のURLを取得するためにデータベースを要求しましたが、当初は適切ではありませんでした。



利用可能なIPアドレスのベースを調べたところ: www.wipmania.com/en/base、www.maxmind.com/en/home、ipgeobase.ru 、ベースがURL [地域番号]を必要とする場合、「素晴らしいアイデア」がありました。その幸せは完全だろう。



これと、ジオターゲティングがロシア地域のみで行われるという条件に基づいて、nginxジオモジュールとipgeobaseのアドレスベースに決定しました。ジオモジュールはテキストファイルをアドレスベースとして受け入れることができるが、ipgeobaseのベースはテキスト形式で配布されるためです。 実際には、アドレスデータベースを目的の形式にすることは変わりません...



だから:

ここから、ipgeobase.ru / files / db / Main / geo_files.tar.gzでデータベースをダウンロードし、アーカイブを取得し、解凍して、cidr_optim.txtとcitys.txtの2つのファイルを取得します。

cidr_optim.txtの記録形式は次のとおりです。

<ブロックの始まり> <ブロックの終わり> <アドレスブロック> <国> <都市識別子>



<beginning of block>は、式a * 256 * 256 * 256 + 256 * 256 * 256 + c * 256 + dに従ってabcd形式のIPアドレスのブロック(範囲)の最初のIPアドレスから取得した数です

<ブロックの終わり>は、式e * 256 * 256 * 256 + f * 256 * 256 + g * 256 + hに従ってefghタイプのIPアドレスのブロック(範囲)の2番目のIPアドレスから取得した数です。

<アドレスのブロック>-abcdの形式のIPアドレスのブロック(範囲)-位置が決定されるefgh

<country>-ブロックが属する国の2文字のコード

<city identifier>-citys.txtファイルの都市ID。 識別子の代わりにダッシュがある場合は、都市を特定できなかったか、ブロックの国がロシアとウクライナではないことを意味します。



city.txtの記録形式は次のとおりです。

<都市識別子> <都市名> <地域名> <地区名> <都市中心緯度> <都市中心経度>

ファイルの説明はこちら( ipgeobase.ru/Help.html#35



これらすべてから、ファイルをデータベースに解析し、ファイルからのデータを含む2つのテーブルを取得しました。次に、地域の名前を使用して、



「abcd-efgh形式のIPアドレスのブロック(範囲)」->(必要なURL)[地域番号]



残っているのは、フォーマットを翻訳することだけです:

「abcd-efgh形式のIPアドレスのブロック(範囲)」は、geoモジュールが理解できる形式です。

0.0.0.0/0(開始アドレス/ビットマスク)。



ここで、奇妙なことに、楽しみが始まりました。 私はお互いを知っているすべての管理者にインタビューし、一緒になって、範囲を必要な形式に変換する方法を経験したと言いましたが、不必要なことに、彼らはすべて長い間忘れており、覚えておく時間がありませんでした Googleは常に支援してくれましたが、アドレスとマスクで範囲を計算するための指示、またはip4ネットワークの形成原理を徹底的に研究するための指示を提供しました。

問題を解決するために、3番目のオプションを選択しました。 ネットワーク上でip-calculator.ruを見つけ、ドメイン管理者に連絡しました。ドメイン管理者は、アドレスを目的の形式に変換する原則の翻訳と説明を支援することに親切に同意しました。 (再びありがとう)。



その結果、「0.0.0.0/0(必要なURL);」という形式のファイルを取得し、57000行ありました。たとえば、geo_ru.confと呼びます。



さて、実際には、nginx:

http {}ブロックで、モジュールを有効にします

geo $region_number { default all; include [   ]/geo_ru.conf }
      
      





つまり アピール後、クライアントのアドレスがファイル内にある場合、対応する値は$ region変数、つまり[region number]にあります。それ以外の場合は 'all'です。 (詳細: nginx.org/ru/docs/http/ngx_http_geo_module.html

さらに、実際には、リダイレクト:

サイトのサーバー{}ブロック内

 #   $get_redirect   donot_redirect set $get_redirect donot_redirect; #  ,          do_redirect if ($uri = '/') { set $get_redirect do_redirect; } #  nginx          $region_number  'all' ,     if ($city = 'all') { set $get_redirect donot_redirect; } #    , ..             (      ) if ($cookie_geolocate = 1) { set $get_redirect donot_redirect; } #         if ($get_redirect = do_redirect) { rewrite ^(.*)$ http://example.com/region/$region_number redirect; }
      
      





(つまり、最終的に、必要なものを得ました-地域への移行/ [地域番号])



さて、最後-クライアントがブロック内でメインページを見ることができるように

場所/ {} Cookieをクライアントに送信:

 add_header Set-Cookie "geolocate=1;Path=/;Domain=.example.com;";
      
      







実際、それがすべてです。 誰かが助けてくれることを願っています。

fedpress.ruで作業を確認できます。

記事を書いた理由は、一見明らかと思われる解決策がすぐには現れなかったからです。 コメント、アドバイス、説明に喜んでいます。



PS親愛なる管理者は、ハブに存在します。IPアドレスとは何か、範囲ごとにマスクを計算する方法、およびその逆について、「ブロックスタート」(a * 256 * 256 * 256 + b * 256 * 256 + c * 256 + d)および<ブロックの終わり>(e * 256 * 256 * 256 + f * 256 * 256 + g * 256 + h)、多くの人に感謝すると思います。



All Articles