Read file, grab ip with fail2ban

Solved with iptables.
Many thanks...

Hello,

Objective:
What I would like to accomplish is :

  • To read file1 line by line and search each word in file2.
  • To grab corresponding ip addresses found in file2
  • To send related ip addresses to fail2ban (not iptables)

By this way, when I want to block any username, I will enter only his username into filtered.txt file and then his connection will be terminated when he tries to login to the system even when he changes his ip address.

Detail:
I have a txt file under /var/text folder and it consists of usernames:

filtered.txt

Code:

mark
angela
dimitriou
anna
michelle

What I need to do is:

1) Search each username (mark, angela, dimitriou, anna, michelle, etc..) in syslog file (it is under /var/log) and print it to a file (iplist)

I already created this file by below command:

Code:

grep -wf /var/test/filtered.txt /var/log/syslog > /var/log/iplist

2) A new fail2ban configuration file will be set. It will read iplist and

I created below conf file:

iplist.conf under /etc/fail2ban/filter.d/

Code:

[Definition]
failregex = mypc_regex_code Network: user .* login attempt from <HOST>
ignoreregex =

mypc_regex_code: It's as shown in syslog file.

I also added below lines into jail.conf in after [ssh] under /etc/fail2ban/

Code:

[iplist]
enabled = true
port = 34567,34789,35890
filter = iplist
logpath = /var/log/iplist
maxretry = 1
bantime = 10800

I stopped and started fail2ban but related ip addresses were not shown in fail2ban.log file. (I am sure that other fail2ban rules are working)

Can anybody give an advice about how to accomplish this objective?
May I add related usernames into deny.hosts file to block the connection?

Thanks in advance
Boris

Do you want to repel users or ip- addresses? What if any of those users logs in from a different node?

Hello,
I solved this issue. I wanted to block a list of users. At first, the script kicks their original ip. When they changed their ip, cron will detect this and ban them once again.

I defined and limited each user's login date and hour and minute.
database.txt (##year_month_day_hour_minute)

sophie.bextor ##201403011017
dido ##201404251049
ray.charles ##201404290159
freddie.mercury ##201404012200
madonna ##201405050900

If he is not allowed to login anymore, the script sends his username to filtered.txt file and then mentioned above scenario starts.

filter_accts.pl

#!/usr/bin/perl

use Time::Local;
open outf, "> filtered.txt";

while (<>) {
    @f = split /#/, $_;
    $yr = substr($f[2], 0, 4);
    $mo = substr($f[2], 4, 2);
    $dy = substr($f[2], 6, 2);
    $hr = substr($f[2], 8, 2);
    $mi = substr($f[2], 10, 2);
    print outf if time > timelocal(0, $mi, $hr, $dy, $mo-1, $yr-1900);
}

When you run below code:

./filter_accts.pl database.txt

Output will be
filtered.txt:

sophie.bextor ##201403011017

to remove ## signs, i created filtered2.txt:

sophie.bextor

Looks up sophie.bextor's ip in syslog file:

grep -wf filtered2.txt /var/log/syslog > new.txt

to remove unneccessary lines:

sed -n '/login/p' /var/test/new.txt > /var/test/login

Then to be able to extract list of ip addresses:

awk '/^[0-9.]+[.][0-9]+$/{if(!a[$0]++)print $0}' RS="[ :/\n]" login > login-ip.txt

The last step is add prefix ( iptables -A INPUT -s ) to the beginning of each line and add -j DROP to the end of each line with below script.

replace.sh

#!/bin/bash
prefix="iptables -A INPUT -s "
file="login-ip.txt"
while read -r line
do
 echo "${prefix}$line"
done <$file > fail2ban_ip
#mv fail2ban_ip $file
sed -e 's/$/ -j DROP/' -i fail2ban_ip

when you open fail2ban_ip file, it will show something like this:

iptables -A INPUT -s 21.166.112.177 -j DROP
iptables -A INPUT -s 21.177.112.142 -j DROP
iptables -A INPUT -s 22.156.112.155 -j DROP
iptables -A INPUT -s 23.146.112.172 -j DROP

then, chmod 755 & ./fail2ban_ip under terminal

I will get those codes together into a script and set cronjob now .

As the problem has been sorted out by means of your valuable support, I would like to thank you all.

Regards
Boris

If I got you right, your setup allows one access to users having changed their IP address. I'm not sure this is what you want. Why not block access for the entire range of IP addresses and explicitely allow single users' nodes? Or, why not block/allow them in /etc/passwd ?

If you want to block a list of users, what are they to be prevented from doing?

  • Login - change their shell to be /bin/false
  • FTP . - Add them to /etc/ftpusers
  • SFTP - Add them to the file referred to in sshd.conf
  • Everything - Change their encrypted password manually to a simple short string, so the encryption at login will never match it.

Does that help?

Robin

They cant get login to system. I am not familiar with ftp or sftp but you can run below script, add a your username into database.txt file and check what he can not do.

test.sh under /var/bin

#!/bin/bash
cd /var/test
./release_ip
./filter_accts.pl database.txt
awk '{print $1}' filtered.txt > filtered2.txt
grep -wf filtered2.txt /var/log/syslog > new.txt
sed -n '/login/p' /var/test/new.txt > /var/test/login
awk '/^[0-9.]+[.][0-9]+$/{if(!a[$0]++)print $0}' RS="[ :/\n]" login > login-ip.txt
./replace.sh
cp -p fail2ban_ip /var/test/release_ip2
sed 's/-A/-D/' release_ip2 > release_ip
chmod 755 fail2ban_ip
chmod 755 release_ip
./fail2ban_ip
iptables-save

PS: You can find filter_accts.pl file in above posts.

System time is 17:09, today is 20140313 and defined username in database.txt will be banned one hour later.
database.txt under /var/test

a_username_to_be_banned ##201403131809

under /etc/crontab

*/10 * * * * root /var/bin/test.sh

Those are what i edited by other board members' help. Not my own codes.

Regards
Boris