The Community Forums

Interact with an entire community of cPanel & WHM users!
  1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Exim Dictionary Deny ACL for cPanel Servers

Discussion in 'General Discussion' started by chirpy, Aug 16, 2004.

  1. chirpy

    chirpy Well-Known Member

    Joined:
    Jun 15, 2002
    Messages:
    13,475
    Likes Received:
    20
    Trophy Points:
    38
    Location:
    Go on, have a guess
    We've developed the following Dictionary Attack ACL for the Exim mail server, with specific instructions on how to use it on a cPanel server. It has been developed so that it not only stops an active dictionary attack, but also prevents further attempts to send email to our server from the spammers IP address:

    http://www.configserver.com/free/eximdeny.html
     
    #1 chirpy, Aug 16, 2004
    Last edited: Apr 6, 2005
  2. sawbuck

    sawbuck Well-Known Member

    Joined:
    Jan 18, 2004
    Messages:
    1,367
    Likes Received:
    5
    Trophy Points:
    38
    cPanel Access Level:
    Root Administrator
    Nicely done. Thank you Chirpy for making this freely available.
     
  3. rs-freddo

    rs-freddo Well-Known Member

    Joined:
    May 13, 2003
    Messages:
    832
    Likes Received:
    1
    Trophy Points:
    18
    Location:
    Australia
    cPanel Access Level:
    Root Administrator
    Your script has the following line:
    flock (IN, LOCK_SH) or die "myexim.pl: $!";

    Now your script dies to myexim.pl a few times - but I have no such file on my server.
    I have exim.pl....

    Surely it should die to an existing script....
     
  4. chirpy

    chirpy Well-Known Member

    Joined:
    Jun 15, 2002
    Messages:
    13,475
    Likes Received:
    20
    Trophy Points:
    38
    Location:
    Go on, have a guess
    Hi Michael,

    It's not an issue as the text between the quotes is just comment, not actual code, in the error and doesn't look for a script called myexim.pl (which is leftover from development).

    To make it more aesthetically pleasing, I'll correct the text though ;)

    Thanks for pointing it out.
     
  5. rs-freddo

    rs-freddo Well-Known Member

    Joined:
    May 13, 2003
    Messages:
    832
    Likes Received:
    1
    Trophy Points:
    18
    Location:
    Australia
    cPanel Access Level:
    Root Administrator
    That's right (michael tries to remember PERL programming)...

    I replaced it with "Fatal Error - /etc/exim_deny.pl" since die does write to the error log.
     
  6. rs-freddo

    rs-freddo Well-Known Member

    Joined:
    May 13, 2003
    Messages:
    832
    Likes Received:
    1
    Trophy Points:
    18
    Location:
    Australia
    cPanel Access Level:
    Root Administrator
    I added this code to the bottom of the exim_deny.pl file so i get emailed after an attack.

    open (MAIL, "|/usr/lib/sendmail -t") or die "Unable to open Mail Program";
    print MAIL "To: root\n";
    print MAIL "From: root\n";
    print MAIL "Subject: Dictionary Attack Stopped\n\n";
    print MAIL "$a was added to exim_deny file\n";
    print MAIL "\n.\n";
    close(MAIL);
     
  7. ramprage

    ramprage Well-Known Member

    Joined:
    Jul 21, 2002
    Messages:
    667
    Likes Received:
    0
    Trophy Points:
    16
    Location:
    Canada
    Excellent work, very nicely done. Can't wait to give it a try on my servers.
     
  8. chirpy

    chirpy Well-Known Member

    Joined:
    Jun 15, 2002
    Messages:
    13,475
    Likes Received:
    20
    Trophy Points:
    38
    Location:
    Go on, have a guess
    I hope you like it ;) I'm also working on a mechanism for intelligently clearing down on an interval basis (rather than simply emptying the deny file) via a CRON job.
     
  9. chirpy

    chirpy Well-Known Member

    Joined:
    Jun 15, 2002
    Messages:
    13,475
    Likes Received:
    20
    Trophy Points:
    38
    Location:
    Go on, have a guess
    I've just released v1.1 of the script which now includes a method to clear down old entries based on the interval you call the script (with no parameters). To upgrade you just need to download the script and chown+chmod as per the instructions on the web page and then create a CRON symlink or crontab as described on the page.
     
  10. rs-freddo

    rs-freddo Well-Known Member

    Joined:
    May 13, 2003
    Messages:
    832
    Likes Received:
    1
    Trophy Points:
    18
    Location:
    Australia
    cPanel Access Level:
    Root Administrator
    Excellent - thanks for the great script!
     
  11. verdon

    verdon Well-Known Member

    Joined:
    Nov 1, 2003
    Messages:
    836
    Likes Received:
    2
    Trophy Points:
    18
    Location:
    Northern Ontario, Canada
    cPanel Access Level:
    Root Administrator
    Hi :)

    I've had this working nicely on a redhat/cpanel server for a couple months now (and it's really helped, thanks!).

    This past weekend I transfered to a CentOS server. Other than that (and some hardware upgrades) the servers are pretty much the same.
    WHM 9.9.8 cPanel 9.9.8-R116**
    CentOS 3.3 i686 - WHM X v3.1.0

    I am unable to get these ACL's to work on the new server. I followed the same steps. I can send and receive mail with no problem, but dictionary attacks are happening and nothing is being added to /etc/exim_deny

    Any suggestions?

    TIA,
     
  12. chirpy

    chirpy Well-Known Member

    Joined:
    Jun 15, 2002
    Messages:
    13,475
    Likes Received:
    20
    Trophy Points:
    38
    Location:
    Go on, have a guess
    A few possibilities:

    1. Have you converted Default Addresses to use :fail: instead of :blackhole: or /dev/null?

    2. Are you 100% sure that you've put it into the Exim Configuration Editor correctly, with the correct number of line breaks inbetween everything.

    3. Sometimes it can be ineffective depending on the nature of the dictionary attack. That is, if the attack is done on separate SMTP connections, rather all on a single one. In those cases Exim cannot keep track of them.
     
  13. verdon

    verdon Well-Known Member

    Joined:
    Nov 1, 2003
    Messages:
    836
    Likes Received:
    2
    Trophy Points:
    18
    Location:
    Northern Ontario, Canada
    cPanel Access Level:
    Root Administrator
    Yes

    This is what I have...
    Code:
    #!!# ACL that is used after the RCPT command
    check_recipient:
      # Exim 3 had no checking on -bs messages, so for compatibility
      # we accept if the source is local SMTP (i.e. not over TCP/IP).
      # We do this by testing for an empty sending host field.
      accept  hosts = :
    
    # begin new ACLs from http://www.webumake.com/free/eximdeny.htm
    
    drop hosts = /etc/exim_deny
      message = Connection denied after dictionary attack
      log_message = Connection denied from $sender_host_address after dictionary attack 
    
     drop message = Appears to be a dictionary attack
      log_message = Dictionary attack  (after $rcpt_fail_count failures)
      condition = ${if > {${eval:$rcpt_fail_count}}{3}{yes}{no}}
      condition = ${run{/etc/exim_deny.pl  $sender_host_address }{yes}{no}}
      !verify = recipient
     
     # end new ACLs from http://www.webumake.com/free/eximdeny.htm
    
    
      # Accept bounces to lists even if callbacks or other checks would fail
      warn     message      = X-WhitelistedRCPT-nohdrfromcallback: Yes
               condition    = \
               ${if and {{match{$local_part}{(.*)-bounces\+.*}} \
                         {exists {/usr/local/cpanel/3rdparty/mailman/lists/${lc:$1}/config.pck}}} \
                    {yes}{no}}
    
    ... a bunch more original stuff after this ...
    Here's a recent attack...

    Code:
    2004-11-30 15:09:22 H=(host51-151.pool8291.interbusiness.it) [82.91.151.51] F=<mlmkfhb@yahoo.com> rejected RCPT <amazing@domain.com>: No Such User Here
    2004-11-30 15:09:22 H=(host51-151.pool8291.interbusiness.it) [82.91.151.51] F=<mlmkfhb@yahoo.com> rejected RCPT <amc@domain.com>: No Such User Here
    2004-11-30 15:09:23 H=(host51-151.pool8291.interbusiness.it) [82.91.151.51] F=<mlmkfhb@yahoo.com> rejected RCPT <andrewt@domain.com>: No Such User Here
    2004-11-30 15:09:23 H=(host51-151.pool8291.interbusiness.it) [82.91.151.51] F=<mlmkfhb@yahoo.com> rejected RCPT <andy@domain.com>: No Such User Here
    2004-11-30 15:09:24 H=(host51-151.pool8291.interbusiness.it) [82.91.151.51] F=<mlmkfhb@yahoo.com> rejected RCPT <anne@domain.com>: No Such User Here
    2004-11-30 15:09:24 H=(host51-151.pool8291.interbusiness.it) [82.91.151.51] F=<mlmkfhb@yahoo.com> rejected RCPT <anneb@domain.com>: No Such User Here
    2004-11-30 15:09:25 H=(host51-151.pool8291.interbusiness.it) [82.91.151.51] F=<vhwtxfjpsg@yahoo.com> rejected RCPT <annep@domain.com>: No Such User Here
    2004-11-30 15:09:26 H=(host51-151.pool8291.interbusiness.it) [82.91.151.51] F=<vhwtxfjpsg@yahoo.com> rejected RCPT <annie@domain.com>: No Such User Here
    2004-11-30 15:09:26 H=(host51-151.pool8291.interbusiness.it) [82.91.151.51] F=<vhwtxfjpsg@yahoo.com> rejected RCPT <anta@domain.com>: No Such User Here
    2004-11-30 15:09:27 H=(host51-151.pool8291.interbusiness.it) [82.91.151.51] F=<vhwtxfjpsg@yahoo.com> rejected RCPT <anthony@domain.com>: No Such User Here
    2004-11-30 15:09:27 H=(host51-151.pool8291.interbusiness.it) [82.91.151.51] F=<vhwtxfjpsg@yahoo.com> rejected RCPT <beaumont@domain.com>: No Such User Here
    2004-11-30 15:09:28 H=(host51-151.pool8291.interbusiness.it) [82.91.151.51] F=<vhwtxfjpsg@yahoo.com> rejected RCPT <bellj@domain.com>: No Such User Here
    2004-11-30 15:09:28 H=(host51-151.pool8291.interbusiness.it) [82.91.151.51] F=<vhwtxfjpsg@yahoo.com> rejected RCPT <benjamin@domain.com>: No Such User Here
    2004-11-30 15:09:29 H=(host51-151.pool8291.interbusiness.it) [82.91.151.51] F=<vhwtxfjpsg@yahoo.com> rejected RCPT <bird@domain.com>: No Such User Here
    2004-11-30 15:09:30 H=(host51-151.pool8291.interbusiness.it) [82.91.151.51] F=<vhwtxfjpsg@yahoo.com> rejected RCPT <blair@domain.com>: No Such User Here
    2004-11-30 15:09:30 H=(host51-151.pool8291.interbusiness.it) [82.91.151.51] F=<vhwtxfjpsg@yahoo.com> rejected RCPT <blake@domain.com>: No Such User Here
    2004-11-30 15:09:32 H=(host51-151.pool8291.interbusiness.it) [82.91.151.51] F=<vbukmtqcpzc@yahoo.com> rejected RCPT <blue@domain.com>: No Such User Here
    2004-11-30 15:09:33 H=(host51-151.pool8291.interbusiness.it) [82.91.151.51] F=<vbukmtqcpzc@yahoo.com> rejected RCPT <brad@domain.com>: No Such User Here
    2004-11-30 15:09:34 H=(host51-151.pool8291.interbusiness.it) [82.91.151.51] F=<vbukmtqcpzc@yahoo.com> rejected RCPT <brent@domain.com>: No Such User Here
    2004-11-30 15:09:34 H=(host51-151.pool8291.interbusiness.it) [82.91.151.51] F=<vbukmtqcpzc@yahoo.com> rejected RCPT <bryan@domain.com>: No Such User Here
    2004-11-30 15:09:35 H=(host51-151.pool8291.interbusiness.it) [82.91.151.51] F=<vbukmtqcpzc@yahoo.com> rejected RCPT <burns@domain.com>: No Such User Here
    2004-11-30 15:09:35 H=(host51-151.pool8291.interbusiness.it) [82.91.151.51] F=<vbukmtqcpzc@yahoo.com> rejected RCPT <business@domain.com>: No Such User Here
    2004-11-30 15:09:36 H=(host51-151.pool8291.interbusiness.it) [82.91.151.51] F=<vbukmtqcpzc@yahoo.com> rejected RCPT <cat@domain.com>: No Such User Here
    
    And here are my files in /etc
    Code:
    -rw-rw----    1 mailnull mail            0 Nov 12 15:35 exim_deny
    -rwxr-xr-x    1 mailnull mail         2560 Aug 31 17:00 exim_deny.pl*
    Note: I added group perms just in case

    Here is my basic environment:
    WHM 9.9.8 cPanel 9.9.8-R116**
    CentOS 3.3 i686 - WHM X v3.1.0
    exim (exim-4.43-40_cpanel_smtpctl_av_rewrite_mm2_mmmtrap_exiscan_md5pass)

    Thanks for the ideas,
    verdon
     
  14. ispro

    ispro Well-Known Member

    Joined:
    Apr 8, 2004
    Messages:
    628
    Likes Received:
    1
    Trophy Points:
    18
    We have just faced with the same problem... By examining logs and trying to understand algo. we have found our problem:

    ls -l /tmp/exim_deny.lock

    I bet that it owned by root ;)

    Just do
    rm -f /tmp/exim_deny.lock

    And it should get fixed.
    At least all our problems were solved at all servers.
     
  15. ispro

    ispro Well-Known Member

    Joined:
    Apr 8, 2004
    Messages:
    628
    Likes Received:
    1
    Trophy Points:
    18
    Dear chirpy,

    We have wondering is it possible easily add IPs from exim_deny to APF /etc/apf/deny_hosts.rules ?

    While we may just symlink to this file it is not good as we have BFD installed and it is writing to the same file. So, when next hourly cron will reset IPs it will remove BFDs ones.

    Perhaps it is ok, but we would like to hear your opinion as well as others guys there.
     
  16. picoyak

    picoyak Well-Known Member

    Joined:
    Jun 10, 2004
    Messages:
    72
    Likes Received:
    0
    Trophy Points:
    6
    FWIW, in my opinion the two issues are dissimilar.

    BFD has a sole purpose of denying from IPs that are specifically trying to gain access to your server via brute force. Chirpy's Dictionary Rules are designed to cut short dictionary attacks.

    Now, if you look at where these dictionary attacks are coming from, you'll see that the same sender will use many mulitple subnets, and very rarely the same one twice, and LOTS of them. In my experience, then dictionary rules are best used on a temporary basis.

    If you were to insert all those IPs into APF, you'd have a pretty long list that creates some decent overhead unnecessarily. Hell, I empty my exim_deny file hourly.

    For me, it boils down to the fact that dictionary spammers are random, and a nuisance while brute force attacks pose a longer term threat to my security.

    Personally I'd keep these systems separate.
     
  17. ispro

    ispro Well-Known Member

    Joined:
    Apr 8, 2004
    Messages:
    628
    Likes Received:
    1
    Trophy Points:
    18
    I do understand that it is better to permanently leave BFD denied IP as itself.

    However why I'm asking for it? Even having exim_deny list it allows scammer to connect, send helo/ehlo, from and he is being dropped at the step 4, when trying to rcpt.

    We got an incredible load and connections overusage due this. That's why we would like to block these IPs at the system's level.

    It would be great to have them blocked for one hour, and then flushed, while BFD IPs to stay there for at least one week/month.

    Is it possible? Has anyone got a solution?
     
  18. chirpy

    chirpy Well-Known Member

    Joined:
    Jun 15, 2002
    Messages:
    13,475
    Likes Received:
    20
    Trophy Points:
    38
    Location:
    Go on, have a guess
    Actually,

    I do have such a script. You can schedule it to run via CRON every couple of mnutes if you wish:

    Code:
    #!/usr/bin/perl
    use Fcntl qw(:DEFAULT :flock);
    
    open (IN, "</etc/exim_deny") or die "apf_deny: $!";
    flock (IN, LOCK_SH) or die "apf_deny: $!";
    @data = <IN>;
    close (IN);
    chomp @IN;
    
    foreach $ip (@data) {
    	$ip =~ s/\r|\n//g;
    	if ($ip eq "") {next}
    #	system("/sbin/iptables -I INPUT -p tcp -s $ip --destination-port 25 -j DROP");
    	system("apf -d $ip");
    }
    
    You'll note that you can either have it inject iptables directly, or use apf instead. An example crontab entry under root might be:

    */2 * * * * perl /pathto/script.pl > /dev/null 2>&1
     
  19. ispro

    ispro Well-Known Member

    Joined:
    Apr 8, 2004
    Messages:
    628
    Likes Received:
    1
    Trophy Points:
    18
    Thank you for the script.

    However I made almost the same one when figured that it will not work.

    -d switch add IP, but it not get removed when exim_deny being flushed.

    This way we will end up with an incredible huge apf deny list.

    I'm thinking on some sort of script that will copy and paste the exim_deny into apf deny list with a pattern matching to easily update it with perl replace and then apf restart.
    This way we will leave BFD IPs and use our dinamic exim_deny

    Perhaps you had it already? :)
     
  20. chirpy

    chirpy Well-Known Member

    Joined:
    Jun 15, 2002
    Messages:
    13,475
    Likes Received:
    20
    Trophy Points:
    38
    Location:
    Go on, have a guess
    The script was written as a quick example of how you could do it, you're right it won't clear anything down. As an alternative, you could always use the iptables method and flush and start APF once a day to clear out those blocked domains - this would then still keep those IP addresses in your allow and deny files in the firewall.
     
Loading...

Share This Page