I've been taking a very heavy-handed approach to stopping spam lately, to help my users maintain a nice clean, spam-reduced mail environment.

First, I should mention that my system's tolerance for spam is nil. I have several hundred rulesets configured in the MTA, to block based on common subjects/heuristics, a very tweaked SpamAssassin setup, 6 different RBLs, including blackholes.us for 7 countries, clamav, and some very detailed procmail recipes to handle the AV and other things that slip through.

That being said, spam still gets in.

The piece of the puzzle that I'm trying to solve now, is being able to firewall off people/machines that are brute-forcing accounts on servers with domains we host (quite a few). An example of this from one of the live servers looks like this.

I cooked up a quick hackish bash script to deal with these, and half-shimmed in some perl to regex out the IP. I'd like to entertain some ideas and approaches to handling this entire thing in Perl exclusively.

Currently, it looks like this, and works perfectly, though is hackish:

# Wrapped for Perl Monks, unwrap before using LOG="/path/to/mail.log" IPT="/sbin/iptables" BAN="$IPT -A INPUT -s {} -p tcp -m tcp --dport 25 -j REJECT" DUP="$IPT -D INPUT -s {} -p tcp -m tcp --dport 25 -j \ REJECT --reject-with icmp-port-unreachable" # Find the offenders and ban them from reaching port 25 grep -A1 "User unknown" $LOG | grep nr \ | perl -lne 'print /\[((?:\d+\.){3}\d+)\]/' \ | sort | uniq -d | xargs -i $BAN # Check the existing rulesets for dupes, and remove $IPT-save | sort | uniq -d | perl -lne 'print /((?:\d+\.){3}\d+)/' \ | xargs -i $DUP

The process is:

  1. Grep the mail log to catch the line directly after the "User unknown" line
  2. Grep the result returned, for the line containing the offender's IP address directly (contains the string 'nrcpts')
  3. Regex out the IP address from that line (appears last in the string, bordered by braces, eg: [1.2.3.4])
  4. Wrap each of the IPs returned in an iptables command to block that IP on port 25
  5. Check the existing list of IP addresses stored in the firewall rules for dupes and remove any which match
  6. Lather. Rinse. Repeat, hourly.

Anyone want to take a stab at converting this little shell'ism to "Pure Perl™"?


In reply to Firewalling brute-force spam attacks by hacker

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.