Tutorial

How to Authenticate Users to a SSH Server Using Monkeysphere on an Ubuntu VPS

Published on March 24, 2014
How to Authenticate Users to a SSH Server Using Monkeysphere on an Ubuntu VPS

Introduction

Administering large numbers of SSH keys and servers can be very difficult as your organization grows. Correctly identifying valid keys and removing invalid keys throughout an organization can be fraught with errors and have huge consequences on your server security.

In addition, when there are server changes, sometimes your users will receive warnings about being unable to establish the authenticity of your server. Most users will not double-check the key fingerprint of the server before connecting, allowing someone to potentially spoof the server and execute a man-in-the-middle attack.

A project called monkeysphere was created to address these issues. It does this by leveraging GPG keys and the web of trust model to both validate a server’s credentials, and provide easy user management.

In a previous guide, we discussed how to setup monkeysphere to validate servers to users. We will continue where we left off in this guide, where we will learn how to authenticate users to our servers automatically, based only on their GPG keys and our server administrator’s trust in these users. This will allow us to create authentication files that use plain English instead of mostly cryptographic information.

This guide will assume that you have the setup that we left off with in the previous guide (server.example.com, admin.example.com, client.example.com with the necessary trust relationships established). Let’s get started.

Create an Identity Certifier on the SSH Server

The first step towards allowing our SSH server to automatically authenticate our users to the server is to establish an identify certifier. An identity certifier is simply a person we are designating as trusted in establishing the identity of users.

In most cases, the simple and logical choice is to have the server administrator identify users who should be able to log in. We are going to go this route. You can also create more than one identity certifier if your situation requires a distribution of that responsibility.

Let’s begin by getting the fingerprint of our administrative user again. On our admin’s computer, we can use the same GPG command we used in the last guide to get the full fingerprint:

gpg --with-colons --fingerprint admin@fakedomain.com

Again, we are looking for the line of output that looks like:

<pre> fpr:::::::::<span class=“highlight”>A61256B85307B7ED9AD8D93E9E06881E49E95F19</span>: </pre>

The section highlighted in red is what we need here.

On the SSH server (server.example.com), we are going to add this key as an identity certifier. You can do this by typing:

<pre> monkeysphere-authentication add-identity-certifier A61256B85307B7ED9AD8D93E9E06881E49E95F19 </pre>

Monkeysphere will then pull the matching GPG information from the keyservers and store it in its own keyring. It will mark this key as one that can verify the identity of other users.

Generate Authentication Subkeys for SSH Users

Now that we have established that our server administrator can identify which users are legitimate, we need to do a bit of work on the client side.

Each client must generate a GPG subkey that will be used for the actual authentication. While the public GPG key is used to identify the user, the subkey is used for the actual login procedure.

The monkeysphere command contains a subcommand that will allow you to easily generate an authentication subkey. On your client, type:

monkeysphere gen-subkey

A subkey will be generated and added to your local GPG keyring under your main key.

We need to upload the key change to the keyserver again so that our SSH server can use this subkey to generate internal authentication files for the user in question. The key we need to publish is our main key, which contains the subkey change. To get the key information, type:

<pre> gpg --list-keys client@fakedomain.com </pre> <pre> pub 2048R/<span class=“highlight”>87791BD0</span> 2014-03-14 uid client <client@fakedomain.com> sub 2048R/3294D31D 2014-03-14 sub 2048R/0FECF512 2014-03-14 </pre>

The highlighted portion is the key ID that we’ll use to send to the server. Use this ID to send the key back to the server:

gpg --keyserver pool.sks-keyservers.net --send-key 87791BD0

Now that our subkey is available on the keyservers (it may take a bit of time to propagate), we can configure our SSH server to generate authentication files using this key.

Creating the Authentication Files on the SSH Server

Now we need to create the actual authentication files. Monkeysphere authentication files come in two distinct categories.

The user-level files are the ones that we should interact with to establish authentication policies. These are simple, straight forward, plain English files that simply specify people by name and email (as committed to GPG) who should be allowed to log in. These files are located in a subdirectory in each user’s home directory, just like regular SSH authorized_keys files.

These files are then used by Monkeysphere to generate authentication files that SSH can understand using the subkeys associated with each valid user that we created above. Monkeysphere generates authentication files for each user in the /var/lib/monkeysphere/authorized_keys directory.

We will create the directories and files on the SSH server in this section.

Start by going to the home directory of whatever user you want to configure access for. Since we’ve needed to be signed in with administrative privileges to get this far, let’s set up access for our root user. In the home directory, create a hidden directory called .monkeysphere:

cd /root
mkdir .monkeysphere

Monkeysphere requires certain permissions on the user-level folders and files in order to consider them valid. Specifically, it requires that there are no write permissions for anyone beyond the file or directory owner.

Let’s set the directory permissions to match this scheme and then let’s move into the directory:

chmod 755 .monkeysphere
cd .monkeysphere

Within this directory, we need to create a file called authorized_user_ids. This is the user-level authentication file. Create it with your text editor:

nano authorized_user_ids

In this file, we simply list the users, by name and email, exactly as they are in GPG. So to see the formatting we need to use, we can type this again on our client machine:

<pre> gpg --list-keys client@fakedomain.com </pre> <pre> pub 2048R/87791BD0 2014-03-14 uid <span class=“highlight”>client <client@fakedomain.com></span> sub 2048R/3294D31D 2014-03-14 sub 2048R/0FECF512 2014-03-14 </pre>

So this is all we have to type in this file:

client <client@fakedomain.com>

If we want to add additional people, we just add them one per line:

