Skip to content

Instantly share code, notes, and snippets.

@yannhowe
Created September 26, 2016 18:06
Show Gist options
  • Star 62 You must be signed in to star a gist
  • Fork 14 You must be signed in to fork a gist
  • Save yannhowe/5ab1501156bd84c8ac261e2c17b8e3e0 to your computer and use it in GitHub Desktop.
Save yannhowe/5ab1501156bd84c8ac261e2c17b8e3e0 to your computer and use it in GitHub Desktop.
.gitlab.ci.yml for SSH with private key.
# Image neeeds to have ssh-client
image: docker:git
services:
- docker:dind
stages:
- staging
before_script:
- docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN $CI_REGISTRY
- mkdir -p ~/.ssh
# Paste the PRIVATE key into a gitlab variable. Pay attention to the linebreak at the end when pasting
- echo "$DEPLOY_SERVER_PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_rsa
- chmod 600 ~/.ssh/id_rsa
- eval "$(ssh-agent -s)"
- ssh-add ~/.ssh/id_rsa
- ssh-keyscan -H 'your.server.hostname' >> ~/.ssh/known_hosts
staging:
stage: staging
tags:
- docker
only:
- staging
script:
- docker build --pull -t $CI_REGISTRY_IMAGE:staging .
- docker push $CI_REGISTRY_IMAGE:staging
# your own server details here
- ssh $SERVER_USER@$SERVER_HOSTNAME < deploy.sh
@TobiGa
Copy link

TobiGa commented Sep 20, 2018

I ran run gitlab-runner exec locally and since Variables are not accessible there at the time,
i got invalid format, nice to know maybe...

@tim-hub
Copy link

tim-hub commented Oct 1, 2018

@van4oza

$ echo "$TEST_SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - >/dev/null
Error loading key "(stdin)": invalid format

I have had the same error.
You added TEST_SSH_PRIVATE_KEY as protected variable to the GitLab CI/CD config. This is fine. But the variable then only gets exposed to protected branches (master for example is per default) and protected tags. I configured the v* wildcard (matches my use case) as protected tags and it did run.

Hi, there, same error,

@fgilio
Copy link

fgilio commented Oct 22, 2018

In case it helps someone:
Just had the Error loading key "(stdin)": invalid format error and solved by adding a line break at the end of the variable in GitLab's UI

@fgilio
Copy link

fgilio commented Oct 22, 2018

In case it helps someone:
Just had the Error loading key "(stdin)": invalid format error and solved by adding a line break at the end of the variable in GitLab's UI

@xd2
Copy link

xd2 commented Nov 14, 2018

Hi. I've written a SSH helper for .gitlab-ci.yml.
Check it out : https://gitlab.com/x4v13r/gitlab-ci

Just include: it to your .gitlab-ci.yml and then you can go with:

ssh_run root myhostname $MYHOST_PKEY "touch foo; cp foo bar; ls -al; rm foo bar; ls -al"

@pagolina
Copy link

pagolina commented Dec 5, 2018

@amatiash i followed your method but i got the following response

Running hooks in /etc/ca-certificates/update.d...
done.
$ mkdir -p ~/.ssh
$ echo "$SSH_PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_rsa
$ chmod 700 ~/.ssh/id_rsa
$ eval $(ssh-agent -s)
Agent pid 3067
$ ssh-add ~/.ssh/id_rsa
Enter passphrase for /root/.ssh/id_rsa: ERROR: Job failed: exit code 1

Why does it request for passphrase?

@ALTELMA
Copy link

ALTELMA commented Jan 4, 2019

So now it fixes or not?

@skyrim61
Copy link

echo ${ID_RSA_DEVELOP} > id_rsa
now id_rsa file is one line,
run this command to check , openssl rsa -in id_rsa -text -noout
output unable to load Private Key

@skyrim61
Copy link

我解决这个问题:

  • echo ${ID_RSA_DEVELOP} > id_rsa
    此时, id.pub 文件格式为1行, job运行时, 报出 密钥文件 出错
    此时, 我更改如下:
  • echo "${ID_RSA_DEVELOP}" > id_rsa
    问题得到解决
    cat ~/.ssh/id.pub , 格式正确

