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:
parent
ae3fe2e4d5
commit
c4b8a7a395
@ -1,4 +1,4 @@
|
|||||||
#
|
#
|
||||||
# Example configuration file for plugins
|
# Example configuration file for plugins
|
||||||
#
|
#
|
||||||
|
|
||||||
@ -6,6 +6,9 @@
|
|||||||
# plugins/http_config for details.
|
# plugins/http_config for details.
|
||||||
# http_config http://localhost/~smtpd/config/ http://www.example.com/smtp.pl?config=
|
# 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 /
|
# The hosts_allow module must be loaded if you want the -m / --max-from-ip /
|
||||||
# my $MAXCONNIP = 5; # max simultaneous connections from one IP
|
# my $MAXCONNIP = 5; # max simultaneous connections from one IP
|
||||||
# settings... without this it will NOT refuse more than $MAXCONNIP connections
|
# settings... without this it will NOT refuse more than $MAXCONNIP connections
|
||||||
@ -48,12 +51,12 @@ virus/klez_filter
|
|||||||
|
|
||||||
|
|
||||||
# You can run the spamassassin plugin with options. See perldoc
|
# You can run the spamassassin plugin with options. See perldoc
|
||||||
# plugins/spamassassin for details.
|
# plugins/spamassassin for details.
|
||||||
#
|
#
|
||||||
spamassassin
|
spamassassin
|
||||||
|
|
||||||
# rejects mails with a SA score higher than 20 and munges the subject
|
# rejects mails with a SA score higher than 20 and munges the subject
|
||||||
# of the score is higher than 10.
|
# of the score is higher than 10.
|
||||||
#
|
#
|
||||||
# spamassassin reject_threshold 20 munge_subject_threshold 10
|
# spamassassin reject_threshold 20 munge_subject_threshold 10
|
||||||
|
|
||||||
|
@ -1,24 +1,29 @@
|
|||||||
#!perl -w
|
#!perl -w
|
||||||
|
|
||||||
=head1 NAME
|
=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
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
The B<hosts_allow> module decides before the SMTP-Greeting if a host is
|
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
|
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
|
host (see -m/--max-from-ip options in qpsmtpd-forkserver) and the config
|
||||||
file I<hosts_allow>.
|
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
|
=head1 CONFIG
|
||||||
|
|
||||||
The config file contains lines with two or three items. The first is either
|
The I<hosts_allow> config file contains lines with two or three items. The
|
||||||
an IP address or a network/mask pair. The second is a (valid) return code
|
first is an IP address or a network/mask pair. The second is a (valid) return
|
||||||
from Qpsmtpd::Constants. The last is a comment which will be returned to the
|
code from Qpsmtpd::Constants. The last is a comment which will be returned to
|
||||||
connecting client if the return code is DENY or DENYSOFT (and of course
|
the connecting client if the return code is DENY or DENYSOFT (and of course
|
||||||
DENY_DISCONNECT and DENYSOFT_DISCONNECT).
|
DENY_DISCONNECT and DENYSOFT_DISCONNECT).
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
192.168.3.4 DECLINED
|
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.
|
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
|
=cut
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
use Qpsmtpd::Constants;
|
use Qpsmtpd::Constants;
|
||||||
use Socket;
|
use Socket;
|
||||||
|
|
||||||
@ -39,41 +64,42 @@ sub hook_pre_connection {
|
|||||||
# local_ip => inet_ntoa($laddr),
|
# local_ip => inet_ntoa($laddr),
|
||||||
# local_port => $lport,
|
# local_port => $lport,
|
||||||
# max_conn_ip => $MAXCONNIP,
|
# max_conn_ip => $MAXCONNIP,
|
||||||
# child_addrs => [values %childstatus],
|
# child_addrs => [values %childstatus],
|
||||||
|
|
||||||
my $remote = $args{remote_ip};
|
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 $num_conn = 1; # seed with current value
|
||||||
my $raddr = inet_aton($remote);
|
my $raddr = inet_aton($remote);
|
||||||
foreach my $rip (@{$args{child_addrs}}) {
|
foreach my $rip (@{$args{child_addrs}}) {
|
||||||
++$num_conn if (defined $rip && $rip eq $raddr);
|
++$num_conn if (defined $rip && $rip eq $raddr);
|
||||||
}
|
}
|
||||||
if ($num_conn > $args{max_conn_ip}) {
|
if ($num_conn > $max ) {
|
||||||
$self->log(LOGINFO,
|
my $err_mess = "too many connections from $remote";
|
||||||
"Too many connections from $remote: "
|
$self->log(LOGINFO, "fail: $err_mess ($num_conn > $max)");
|
||||||
. "$num_conn > " . $args{max_conn_ip}
|
return (DENYSOFT, "Sorry, $err_mess, try again later");
|
||||||
. "Denying connection.");
|
|
||||||
return (DENYSOFT, "Sorry, too many connections from $remote, "
|
|
||||||
."try again later");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($self->qp->config("hosts_allow")) {
|
foreach ($self->qp->config("hosts_allow")) {
|
||||||
s/^\s*//;
|
s/^\s*//;
|
||||||
my ($ipmask, $const, $message) = split /\s+/, $_, 3;
|
my ($ipmask, $const, $message) = split /\s+/, $_, 3;
|
||||||
next unless defined $const;
|
next unless defined $const;
|
||||||
|
|
||||||
my ($net,$mask) = split '/', $ipmask, 2;
|
my ($net,$mask) = split '/', $ipmask, 2;
|
||||||
if (!defined $mask) {
|
$mask = 32 if !defined $mask;
|
||||||
$mask = 32;
|
|
||||||
}
|
|
||||||
$mask = pack "B32", "1"x($mask)."0"x(32-$mask);
|
$mask = pack "B32", "1"x($mask)."0"x(32-$mask);
|
||||||
if (join(".", unpack("C4", inet_aton($remote) & $mask)) eq $net) {
|
if (join(".", unpack("C4", inet_aton($remote) & $mask)) eq $net) {
|
||||||
$const = Qpsmtpd::Constants::return_code($const) || DECLINED;
|
$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);
|
return($const, $message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$self->log( LOGDEBUG, "pass" );
|
||||||
return (DECLINED);
|
return (DECLINED);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user