今天客户有个需求,就是将不存在的解析域名请求都解析到他们的一台设备上,其实这个就是类似与电信或者联通的域名纠错系统了。
其中SSAC有一篇文章,就是讲这个的,sac-032-en
这个根据网上的资料有几个实现思路
A、F5上配合filter进行实现
B、修改dns源码
C、bind原生支持
F5的实现方式
首先说一下F5上的实现:我们的产品前面确实有F5的负载均衡设备,但是在上面跑着很重要的服务,所以也没去实验,但根据网上的说法这个是可行的:利用rules,就是拆解dns的响应包,如果状态码是NXDOMAIN,则插入A记录或者其它东西;
DNS用于响应的报文由12字节长的首部和4个长度可变的字段组成。其中从第28位开始的4位的标志字段的子字段为rcode为返回码字段,通常的值为0(没有差错)和3(名字差错),名字差错从一个授权的名字服务器上返回,表示在查询中指定的域名不存在。因此把rcode字段返回的值变更为指定的字符串,就可以完成nxdomain redirect的要求
具体实现代码
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
rule dns_redirect { when RULE_INIT { set ::header_without_id [binary format S5 {0x8180 0x0001 0x0001 0x0000 0x0000}] set ::answerpart [binary format S6c4 {0xC00C 0x0001 0x0001 0x0000 0x0D1B 0x0004} {8 8 8 8}] #后面的这四个8 代表ip,8.8.8.8 } when SERVER_DATA { binary scan [ string range [UDP::payload] 2 3 ] S sflags set rcode [expr $sflags & 0x000f] if {$rcode == 3 }{ binary scan [string range [UDP::payload] 12 13 ] c foo set byte [expr $foo & 0xff] set offset 12 set i 0 while {$byte > 0 && $i < 10} {# grab a part and put it in our text QNAME section set offset [expr $offset + $byte + 1] # grab the length of the next part, and make it an unsigned integer set byte [string range [UDP::payload] $offset [expr $offset + 1]] binary scan $byte c foo set byte [expr $foo & 0xff] incr i } incr offset binary scan [string range [UDP::payload] $offset [expr $offset + 2]] S qtype content if {$qtype == 0x0001} { UDP::payload replace 0 0 [binary format a2a*a*a* [string range [UDP::payload] 0 1] $::header_without_id [string range [UDP::payload] 12 [expr $offset+3]] $::answerpart] } } } } |
总之,F5还是很灵活的,并且很多isp都在使用,上面的方案就是某isp的一个方案;
修改源代码的方案
接着说下修改源代码的这个方案,当然可以实现,但是开发成本挺高,暂时不考虑
bind-9.9.2 nxdomain redirect
下面就说下使用bind-9.9.2中最新的nxdomain redirect 功能
1、下载
wget ftp://ftp.isc.org/isc/bind9/9.9.2-P1/bind-9.9.2-P1.tar.gz
2、解压
tar zxf bind-9.9.2-P1.tar.gz
3、编译安装
cd bind-9.9.2-P1
./configure --prefix=/var/named --enable-threads --without-openssl --sysconfdir=/var/named/etc --with-libtool
make install
4、几个重要的配置文件
/var/named/etc/named.conf
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
[root@chenqing ~]# cat /var/named/etc/named.confoptions {directory "/var/named";// dump-file "/var/named/data/cache_dump.db";// statistics-file "/var/named/data/named_stats.txt";// memstatistics-file "/var/named/data/named_mem_stats.txt";allow-query { any; };recursion yes;//forward first ;//forwarders {127.0.0.1;};dnssec-enable no;dnssec-validation no;dnssec-lookaside no;/* Path to ISC DLV key */bindkeys-file "/etc/named/bind.key";};logging {channel default_debug {file "data/named.run";severity dynamic;};};zone "." IN {type hint;file "named.ca";};zone "." {type redirect;file "redirect.db";}; |
/var/named/named.ca
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
; <<>> DiG 9.5.0b2 <<>> +bufsize=1200 +norec NS . @a.root-servers.net;; global options: printcmd;; Got answer:;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 34420;; flags: qr aa; QUERY: 1, ANSWER: 13, AUTHORITY: 0, ADDITIONAL: 20;; OPT PSEUDOSECTION:; EDNS: version: 0, flags:; udp: 4096;; QUESTION SECTION:;. IN NS;; ANSWER SECTION:. 518400 IN NS M.ROOT-SERVERS.NET.. 518400 IN NS A.ROOT-SERVERS.NET.. 518400 IN NS B.ROOT-SERVERS.NET.. 518400 IN NS C.ROOT-SERVERS.NET.. 518400 IN NS D.ROOT-SERVERS.NET.. 518400 IN NS E.ROOT-SERVERS.NET.. 518400 IN NS F.ROOT-SERVERS.NET.. 518400 IN NS G.ROOT-SERVERS.NET.. 518400 IN NS H.ROOT-SERVERS.NET.. 518400 IN NS I.ROOT-SERVERS.NET.. 518400 IN NS J.ROOT-SERVERS.NET.. 518400 IN NS K.ROOT-SERVERS.NET.. 518400 IN NS L.ROOT-SERVERS.NET.;; ADDITIONAL SECTION:A.ROOT-SERVERS.NET. 3600000 IN A 198.41.0.4A.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:503:ba3e::2:30B.ROOT-SERVERS.NET. 3600000 IN A 192.228.79.201C.ROOT-SERVERS.NET. 3600000 IN A 192.33.4.12D.ROOT-SERVERS.NET. 3600000 IN A 128.8.10.90E.ROOT-SERVERS.NET. 3600000 IN A 192.203.230.10F.ROOT-SERVERS.NET. 3600000 IN A 192.5.5.241F.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:500:2f::fG.ROOT-SERVERS.NET. 3600000 IN A 192.112.36.4H.ROOT-SERVERS.NET. 3600000 IN A 128.63.2.53H.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:500:1::803f:235I.ROOT-SERVERS.NET. 3600000 IN A 192.36.148.17J.ROOT-SERVERS.NET. 3600000 IN A 192.58.128.30J.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:503:c27::2:30K.ROOT-SERVERS.NET. 3600000 IN A 193.0.14.129K.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:7fd::1L.ROOT-SERVERS.NET. 3600000 IN A 199.7.83.42M.ROOT-SERVERS.NET. 3600000 IN A 202.12.27.33M.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:dc3::35;; Query time: 147 msec;; SERVER: 198.41.0.4#53(198.41.0.4);; WHEN: Mon Feb 18 13:29:18 2008;; MSG SIZE rcvd: 615 |
/var/named/redirect.db
|
1
2
3
4
5
6
7
8
9
10
11
|
$TTL 300@ IN SOA ns.example.net hostmaster.example.net 0 0 0 0 0@ IN NS ns.example.net; NS records do not need address records in this zone as it is not in the; normal namespace.*. IN A 8.8.8.8 |
5、启动 named
/var/named/sbin/named -c /var/named/etc/named.conf -u named
6、验证
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
[root@chenqing ~]# dig xxxxxx.chenqing.org; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.10.rc1.el6_3.6 <<>> xxxxxx.chenqing.org;; global options: +cmd;; Got answer:;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 37117;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0;; QUESTION SECTION:;xxxxxx.chenqing.org. IN A;; ANSWER SECTION:xxxxxx.chenqing.org. 300 IN A 8.8.8.8;; Query time: 1301 msec;; SERVER: 127.0.0.1#53(127.0.0.1);; WHEN: Wed Mar 20 22:02:43 2013;; MSG SIZE rcvd: 53 |

