One of our machines at work gets hammered by ssh password guessers, and this is about a neat and cheap (IMHO) way of dealing with this.

Possible solutions: block ssh for all unknown clients, use a log-scraping blacklister like this one to detect mischief, change over to key-only authentication, port-knocking or connection rate limiting.

Blocking unknown clients doesn't work as not all legitimate users have fixed addresses, the blacklister is inelegant but works, key-only is an ssh-specific fix and doesn't keep the suckers from using up cpu on our box, and for port-knocking I'd need central admin to open up more network ports. All not overly clean nor close to perfection.

Connection rate limiting using iptables is great: let's allow everybody one new connection in a window of, say, 5 minutes. The problem is that if you legitimately need more connections, you're screwed: with ipt_recent, all animals are equal.

I'd like some animals to be more equal than others, but not based on advance knowledge of their client addresses: let them prove their worth. This is where my add-on comes into play.

The pam_recent module provides a PAM session management function, and session management is only run after authentication has succeeded. The module adds or removes the client IP address to/from an ipt_recent list (via the cool /proc-interface to ipt_recent).

In the most trivial deployment, you'd allow everybody a very few new connections within a longish window. If the client manages to login, his history is cleared and subsequent new connections are not blocked. Password guessers, however, would not manage to prove their legitimacy and be blocked on a second/third/whatever connection. That's it: no need to know your clients, they're all treated as scum unless they can prove to be Good People.

This idea is obviously similar to pam_abl, the auto-blacklist module, but in contrast my pam_recent doesn't need to manage its own databases and is a lot more lightweight and simpler. Also, pam_recent can add to or remove from any ipt_recent list, meaning that you could open up different/all services or ports upon successful authentication to a particular service.

Plus pam_recent is super-trivial and simple: a mere 150 lines of C (survives -Wall -pedantic, TYVM), most being error handling. Docs are included at the top of the file, licence is GPL V1 or V2. The downside is that it's iptables-specific and works only together with the recent match extension.

Download pam_recent.c (v1.2). Share and enjoy!