LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Security (https://www.linuxquestions.org/questions/linux-security-4/)
-   -   dynamic iptables based on ftp logs (https://www.linuxquestions.org/questions/linux-security-4/dynamic-iptables-based-on-ftp-logs-318150/)

epoo 04-28-2005 02:07 PM

dynamic iptables based on ftp logs
 
i was wondering if it's possible to add iptables rules based on unsuccessful logins to the ftp server.

for example, i'm running proftp, and the account to access my ftp site is NOT 'ftp'. so i have a lot of sessions opened and closed, but no successful logins. there's only a few people that i want to have access to my site, but their ip doesnt stay the same. so i want to be able to look at the logs, and when it sees a connection opened, then closed with no success, it adds the ip as an iptable rule.

thanks in advance :)

Matir 04-28-2005 02:22 PM

Most likely, once they have been denied, users will go away. Do you see a pattern of the same IP(s) banging on your door? (5+ unsuccessful logins from same IP)

epoo 04-28-2005 03:39 PM

there's been a few multiple attempts from the same ip, and there's been attempts from different ip's that were just seconds or minutes apart (which is not common since i see about 1 attempt every 3 or 4 days.

but besides that, ive actually been wondrering about how to do this for a while. is there another forum i should try it, maybe one more geared towards scripting ?

Matir 04-28-2005 05:00 PM

I don't know the log format of the proftp logs, but I imagine writing such a script would be trivial. If you post some of the log output (so I can see the format), I'd be glad to work something up for you.

epoo 04-28-2005 06:40 PM

Apr 27 13:16:13 server proftpd[3178] localhost (220.66.108.21[220.66.108.21]): FTP session opened.
Apr 27 13:16:13 server proftpd[3178] localhost (220.66.108.21[220.66.108.21]): FTP session closed.
Apr 27 13:18:34 server proftpd[3266] localhost (220.66.108.21[220.66.108.21]): FTP session opened.
Apr 27 13:18:34 server proftpd[3266] localhost (220.66.108.21[220.66.108.21]): FTP session closed.
Apr 27 14:16:23 server proftpd[3923] localhost (211.107.232.1[211.107.232.1]): FTP session opened.
Apr 27 14:16:23 server proftpd[3923] localhost (211.107.232.1[211.107.232.1]): FTP session closed.
Apr 28 18:34:19 server proftpd[25010] localhost (192.168.0.101[192.168.0.101]): USER ftp (Login failed): Incorrect password.
Apr 28 18:34:22 server proftpd[25010] localhost (192.168.0.101[192.168.0.101]): USER ftp (Login failed): Incorrect password.
Apr 28 18:34:25 server proftpd[25010] localhost (192.168.0.101[192.168.0.101]): USER ftp (Login failed): Incorrect password.
Apr 28 18:34:25 server proftpd[25010] localhost (192.168.0.101[192.168.0.101]): Maximum login attempts (3) exceeded
Apr 28 18:34:25 server proftpd[25010] localhost (192.168.0.101[192.168.0.101]): FTP session closed.
Apr 28 18:35:07 server proftpd[25021] localhost (192.168.0.101[192.168.0.101]): FTP session opened.
Apr 28 18:35:07 server proftpd[25021] localhost (192.168.0.101[192.168.0.101]): USER ftp (Login failed): Incorrect password.
Apr 28 18:35:09 server proftpd[25021] localhost (192.168.0.101[192.168.0.101]): FTP session closed.

there's a few things id like to do. i'd like to drop packets coming from the ip when it sees a session opened and closed, even without a login attempt, as well as sessions where they try entering a username that's incorrect.
anytime there's a session opened and closed right away, id like that ip added to iptables just so they don't see that there's a server running and decide to come back later for a crack at it.
thanks again :)

Matir 04-28-2005 09:15 PM

How do you want to compare those who are bad logins (session opened/closed) versus those who are valid logins?

Can you post a sample of the good logins so I can compare it?

epoo 04-29-2005 12:19 AM

for the ones that don't try a name, i was thinking it could search for the "session opened", then look ahead and if the next line says "session closed" then that's an ip that would be added to iptables.
in the case that they try a user name that's invalid, it could have the script look at the word after USER, and if it isnt a valid username, then ban that one too, or even if it's "ftp", since that's the default ftp username.

Apr 23 17:14:52 server proftpd[32078] localhost (192.168.0.101[192.168.0.101]): FTP session opened.
Apr 23 17:14:52 server proftpd[32078] localhost (192.168.0.101[192.168.0.101]): USER ftpuser: Login successful.
Apr 23 17:15:12 server proftpd[32078] localhost (192.168.0.101[192.168.0.101]): FTP session closed.

that's what it looks like if the user logs in successfully and logs out. if a user logs in and transfers a file and then logs out, it still looks the same.

Matir 04-29-2005 09:02 AM

I'll try to whip up a script to parse that stuff later today.

bulliver 04-29-2005 06:22 PM

Here is a perl script I wrote that parses my apache logs and bans ips that are screwing around (edited for brevity). I run it as an hourly cron task. It requires you create a user-defined chain which I call 'banned' with default policy set to drop. Perhaps you can edit it to suit your purposes:

Code:

#!/usr/bin/perl -w

open ALOG, "/var/log/apache2/error_log";

chomp(@alines = <ALOG>);
foreach $aline (@alines) {
    if ($aline =~ m/URI too long/) {
        @aip = split / /, $aline;
        my $aip = "$aip[7]\n";
        $aip =~ s/[\]]//;
        push(@arbl, $aip);
        }
    }

close ALOG;

push(@arbl, @erbl);
@arbl = sort @arbl;

# just like unix uniq
%seen = ();
foreach $item (@arbl) {
    push(@arbls, $item) unless $seen{$item}++;
    }

# grab already banned ip addresses.
foreach $rule (`iptables -L banned -n`) {
    chomp($rule);
    if ($rule =~ m/[0-255]\.[0-255]\.[0-255]\.[0-255]/) {
        $rule =~ s/\s+/ /g;
        @_ = split / /, $rule;
        push (@banned, $_[3]);
        }
    }

$i = 0;
$already_banned = 0;

foreach $bl (@arbls) {
    chomp($bl);
    foreach $ip (@banned) {
        if ($bl eq $ip) {
            $already_banned = 1;
            delete $arbls[$i];
            }
        }
    if (!$already_banned) {
        print "banning $bl\n";
        system "iptables -A banned -s $bl -j DROP";
        }
    else {
        $already_banned  = 0;
        print "$bl\t already banned\n";
        }
    $i++;
    }


epoo 04-30-2005 12:10 AM

thanks for the script... looks complicated, but i'll see if i can make it work.

bulliver 04-30-2005 12:22 AM

Hey, it's not too complicated...it's just that perl makes everything look like chicken scratch....

If you need clarification on what something is doing just ask ;)


All times are GMT -5. The time now is 07:33 AM.