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...")