IP drop list

Michael Orlitzky michael at orlitzky.com
Thu Mar 5 01:13:10 UTC 2015


On 03/04/2015 06:12 PM, Jochen Bern wrote:
> On 03/04/2015 09:45 PM, Dave McGuire wrote:
>> On 03/04/2015 03:37 PM, Oliver Welter wrote:
>>> Am 04.03.2015 um 21:03 schrieb Dave McGuire: 
>>>> Am 04.03.2015 um 20:12 schrieb Michael Orlitzky: 
>>>>> Please add [DNSBL] support to iptables instead of Dovecot. It's a waste of
>>>>> effort to code it into every application that listens on the network.
> 
> (FWIW, I agree that DNSBL hooks have no business being in kernel space.
> A standard *userland* DNSBL client communicating with iptables and
> similar by means of libnetfilter_queue would sound quite promising,
> however ...)
> 

This is what I had in mind. Here's a proof of concept. First, the
iptables rule:

  iptables -A tcp_packets -p tcp --dport 443 -j NFQUEUE --queue-num 1

(the details aren't important, just send something to NFQUEUE #1).

Then create the queue as root, and drop privileges. After that you can
make accept/drop decisions in userspace. This took maybe 15 minutes
using NetfilterQueue from pypi. It would be easy to replace the

  if ipp.src == badguy

test with a real RBL lookup. But then you'd need to make the RBL list
configurable, and implement a scoring system, and document it, etc.
(i.e. all the /actual/ work).

------


import os, pwd, grp
from netfilterqueue import NetfilterQueue
from scapy.all import IP


def drop_privileges(uid_name='dovecot', gid_name='dovecot'):
    """
    Drop user/group privileges from root/root to the given ones.
    """
    if os.getuid() != 0:
        # We're not root *shrug*.
        return

    # Get the uid/gid from the name
    running_uid = pwd.getpwnam(uid_name).pw_uid
    running_gid = grp.getgrnam(gid_name).gr_gid

    # Remove group privileges
    os.setgroups([])

    # Try setting the new uid/gid
    os.setgid(running_gid)
    os.setuid(running_uid)

    # Ensure a very conservative umask
    old_umask = os.umask(077)


def callback(packet):
    """
    Callback function registered through netfilter. Will be called on
    every packet passed to the netfilter queue.
    """
    badguy = "127.0.0.1"
    ipp = IP(packet.get_payload())

    if ipp.src == badguy:
        print("Dropping packet from %s..." % badguy)
        packet.drop()
    else:
        packet.accept()


nfqueue = NetfilterQueue()
nfqueue.bind(1, callback)

drop_privileges()

try:
    nfqueue.run()
except KeyboardInterrupt:
    print("Bailing...")



More information about the dovecot mailing list