EvilZone
Programming and Scripting => Scripting Languages => : frog June 13, 2014, 08:21:38 AM
-
So I was bored laying in bed watching movies on my Linux box and I decided to check some things while I was relaxing. I saw I had a tcp connection open on port 22 when using 'netstat -apn' so I checked the auth logs and sure enough somebody was actively brute-forcing user 'root' on my ssh server. There were other entries as well, trying silly ass usernames like 'postgres' and 'admin'.
I found this interesting, as I don't know who in the right mind would allow remote root login for their ssh daemon.
I got to thinking about /etc/hosts.deny and I thought wouldn't it be neat to write a script that audits my logs and automatically adds entries to /etc/hosts.deny?
So that's what I did. I made it so the script does not log duplicate hosts from the auth log. Works quickly, all you need is a cron job to run every 30min or something and you're good to go. Try it out, I was surprised how many entries it found.
The only problem I can think of.. What if I accidentally type a bogus username when logging into the system? My script checks for entries with the string 'Invalid user'. I will be locked out the first time that the script runs after that.
Edit: Took out search string 'Invalid user'(line 38) as it was locking me out after trying to log in with wrong username. Now the script only looks for connections made with username 'root'. I never log in as root remotely so this will work for now. My goal is to blacklist all suspicious ssh connections.
#!/bin/bash
##
### ssh-lfd.sh - ssh-l(ogin)-f(ail)-d(eny)
##
#
export DENYHOST="/etc/hosts.deny"
export AUTHLOG="/var/log/auth.log"
export LOGFILE="/var/log/ssh-lfd.log"
export TMPFILE="/tmp/ssh-lfd.tmp"
export HOSTLIST="/tmp/ssh-lfd.hosts"
banner() {
log ""
log " ssh-lfd.sh - l(ogin)-f(ail)-d(eny)"
log " Nobody enables ssh root login, right?"
log ""
}
log() {
echo $1
echo $1 >> $LOGFILE
}
cancel() {
rm -f $TMPFILE $HOSTLIST
}
trap cancel SIGINT
if [ $(whoami) != "root" ]; then
banner
log "[!] Error: login as root and try again."
exit
fi
log "[-] Parsing $AUTHLOG.."
cat $AUTHLOG | grep sshd | grep "Failed password for root" | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' >> $TMPFILE
sort -u $TMPFILE > $HOSTLIST
rm -f $TMPFILE
log "[-] Checking $DENYHOST for previous entries.."
for item in $(cat $HOSTLIST); do
if [ -z $(cat $DENYHOST | grep $item) ]; then
log "[+] Adding $item to $DENYHOST"
echo "sshd:$item" >> $DENYHOST
else
continue
fi
done
log "[-] Deleting files in /tmp.."
rm -f $TMPFILE $HOSTLIST
log "[*] Done. $(date)"
-
I attached the script in case anybody wants to use it.
-
This is cool, I might use it for my own server :)
Though it would probably be a good idea to remove blocked logins after a week or two, otherwise it would accumulate too much maybe?
-
This is cool, I might use it for my own server :)
Though it would probably be a good idea to remove blocked logins after a week or two, otherwise it would accumulate too much maybe?
I can't see having a large /etc/hosts.deny entry list being a bad thing. It's good for the following reasons:
- I never log in as root, and anybody doing so should never run this script
- These hosts will never be able to initiate a socket with my sshd
again(theoretically), and the idea of this makes me happy; however unrealistic
And bad for the following reasons:
- I might want to connect from a host listed in hosts.deny?(I don't see why, unless
I'd have backdoor'd a host that was once attacking me)
- Hosts I don't necessarily know can't connect to my sshd?
-
looks good
maybe you already know of fail2ban, if not check it out and maybe you get some more ideas...
* http://www.fail2ban.org/wiki/index.php/Main_Page
you could also work with iptables if you just login from a certain range
change ssh port
disable root login
-
I can't see having a large /etc/hosts.deny entry list being a bad thing. It's good for the following reasons:
- I never log in as root, and anybody doing so should never run this script
- These hosts will never be able to initiate a socket with my sshd
again(theoretically), and the idea of this makes me happy; however unrealistic
And bad for the following reasons:
- I might want to connect from a host listed in hosts.deny?(I don't see why, unless
I'd have backdoor'd a host that was once attacking me)
- Hosts I don't necessarily know can't connect to my sshd?
IPtables might be more efficient when it comes to system performance , this might be interesting for a server with high traffic , not really relevant for home use.
-
IPtables might be more efficient when it comes to system performance , this might be interesting for a server with high traffic , not really relevant for home use.
Well /etc/hosts.deny uses a tcpwrapper(tcpd,libwrap), which means there is probably more function calls involved(more overhead). The benefit of /etc/hosts.deny is that you can deny a remote host a specific service and still take other types of connections.
Let's talk iptables. You could write rules to file or make it temporary, and I like the idea of that. The only thing iptables can't do is filter traffic based on service name. You could augment iptables with bash to achieve this but why when you have /etc/hosts.deny?
My conclusion is that both iptables and /etc/hosts.deny have their place and their purpose. They are both good for different things.
In my opinion this is completely relevant for a home ssh server. Look at my /etc/hosts.deny:
sshd:113.161.0.114
sshd:116.10.191.166
sshd:116.10.191.168
sshd:116.10.191.170
sshd:116.10.191.172
sshd:116.10.191.174
sshd:116.10.191.177
sshd:116.10.191.178
sshd:116.10.191.182
sshd:116.10.191.187
sshd:116.10.191.190
sshd:116.10.191.197
sshd:116.10.191.198
sshd:116.10.191.200
sshd:116.10.191.203
sshd:116.10.191.209
sshd:116.10.191.210
sshd:116.10.191.214
sshd:116.10.191.215
sshd:116.10.191.216
sshd:116.10.191.219
sshd:116.10.191.221
sshd:116.10.191.222
sshd:116.10.191.223
sshd:116.10.191.231
sshd:116.10.191.232
sshd:116.10.191.233
sshd:116.10.191.238
sshd:116.10.191.239
sshd:117.79.91.220
sshd:122.226.95.219
sshd:162.255.182.201
sshd:168.63.205.47
sshd:168.63.211.27
sshd:188.113.22.70
sshd:198.211.28.154
sshd:216.127.160.146
sshd:218.189.132.130
sshd:222.186.50.61
sshd:222.186.51.150
sshd:222.186.58.10
sshd:222.186.58.70
sshd:222.187.220.246
sshd:60.169.4.157
sshd:60.173.11.22
sshd:60.217.32.85
sshd:61.147.103.148
sshd:61.174.50.177
sshd:61.174.51.205
sshd:61.174.51.215
sshd:61.174.51.217
sshd:61.174.51.220
sshd:61.174.51.232
sshd:61.174.51.235
sshd:61.19.247.185
sshd:81.171.86.201
sshd:81.7.101.142
sshd:83.229.14.130
sshd:91.208.16.232
sshd:116.10.191.183
sshd:116.10.191.235
sshd:116.10.191.204
sshd:219.138.135.62
sshd:116.10.191.234
All of these came from brute-force attacks in the last 5 days. I just reinstalled the OS on my linux box and like I said, just 5 days in.
My benefit is that I've reduced network traffic(through blocking failed login attempts) and at the same time I've saved cpu time that sshd would have wasted handling all those connections.