Logbook + Scratchpad

SSH

In the previous post I mentioned the usage of ssh-keyscan to get and store a server's public SSH key. My doubt was that it may not be a secure-enough solution.

From what I understand, ssh-keyscan is just another instance of TOFU, or trust on first use. Basically, it only automates what you do when you're prompted to verify a key fingerprint upon first connection to a server. If the known_hosts file does not continuously change, it is ok to use this.

Anyway, I have still decided to update the GitHub Action and make use of a GitHub secret to hold the public key of the server I am connecting to.

#SSH #tricks

I decided to try and use a GitHub Action to copy some content onto an FTP server. At first I tried to use an existing action, but it didn't work and debugging was proving to be cumbersome. Then, I changed strategy and used an action with CLI commands instead.

Note: I would prefer using rsync but it is not an option in this case. Also, I do not have SSH access to the server – it's SFTP only.

The action looks roughly like this:

name: Copy files
on:
  push:
    branches:
      - main

jobs:
  deploy:
    name: Deploy
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: scp
        run: |
          mkdir -p ~/.ssh/
          chmod 700 ~/.ssh/
          touch ~/.ssh/known_hosts
          ssh-keyscan ${{ secrets.HOST }} >> ~/.ssh/known_hosts
          echo "$SSH_PRIVATE_KEY" > ~/.ssh/deploy_key
          chmod 600 ~/.ssh/deploy_key
          scp -i ~/.ssh/deploy_key -s -r some_file some_dir "${{ secrets.USERNAME }}@${{ secrets.HOST }}:"
        env:
          SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}

Getting to this has been a bit difficult, so here are a few notes on the details:

  • scp needs to use a private SSH key, which cannot be added to GitHub as a file. I've added the key material as a GitHub secret and imported it as an environment variable. The key file is then (re)written by the action itself.
  • The .ssh directory has to be created manually, first of all because the host key has to be added to known_hosts (here with ssh-keyscan). If this is not done, scp fails with Host key verification failed. (Seen on StackOverflow)
  • The scp command needs to include the -s switch to force the SFTP protocol. This will likely change in the future, but with the current ubuntu-latest the installed OpenSSH version does not use SFTP as a default.

I am not yet 100% sure this is completely secure, so I'll keep checking. For example: is ssh-keyscan good enough, or do I need to get the key beforehand and then inject it manually into known_hosts?

#SSH #tricks