Using SSH from Jenkins

Written by: Stephen Connolly

Credentials management in Jenkins is an area that is in need of a radical overhaul. In fact for just that reason we open-sourced the credentials plugin  at the start of this year.

Jenkins manage credentials

Of course, like a lot of things in Jenkins, it can take a while for people to get their head around how to use these things. And there is often a need for some examples. So while we in CloudBees all get to see our internal use of the Credentials plugin in our closed source plugins for managing a users CloudBees credentials or for managing their Google AppEngine credentials, the open source world does not benefit from such example code.

So, we open sourced the SSH Credentials plugin  to show people how you might manage SSH credentials… but unfortunately deciphering how to apply that to peoples plugins has proved somewhat tricky… in large part due to a lot of people favouring the JSch SSH library in place of the discontinued Trilead SSH library that is bundled within Jenkins.

        SSHUser user = null;
        for (SSHUser u : CredentialsProvider.lookupCredentials(SSHUser.class, project, ACL.SYSTEM)) {
            if (userId.equals(u.getId())) {
                user = u;
                break;
            }
        }
        Connection connection = new Connection(host, port);
        connection.connect();
           SSHAuthenticator instance = SSHAuthenticator.newInstance(connection, user);
           instance.authenticate();

Example of how to connect and authenticate with Trilead SSH API

So I updated the SSH Credentials API to make it easier to use with JSch … and then a colleague suggested that it would be really cool to expose the SSH credentials to a job via ssh-agent. 

        SSHUser user = null;
        for (SSHUser u : CredentialsProvider.lookupCredentials(SSHUser.class, project, ACL.SYSTEM)) {
            if (userId.equals(u.getId())) {
                user = u;
                break;
            }
        }
        JSchConnector connector = new JSchConnector(user.getUsername(), host, port);
        SSHAuthenticator instance = SSHAuthenticator.newInstance(connector, user);
        instance.authenticate();
        Session session = connector.getSession();
        session.connect();

Example of how to authenticate and connect with JSch API

So here it is… https://github.com/jenkinsci/ ssh-agent-plugin … ok there are some minor issues such as it requiring the Apache Tomcat Native libraries be installed on any machine that is doing the build (if you want to use passphrase protected private keys)… but I thought I would show how cool this plugin actually is!

First off, we create a folder… I could use globally managed credentials, but by using a folder I can restrict access to the folder using the RBAC plugin and therefore limit the scope of availability of the credentials.

RBAC plugin

Once I have created the folder I then can add the credentials to the folder:

Jenkins add credentials

In this case I am going to add SSH Username with private key, as that's what the ssh-agent needs.

add SSH Username

There are a number of options available, such as entering the absolute path to the file as stored on the master, or picking up the key from the Jenkins Process's home directory. The SSH Credentials plugin will take care of ensuring that the build node has the key even though the key is stored on the master. In this case we will use the Copy & Paste solution.

This allows us to have a key that is used only by Jenkins, and that gives much more flexibility as if it does become compromised we can revoke that key specifically rather than revoking a key that may be used for other tasks (by virtue of it “just being there on the file system”… too often the cry of a hack that needs to be fixed later, but never is)

Clicking on the advanced button allows us to provide the key's passphrase (you should always use a passphrase… at the very least it prevents somebody copying out the private key from the config screen!) and we can also provide a friendly description.

add SSH Username description

Now we can create a job within the folder and it will have access to those credentials.

create job for credentials

And the shell process will auto-magically have an ssh-agent session with the selected credentials already available.

Note: the key used for the above screenshots has been revoked prior to uploading this post!

Hopefully people will find this inspiring enough to start reworking their existing plugins to use the Credentials API! 

 

—Stephen Connolly
CloudBees
cloudbees.com


Stephen Connolly  has nearly 20 years experience in software development. He is involved in a number of open source projects, including Jenkins . Stephen was one of the first non-Sun committers to the Jenkins project and developed the weather icons. Stephen lives in Dublin, Ireland - where the weather icons are particularly useful. Follow Stephen on Twitter  and on his blog .


Learn More

Want to learn the latest in Jenkins? Subscribe to the Jenkins newsletter , Continuous Information . This monthly newsletter contains all of the latest interesting and useful happenings in the Jenkins community, sent directly to your inbox. 

 

 


 

 

 

Stay up to date

We'll never share your email address and you can opt out at any time, we promise.