client <client@fakedomain.com>
admin <admin@fakedomain.com>

This is much easier to read and manage than large authorized_keys files. Those files tend to get out-of-date and it is difficult to tell if an older key is still valid or not. With this method, it is easy to be able to ask yourself “should Bob have access to this machine?” If not, simply remove his name.

Save and close the file when you are finished.

Now, we need to remember to take away write permissions from anyone not the owner:

chmod 644 authorized_user_ids

Repeat this procedure for any user you wish to configure remote access for.

Generating Internal Authentication Files

Now that we have our user-level authentication files in place, we can generate our internal authentication files easily.

All we have to do is issue this command:

monkeysphere-authentication update-users

You should run this command after making any changes to the user-level authentication files.

If you only want to update a specific user, you can add their name as an argument:

monkeysphere-authentication update-users root

Let’s see what files were generated by this procedure. We need to go to the directory where these are stored:

cd /var/lib/monkeysphere/authorized_keys

Inside, you should see a file for each user on the system that you configured access for. The one small caveat to this is that each user in the user-level authentication file needs to have an associated subkey available on the public GPG keyserver network.

ls

demouser  root

If we look at the files, we will see a key that looks like:

ssh-rsa
AAAAB3NzaC1yc2EAAAADAQABAAABAQD0CdVIlUptYdZBz/0pn+7XIa2jdzy/VnayAZDXhFdHDTZU0hB8MDGHC9yjUrn9RCMj2NWD3Ls7JjqVAzmRsUn56UwyCJt8/GVmHpeIhYzmUAUjMaaMnjBG3Nhdpm9rsnJt0XVUvOu9oxrvTWYH6ZCVNwsY1O7aX/kQWnaXQW6/B6oiQJ76feZyoLEBR8D/nbxGTtNlkEMcTMTylHN0jHLACJy483SFUkSjHneNK9gNFoxTlUyF/ZBo5+Bo8Uld4iAyhaW7Di4HzfUJzvebZYX1Z1O0yS/db8anSJoZX90MLt7eIFsixuDMS3m31dsX26RI71tJGihvzF0fUsUPDg17
MonkeySphere2014-03-22T13:14:31 client <client@fakedomain.com>

As you can see, this is basically a normal authorized_keys entry. We have abstracted this away though for easier user management and the ability for users to dynamically update their keys through GPG.

You may also see additional lines in this file that are not related to any entry you made in in the authorized_user_ids file. This is because, by default, monkeysphere appends any entries it finds in existing authorized_keys files to the end of the generated file. This is to help you in transitioning between the two systems and for users who are unable, for whatever reason, to switch.

Now that we’ve generated these new authorization files, we need to update the SSH daemon’s configuration to look at these files instead of the files within each user’s directory.

Open the config file with your editor (make sure you are selecting sshd_config, not ssh_config):

nano /etc/ssh/sshd_config

Within this file, find and modify the AuthorizedKeysFile parameter, or create it if it does not exist. Set the value to this:

AuthorizedKeysFile /var/lib/monkeysphere/authorized_keys/%u

Save and close the file when you are finished.

Now, we just need to restart the SSH daemon for the change to take place:

service ssh restart

Configure Client to Send GPG Key for Authentication

Now, our server is completely configured to accept the GPG subkey that we created for authentication.

We need to configure our client to connect using this information instead of the usual password or RSA keys. Monkeysphere does this through the use of the ssh-agent utility, which is used to store authentication details for SSH connections for extended periods of time.

We can try it out without starting the agent itself by using a one-off command like this:

ssh-agent sh -c 'monkeysphere subkey-to-ssh-agent && ssh server.example.com'

This will work, and after you have entered your password for the GPG key, you should be able to connect to the server without entering any password for the server’s account.

However, it’s probably worthwhile to start an agent session. You can do that in your current shell by typing:

eval $(ssh-agent)

To start this automatically every time we login, we can add it to the client’s ~/.bash_profile file:

echo 'eval $(ssh-agent)' >> ~/.bash_profile

Either way, we then need to add our GPG subkey to the SSH agent so that it can use it for authentication. Do this by typing:

monkeysphere subkey-to-ssh-agent

You will have to type in your GPG key password, but this will only be required once per session.

We can see that it has been accepted by typing:

ssh-add -l

2048 2a:1a:1d:52:32:e5:f4:45:b2:a3:ff:d0:c0:6e:69:f6 client <client@fakedomain.com> (RSA)

We can now login without being prompted for anything to any account that we have access to using our GPG subkey:

ssh server.example.com

Conclusion

After getting Monkeysphere set up on your infrastructure, you’ll have a sustainable way of managing server and human interactions for your organization. This method can handle server administrators joining and leaving the organization because all user-level authentication is in plain English. Additionally, you will not have to worry about an attacker trying to spoof access to your servers.

<div class=“author”>By Justin Ellingwood</div>

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about us


Tutorial Series: How To Use Monkeysphere to Validate SSH Servers and Clients

SSH is an excellent way of securely connecting to remote hosts. However, there are some issues with easily validating the identity of the server you are attempting to connect to. Additionally, it can be hard to keep track of which users are authorized to use a busy infrastructure, especially with changing keys. Monkeysphere is a project meant to address these issues by leveraging GPG keys and the web of trust model. Using this system, we can safely make SSH connections.

About the authors

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
1 Comments


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Good guide and thorough. You may also want to consider adding “monkeysphere-authentication update-users” as a cron job. That way when keys expire or are revoked on the keyservers your server will notice and stop granting access to the user of that key.

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel