オープンリゾルバ撲滅に向けて
イタズラしたい人はご遠慮ください。作り方を公開しておきます。
※ Nginx + Mojolicious の環境を前提としています。
apacheでも大丈夫です♪
■Mojoliciousの環境作成
apt-get install perlbrew
perlbrew init
perlbrew install perl-5.16.3
perlbrew install-cpanm
cat ~/perl5/perlbrew/etc/bashrc >> ~/.bashrc
sourc ~/.bashrc
perlbrew use perl-5.16.3
cpanm install Mojolicious
cpanm install Net::DNS
cpanm install IO::Socket::IP
■プログラム
vi myapp.pl
-----
#!/usr/bin/env perl
use Mojolicious::Lite;
use Net::DNS;
use Sys::Syslog;
use IO::Socket::IP;
# share
our %h_checkedFlag;
# Documentation browser under "/perldoc"
plugin 'PODRenderer';
openlog("dnschk", 'ndelay,pid', 'user');
my $res = Net::DNS::Resolver->new;
$res->udp_timeout(1);
$res->tcp_timeout(1);
get '/check' =>sub {
my $c = shift;
my $flag = 0;
#my $rAddr = $c->tx->remote_address;
my $rAddr = $c->req->headers->header('X-Forwarded-For');
# When the IP is same, stop 60 sec.
if(time - $h_checkedFlag{$rAddr} < 60 ){$flag = 3;}
$h_checkedFlag{$rAddr} = time;
if($rAddr =~ /[^.:0-9a-fA-F]+/) {
$flag = 2;
$rAddr = '';
}
elsif(!$flag) {
foreach my $vc (0..1) {
$res->usevc($vc);
$res->nameservers($rAddr);
my $reply = $res->search("m.ROOT-SERVERS.NET");
if ($reply) {
foreach my $rr ($reply->answer) {
next unless $rr->type eq "A";
my $addr = $rr->address;
$flag = 1;
syslog('info', '%s,%s', $rAddr, $addr);
}
} else {
syslog('info', 'query failed %s', $rAddr);
}
}
}
my $data = { ip => $rAddr, flag => $flag };
$c->render(json => $data);
};
closelog;
app->start;
-----
プログラムを起動する
morbo myapp.pl
■index.html
cd /var/www/vhost/dnschk.snowdrop.asia/
wget 'http://code.jquery.com/jquery-1.11.1.min.js'
vi index.html
------
------
■nginxの設定
vi /etc/nginx/conf.d/dnschk.snowdrop.asia.conf
-----
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Remote-Addr $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location /check {
proxy_pass http://127.0.0.1:3000/check;
}
-----
反映する
sudo /etc/init.d/nginx reload