ApacheとVarnishでIPブロックを共有管理 RE: IPアドレスブロックを集中管理する方法と、その活用法
hirose31さんの「IPアドレスブロックを集中管理する方法と、その活用法」のような感じでApacheとVarnishのIPブロック設定を行う方法
某所でも、WWW::MobileCarrierJPをつかってIPリストを取得していますが、これまでApacheしか使ってないこともあって、吐き出し方法は直接Apacheのconfにしています。
■mobileip(docomo|ezweb|softbank..).conf
Allow from 210.153.84.0/24
Allow from 210.136.161.0/24
Allow from 210.153.86.0/24
...
これを、httpd.confからIncludeして使ってます。
VarnishでもキャリアのIPセグメントでアクセス制御をする必要があって、ちょっと考えましたが次の方法でやっています。
Varnishの場合、ACLは以下のような感じに書きます
acl local {
"192.168.0.0"/16; #ローカル
"127.0.0.1";
}
sub vcl_recv {
if ( !client.ip ~ local) {
error 403;
}
}
Apacheとはフォーマットが異なるので、上記のmobile_ip.confから簡単なPerlスクリプトで変換して、ACLブロックを生成します。
my @ip;
foreach my $conf ( <$FindBin::Bin/mobile_ip*.conf> ) {
open(my $fh, $conf ) or die $!;
while ( my $line = <$fh> ) {
next unless $line =~ m!^Allow\sfrom\s([0-9\.\/]+)!;
my $ip = $1;
if ( $ip =~ m!([0-9\.]+)/([0-9]+)! ) {
$ip = qq{"$1"/$2};
}
else {
$ip = qq{"$ip"};
}
push @ip, $ip;
}
}
my $acl = join "\n", map { qq/ $_;/ } @ip;
print <<EOF;
acl mobileip {
$acl
}
include "/path/to/default.vcl";
EOF
ACLのブロックを作成し、そのあと、includeで本来の設定を読み込みます。これで設定はできました。mobileipのACLを利用するようにdefault.vclを書きます
sub vcl_recv {
if ( !client.ip ~ local && !client.ip ~ mobileip ) {
error 403;
}
}
あとは、設定を変更したときに、手動でこのscriptを動かすのは面倒なので、varnishの起動script(daemontools)に追加してしまいます。
ulimit -n 131072
ulimit -l 82000
perl /path/to/make_acl.pl > /var/run/mobileip.vcl
echo 2>&1
exec softlimit -l 82000 -o 131072 /usr/sbin/varnishd -F -f /var/run/mobileip.vcl $DAEMON_OPTS
あとは、ファイルの監視を行い、daemontoolsに対してHUPを送るscirptを動かします
use Filesys::Notify::Simple;
my $w = Filesys::Notify::Simple->new([ $FindBin::Bin ]);
$w->wait(sub {
my @path = grep { $_->{path} =~ m!default\.! } @_;
if ( ! @path ) {
system('/usr/local/bin/svc','-t','/service/varnishd');
}
});
このscriptもdaemontoolsで動かしてしまいます。Filesys::Notify::Simpleでファイルの変更を監視し、変更があれば、svc -tでvarnishにHUPを送り、make_acl.plが動き設定を生成し新しいIPアドレスが適用されるようになります。ちなみにdefault.vclを変更した際は手動で再起動するようにしています。
modcidrlookup使いたいな。。