The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Plack::Middleware::DNSBL - An IPv4 DNS Blacklist middleware for Plack

SYNOPSIS

use Plack::Builder;
use Plack::Middleware::DNSBL;

my $app = sub { ... };

builder {
    enable 'DNSBL',
        blacklists => {
            'your-trusted-blacklist' => '$ip.your.trusted.blacklist',
            'ip-port-blacklist'      => '$ip.$port.ip-port.trusted.blacklist',
        };

    $app;
}

DESCRIPTION

The Plack::Middleware::DNSBL middleware provides a simple yet customizable way of blocking ill-intentionated requests from reaching your main application by using an external blacklist.

CONFIGURATIONS

blacklists
enable 'DNSBL',
    blacklists => {
        'blacklist-name-1' => 'blacklist-query-address',
        'blacklist-name-2' => 'blacklist-query-address',
        'blacklist-name-3' => 'blacklist-query-address',
        # ...
        'blacklist-name-n' => 'blacklist-query-address',
    };

The blacklists option specifies a hashref with all the blacklists' name and query address pairs. The query address will have every $ip and $port substrings replaced respectively by the $enviroment's reversed IPv4 address and server's port.

Therefore:

enable 'DNSBL',
    blacklists => {
        'my example blacklist' => '$ip.$port.blacklist.example.com', # single quotes!
    };

Will query 1.0.0.127.80.blacklist.example.com for IP 127.0.0.1 acessing over port 80.

blacklisted
enable 'DNSBL',
    blacklists => { ... },
    blacklisted => sub {
        my ($env, $blacklist, $is_cached) = @_;

        # Do some logging here

        if (!$is_cached && $blacklist eq 'blacklist name') {
            warn "$blacklist matched another address!";
        }

        if ($ENV{DEBUG} || $ENV{FRIENDLY}) {
            return [ 200, [ 'Content-type' => 'text/html' ], [
                "<html><body>",
                "<h1>Hello, buddy ($env->{REMOTE_ADDR})!</h1>",
                "<p>Looks like you're banned at $blacklist!</p>",
                "<p>Sorry :(</p>",
                "</body></html>",
            ] ];
        }

        [ 500, [ 'Content-type' => 'text/plain' ], [ "Die, spammer!" ] ];
    };

The blacklisted option specifies a coderef that will be called at the first blacklist that detect this IP as flagged, returing immediately it's return value.

Defaults to:

sub { [ 500, [ 'Content-Type' => 'text/plain' ], [ '' ] ] }
cache, cache_time
enable 'DNSBL',
    blacklists => { ... },
    cache_time => '1h',
    cache      => $cache;

The cache option specifies an object which handles get and set methods for caching whether an IP is blacklisted or not. If this option is set, it expects cache_time to be a string that can be parsed by this object and contains how long should this data be cached. Defaults to '86400' (1 day).

resolver
my $my_resolver = Net::DNS::Resolver->new(
    nameservers => [ '10.1.1.128', '10.1.2.128' ],
    recurse     => 0,
    debug       => 1
);

builder {
    enable 'DNSBL',
        resolver   => $my_resolver,
        blacklists => { ... };
    $app;
};

A Net::DNS::Resolver object. Defaults to Net::DNS::Resolver->new.

WHITELISTING

There's no build-in way of whitelisting IPs or certain paths, however this can be quickly solved by using Plack::Builder's enable_if:

builder {
    enable_if {
        !$ENV{DEBUG} && $_[0]->{REMOTE_ADDR} ne '127.0.0.1'
    } 'DNSBL', ...;
    $app;
};

SEE ALSO

Net::DNS::Resolver

AUTHOR

Victor Franco, <victorfrancovl at gmail.com>

BUGS

Patches welcome at https://www.github.com/vtfrvl/plack-middleware-dnsbl

LICENSE

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself