Access remote hosts via SSH

You can set up SSH authentication for Bitbucket Pipelines for simplified SSH, SFTP, and SCP access to remote hosts directly from your build pipeline.

Setting up the authentication makes remote hosts accessible via SSH to all users with the write access to the repository. 

 


 

On this page

To set up remote host SSH configuration for Bitbucket Pipelines:

See also


 

  Check whether you have SSH installed

Go to the terminal and run: 

$ ssh -V 

If you have SSH installed, the command returns the version details.

 


 

Step 1: Generate an SSH key pair

First, generate an RSA key pair without a passphrase. On Linux or OS X, open the terminal and run:

 

$ ssh-keygen -t rsa -b  4096 -N '' -f my_ssh_key

 

where:

ssh-keygen

The script generates a key pair. For more information, see keygen

-t rsa

The type of the key is RSA
-b 4096

The size of the key is 4096 bits for better security

-N ''
The key pair doesn't require a passphrase. Keys that are used in scripts don't require passphrases
-f my_ssh_key
The key file names will start with my_ssh_key

 

The output of the command might look like this:

Generating public/private rsa key pair.
Your identification has been saved in my_ssh_key.
Your public key has been saved in my_ssh_key.pub.
The key fingerprint is:
<your_key_fingerprint>
The key's randomart image is:
<your_key_randomart>

Result

The script creates two files:

my_ssh_key Your private key
my_ssh_key.pub Your public key

 

 

  Check whether the key files exist

You can check whether the files exist by running the following command:

$ ls -a

 


 

Step 2: Encode the private key and add it as a secure environment variable

Currently, Pipelines doesn't support line breaks in environment variables. To make sure that your SSH private key goes safely through the Bitbucket Pipelines GUI, base-64 encode it by running:

 

$ base64 < my_ssh_key

 

Copy the output of the command from the terminal and add it as a Bitbucket Pipelines environment variable called MY_SSH_KEY:

  1. Go to Account > Bitbucket Settings.
  2. Select an individual account or a team for which you want to configure variables.
  3. In the menu on the left, go to Pipelines > Environment variables.
  4. Copy the output of the base64 command from the terminal.
  5. Paste the command output as the value of the secured  MY_SSH_KEY variable:

For more information, see Environment variables in Bitbucket Pipelines.

 

There are security risks associated with passing private SSH keys as environment variables:

  • Environment variables get copied to child processes that your pipelines build may spawn.
  • Secured variables can be retrieved by all users with write access to a repository.

We recommend that you never pass your own personal SSH key as an environment variable, but instead generate a new SSH key-pair for Pipelines that easily be disabled if it is compromised.

Result

The variable that contains your private SSH key is present in the list of Bitbucket Pipelines variables:

 

 


 

Step 3: Install the public key on a remote host

To make the authentication between Pipelines and a remote host possible, you must install the public key on the remote host. Bitbucket lets you upload keys from the GUI, other remote hosts might require some manual setup.

Bitbucket Cloud repositories

If you want to access some other Bitbucket Cloud repository as part of your Pipelines builds, you can add the public key directly in Bitbucket Cloud as described in Add an SSH key to an account. Once you add your public key to Bitbucket Cloud, you can proceed to Step 4 of this guide.

All other remote hosts

If you have SSH access to the server, you can use the ssh-copy-id  command. Typically, the command appends the key to the ~/.ssh/authorized_keys file on the remote host.

$ ssh-copy-id -i my_ssh_key.pub username@server.example.com

 

where:

 

ssh-copy-id
The script that copies the public key to a remote host. For more information, see ssh-copy-id.
-i my_ssh_key.pub
The key file that will be copied
username@server.example.com
The details of the remote host into which you want to copy the public key

 

Result

The command uploads your public key to the location that tells the SSH server to allow the connection between Pipelines and the remote host.

 

  Check whether you can SSH into the server
Verify whether you can SSH into the remote host with your public key without having to enter a password:

 

$ ssh -i my_ssh_key username@server.example.com

Note: The command just opens a prompt within the terminal.

 


 

Step 4: Create the my_ known_hosts file and add it to your repo

The known_hosts file contains DSA host keys of SSH servers accessed by the user. It's important for verification that you're connecting to the correct remote host.

  1. Create the my_known_hosts file that includes the public SSH key of the remote host. You can do this by executing the following command:

    $ ssh-keyscan -t rsa server.example.com > my_known_hosts

  2. Commit the my_known_hosts file to your repository from where your pipeline can access it.


Alternatively

You can copy an existing known_hosts file from the ~/.ssh directory of a user that has previously accessed the remote host via SSH. You can remove all unrelated lines.

Result

Now you can run SSH-based commands for the configured remote host without passwords.

Here's an example of uploading a file using SFTP:

 

$ sftp username@server.example.com <<< $'put file-to-upload.txt'

 


 

Step 5: Tie everything together in your bitbucket-pipelines.yml file

Pipelines spin up a new Docker container environment for every build. You can make the SSH configuration accessible by adding it to the bitbucket-pipelines.yml file. 

To configure SSH for Docker containers that run your pipelines:

 

- mkdir -p ~/.ssh
- cat my_known_hosts >> ~/.ssh/known_hosts
- (umask  077 ; echo $MY_SSH_KEY | base64 --decode > ~/.ssh/id_rsa)

 

where:

mkdir -p ~/.ssh
Creates the .ssh directory and its parents in the Docker container
cat my_known_hosts >> ~/.ssh/known_hosts
Adds the list of known hosts with your remote host details to the list of known hosts in the Docker container
(umask  077 ; echo $MY_SSH_KEY | base64 --decode > ~/.ssh/id_rsa)

Places the my_ssh_key private key in the Docker container as an id_rsa private key and sets the umask permissions to:

  • allow read, write, and execute permission for the file's owner
  • but prohibit read, write, and execute permission for everyone else

   

  base64: invalid input error

Add -i to your base64 decoding command, like this:

- (umask  077 ; echo $MY_SSH_KEY | base64 --decode -i > ~/.ssh/id_rsa)


 

Example

Your bitbucket-pipelines.yml file can look like this: 

bitbucket-pipelines.yml
image: node:6    # specify your Docker image here
pipelines:  
  default:
    - step:
        script:
           - mkdir -p ~/.ssh
           - cat my_known_hosts >> ~/.ssh/known_hosts
           - (umask  077 ; echo $MY_SSH_KEY | base64 --decode > ~/.ssh/id_rsa)
           - ssh <user>@<host> 'echo "connected to `hostname` as $USER"'

 

The example above just connects to a server and echoes "connected to <server> as <user>". You can modify the last line to use scp to transfer files or git to clone files from a remote server via SSH.

Troubleshooting

The clone asks for a passphrase

Things that you can check:

  • The SSH key pair that you created in Step 1 must be created without a passphrase.
  • The private SSH key that you generated is base64 encoded as described in Step 2.

 


 

Was this helpful?

Thanks for your feedback!

Why was this unhelpful?

Have a question about this article?

See questions about this article

Powered by Confluence and Scroll Viewport