Fail2ban for Owncloud: Brute force prevention and alerting

In this guide, I will show you how to configure your ownCloud server so that brute force attacks are one less thing to worry about. Not only will fail2ban block someone from having X number of failed login attempts to your ownCloud server, it will also notify you via pushbullet that an attempt has been blocked.

So lets begin!

Step 1: Install fail2ban and ownCloud filters

Following this excellent guide here (src: https://github.com/AykutCevik/owncloud-fail2ban) you can have fail2ban and ownCloud filters configured in no time. Simply run the command:

.. and follow the instructions. Make sure you enter the logfile path correctly; i.e. /var/log/owncloud.log, or /var/www/owncloud/owncloud.log, etc.

Once configured, this will add two main files of interest:

The first, ‘/filter.d/’, is the regex that fail2ban will use to parse your specified ownCloud log for failed login attempts.

The second, ‘/jail.d/’, tells fail2ban to actively use that filter, what port to monitor on, and the logpath (edit the logpath here if you entered it wrong during setup).

The logfile, /var/log/owncloud.log (for example) must log using a few specifics. To set these specifics, crack open your config.php (i.e. /var/www/owncloud/config/config.php) and set the following directives:

Make sure that you have the logtimezone set to your local timezone, otherwise fail2ban wont work.

.. and thats fail2ban setup. So how does it work?

Fail2ban will create a new iptables chain called ‘f2b-owncloud’, which is visible if you run ‘iptables -nL –lin’ as below:

Basically, iptables will detect if traffic has come into the server on the port specified earlier (https), and will direct all traffic to the new chain ‘f2b-owncloud’. When fail2ban detects an IP has had 5 failed logins, it will then add a iptables REJECT rule for that specific IP, at the top of the f2b-owncloud chain. This means that the IP will be rejected, but all other traffic will pass.

Obviously this means that HTTPS traffic will bypass all other iptables rules in your INPUT chain as it is being diverted to the f2b-owncloud chain, so ensure you add your rules to that chain also, i.e.:

Using ipset, I only allow GB IP addresses access to HTTPS, so I’ve had to add this rule to the f2b-owncloud chain, along with a REJECT all. Now when fail2ban bans an IP, it’ll get added to the top. The flow will be then be:

  1. Is the source IP banned? If yes, then reject, if not ..
  2. Is the source IP from the GB IP range? If no, then reject, if yes, then allow.
  3. Reject everything else.

Step 2: Testing

Next we need to test that fail2ban will actually block the malicious IP. Simply attempt some invalid logins, and then run the command ‘fail2ban-client status owncloud’:

Here you can see you have now been banned from accessing the ownCloud server via HTTPS. You can confirm this via iptables -nl –lin:

You should now be unable to access your owncloud server. To unban yourself, simply run:

Where 134.. is your IP. If your not being being, double check the regex is valid and picking up your logs correctly using the command:

This should show an output similar to the below:

If you have issues, double check your /var/log/fail2ban.log. If you see an error like the below, then double check the config.php file for your owncloud server:

I saw this issue when I had a specific ‘logdateformat’ entry in config.php. Simply removing this entry solved my problem.

Step 3: Notifications

Now that fail2ban is actively blocking brute force attackers, we want to be notified about it. Doing this is rather simple, thanks to this excellent guide here (src: http://blog.meinside.pe.kr/How-to-get-Pushbullet-notification-on-Fail2ban-ban-actions/).

Firstly, install Go:

Next, setup your users .bashrc profile to contain the necessary paths by adding the following lines to ~/.bashrc:

Next, download the pushbullet-fail2ban.go code:

Next, edit that file and enter your pushbullet API key (to find out your key, visit: https://www.pushbullet.com/account 

Find the line ‘MyPushbulletToken = ‘ ‘ and add your API key within the quotes (no spaces at the start or end).

Once done, build the notification script:

This will leave you with a file called ‘pushbullet-fail2ban’. Move this file to /etc/fail2ban/ using the command:

Next, test that the notification works using the command:

You should get an alert on your mobile phone similar to:

38786f12-83c7-11e5-95b4-f431a84c53d9

Next, we need to modify fail2ban to use this new pushbullet-fail2ban method. To do this, simply copy the method fail2ban uses to ban IP’s using iptables, and edit the copied method:

Within this file, find the line ‘actionban =’ and replace it with the following:

 

Next, lets tell fail2ban to use this new method and not the existing ‘iptables-multiport.conf’. Edit the file /etc/fail2ban/jail.conf:

.. and amend the line ‘banaction’ (line 157) to look like:

And thats it. Simply restart fail2ban, update your iptables rules (if you have modified them as per my step 1) and your fail2ban protected owncloud is now ready:

Next time a naughty hacker tries to brute force your box, you’ll get a push notification similar to:

Screenshot 2016-01-13 11.23.49

Notes

My iptables rules for fail2ban/owncloud look like the below:

These rules send all HTTPS traffic to the f2b-owncloud chain, and then the HTTPS traffic is parsed through that traffic. I have an ipset rule here, and then a reject to end the chain. Hope this helps!

Fail2ban for Opsview Monitor

This guide will show you a very quick and dirty way to use Fail2ban to prevent brute-force attacks on your Opsview Monitor 5.0 server. This should work the same for Opsview 4.x servers, but I havent tested it.

Fail2ban, for those who arent familiar, is “an intrusion prevention framework written in the Python programming language. It works by reading SSH, ProFTP, Apache logs etc.. and uses iptables profiles to block brute-force attempts.” (src: https://help.ubuntu.com/community/Fail2ban).

Firstly, install fail2ban. In my example I am using Ubuntu 14.04, so simply:

Next, go to the fail2ban directory and create the opsview ‘filter’:

Within here, copy and paste the following:

This is a simple regex that filters for the source IP of the ‘hacker’, using the standard syslog message left in opsview- web.log. Example message below:

Next, lets tell fail2ban to actually use this rule. Create a new file called ‘/etc/fail2ban/jail.local’ and add the following:

Obviously, if you arent using https then change this to ‘http’. Next, modify /etc/fail2ban/jail.conf and modify the line

to

Finally,  Simply start fail2ban using the command:

You can view the ‘jail’ by running the script here: https://gist.github.com/kamermans/1076290 . Simply clone this file, chmod +x and then run, as below:

This will give an output similar to:

Now, go and try and brute force 10-15 times and see what happens when you run the command above again:

Here you can see that 10 failed attempts have been made, and an IP address has now been banned from trying to login. To prove this, run the iptables command below:

To unblock an IP address, simply run the command:

Sorted. Now, go forth and fail2ban!

Multiple SSL-enabled websites with Apache

multi-ssl-apache2

This blog will cover how to have 2 SSL (HTTPS) websites configured and running smoothly on the same Apache2 web server (which aint easy!).

First of all, ensure you have your two websites created already (/var/www/site1 and /var/www/site2, for example). Also, ensure you have your DNS setup for those two websites to point to the same server, i.e.

site1 IN A 3.4.5.6

site2 IN A 3.4.5.6

(Where 3.4.5.6 is the external IP of my router, and I have port forwarding sending all TCP443 traffic to the internal IP of 192.168.0.2 (for example)).

Firstly, once Apache2 is installed, navigate to /etc/apache2/sites-available and create two files, ‘site1.conf’ and ‘site2.conf’ as below:

These are the two config files for your websites. Within each of these files, you will need to tell Apache2 where your actual website is (i.e. /var/www/site1 and /var/www/site2). So lets crack open site1 and populate it:

This is a very simple apache config that tells Apache we have created a virtualhost, listening on any IP that box has, for traffic on port 443. We tell Apache what our website domain is (site1.ehertz.uk) and where to go when that domain is hit (/var/www/site1). Do the same for site2, but change the names from ‘site1..’ to ‘site2..’ and your done.

Next, we need to generate the SSL certificates.

SSL

I use StartSSL.com for my certificates, as it is completely free and is very simple to use. I am not going to go through the ins and outs of signing up (as i cant remember myself!) however there is a great guide that covers it here (Start reading from: “Verify Your Domain Name with StartSSL”) and stop once your website is verified.

Now, this is VERY IMPORTANT. You cannot generate your certificates with startssl.com until you have first generated your keys on the server on which you will be hosting your website(s).

So, lets generate the keys!

Firstly, navigate to /etc/apache2/ssl and create two directories – /site1.ehertz.uk and /site2.ehertz.uk:

Next, navigate into the first directory:

Now lets go ahead and create our keys, and then create our CSR which we will then use to generate our startssl certificate. Note, after running the first command you will be prompted for some information – please ensure the FQDN of your domain is correct (i.e. it is site1.ehertz.uk if thats the name you’ll be adding in startssl.com, etc):

Next, lets go to the site2 folder in /ssl and do the same:

We now have the two .csrs required to create certificates on startssl.com. Once logged into startssl.com, navigate to ‘Certificates Wizard’ and choose ‘Web Server SSL/TLS Certificate’:

cert wizard 1

Next, enter the domain in the ‘Domain:’ field. This should be the same domain you entered in the apache config file and also the same domain you entered when creating your keys a few minutes ago (i.e. site1.ehertz.uk):

cert wizard 2

Now, go back to the command line and navigate to /etc/apache2/ssl/site1.ehertz.uk and copy the contents of the site1ehertz.csr file:

Copy the output, and then paste it into the ‘Please submit your Certificate Signing Request (CSR):’ box on startssl.com:

cert wizard 3

On clicking submit, your certicate will be generated and become available to download as a zip file via the ‘SSL/TLS Server’ column on the right hand side (simply click on the domain name):

Screenshot 2015-12-23 10.58.24

Once downloaded, unzip the file and then unzip the ‘Apache ..zip’ file also. This will give you two files:

  • 2_site1.ehertz.uk.crt
  • 1_root_bundle.crt

Copy the ‘2_site1.ehertz.uk.crt’ file to the /etc/apache2/ssl/site1.ehertz.uk/ folder (you will likely need to scp the file to the server first, then copy it).

Once the file is in there, you should be able to see three files:

Do this exact process for site2.ehertz.uk, and you will now have two valid certificates and two valid keys in each folder (1 per folder…). There is one final file we need to download before we can configure Apache.

Simply go to the directory above (/etc/apache2/ssl/) and download the ca.pem file from startssl:

And thats it! Now, lets configure Apache2.

Now, we have only one thing left to do – configure the actual apache configs for our two websites.

Within site1.conf, remove the config and add  the following config:

Do the same for site2.conf (changing ‘site1.’ to ‘site2.’ wherever mentioned) and voila, you now have two SSL enabled websites.

Next, ensure you’ve enabled both site1 and site2 by running

Run ‘apachectl configtest’ to test your configs (all should be fine), and then bounce apache2 one final time using ‘service apache2 reload’ and voila – you now have 2, SSL enabled virtualhosts on the same server.

Easily accessing containers/KVM hosts using ProxyPass

port forward proxypass

This guide is for HTTPS, however it works exactly the same for HTTP.

This is a short and sweet guide, however its something that needs to be documented as it is extremely fiddly!

At home I have a few KVM-based virtual machines, and quite a few Docker containers running using internal networks that (by design) only the server and themselves can access.

This is all well and good and secure, however its a bit of a pain in the ass when you want to test things or even worse use them (without a plethora of routes, or having to NAT the hell out of everything…).

In this example, I have a virtual machine listening on the internal 192.168.70.0/24 network running an Apache based application. I know it works because if I hit it up on telnet it works:

Naturally if i try that from a desktop not containing a route (or if my server didnt have NAT) then it wouldnt work.

What I want to be able to do is hit a URL, i.e. ‘site.ehertz.uk’, and have that Apache application, on that VM (or container) appear.

You can do this with iptables, as mentioned earlier:

.. along with enabling conntrack, ipv4_forward, etc.

(In my example above i’ve got port 80 in use, which is common, so im having to redirect on a different port).

This is a pain in the ass as you have to connect to the host and remember to enter the port every time, and its not hugely elegant.

So, whats the answer?

ProxyPass

What I ended up with, was using ProxyPass and DNS to allow me to hit a URL, i.e. site.ehertz.uk and have the Apache application on the VM load.

First, simply create a DNS A record to your server’s IP using your chosen DNS server – i.e. in bind it’ll be:

Once you can dig that address and get the correct IP (i.e. ‘dig site.ehertz.uk’ returns the IP 192.168.0.176), you can crack on with the ProxyPass configuration.

First, ensure that you have the correct modules enabled:

Next, navigate to /etc/apache2/sites-available/ and create a new site:

Within this new conf, paste something similar to the following:

Few points:

  • Ensure your SSL crt, key and pem file paths are all correct.
  • Ensure your VirtualHost IP is correct.
  • Ensure your port is set to 443 for SSL.
  • If you are not using SSL, change 443 to 80 and remove all the lines between ‘Configuration for SSL’ and ‘End of SSL configuration’.
  • Ensure the IP (192.168.70.72) is set to the IP of the internal VM/container on both lines at the bottom of the config!

Thats about it really. Restart apache2 using ‘service apache2 reload’, and then test it out. If you have any issues then double check /var/log/apache2/error.log.