All entries for Wednesday 17 May 2006
May 17, 2006
Most applications log messages out to a log file somewhere on a server but they are a pain to look at. You could setup log4j to append messages via email, but to me it seems unreliable. Also, you have to decide who is going to get these emails and they can be quite invasive if you don't always need to read them all.
RSS has been a great step forward in opting into information on the web rather than emails. So, why not do the same for system messages.
My particular use case involves some data from our Web Sign On system and these messages are quite sensitive so it is no good just publishing a public RSS feed.
My solution looks something like this:
1) I have a listener class within SSO that monitors activity and logs it in the usual way.
2) I have another listener that receives messages from the logging listener that looks for unusual activity, such as repeated login failures or lots of requests for the same IP address. When it finds something unusual, it puts an entry into the feed that will be displayed to the admin user. This is done with the Rome Atom/RSS java utilities project. This is a great open source project that allows you to easily create/read feeds in all different formats.
SyndEntry entry; SyndContent description; entry = new SyndEntryImpl(); entry.setTitle("Warning for user " + user); entry.setPublishedDate(new Date()); entry.setUri("" + entry.getPublishedDate().getTime()); description = new SyndContentImpl(); description.setType("text/plain"); description.setValue(logMessage + "<br><br>" + authFailures); entry.setDescription(description); getMessages().add(entry);
These SyndEntry's are generic enough to be turned into any kind of feed, be it Atom, RSS 2.0 or RSS 1.0.
3) I then have a controller that pulls all of those messages and puts them in a feed for that admin user view view:
SyndFeed feed = new SyndFeedImpl(); feed.setTitle("SSO brute force warning log"); feed.setLink("http://www.warwick.ac.uk/"); feed.setDescription("This feed shows warnings when users repeatedly fail to login"); feed.setEntries(getMessages()); feed.setFeedType("rss_2.0"); response.setContentType("application/xml; charset=UTF-8"); SyndFeedOutput output = new SyndFeedOutput(); output.output(feed, response.getWriter());
4) This page is protected by our SSOClientFilter. This will allow HTTP Basic Auth, but only over SSL. As I don't trust Bloglines or anyone with my username and password, I just need to put the address into Thunderbird or a similar RSS reader like this:
The "forcebasic=true" on the end tells the SSOClientFilter to use Basic Auth rather than redirecting to our SSO login screen as it would usually if it was requested by me in the browser. When Thunderbird tries to read the feed, it is prompted for authentication and so prompts me the user in Thunderbird for my username and password and sends those securely to the feed.
5) Hey presto, we have an authenticated RSS system log:
<?xml version="1.0" encoding="UTF-8" ?> <rss xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"> <channel> <title>SSO brute force warning log</title> <link>https://websignon.warwick.ac.uk/</link> <description>This feed shows warnings when users repeatedly fail to login</description> <item> <title>Warning for user cusyac</title> <description>The last 3 login attempts for user cusyac were failures. Check wsos_auth.log Tue May 16 17:37:47 BST 2006|Auth failed|cusyac|Username/password not found|137.205.x.x<br> Tue May 16 17:36:38 BST 2006|Auth failed|cusyac|Username/password not found|137.205.x.x<br> Tue May 16 17:34:37 BST 2006|Auth failed|cusyac|Username/password not found|137.205.x.x<br></description> <pubDate>Tue, 16 May 2006 16:42:58 GMT</pubDate> <guid isPermaLink="false">1147797778580</guid> <dc:date>2006-05-16T16:42:58Z</dc:date> </item> </channel> </rss>