continuous-integrationssh-keysbitbucket-pipelines

Bitbucket pipeline SSH key setting: Can't fetch host fingerprints


I am trying to set up ssh keys for my pipeline and send files of the artifacts of my build step to an embedded device using scp deploy pipe. I generated the ssh key in the repository settings and copied the public key into the authorized_keys files of my embedded device following https://support.atlassian.com/bitbucket-cloud/docs/set-up-pipelines-ssh-keys-on-windows/. However when i try to fetch the known host finger print (using the embedded device's ip address), it loads for a moment and nothing happens. There is no error message or any fingerprint fetched. The scp deployment pipe also fails because host key verification failed. My embedded devices have their own wifi (without internet) but are connected and discoverable on my network (with internet). I also run my pipeline on a self-hosted linux docker runner, which on that linux machine i am able to connect to the devices via ssh just fine. I am unsure where does bitbucket executes this fetch fingerprint process (My runner server / their own bitbucket server / my laptop) and am wondering if the device ip are not discoverable there.

I am relatively new to pipelines and ssh so i am quite lost as to what went wrong.

The fetch fingerprint buffers Doesn't show any error or fingerprints after buffer

I tried creating the ssh key pair manually following the documentation's instructions and still i cannot connect with ssh/scp from my pipeline. I ensured the permissions of the .ssh and authorized_keys files are 700 and 600 respectively. Similarly i am not able to fetch the known host fingerprints.


Solution

  • My guess always was that SSH fingerprints are fetched from the server, be it your on-premise hardware or Atlassian's Bitbucket Cloud ® infrastructure. Not from your self-hosted pipeline runner (how would you choose it?) and definitely not from your laptop.

    So, to the question on how to fetch ssh fingerprints for intranet hosts, I imagine three solutions.

    1. If you were using an on-premise Bitbucket server, the hosts you put in its same network should be discoverable. This is a very tailored solution to setup and I'd advise against it. But if this happened to be your current setup already... I think fetching from the web UI should work.

    2. Forward some ports to intranet ssh hosts in your firewall. Just fetch your intranet public-facing IP address + each forwarded port. IMHO a suboptimal approach as this can be against many sensible security policies even if you whitelisted Atlassian's public IP ranges.

    3. My choice: fetch the ssh from your computer and save the result in a file in your git repository! ssh-keyscan intranet-address >> ./known_hosts. Then, in the pipeline script append that file to the one that possibly contains fingerprints that were discoverable from the web UI:

    pipelines:
      default:
        - step:
            name: Hi intranet
            runs-on:
              - self.hosted
            script:
              - cat ./known_hosts >> ~/.ssh/known_hosts
              - pipe: atlassian/ssh-run:0.8.0
                variables:
                  SSH_USER: daniel
                  SERVER: intranet-address
                  COMMAND: echo hello
    

    Suffice to say, this is only useful if your pipeline runs in a self-hosted runner in the same actual network as those remote hosts! Otherwise refer to How to enable Continuous Deployment to an internal server from BitBucket

    Also, if your computer needed some kind of NAT to reach those intranet hosts, most probably you will need to manipulate the names, addresses and ports that are recorded in the known_hosts file. It is imperative that it lists the names, addresses and ports that will be apparent to your self-hosted runner instead of your computer.

    Related resources: https://docs.gitlab.com/ee/ci/ssh_keys/#verifying-the-ssh-host-keys


    The key pair generated from the web UI should work just fine if you already put it in the right ~/.ssh/authorized_keys files.