今天客户有个需求,就是将不存在的解析域名请求都解析到他们的一台设备上,其实这个就是类似与电信或者联通的域名纠错系统了。
其中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.conf options { 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.4 A.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:503:ba3e::2:30 B.ROOT-SERVERS.NET. 3600000 IN A 192.228.79.201 C.ROOT-SERVERS.NET. 3600000 IN A 192.33.4.12 D.ROOT-SERVERS.NET. 3600000 IN A 128.8.10.90 E.ROOT-SERVERS.NET. 3600000 IN A 192.203.230.10 F.ROOT-SERVERS.NET. 3600000 IN A 192.5.5.241 F.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:500:2f::f G.ROOT-SERVERS.NET. 3600000 IN A 192.112.36.4 H.ROOT-SERVERS.NET. 3600000 IN A 128.63.2.53 H.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:500:1::803f:235 I.ROOT-SERVERS.NET. 3600000 IN A 192.36.148.17 J.ROOT-SERVERS.NET. 3600000 IN A 192.58.128.30 J.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:503:c27::2:30 K.ROOT-SERVERS.NET. 3600000 IN A 193.0.14.129 K.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:7fd::1 L.ROOT-SERVERS.NET. 3600000 IN A 199.7.83.42 M.ROOT-SERVERS.NET. 3600000 IN A 202.12.27.33 M.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 |