1package Mail::SpamAssassin::Spamd::Apache2::AclIP; 2use strict; 3use Apache2::Connection (); 4use Apache2::Const -compile => qw(OK FORBIDDEN SERVER_ERROR); 5 6use Apache2::Module (); 7use Apache2::ServerRec (); 8 9use Apache::Test; 10use constant APACHE24 => have_min_apache_version('2.4.0'); 11 12use Mail::SpamAssassin::Logger; 13 14=head1 NAME 15 16Mail::SpamAssassin::Spamd::Apache2::AclIP - host-based spamd access control 17 18=head1 SYNOPSIS 19 20 ##### in httpd.conf: 21 PerlLoadModule Mail::SpamAssassin::Spamd::Apache2::Config 22 SAallow from 127.0.0.1 192.168.0.0/24 23 24=head1 DESCRIPTION 25 26Allows / denies access to spamd basing on client's network address. 27This is a simple version of C<mod_authz_host> (which, unfortunately, 28is too HTTP-centric to use here). 29 30Should be before C<Mail::SpamAssassin::Spamd::Apache2::AclRFC1413> 31in the handler chain. 32 33=head1 NOTE 34 35This module doesn't prevent Apache from accepting a connection; child 36(and therefore we) get control after client actually sends something. 37It's possible to open C<$toomany> connections to the parent server and 38DoS this way. 39 40=head1 BUGS 41 42See <http://bugzilla.spamassassin.org/> 43 44=head1 SEE ALSO 45 46C<Mail::SpamAssassin::Spamd::Apache2::Config(3)> 47 48=cut 49 50use APR::IpSubnet (); 51 52sub handler { 53 my ($c) = @_; 54 55 my $srv_cfg = 56 Apache2::Module::get_config('Mail::SpamAssassin::Spamd::Apache2::Config', 57 $c->base_server); 58 59 # TODO: log it somewhere (or not?) -- means all denied 60 return Apache2::Const::SERVER_ERROR 61 unless $srv_cfg && exists $srv_cfg->{allowed_ips}; 62 63 # use NetAddr::IP::Lite (); 64 # my $ip = NetAddr::IP::Lite->new($c->remote_ip) 65 # or return Apache2::Const::SERVER_ERROR; # log it, shouldn't happen 66 67 #use Apache::Test have_min_apache_version to support MP under Apache 2.2 and 2.4 68 my $remote = APACHE24 ? $c->client_addr : $c->remote_addr; 69 70 for my $allowed (@{ $srv_cfg->{allowed_networks} }) { 71 # depends on allowed_ips format; TODO; if NetAddr::IP::Lite: 72 # return Apache2::Const::OK if $allowed->contains($ip); 73 return Apache2::Const::OK if $allowed->test($remote); 74 } 75 76 info(sprintf "access denied for '%s'", APACHE24 ? $c->client_ip : $c->remote_ip); 77 78 return Apache2::Const::FORBIDDEN; 79} 80 811; 82 83# vim: ts=8 sw=2 et 84