Silly Security 2: Chroot Jail

I am not a security professional or expert. I’m an average guy¬†just learning and trying stuff out.

Picking up from last post, we have a couple things setup.

  1. Entry user “somebody” with limited capabilities (no file system write access, etc)
  2. A user we want to user: “intendeduser”
  3. Remote ssh is allowed for “somebody”, but only local ssh is enabled for “intendeduser”

Least Privilege

Why give “somebody” more access than required? The user’s only purpose is to serve as a staging area for access to the intended user. As of now, “somebody” can scan through most of the file system and explore other users’ home directories.

What is the minimum set of capabilities “somebody” requires?

SSH.

Chroot Jail

The plan is to force “somebody” into a modified jail environment using chroot. Chroot is an operation that changes the apparent root directory of a user.

My goal is to create a jail environment that allows nothing but SSH.

Implementation

I followed the steps from: http://allanfeid.com/content/creating-chroot-jail-ssh-access

But added these changes:

  • Only copied over the bash and ssh binaries
  • Bound /dev/tty and /dev/urandom to their jail equivalents

The final step was crucial. I struggled for almost an hour trying to debug ssh. The key was to copy over strace and use it to slowly determine and satisfy the missing dependencies.

I discovered several missing libraries through strace, but the most difficult step was diagnosing the need for /dev/tty.

When all else seemed to be working, ssh would exit with:

Could not create directory '/nonexistent/.ssh'.
The authenticity of host 'localhost (127.0.0.1)' can't be established.

The program exited without prompting for a password. A smarter man would’ve known that /dev/tty is required for the prompt.

Don’t make the same mistakes I did.

Silly Security

No one gives a shit about my servers. They host a few funny sites and services mostly for personal consumption.

But recently I made the mistake of reading the details of the security update offered for my Mac.

So I set off to secure my shit once!

High Level Strategy:

  1. No more password authentication on my front-facing servers, ssh key auth only from a single control server.
  2. Design a hardened login scheme for the central control server.

Central Server Login Scheme:

Normal Setup

  • Create “intendeduser”, my user for personal, everyday activity.
  • Add “intendeduser” to sudoers
  • Install fail2ban, which mitigates brute force attacks to some extent.
  • Disable root login

Tiered Users

I made a duplicate of the nobody user, somebody:

$ useradd somebody -d /nonexistent -s /bin/sh

The somebody user would have no privileges, and would simply serve as the first stage in a 2-stage auth scheme. Remotely, you could ssh in as “somebody”, but no other user. A second ssh intendeduser@localhost would be required to complete the login as the intended user.

This was accomplished by adding the following to my /etc/ssh/sshd_config file:

AllowUsers somebody intendeduser@localhost

This allows “somebody” to ssh in from anywhere, but only allows us to ssh in as “intendeduser” locally.

Note: I wonder if localhost doesn’t actually guarantee local access only. I’ll investigate more later.

Issues

The “somebody” user still has a significant amount of access. He/she can browse and read the majority of the files on the machine. Guessing the “intendeduser” would be pretty trivial.

In my next post, I’ll discuss a solution using a chroot jail!

Possible Improvements:

Quick list of things that came to mind

  • Two-Factor authentication using a PAM (Pluggable authentication module)
  • Switch ssh port (I didn’t just for convenience)
  • Limited login time before “somebody” user is automatically logged out