Help us understand the problem. What is going on with this article?

Bind 9.10のGeoIP機能を使って、リクエスト元に近いサーバのIPを返す

More than 3 years have passed since last update.

はじめに

海外から日本のサーバに接続すると、予想外の遅さに少し驚くことがあります。
例えば、ロンドンから日本のサーバにHTTPでアクセスをすると、明らかにワンテンポ遅い感じです。
試しにhttpingコマンドでqiita.comへのHTTP接続を計測してみたところ、547msの平均応答速度でした。

仮に日本以外に海外でも展開するサービスを作るとしたら、もっと応答時間を早くしたいものです。

$ httping -c 3 qiita.com
PING qiita.com:80 (/):
connected to 54.248.127.202:80 (386 bytes), seq=0 time=579.29 ms
connected to 54.248.127.202:80 (386 bytes), seq=1 time=530.49 ms
connected to 54.248.127.202:80 (386 bytes), seq=2 time=533.82 ms
--- http://qiita.com/ ping statistics ---
3 connects, 3 ok, 0.00% failed, time 4645ms
round-trip min/avg/max = 530.5/547.9/579.3 ms

これは、予算に余裕があれば、Amazon Route 53Amazon CloudFront CDN, CloudFlare等を使えばすぐに解決できる問題ですけど…。
ConoHaにもGeoDNS機能があり、コスパも高いし魅力的なのですが、リージョンにヨーロッパがないのが残念。

オレオレCDN

  1. 海外の格安VPSを活用して、複数の大陸にサーバを設置
  2. DNSでの名前解決で、リクエスト元に近いサーバのIPを返せばOK

Bind 9.10 の新機能として、GeoIP機能が搭載されており、クライアントのIPの国・都市・タイムゾーンなどを元に、名前解決の結果を分ける事ができます。
この機能を使って、例えばヨーロッパの利用者はヨーロッパのサーバのIP、アジアの利用者は日本のサーバのIPを返すように構成すれば良さそうです。

構成

リクエスト元 近いサーバの場所
ヨーロッパ・アフリカ・中東・ロシア ロンドン
日本・韓国・中国・東南アジア 東京
北米・南米・その他 ニューヨーク

海外格安VPSを活用する (Vultr編)

最近、格安海外VPSのVultrを使い始めました。
Vultrを選んだ理由は、ArchLinuxをインストールできる事と安い事なのですが、ふと簡易CDNとしても使えるのではないかと思い立ちました。

Vultrは、DigitalOcean的な立ち位置のVPS業者ですが、東京にもリージョンがある、月$5の最安プランでのサーバのメモリ容量が768MBとDigitalOceanより256MB多い(その代りSSD容量は5GB少ない)のがより魅力的に感じました。
オフィシャルのクーポンもあり、2016年1月現在では$50(ただし2ヵ月で消える)のクレジットが貰えるようです。

ヨーロッパと日本、アメリカに3台サーバを設置したとして、月$15です。
転送量は月1TBまで無料。
小規模のスタートアップや個人で運用するサービスには、なかなか良いのではないでしょうか。

動作確認環境

  • Ubuntu 14.04 64-bit
  • BIND 9.10.3

Bind 9.10

インストール

ubuntu14.04-add-bind9.10-ppa.sh
#!/bin/bash
sudo add-apt-repository ppa:mgrocock/bind9
sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 083F021DDC682B55
sudo apt-get up{dat,grad}e -y

BindでGeoIP機能が有効かを確認

$ named -V | sed -r 's/ +/\n/g'|grep geoip
'--with-geoip=/usr'
# OK

GeoIPデータベースを入れる

# $ sudo apt-get install geoip-database
or
$ sudo apt-get install geoip-database-contrib

※geoip-databaseの方は内容が古いようで、一部のIPの国を認識できなかったので、geoip-database-contribの方がお勧めです。

設定

試しに、日本と英国、二カ国からのアクセスに対して設定してみます。

  • 「example.com」への名前解決要求

    • クライアントのIPが日本 ⇒ 東京サーバのIPを返す
    • クライアントのIPが英国 ⇒ ロンドンサーバのIPを返す
/etc/bind/named.conf.options
/* 地域 */
acl "jp" { geoip country JP; };                                                                                    
acl "uk" { geoip country GB; }; 

/* 中略 */

/* 追記 */
options {
    geoip-directory "/usr/share/GeoIP";
};

国コードには、ISO-3166-1の2文字、又は3文字のコードを指定します。

geoip ディレクティブには、他にも都市やタイムゾーンも指定できるとのことです。
Chapter 6. BIND 9 Configuration Reference より抜粋:

geoip [db database] field value

# examples
geoip country US;
geoip country JAP;
geoip db country country Canada;
geoip db region region WA;
geoip city "San Francisco";
geoip region Oklahoma;
geoip postal 95062;
geoip tz "America/Los_Angeles";
geoip org "Internet Systems Consortium";

次にゾーンファイルを更新します。`
match-clients に、先ほど定義した国に対応したaclを指定するだけです。

/etc/bind/named.conf.default-zones
view "jp" {
 match-clients { jp; };
 zone "example.com" {
  type master;
  file "/etc/bind/example.com.tokyo.zone";
  /* 以下略 */
 };
};

view "uk" {
 match-clients { uk; };
 zone "example.com" {
  type master;
  file "/etc/bind/example.com.london.zone";
  /* 以下略 */
 };
};

view "other" {
 zone "example.com" {
  type master;
  file "/etc/bind/example.com.other.zone";
  /* 以下略 */
 };
};

ゾーンファイルの example.com.london.zone の内容は、特筆することはなくごく普通です。
IPのAレコードが国ごとに違うだけ。

デバッグ

国と対応させたviewが正しく識別されているかをログで確認します。

参考: BINDのviewを用いた内部向けDNS構築メモ

named.conf.options
logging {
 channel queries_file {
  file "/var/log/named/queries.log"
  versions 3 size 5m;
  severity dynamic;
  print-time yes;
 };
};

各国のクライアントからテストでDNSクエリを送ります。
※1.2.3.4は本当は上で設定したIP

$ nslookup examples.com 1.2.3.4 

ログを確認します。

/var/log/named/queries.log
08-Jan-2016 8:45:10.527 client 104.238.171.177#39341 (example.com): view uk: query: example.com IN A + (172.31.22.25)
08-Jan-2016 8:49:30.593 client 202.157.182.142#2043 (example.com): view other: query: example.com IN SOA -T (172.31.22.25)
08-Jan-2016 8:54:06.839 client 157.192.160.134#40687 (example.com): view jp: query: example.com IN A + (172.31.22.25)

OK

あとは、aclでの国定義を増やしていき、クライアントの国に対応したサーバを更に適切に返せるように詰めていけば良さそうです。

参考

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away