Wednesday, September 13, 2006

Auditing challenged with SSH

I recently had a real dilemma thrown at me by the security team at a site I work on. The site's policy dictates that no authentication should take place without a password. Any exceptions require both a business case justification on file, and an expiration. This presents a real challenge with SSH. SSH allows public key authentication as an alternative to passwords, and the private key can be created without a passphrase. In addition, there is no way to enforce a key expiration at a server level (at least, not that I've been able to find).

SSH supports two primary means of authentication. Password authentication is essentially the same process that occurs through Telnet, except we use a secure tunnel instead. Public Key authentication bypasses the system's password channel completely. At first glance, it's easy to say, "so disable public key authentication and be done with it."

There are two benefits to using public key authentication with SSH. First, you have the ability to confiigure your private key (residing on the client) without a passphrase. In doing so, you increase the risk of private key compromise, but enable passwordless authentication. This makes batch jobs much easier because it elminiates an interactive session.

The second benefit is that public key authentication is a two-factored authentication. It combines something you have, a private key, and something you know: a passphrase. As such, it's much more secure than traditional password based authentication which onyl uses single factor authentication. Even if someone compromises your private key file, it can't be used unless they know the passphrase, which SHOULD be a complex phrase.

The problem is that there is no way to control who on a server is authorized to use public key encryption, no way to enforce passphrase complexity, and no way to expire a public key. I could create a public / private key pair on a machine under my desk that isn't subject to production data center security scans and audits. Let's next say that I decided not to use a passphrase, or that the passphrase was weak and easily guessed. Next, assume I'm the DBA for the company's Oracle Fincancials encironment. It would require very little effort for someone to compromise my under-desk system and gain passwordless access to the company's critical systems. This is a low-risk, high payoff scenario that people who know what they're doing would be likely to attempt.

Another issue with the public key encryption capabilities of SSH is that you can enter any passphrase (or no passphrase). With my system password, I can install a crack module into the Pluggable Authentication Module (PAM) stack and enforce very complex passwords. Unfortunately, because key pairs are generated on clients, there is no way to enforce sanity at the server level.

After some research I determined that the version of Sun SSH which ships with Solaris 9 is far less capable than the OpenSSH releases one could obtain and build. Using OpenSSH it is possible to move the default $HOME/.ssh to another base directory (like /var). In doing so, it is much easier to create a root controlled environment where someone can not use the authorized_keys file unless authroized by a superuser. Unfortunately, the maintenance issues created by doing this are not justified, and our policy is to stick with vedor provided and supported software in all but the most extenuating circumstances. Under Solaris 9, there's just no safe and auditable way to allow publick key authentication. In an ideal world, I should be able to not just configure public key authentication at a server leve, but specify which keys were respected by the server's SSH daemon.

There is no solution I can see to the issue of enforcing passphrase complexity, or auditing use of non-interactive key pairs because that part of the process is handled entirely by the client. It's very difficult to convnice a security officer that key generated on an uncontrolled device can be trusted for authentication against Sarbox servers.

Our decision, much to my dismay, was to disable public key authentication site-wide. I feel like we're throwing the baby out with the bath water, but at the same time I understand the need to audit system access, and be able to enforce policy. I'm anxious for our Solaris 9 fleet to turn over to Solaris 10 so we can begin using the more capable version of SSH it includes.


Nick Owen said...

Interesting post. FYI: I blogged about your post in my blog: Hope you don't mind.


Gabriel said...

One thing to keep in mind: ssh agent !

Look it up it's the answer to these problems.

Christopher Hubbell said...


ssh-agent is not what I would consider a solution for enterprise application. From the man page (ssh-agent(1)):

The idea is that ssh-agent is started in the begin-
ning of an X-session or a login session, and all other windows or pro-
grams are started as clients to the ssh-agent program.

ssh-agent is interactive at start-up. This is convenient for an administrator on a UNIX workstation who needs to connect to many servers.

However, these feeds are generated by cron jobs with no user interaction. ssh-agent would not work in this scenario because there is no option for a user to unlock the keys when starting the tool. These servers must require no interaction following a reboot; not on the feed originator, or the feed recipient.

hevisko said...

Yes, The part I miss in this is the *USER*'s RESPONSIBILITY... ie. the System Administrator's.

This *SHOULD* be policy in so far as that the user needs to show that he done the necessary to protect the access that have been granted to him, and that he/she will be responsible for any and all break ins on his/her account nuasea

this is the first and major point of security for any organization, the PERSONNEL!
Doesn't matter how hard you try to protect something if they aren't trustable, you have a problem period. Long hard to guess passphrases et al.

Greg Baker said...

I know this is a super old post, but you can certainly disable public key login for the entire server, and then override the behavior for individual users.