@willcooley
Copy link

willcooley commented Feb 2, 2019

@amatiash i followed your method but i got the following response

Running hooks in /etc/ca-certificates/update.d...
done.
$ mkdir -p ~/.ssh
$ echo "$SSH_PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_rsa
$ chmod 700 ~/.ssh/id_rsa
$ eval $(ssh-agent -s)
Agent pid 3067
$ ssh-add ~/.ssh/id_rsa
Enter passphrase for /root/.ssh/id_rsa: ERROR: Job failed: exit code 1

Why does it request for passphrase?

yo, it looks like the ssh key you created to use was created with a password, you might want to create a new ssh key that doesn't use a password. It is recommended that you don't use a password for SSH keys for server communication because it will error out the process since you can't put the password in manually when it ask for it when Gitlab's runner process is going. I had this issue a few weeks ago; so this is why I am suggesting that to you.

@willcooley
Copy link

willcooley commented Feb 2, 2019

this worked for me:
`

 deploy:

   image: docker:stable

     - services: docker/dind

   stage: deploy

   script:

     - echo "$RELEASE_IMAGE"

     - 'which ssh-agent || ( apk --update add openssh-client )'

     - eval $(ssh-agent -s)

     - mkdir -p ~/.ssh

     - echo "$SERVER_PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_rsa

     - chmod 700 ~/.ssh/id_rsa

     - eval "$(ssh-agent -s)"

     - ssh-add ~/.ssh/id_rsa

     - ssh-keyscan -H 'YOUR_IP_ADDRESS' >> ~/.ssh/known_hosts

     - ssh-keyscan YOUR_IP_ADDRESS | sort -u - ~/.ssh/known_hosts -o ~/.ssh/known_hosts

     - '[[ -f /.dockerinit ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'

`

@subhakant0
Copy link

subhakant0 commented Mar 30, 2019

If you need to enter the password, then you have to. I found a way how to do that.

before_script:
    - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
    - 'which sshpass || ( apt-get update -y && apt-get install sshpass -y )'
    - mkdir -p ~/.ssh
    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_rsa
    - chmod 700 ~/.ssh/id_rsa
    - eval $(ssh-agent -s)
    - ssh-add ~/.ssh/id_rsa
    - ssh-keyscan -H 'gitlab.com' >> ~/.ssh/known_hosts
    - ssh-keyscan gitlab.com | sort -u - ~/.ssh/known_hosts -o ~/.ssh/known_hosts
    - rm -rf .git
    - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
  script:
    - sshpass -p "<your password goes here>" ssh  username@hostname "your commands"

I used sshpass

@etarndt
Copy link

etarndt commented Apr 11, 2019

I generated ssh keys that didn't need a password so I used that code above without sshpass, but am receiving this issue:

Warning: Permanently added the ECDSA host key for IP address '##.##.###.##' to the list of known hosts.
Permission denied, please try again.
Permission denied, please try again.
Permission denied (publickey,password).

Code:

before_script:
 - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
 - mkdir -p ~/.ssh
 - echo "$SSH_PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_rsa
 - chmod 700 ~/.ssh/id_rsa
 - eval $(ssh-agent -s)
 - ssh-add ~/.ssh/id_rsa
 - ssh-keyscan -H 'host.host.com' >> ~/.ssh/known_hosts
 - ssh-keyscan host.host.com | sort -u - ~/.ssh/known_hosts -o ~/.ssh/known_hosts
 - rm -rf .git
 - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'

testSSH:
  script:
    - ssh host@host.host.com "cd Desktop/testssh && git pull origin master"

I have been troubleshooting for hours and cannot resolve the issue. Could anyone please help?

@ibraah88
Copy link

If you need to enter the password, then you have to. I found a way how to do that.

before_script:
    - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
    - 'which sshpass || ( apt-get update -y && apt-get install sshpass -y )'
    - mkdir -p ~/.ssh
    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_rsa
    - chmod 700 ~/.ssh/id_rsa
    - eval $(ssh-agent -s)
    - ssh-add ~/.ssh/id_rsa
    - ssh-keyscan -H 'gitlab.com' >> ~/.ssh/known_hosts
    - ssh-keyscan gitlab.com | sort -u - ~/.ssh/known_hosts -o ~/.ssh/known_hosts
    - rm -rf .git
    - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
  script:
    - sshpass -p "<your password goes here>" ssh  username@hostname "your commands"

I used sshpass

how can i use a different ssh port (like 2222) ??

@taozhi8833998
Copy link

useful tip, thanks

@Porkts
Copy link

Porkts commented Jul 25, 2019

If you need to enter the password, then you have to. I found a way how to do that.

before_script:
    - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
    - 'which sshpass || ( apt-get update -y && apt-get install sshpass -y )'
    - mkdir -p ~/.ssh
    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_rsa
    - chmod 700 ~/.ssh/id_rsa
    - eval $(ssh-agent -s)
    - ssh-add ~/.ssh/id_rsa
    - ssh-keyscan -H 'gitlab.com' >> ~/.ssh/known_hosts
    - ssh-keyscan gitlab.com | sort -u - ~/.ssh/known_hosts -o ~/.ssh/known_hosts
    - rm -rf .git
    - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
  script:
    - sshpass -p "<your password goes here>" ssh  username@hostname "your commands"

I used sshpass

how can i use a different ssh port (like 2222) ??

Use

script:
    - sshpass -p "<your password goes here>" ssh -p2222  username@hostname "your commands"

@sofyansitorus
Copy link

I had to also run this on the deployment server

https://stackoverflow.com/questions/44363537/gitlab-ci-ssh-permission-denied-publickey-password

cat ~/.ssh/id_rsa.pub > ~/.ssh/authorized_keys

This did the trick!

@danpercic86
Copy link

@van4oza

$ echo "$TEST_SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - >/dev/null
Error loading key "(stdin)": invalid format

I have had the same error.
You added TEST_SSH_PRIVATE_KEY as protected variable to the GitLab CI/CD config. This is fine. But the variable then only gets exposed to protected branches (master for example is per default) and protected tags. I configured the v* wildcard (matches my use case) as protected tags and it did run.

This worked

@quochoangvp
Copy link

quochoangvp commented Feb 17, 2020

@van4oza

$ echo "$TEST_SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - >/dev/null
Error loading key "(stdin)": invalid format

I have had the same error.
You added TEST_SSH_PRIVATE_KEY as protected variable to the GitLab CI/CD config. This is fine. But the variable then only gets exposed to protected branches (master for example is per default) and protected tags. I configured the v* wildcard (matches my use case) as protected tags and it did run.

It worked for me

@yannhowe
Copy link
Author

So sorry I can't really contribute guys cos I've moved on to other tools and things over the past few years after a short time kicking the tires on gitlab. This gist has really taken on a mind of its own. Glad it facilitated some useful discussion.

@duclm2609
Copy link

duclm2609 commented May 3, 2020

Which tool do use you now for CI/CD? I'm tired with Jenkins, yet moved to Gitlab CI/CD but the SSH way was just too f**king dumb.

@tyliggity
Copy link

tyliggity commented May 21, 2020

Hey all, just tackled this today. FYI, this is how you can do git operations (i.e. tagging) from within CI as of today (variable of type 'File'):

tagging_job:
  stage: release
  image: ubuntu
  before_script:
    - mkdir -p ~/.ssh
    # Settings > Repository > Deploy Keys > "DEPLOY_KEY_PUBLIC" is the public key of the utitlized SSH pair (choose `Write access allowed` on creation)
    # Settings > CI/CD > Variables > "DEPLOY_KEY_PRIVATE" is the private key of the utitlized SSH pair, type is 'File' and ends with empty line
    - mv "$DEPLOY_KEY_PRIVATE" ~/.ssh/id_rsa
    - chmod 600 ~/.ssh/id_rsa
    - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client git -y )'
    - eval "$(ssh-agent -s)"
    - ssh-add ~/.ssh/id_rsa
    - ssh-keyscan -H 'gitlab.com' >> ~/.ssh/known_hosts
  script:
    # try to connect to GitLab.com
    - ssh git@gitlab.com
    # fresh clone
    - mkdir ~/source && cd $_
    - git clone git@gitlab.com:$CI_PROJECT_PATH.git
    - cd $CI_PROJECT_NAME
    # Version tag
    - git tag my-tag
    - git push --tags -o ci.skip

The -o ci.skip part causes the generated pipeline to be skipped (not auto-ran). If you want to not generate a pipeline at all for your tag push, add this to the top of the .gitlab-ci.yml:

workflow:
  rules:
    - if: $CI_COMMIT_TAG
      when: never
    - when: always

Peace

@khechoomian
Copy link

I had to also run this on the deployment server
https://stackoverflow.com/questions/44363537/gitlab-ci-ssh-permission-denied-publickey-password

cat ~/.ssh/id_rsa.pub > ~/.ssh/authorized_keys

This did the trick!

Hi Guys
This trick works...try it.
thanks @sofyansitorus

@rafaelstz
Copy link

I had to unprotect the variable to make it work.

Capture d’écran, le 2020-08-09 à 18 19 55

@mochadwi
Copy link

I had to unprotect the variable to make it work.

Capture d’écran, le 2020-08-09 à 18 19 55

This also happened to me. Thanks!

@nwpray
Copy link

nwpray commented Dec 13, 2020

@van4oza

$ echo "$TEST_SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - >/dev/null
Error loading key "(stdin)": invalid format

I have had the same error.
You added TEST_SSH_PRIVATE_KEY as protected variable to the GitLab CI/CD config. This is fine. But the variable then only gets exposed to protected branches (master for example is per default) and protected tags. I configured the v* wildcard (matches my use case) as protected tags and it did run.

This was exactly what is going on for me. And anyone else that feels like they need to unprotect their variable, don't do that. Just go configure your protected branches and tags to inject these variables like @richardhj said.

@DurandSacha
Copy link

DurandSacha commented Feb 22, 2021

eval $(ssh-agent -s) echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null mkdir -p ~/.ssh chmod 700 ~/.ssh ssh-keyscan xxx.xxx.xxx.xxx >> ~/.ssh/known_hosts chmod 644 ~/.ssh/known_hosts

is worked for me
( add a SSH_PRIVATE_KEY in var settings )

@xyj404
Copy link

xyj404 commented Mar 23, 2021

Thanks @amatiash !

@Aiswariyasugavanam
Copy link

How to add multiple Private keys to known_host??

@alljinx
Copy link

alljinx commented Feb 3, 2023

Hey all, just tackled this today. FYI, this is how you can do git operations (i.e. tagging) from within CI as of today (variable of type 'File'):

tagging_job:
  stage: release
  image: ubuntu
  before_script:
    - mkdir -p ~/.ssh
    # Settings > Repository > Deploy Keys > "DEPLOY_KEY_PUBLIC" is the public key of the utitlized SSH pair (choose `Write access allowed` on creation)
    # Settings > CI/CD > Variables > "DEPLOY_KEY_PRIVATE" is the private key of the utitlized SSH pair, type is 'File' and ends with empty line
    - mv "$DEPLOY_KEY_PRIVATE" ~/.ssh/id_rsa
    - chmod 600 ~/.ssh/id_rsa
    - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client git -y )'
    - eval "$(ssh-agent -s)"
    - ssh-add ~/.ssh/id_rsa
    - ssh-keyscan -H 'gitlab.com' >> ~/.ssh/known_hosts
  script:
    # try to connect to GitLab.com
    - ssh git@gitlab.com
    # fresh clone
    - mkdir ~/source && cd $_
    - git clone git@gitlab.com:$CI_PROJECT_PATH.git
    - cd $CI_PROJECT_NAME
    # Version tag
    - git tag my-tag
    - git push --tags -o ci.skip

The -o ci.skip part causes the generated pipeline to be skipped (not auto-ran). If you want to not generate a pipeline at all for your tag push, add this to the top of the .gitlab-ci.yml:

workflow:
  rules:
    - if: $CI_COMMIT_TAG
      when: never
    - when: always

Peace

Thx, you made my day !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment