使用 GeoDNS 根据国家/地区加载不同的网站内容

使用 GeoDNS 绑定补丁,只有当加载页面的请求 IP 地址位于美国时,我们才能让 example.com 解析到美国的服务器,然后将所有其他请求转发到位于另一个国家的服务器。
我们将能够使用此方法将来自任何国家/地区代码的域请求指向指定的 DNS 记录。

在此示例中,我们将从充当名称服务器的测试服务器 (CentOS 6.3) 上的源代码编译 Bind,即它用于提供 DNS。

使用 GeoDNS 补丁编译绑定

下载并安装 Maxmind 的 GeoIP C API 我使用的是当前最新版本 1.4.8.

wget http://geolite.maxmind.com/download/geoip/api/c/GeoIP-1.4.8.tar.gz
tar xf GeoIP-1.4.8.tar.gz 
cd GeoIP-1.4.8
./configure --prefix=/usr/local/geoip
...
checking zlib.h usability... no
checking zlib.h presence... no
checking for zlib.h... no
configure: error: Zlib header (zlib.h) not found. Tor requires zlib to build. You may need to install a zlib development package.

要修复此错误,我们只需要安装 zlib 开发包(Debian 上的 zlib1g-dev)。

yum install zlib-devel.x86_64
./configure --prefix=/usr/local/geoip
make
make install

下载用于绑定的 GeoDNS 补丁。

cd ..
wget http://www.caraytech.com/geodns/bind-9.4.1-geodns-patch.tar.gz
tar xf bind-9.4.1-geodns-patch.tar.gz

接下来下载绑定。

请注意,我正在使用此版本的 Bind (9.4.1-P1),因为这是当前补丁所针对的版本。
我尚未使用较新版本的 Bind 测试该补丁,但相信它仍然有效,但请在应用到生产环境之前进行测试。

wget http://ftp.isc.org/isc/bind9/9.4.1-P1/bind-9.4.1-P1.tar.gz
tar xf bind-9.4.1-P1.tar.gz

现在我们将使用 Patch 命令,最初我没有安装它,所以它是使用 yum 安装的。

patch -p0 < bind-9.4.1-geodns-patch/patch.diff
bash: patch: command not found
yum install patch
...
patch -p0 < bind-9.4.1-geodns-patch/patch.diff
...
patching file bind-9.4.1-P1/lib/dns/acl.c
patching file bind-9.4.1-P1/lib/dns/include/dns/acl.h
patching file bind-9.4.1-P1/lib/isccfg/aclconf.c

现在我们将编译绑定,指定我们之前在 /usr/local/geoip/ 中的 GeoIP 安装。

cd bind-9.4.1-P1
CFLAGS="-I/usr/local/geoip/include" LDFLAGS="-L/usr/local/geoip/lib -lGeoIP" ./configure --prefix=/usr/local/bind
...
checking for C compiler default output file name... a.out
./a.out: error while loading shared libraries: libGeoIP.so.1: cannot open shared object file: No such file or directory
See `config.log' for more details.

这只发生在我运行的 CentOS 6.3 测试中,而在 Debian 6 中没有发生,修复很简单。

nano /etc/ld.so.conf
Add "/usr/local/geoip/lib/" into file and save.
ldconfig

现在再次尝试应该会成功。

CFLAGS="-I/usr/local/geoip/include" LDFLAGS="-L/usr/local/geoip/lib -lGeoIP" ./configure --prefix=/usr/local/bind
make
make install

配置

现在 Bind 已经编译并安装了 GeoDNS 补丁,我们只需要按照我们想要的方式配置我们的 DNS。

这是通过 named.conf 文件完成的,我在 /usr/local/bind/etc/ 中创建了这个文件,它包含以下内容:

include "/etc/rndc.key";
controls {
        inet 127.0.0.1 allow { localhost; } keys { "rndc-key"; };
};
options {
    directory                "/var/named"; // the default
    pid-file                 "/var/run/named/named.pid";
    dump-file                "data/cache_dump.db";
    statistics-file          "data/named_stats.txt";
        allow-transfer {"none";};
}
logging {
    channel default_debug {
            file "data/named.run";
            severity dynamic;
    };
};

在此示例中,包含文件“/etc/rndc.key”存在并包含以下内容。

key "rndc-key" {
        algorithm hmac-md5;
        secret "RSQjVF5KKE0pI0VNVA==";
};

秘密是一个简单的 base 64 字符串。

现在在此之下我们定义我们的观点。
在这个例子中,我们将把请求 example.com 的所有北美用户发送到托管在 1.1.1.1 的站点,同时将世界其他地区的用户发送到 2.2.2.2.

view "north_america" {
      match-clients { country_US; country_CA; country_MX; };
      recursion no;
      zone "example.com" {
            type master;
            file "/var/named/example-us.com.db";
      };
};
view "other" {
      match-clients { any; };
      recursion no;
      zone "private-software.com" {
            type master;
            file "/var/named/example.com.db";
      };
};

所以我们的 named.conf 文件用于指定应该使用哪个 .db 区域文件,在这个例子中,我们有两个文件 example.com 给出了不同的 DNS,如下所示。

/var/named/example-us.com.db

; Zone file for example.com
$TTL 14400
example.com.   86400   IN      SOA     ns1.example.com.       admin.example.com.     (
  2012080500 ;Serial Number
  86400 ;refresh
  7200 ;retry
  3600000 ;expire
  86400   )
example.com.        300     IN      A       1.1.1.1

/var/named/example.com.db

; Zone file for example.com
$TTL 14400
example.com.   86400   IN      SOA     ns1.example.com.       admin.example.com.     (
  2012080500 ;Serial Number
  86400 ;refresh
  7200 ;retry
  3600000 ;expire
  86400   )
example.com.        300     IN      A       2.2.2.2

一旦所有更改都到位,named 就可以开始了。

cd /usr/local/bind/sbin/
./named

我们需要确认它已启动且没有错误,因为 named.conf 的问题会导致此操作失败。
查找错误的好地方是 /var/log/messages。
或者运行 netstat -antp 并查看服务器是否在端口 53 上侦听 DNS。

日期:2020-07-07 20:56:51 来源:oir作者:oir