qpsmtpd Wiki


You are here: start » plugins » spam » connection_shaper


You are currently not logged in! Enter your authentication credentials below to log in. You need to have cookies enabled to log in.


You don't have an account yet? Just get one: Register

Forgotten your password? Get a new one: Set new password

Plug-in Summary

Plug-in name: connection_shaper
Info: limit the connection rate for each IP address
Author: Yoshifumi Kinoshita
Email: yoshifumi1975@gmail.com
Compatibility: all
Download: here


=head1 NAME 
connection_shaper - limit the connection rate for each IP address.
The B<connection_shaper> module reject clients who try to connect more than specified
times during specified period. The rate is specified in the config file I<connection_shaper>.
memcached 1.2.4 or newer is required.
C<Cache::Memcached::Fast> module from CPAN is required.
=head1 CONFIG
The config file contains lines with two. The first is a key.
The second is a value.
exptime 60
threshold 10
memcached_port 11211
memcached_server memcached.example.com
whitelist 192.168.1., 192.168.2., 10.0.0
It means that a client can connect upto 10 times every 60 seconds.
=head1 AUTHOR
Copyright 2008 Yoshifumi Kinoshita <yoshifumi1975@gmail.com>
This software is free software and may be distributed under the same
terms as qpsmtpd itself.
use Qpsmtpd::Constants;
use Socket;
use Cache::Memcached::Fast;
my $memcached;
my $config;
my @whitelist;
sub hook_pre_connection {
    my ($self,$transaction,%args) = @_;
    foreach ($self->qp->config("connection_shaper")) {
        next if( m/^#/ );
        my ($key, $value) = split /\s+/, $_, 2;
        $config->{$key} = $value;
    $config->{exptime} ||= 60; # 1 min.
    $config->{threshold} ||= 10;
    @whitelist = split /,\s*/, $config->{whitelist};
    $memcached = init_memcached($config);
    return (DECLINED, "") if match_whitelist( $args{remote_ip} );
    $memcached->add($args{remote_ip}, 0, $config->{exptime});
    my $current_value = $memcached->incr($args{remote_ip}) || 0;
    if( $current_value > $config->{threshold} ){
        $self->log(LOGINFO, "Exceeds the threshold from $args{remote_ip}.");
        return (DENYSOFT, "");
    return (DECLINED, "");
sub init_memcached{
    my($config) = shift;
    $config->{memcached_server} ||= 'localhost';
    $config->{memcached_port} ||= 11211;
    return new Cache::Memcached::Fast({
        servers => [ { address => "$config->{memcached_server}:$config->{memcached_port}" } ],
        failure_timeout => 2,
        max_failures => 1,
sub match_whitelist{
    my($remote_ip) = shift;
    foreach (@whitelist){
        return 1 if( $remote_ip =~ m/$_/ );
    return 0;