Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is pasting a private key into the Jenkins web portal secure?

In Jenkins, I've only every seen one method for storing a private ssh key credential.

This method is recommended by everybody: Open the Jenkins server web portal in a web browser, go to Credentials, and under Add Credentials, select SSH Username with private key, paste the private key into the web page, and hit ok.

This, I assume, uses an HTML form to send the private key in a POST request over HTTPS to the Jenkins server, which then saves the private key locally on the server's disk.

The problem: The top voted answer to the question "How to securely send private keys?" states that a private ssh key can only be secured by not transmitting it at all.

My question: is pasting a private key into the Jenkins web portal and transmitting them over HTTPS actually secure? If not, what is the best way to get a private key into the Jenkins credentials?

like image 703
cowlinator Avatar asked Mar 17 '20 22:03

cowlinator


Video Answer


1 Answers

in situ

Using the web UI for this is probably secure enough for almost every use case, and is hard to beat with respect to convenience.

Nevertheless, generating private keys where they are needed is certainly good advice, and is definitely possible with Jenkins. One approach:

  • SSH into the Jenkins server, and generate the keys
  • Run some groovy in the script console to create the Jenkins credential
  • Exfiltrate the public key
  • Delete the generated keys on the server

In this example, on the Jenkins server both $HOME and $JENKINS_HOME point to /var/jenkins_home, and the keys are generated in ~/temp.


Generate the key on Jenkins server

ssh [email protected]
mkdir ~/temp
cd ~/temp
ssh-keygen -t rsa -b 4096 -C "some-meaningful-label" -f "./my-in-situ-key"

This creates my-in-situ-key and my-in-situ-key.pub in /var/jenkins_home/temp.


Create the Jenkins credential

In Jenkins script console:

import com.cloudbees.jenkins.plugins.sshcredentials.impl.BasicSSHUserPrivateKey
import com.cloudbees.plugins.credentials.CredentialsScope
import com.cloudbees.plugins.credentials.domains.Domain

def domain = Domain.global()

def store = Jenkins.instance.getExtensionList('com.cloudbees.plugins.credentials.SystemCredentialsProvider')[0].getStore()

def privateKeyString = new File('/var/jenkins_home/temp/my-in-situ-key').text
def keySource = new BasicSSHUserPrivateKey.DirectEntryPrivateKeySource(privateKeyString)

def privateKeyCredential = new BasicSSHUserPrivateKey(
    CredentialsScope.GLOBAL,
    "temp-stack-overflow-key",      // id
    "jenkins",                      // username
    keySource,                      // private key
    "",                             // passphrase
    "Temporary Demo Key"            // description
)

store.addCredentials(domain, privateKeyCredential)
"Credential Added"

Test the credential before cleaning up.


Clean up

Grab the public key and be sure to delete the private key on your way out the door.

cat ~/temp/my-in-situ-key.pub
rm -rf ~/temp

Relevant Javadoc

like image 169
Mike Patrick Avatar answered Sep 17 '22 17:09

Mike Patrick