I’ve previously written about how Known has built in support for OAuth2 and Open ID connect (both as a client and as a server). Well, over the past few weeks I’ve been doing some work to make this even more useful.

So, I thought I’d quickly jot down some notes as to what you can do with this functionality, and why you might find it cool.

Turn your Known site into an identity provider

The first thing you can do is use the OAuth2 server built in to Known to turn your site into an identity provider.

This means you will be able to create “apps”, allowing users on your site to be able to use third party applications and apps to make authenticated API calls.

It also means you can easily create a “login with” button, allowing your users to log into other sites using their Known profile on your site.

Connect your Known site to an identity provider

The next thing you can do is connect your site to another third party IDP using OAuth2, and allow those users to log in to your site.

This third party IDP could be your organisation’s single sign on service, a third party one, or another Known site.

If the IDP you’re connecting to supports OpenID connect, you can also enable the Federation feature.

What this does is let users with a valid OpenID Token retrieved from the IDP to make authenticated API calls on any Known sites that share that IDP, regardless of whether the user has used that site before.

Primarily, this functionality is designed for a modern micro service architecture world – so for example, you might have a React front end that needs to talk to one or more data sources over GraphQL, including getting blog data from a Known site. All of these services live in different containers, in distributed locations, with different local databases.

But…

Federation…

Something I’ve been pondering recently is whether this functionality might be able to let you do something pretty neat.

Consider, a Known site can be both a client and a server, and both issue and receive public key signed and verifiable OpenID Connect tokens for their users.

Each token knows where it comes from and can state who issued it.

This raises the possibility of being able to establish reciprocal links between sites – each Known (or other site – it’s an open protocol after all) could be both a client and server of each other.

With a bit of UX massaging, this could potentially let the users of each of these sites flow between each site in the network, and getting all the functionality of the local users.

Sure I’m not the first to be thinking this way, but it’s something to play with, and certainly will work a lot more seamlessly than the previously mooted PGP signed login (although I still think that’s pretty cool).

Two factor authentication (also known as 2FA), is a mechanism to provide extra security to website accounts by requiring a special one time use code, in addition to a user name and password.

This code is typically generated by a hardware dongle or your phone, meaning that you must not only know the password, but also physically have the code generator.

I thought it would be cool if Known had this capability, and so I wrote a plugin to implement it!

How it works

Once the plugin is installed and activated by the admin user, each user will be able to enable two step authentication through a menu on their settings page.

Enabling two factor will generate a special code, which can be used to generate time limited access tokens using a program such as the Google Authenticator. To make setup easier, the plugin generates a special QR code which can be scanned by the reader.

From then on, when you log in, you will get an extra screen which will prompt you for a code.

Enter the code produced by your authenticator and you will be given access!

» Visit the project on Github...

Fail2Ban is a simple, but powerful, open source intrusion detection and prevention system which can run on most POSIX compliant operating systems. It works by monitoring various system logs for signs of intrusion attempts (failed logins etc), and on finding them, executes a preconfigured action.

Typically, this action is to block further access attempts from the remote host, using local firewall rules.

Out of the box, Fail2Ban comes configured to monitor SSH for signs of intrusion. However, since it works by monitoring log files, Fail2Ban can be configured to monitor many other services. I figured it would be pretty cool if you could also use it to protect Elgg sites as well.

Elgg already has a per user account lockout on login, however it is not without its limitations. It is pretty basic, and while it protects against access to specific accounts, it does not protect against dictionary attacks against multiple or non-existent accounts. Using Fail2Ban, you can protect against multiple access attempts from the same IP address easily, and the cut them off at the network level, frustrating the attack.

Installing Fail2Ban

The first step to getting this all working is to install Fail2Ban.

This is covered in detail elsewhere, but on Debian/Ubuntu it was a simple matter of pulling it from the apt repo:

sudo apt-get install fail2ban

Out of the box Fail2Ban will block using IPTables, but if you use shorewall, as I do, you’ll need to modify the actions to use that.

Getting Elgg to log access

It is an omission (quite possibly on my part), but the default Elgg login action does not explicitly log login attempts and login errors. While it is quite probable that you could hack together some regexp to parse the apache error logs, these are often quite noisy, highly changeable, often stored in odd locations, and, more often than not, are turned off in production environments.

I thought I’d make things a little easier on myself, and so I wrote a tiny Elgg plugin which overrides the default login action and outputs explicit error messages to the system auth.log, on both success and failure.

Once installed, you should begin to see logging messages start to appear in your server’s auth log (usually /var/log/auth.log) along the lines of this:

Mar 22 18:24:43 web elgg(web.example.com)[16483]: Authentication failure for fakeuser from 111.222.333.444
Mar 22 18:25:05 web elgg(web.example.com)[16483]: Accepted password for admin from 111.222.333.444

Again, to keep things simple, and to avoid getting a regular expression headache, I kept the authentication messages similar to those used by the SSH filter.

Monitoring the log with Fail2Ban

Finally, you need to configure fail2ban to look out for the Elgg messages in the auth.log.

  • Copy the elgg.conf into your fail2ban filters directory, on Debian this is in /etc/fail2ban/filters.d/
  • Create a jail.local in /etc/fail2ban/ if you have not already done so, and then create a rule, along the lines of the following:

    [elgg]
    enabled = true
    filter = elgg
    logpath = /var/log/auth.log
    port = all

Restart Fail2Ban, and you should be up and running! To test, attempt to log in (using a machine on a different machine if at all possible) and try a few failed logins.

A future enhancement of this that you could consider, especially if running in a production environment, is to modify the block action to redirect queries from the offender’s IP to a place-holder page explaining why they have been banned. This could probably be done quite easily using a REDIRECT rule, although I’ve not tried it yet.

Anyway, code, as always, is on github. Have a play!

» Visit the project on Github…