免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 4268 | 回复: 11
打印 上一主题 下一主题

【求助】如何用Perl做一个DNS代理服务器 [已解决] [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-04-03 10:37 |只看该作者 |倒序浏览
本帖最后由 hhs66317 于 2013-04-05 20:45 编辑

我的构想是这样的:
1、在本地用Perl模块 Net:NS::Nameserver 建立一个DNS服务器,监听本地TCP、UDP的53端口
2、接收到本地应用程序对DNS的UDP请求时,服务器通过 ReplyHandler => \&reply_handler 进行处理
3、在&reply_handler中,获取具体请求的 name 和 type
4、用Perl模块 Net:NS::Resolver 根据请求的 name 和 type 用TCP协议发送DNS请求到 8.8.8.8、8.8.4.4
5、得到正确的DNS相应后,将该相应用UDP协议发送给本地应用程序,从而完成DNS的代理

不知道我的想法是否正确,另外我在实际操作中遇到了问题,我不知道如何完成上述第五步

下面是一些零碎的代码,基础太差,没办法组装起来,请各位路过的perler指点斧正

  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use Net::DNS::Nameserver;

  5. my $ns = new Net::DNS::Nameserver(
  6.     LocalAddr    => ['::1' , '127.0.0.1' ],
  7.     LocalPort    => 53,
  8.     ReplyHandler => \&reply_handler,
  9.     Verbose      => 1,
  10.     Truncate     => 0
  11.     ) || die "couldn't create nameserver object\n";

  12. $ns->main_loop;

  13. sub reply_handler {
  14.     my ($qname, $qclass, $qtype, $peerhost,$query,$conn) = @_;
  15.     ....
  16. }
复制代码

  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use Net::DNS;

  5. my $res = Net::DNS::Resolver->new(
  6.     nameservers => [qw(8.8.8.8 8.8.4.4)],
  7.     usevc       => 1,
  8. #    debug       => 1,
  9. );
  10. my $packet = $res->query('www.google.com','A');

复制代码

论坛徽章:
0
2 [报告]
发表于 2013-04-03 16:21 |只看该作者
为什么这么多路过的神仙一句话也不说呢,随便说两句,给点思路也成啊

论坛徽章:
27
水瓶座
日期:2014-08-22 21:06:34程序设计版块每日发帖之星
日期:2015-11-25 06:20:0015-16赛季CBA联赛之新疆
日期:2015-12-19 19:05:48IT运维版块每日发帖之星
日期:2015-12-25 06:20:31IT运维版块每日发帖之星
日期:2015-12-25 06:20:31IT运维版块每日发帖之星
日期:2015-12-25 06:20:3315-16赛季CBA联赛之上海
日期:2016-04-15 19:51:31程序设计版块每日发帖之星
日期:2016-04-17 06:23:29程序设计版块每日发帖之星
日期:2016-04-23 06:20:00程序设计版块每日发帖之星
日期:2016-05-26 06:20:00每日论坛发贴之星
日期:2016-05-26 06:20:0015-16赛季CBA联赛之辽宁
日期:2017-02-16 23:59:47
3 [报告]
发表于 2013-04-03 18:06 |只看该作者
帅哥,我刚才看了cpan上有了,你的这个题目太大了,别人几分钟内是没法帮你完成的。
http://search.cpan.org/~maja/Net ... script/dns-proxy.pl

论坛徽章:
0
4 [报告]
发表于 2013-04-05 04:15 |只看该作者
回复 3# shijiang1130

感谢帅帅哥的回复,我在windows上工作,因为dns污染的缘故,有了做本地dns代理的需求,目前使用的是python版本的一个实现,就一直琢磨着要搞一个perl的。基础太差,看了半天也就整理出这么点东西,才跑来请教的。
我这就循着你指点的链接过去看看,在这之前,必须先跟你说声谢谢。若还有疑问,再来讨教。

论坛徽章:
0
5 [报告]
发表于 2013-04-05 06:28 |只看该作者
根据你的提示,我安装了模块Net:NS:ynamic:roxyserver
这个模块不能在windows上正常运行,我强制安装后,写了个demo:

  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use Net::DNS::Dynamic::Proxyserver;
  5. my $proxy = Net::DNS::Dynamic::Proxyserver->new(
  6.     debug => 1,
  7.     host => '*',
  8.     port => 53,
  9.     uid => 65534,
  10.     gid => 65534,
  11.     nameservers      => [ '8.8.8.8', '8.8.4.4' ],
  12.     nameservers_port => 53,
  13. );

  14. $proxy->run();
复制代码
但是这个demo不能正常运行,出现下面的提示:

  1. Attribute (nameserver) does not pass the type constraint because: Validation failed for 'Net::DNS::Nameserver' with value undef at accessor Net::DNS::Dynamic::Proxyserver::nam
  2. eserver (defined at D:/Strawberry/perl/site/lib/Net/DNS/Dynamic/Proxyserver.pm line 231) line 4
  3.         Net::DNS::Dynamic::Proxyserver::nameserver('Net::DNS::Dynamic::Proxyserver=HASH(0x130e67c)', undef) called at D:/Strawberry/perl/site/lib/Net/DNS/Dynamic/Proxyserver.p
  4. m line 259
  5.         Net::DNS::Dynamic::Proxyserver::BUILD('Net::DNS::Dynamic::Proxyserver=HASH(0x130e67c)', 'HASH(0x2dbe94)') called at constructor Net::DNS::Dynamic::Proxyserver::new (de
  6. fined at D:/Strawberry/perl/site/lib/Net/DNS/Dynamic/Proxyserver.pm line 542) line 116
  7.         Net::DNS::Dynamic::Proxyserver::new('Net::DNS::Dynamic::Proxyserver', 'debug', 1, 'host', '*', 'port', 53, 'uid', 65534, 'gid', 65534, 'nameservers', 'ARRAY(0x2dbba4)'
  8. , 'nameservers_port', 53) called at D:\Desktop\dns-proxy.pl line 5
  9. shell returned 2
  10. Hit any key to close this window...
复制代码
前后查看了半天,也没找到啥原因导致的

论坛徽章:
0
6 [报告]
发表于 2013-04-05 09:29 |只看该作者
真折腾啊!
那个新模块用不来,就按原来的思路,组装起来一个,勉强能用,但是用了一会儿,就不能正常工作了,劳烦各位老师指点下,看看问题出在哪里
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use Net::DNS;
  5. use Net::DNS::Nameserver;

  6. my $res = Net::DNS::Resolver->new(
  7.     nameservers => [qw(114.114.114.114 8.8.8.8 8.8.4.4)],
  8.     usevc       => 1,
  9.     persistent_tcp => 1,
  10. );


  11. my $ns = new Net::DNS::Nameserver(
  12.     LocalAddr    => [ '127.0.0.1' ],
  13.     LocalPort    => 53,
  14.     ReplyHandler => \&reply_handler,
  15.     Truncate     => 0
  16.     ) || die "couldn't create nameserver object\n";

  17. $ns->main_loop;

  18. sub reply_handler {
  19.     my ($qname, $qclass, $qtype, $peerhost,$query,$conn) = @_;
  20.     print "$peerhost => $qname , $qclass , $qtype\n";
  21.     my ($rcode, @ans, @auth, @add);

  22.     my $answer = $res->send($qname, $qtype, $qclass);

  23.     if ($answer) {
  24.            $rcode = $answer->header->rcode;
  25.            @ans   = $answer->answer;
  26.            @auth  = $answer->authority;
  27.            @add   = $answer->additional;
  28.         return ($rcode, \@ans, \@auth, \@add);
  29.     }
  30.     else {
  31.         $rcode = "NXDOMAIN";
  32.         return ($rcode, \@ans, \@auth, \@add, { aa => 1, ra => 1 });
  33.     }
  34. }
复制代码
现在的情况是,我用ping测试,能正常解析,但是一打开网页,很快就挂了,也不知道问题出在那里,哎

论坛徽章:
27
水瓶座
日期:2014-08-22 21:06:34程序设计版块每日发帖之星
日期:2015-11-25 06:20:0015-16赛季CBA联赛之新疆
日期:2015-12-19 19:05:48IT运维版块每日发帖之星
日期:2015-12-25 06:20:31IT运维版块每日发帖之星
日期:2015-12-25 06:20:31IT运维版块每日发帖之星
日期:2015-12-25 06:20:3315-16赛季CBA联赛之上海
日期:2016-04-15 19:51:31程序设计版块每日发帖之星
日期:2016-04-17 06:23:29程序设计版块每日发帖之星
日期:2016-04-23 06:20:00程序设计版块每日发帖之星
日期:2016-05-26 06:20:00每日论坛发贴之星
日期:2016-05-26 06:20:0015-16赛季CBA联赛之辽宁
日期:2017-02-16 23:59:47
7 [报告]
发表于 2013-04-05 13:34 |只看该作者
本帖最后由 shijiang1130 于 2013-04-05 14:00 编辑

回复 6# hhs66317
把你的程序再组装一下是能用的。
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use Net::DNS;
  5. use Net::DNS::Nameserver;

  6. my $ns = new Net::DNS::Nameserver(
  7.     LocalAddr    => [ '127.0.0.1' ],
  8.     LocalPort    => 53,
  9.     ReplyHandler => \&reply_handler,
  10.     Truncate     => 0,
  11. #  Verbose      => 1
  12.     ) || die "couldn't create nameserver object\n";

  13. $ns->main_loop;

  14. sub reply_handler {
  15.     my ($qname, $qclass, $qtype, $peerhost,$query,$conn) = @_;
  16.     print "$peerhost => $qname , $qclass , $qtype\n";
  17.     my ($rcode, @ans, @auth, @add);

  18. my $res = Net::DNS::Resolver->new(
  19.     nameservers => [qw(8.8.8.8 8.8.4.4)],
  20.     usevc       => 1,
  21.     persistent_tcp => 1,
  22. );

  23. #$res->tcp_timeout(10);
  24. #$res->retry(10);       
  25.        
  26.     my $answer = $res->send($qname, $qtype, $qclass);
  27.        
  28. #        print "#####################################\n";
  29. #    print $res->print;
  30. #        print "#####################################\n";
  31.     if ($answer) {
  32.            $rcode = $answer->header->rcode;
  33.            @ans   = $answer->answer;
  34.            @auth  = $answer->authority;
  35.            @add   = $answer->additional;
  36.         return ($rcode, \@ans, \@auth, \@add);
  37.     }
  38.     else {
  39.         $rcode = "NXDOMAIN";
  40.         return ($rcode, \@ans, \@auth, \@add, { aa => 1, ra => 1 });
  41.     }
  42. }
复制代码

论坛徽章:
0
8 [报告]
发表于 2013-04-05 14:37 |只看该作者
感谢 shijiang1130 的持续关注!!!

奇怪了,果然这么写确实能保证正常解析不出问题了
这是什么原因呢?,我对比了下,不同的地方就是把创建DNS解析对象放在回掉函数里边去了
另外这个代理服务器,刚开始解析的时候好慢,不过现在是可用的,除了有以下两个返回的信息比较碍眼:
  1. Maximum reply length as advertised in EDNS from 127.0.0.1:59007: 512
复制代码
  1. the Peer host and sock host appear to be undefined: bailing out of handling the UDP connectionWaiting for connections...
复制代码

论坛徽章:
0
9 [报告]
发表于 2013-04-05 15:00 |只看该作者
保暖思淫欲,刚刚不死心又跑去尝试模块 Net:NS:ynamic:roxyserver

瞎折腾半天,还是原来的错误提示 。。。。

困死了,晚上没睡好。。。

论坛徽章:
27
水瓶座
日期:2014-08-22 21:06:34程序设计版块每日发帖之星
日期:2015-11-25 06:20:0015-16赛季CBA联赛之新疆
日期:2015-12-19 19:05:48IT运维版块每日发帖之星
日期:2015-12-25 06:20:31IT运维版块每日发帖之星
日期:2015-12-25 06:20:31IT运维版块每日发帖之星
日期:2015-12-25 06:20:3315-16赛季CBA联赛之上海
日期:2016-04-15 19:51:31程序设计版块每日发帖之星
日期:2016-04-17 06:23:29程序设计版块每日发帖之星
日期:2016-04-23 06:20:00程序设计版块每日发帖之星
日期:2016-05-26 06:20:00每日论坛发贴之星
日期:2016-05-26 06:20:0015-16赛季CBA联赛之辽宁
日期:2017-02-16 23:59:47
10 [报告]
发表于 2013-04-05 15:24 |只看该作者
hhs66317 发表于 2013-04-05 15:00
保暖思淫欲,刚刚不死心又跑去尝试模块 Net:NS:ynamic:roxyserver

瞎折腾半天,还是原来的错误提示 ...

I like that !
我也装了那个模块,现在可以工作。把我的步骤说一下吧,看你能不能也设置好。
  1. OS Name:                   Microsoft Windows 7 Professional
  2. OS Version:                6.1.7601 Service Pack 1 Build 7601
  3. OS Manufacturer:           Microsoft Corporation
  4. C:\Users\test>perl -v

  5. This is perl 5, version 16, subversion 3 (v5.16.3) built for MSWin32-x64-multi-t
  6. hread
  7. (with 1 registered patch, see perl -V for more detail)

  8. Copyright 1987-2012, Larry Wall

  9. Binary build 1603 [296746] provided by ActiveState http://www.ActiveState.com
  10. Built Mar 13 2013 13:31:10

  11. Perl may be copied only under the terms of either the Artistic License or the
  12. GNU General Public License, which may be found in the Perl 5 source kit.

  13. Complete documentation for Perl, including FAQ lists, should be found on
  14. this system using "man perl" or "perldoc perl".  If you have access to the
  15. Internet, point your browser at http://www.perl.org/, the Perl Home Page.
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP