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