hosts_allow: added logging, POD, deploy notes

added LOGINFO logging for denials, and LOGDEBUG for other results
added SEE ALSO pod
improved readability
This commit is contained in:
Matt Simerson 2012-05-11 01:50:03 -04:00 committed by Robert
parent ae3fe2e4d5
commit c4b8a7a395
2 changed files with 54 additions and 25 deletions

View File

@ -6,6 +6,9 @@
# plugins/http_config for details.
# http_config http://localhost/~smtpd/config/ http://www.example.com/smtp.pl?config=
# hosts_allow does not work with the tcpserver deployment model!
# perldoc plugins/hosts_allow for an alternative.
#
# The hosts_allow module must be loaded if you want the -m / --max-from-ip /
# my $MAXCONNIP = 5; # max simultaneous connections from one IP
# settings... without this it will NOT refuse more than $MAXCONNIP connections

View File

@ -2,7 +2,7 @@
=head1 NAME
hosts_allow - decide if a host is allowed to send mail
hosts_allow - decide if a host is allowed to connect
=head1 DESCRIPTION
@ -10,15 +10,20 @@ The B<hosts_allow> module decides before the SMTP-Greeting if a host is
allowed to connect. It checks for too many (running) connections from one
host (see -m/--max-from-ip options in qpsmtpd-forkserver) and the config
file I<hosts_allow>.
The plugin takes no arguments.
The plugin takes no config/plugin arguments.
This plugin only works with the forkserver and prefork deployment models. It
does not work with the tcpserver deployment model. See SEE ALSO below.
=head1 CONFIG
The config file contains lines with two or three items. The first is either
an IP address or a network/mask pair. The second is a (valid) return code
from Qpsmtpd::Constants. The last is a comment which will be returned to the
connecting client if the return code is DENY or DENYSOFT (and of course
The I<hosts_allow> config file contains lines with two or three items. The
first is an IP address or a network/mask pair. The second is a (valid) return
code from Qpsmtpd::Constants. The last is a comment which will be returned to
the connecting client if the return code is DENY or DENYSOFT (and of course
DENY_DISCONNECT and DENYSOFT_DISCONNECT).
Example:
192.168.3.4 DECLINED
@ -26,8 +31,28 @@ Example:
This would exclude 192.168.3.4 from the DENY of 192.168.3.0/24.
=head1 SEE ALSO
To get similar functionality for the tcpserver deployment model, use
tcpserver's -x feature. Create a tcp.smtp file with entries like this:
70.65.227.235:deny
183.7.90.207:deny
:allow
compile the tcp.smtp file like this:
/usr/local/bin/tcprules tcp.smtp.cdb tcp.smtp.tmp < tcp.smtp
and add the file to the chain of arguments to tcpserver in your run file.
See also: http://cr.yp.to/ucspi-tcp.html
=cut
use strict;
use warnings;
use Qpsmtpd::Constants;
use Socket;
@ -42,20 +67,18 @@ sub hook_pre_connection {
# child_addrs => [values %childstatus],
my $remote = $args{remote_ip};
my $max = $args{max_conn_ip};
if ($args{max_conn_ip}) {
if ( $max ) {
my $num_conn = 1; # seed with current value
my $raddr = inet_aton($remote);
foreach my $rip (@{$args{child_addrs}}) {
++$num_conn if (defined $rip && $rip eq $raddr);
}
if ($num_conn > $args{max_conn_ip}) {
$self->log(LOGINFO,
"Too many connections from $remote: "
. "$num_conn > " . $args{max_conn_ip}
. "Denying connection.");
return (DENYSOFT, "Sorry, too many connections from $remote, "
."try again later");
if ($num_conn > $max ) {
my $err_mess = "too many connections from $remote";
$self->log(LOGINFO, "fail: $err_mess ($num_conn > $max)");
return (DENYSOFT, "Sorry, $err_mess, try again later");
}
}
@ -65,15 +88,18 @@ sub hook_pre_connection {
next unless defined $const;
my ($net,$mask) = split '/', $ipmask, 2;
if (!defined $mask) {
$mask = 32;
}
$mask = 32 if !defined $mask;
$mask = pack "B32", "1"x($mask)."0"x(32-$mask);
if (join(".", unpack("C4", inet_aton($remote) & $mask)) eq $net) {
$const = Qpsmtpd::Constants::return_code($const) || DECLINED;
if ( $const =~ /deny/i ) {
$self->log( LOGINFO, "fail: $message" );
};
$self->log( LOGDEBUG, "pass: $const, $message" );
return($const, $message);
}
}
$self->log( LOGDEBUG, "pass" );
return (DECLINED);
}