Visualizing failed SSH login attempts

Shortly after Christmas I opened the ssh port 22 at home to access my network from the Internet, while commuting or traveling. To secure the open port I installed fail2ban on the machine I redirected the port to. As soon as the jail was enabled in the file /etc/fail2ban/jail.conf and fail2ban was restarted it blocks the source IP for 5 minutes after 6 failed login attempts by default. If I remember right, it took only a few minutes and the first IP was blocked. I decided, that 5 minutes is too short and extended the blocking to one day, as well as the number of allowed login attempts, which I reduced to 3.

Since I use ssh-keys, I also decided to deny root login at all and password logins via pam by modifying /etc/ssh/sshd_config:

PermitRootLogin no
PasswordAuthentication no
UsePAM no

However, this caused some trouble with fail2ban. The log entries of failed login attempts in /var/log/auth.log now looked differently. And soon there was someone (more likely a bot?) trying to login 1960 times within 1:15 hours from the IP address 61.183.1.8. Therefore, I added the following lines to failregex in /etc/fail2ban/filter.d/sshd.conf

^%(__prefix_line)sConnection closed by \[preauth\]\s*$
^%(__prefix_line)sReceived disconnect from : 11: Bye Bye \[preauth\]\s*$

Now fail2ban blocks the login attempts again.

Before I turned off pam authentication, I searched the Internet for how to log passwords and came across this article on a Symantec site using so called honeypots to attract hackers with a weak system. This inspired me to evaluate at least the data I can extract from my auth.log files. I wrote a perl script, which creates a SQLite database of the failed logins and an R script using ggplot2 to display the results, which is even possible without using fail2ban. To find out the subnet and country of the source IP I found a function for R here, which I used for whois lookups. There are other possibilities to visualize the data, too, for example on the fail2ban webpage itself.

There were 4628 failed logins at total from 1005 IP addresses (457 subnets) with 296 usernames. And here are my results:

Timeseries for the one month my port is open now:

ts

The usernames used. Note that since I deny password logins usernames are only logged when they are before connecting (e.g. ssh admin@<host> for command line ssh). Note the x-axis are scaled logarithmic and only a subset of the total usernames, subnets and countries are shown:

user

The subnets, from which most attacks came:

subnet

The countries:

country

And finally the map (with this worldmap) with the number of attacks color coded (again logarithmic):

map

The strange colorbar is somehow related to cairoDevice. However, fonts are much better with it than with the default png device.

Both scripts I wrote are available on GitHub.

Another related link from Cisco: http://www.cisco.com/web/about/security/intelligence/ssh-security.html.

Advertisements

Setting up a Raspberry Pi with Raspbian

Just recently I bought a new toy: Raspberry Pi B+ and a 16GB SD card. The card is quiet large, however, keeping in mind that SD cards have limited write cycles I decided to buy a large one. I plan to set up a web-server on it running nginx under Raspbian in the DMZ (between my own router and the one of my provider) on it. The server should be accessible from the internet for me. Nevertheless, that will become another story. Here I will describe, how I set up the Raspberry Pi. As operating system on my PC I use a mix of Debian testing and unstable. The PC has a (micro-) SD card reader.
Once you have the hardware, you can download the image at http://www.raspberrypi.org/downloads/. Enter the SD card in the reader and find out which disk is your SD card, in my case it is /dev/sdg. As root (or sudo) write the image to the card by executing

> dd bs=4M if=Downloads/2014-09-09-wheezy-raspbian.img of=/dev/sdg

In other blogs I found that you might need to set bs=1M, however, for me the previous worked. Make sure the buffer is written to the card by syncing.

> sync

Increasing the partition size as described elsewhere to the full size of the card is not necessary, since that can be done once you start up Raspbian.
That’s it already, now you can power up the Raspberry Pi. I connected the Raspberry Pi to my router to start it headless (without keyboard, mouse and monitor). If you have local network with DHCP, and the server accepts “send host-name” from the client (in /etc/dhcp/dhclient.conf), you can log in via SSH immediately. Otherwise, you have to find out the IP address, p.e. with nmap, scanning a subnet for the open port 22 (SSH), including some details:

> nmap –sV -p 22 192.168.122.0/24
Starting Nmap 6.47 ( http://nmap.org ) at date time
[...]
Nmap scan report for raspberrypi (192.168.122.173)
Host is up (-0.076s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 6.0p1 Debian 4+deb7u2 (protocol 2.0)
MAC Address: B8:27:EB:00:00:00 (Raspberry Pi Foundation)
[...]

This gives you the IP address of your Raspberry Pi, and maybe some unexpected results for other devices in your network. Note: the MAC address is only displayed if you are on the same subnet and in my case only if you execute nmap with root privileges. If the MAC address is returned, the Raspberry Pi can be identified by the first 24 bits (Organizationally Unique Identifier: B8:27:EB). Now you can login, but don’t forget to replace the IP address with yours.

> ssh pi@raspberrypi

or

> ssh pi@192.168.122.173

The default username is “pi” password is “raspberry”, which you should as a matter of course change immediately. Also increasing the partition size to fill up the whole disk can be done now. Both is possible with the command:

> sudo raspi-config

I will continue running the Raspberry Pi headless, therefore I uninstalled almost al X stuff (p.e. packages starting with “lx”). And since I plan to install a web server with a SQL database I decided to connect an external hard disk for the /tmp and /var directories. However, I didn’t find a way switching to init 1 without loosing my ssh connection, so that there is no process with open file handles on /var 😦 So I only moved /tmp, /var/www and /var/lib/mysql to the external hard disk.