如何在Unix/Linux上使用Perl执行批量DNS查询?

4
我有一个系统列表,想要获取相应的IP地址。我已经成功地使用了Perl中Net::DNS模块来查询单个主机的IP地址。但是我有1000个需要查询IP地址的系统。
有没有一种方法可以通过一个查询获得所有这些IP地址?
如果不能,是否有一种方法可以获取整个DNS条目列表,比如对于一个单独的域?如果我能这样做,那么我就可以将它放入哈希表中,并引用IP地址。

你为什么不直接循环主机名呢? - Chas. Owens
性能。我只是不想在一个请求就能完成的情况下进行1,000个单独的查询! - wsaxton
2
你是否证明了进行1000个单独的查询会对程序或DNS服务器的性能产生负面影响?如果没有,那么你是在过早地进行优化。大多数DNS服务器每秒可以处理数万个查询,我不认为仅查询它会有问题。 - Chas. Owens
一些域名可能允许您 AXFR 其区域数据,但我强烈建议不要尝试探索此功能。只需循环遍历您的 1000 条记录即可。您的本地 DNS 服务器将缓存结果,因此大多数重复查询不会传播太远。 - tripleee
2个回答

10

不需要使用自定义的Perl脚本。可以使用dig(BIND工具的一部分)的-f选项来实现此目的:

$ dig -f /path/to/host-list.txt

感谢你的回复。我知道 dig 命令,但与 Net::DNS 返回的整洁对象相比,它似乎需要进行大量解析。如果没有收到更“简单”的答案,我会考虑这个作为被接受的答案。 - wsaxton
1
它可以变得更加安静和简洁 - 仍然需要一些解析,但请探索选项。 - tripleee
1
实际上,经过测试,+noall +answer选项看起来正是我需要的,而且解析起来也容易得多。 - wsaxton

3

对于一个大型域名数据集,这个方法可以快速完成,而且不需要解析结果;一个IP地址总是在$results{$domain}[0][4]中。虽然不是单个查询,但它们将同时进行(任何时候最多10个查询正在进行),因此将很快完成。只需确保DNS服务器操作员不会在短时间内对这么多请求有问题。

use AnyEvent::DNS;
use Data::Dumper;

my @domains = qw/google.com/;
my $resolver = AnyEvent::DNS->new( server => '8.8.4.4' );
my %results;

### Set up the condvar
my $done = AE::cv;
$done->begin( sub { shift->send } );

for my $domain (@domains) {
  $done->begin;
  $resolver->resolve($domain, 'a', sub {push @{$results{$domain}}, \@_; $done->end;});
}

### Decrement the cv counter to cancel out the send declaration
$done->end;

### Wait for the resolver to perform all resolutions
$done->recv;

print Dumper \%results;

输出:

$VAR1 = {
          'google.com' => [
                            [
                              'google.com',
                              'a',
                              'in',
                              300,
                              '74.125.225.52'
                            ],
                            [
                              'google.com',
                              'a',
                              'in',
                              300,
                              '74.125.225.50'
                            ],
                            [
                              'google.com',
                              'a',
                              'in',
                              300,
                              '74.125.225.49'
                            ],
                            [
                              'google.com',
                              'a',
                              'in',
                              300,
                              '74.125.225.48'
                            ],
                            [
                              'google.com',
                              'a',
                              'in',
                              300,
                              '74.125.225.51'
                            ]
                          ]
        };

谢谢您的回答。我们可能会采用这个解决方案,即使它从技术上来说并不是问题的答案(因为仍然有1,000个查询正在进行)。 - wsaxton
1
嗯,我猜你试图合并它们是因为Net::DNS太慢了。这是非阻塞的,可以适配其他基于事件的编程,并且通常应该只需运行即可。您实际上无法在单个数据包中查询多个域名查找;协议不支持这种方式。幕后,像dig之类的工具仍将执行多个查找。参考http://groups.google.com/group/comp.protocols.dns.bind/browse_thread/thread/b8e5b13649bb0158。 - Oesor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接