I have a code that wraps around some SSH operations. I would like to build CI for this code. Is there a way to generate two virtual machine and SSH between them?
Technically you should be able to use Qemu (possibly with libvirt) on an Ubuntu runner, maybe with Vagrant or something to set them up automatically.
However I’d recommend using containers instead if possible, because the performance is much better. I have a Dockerfile that starts an SSH server inside a container for a project of mine. In that project a script creates the necessary
authorized_keys file after the container has been started, but you could also do that with a volume or in the Dockerfile. Maybe that example can help you get started.
It’s actually a good idea to use an ssh server! I’ll try to get started based on your example, thanks.
@airtower-luna I’ve been trying your suggestion. Here is what I have in my action:
- name: Install SSH server if: runner.os == 'Linux' run: | sudo apt-get install openssh-server sudo systemctl enable ssh sudo systemctl start ssh mkdir -p "$HOME/.ssh" chmod 0700 "$HOME/.ssh" ssh-keygen -t rsa -q -f "$HOME/.ssh/id_rsa" -N "" cat "$HOME/.ssh/id_rsa.pub" >> "$HOME/.ssh/authorized_keys" chmod 640 "$HOME/.ssh/authorized_keys" echo "NoHostAuthenticationForLocalhost yes" >> ~/.ssh/config sudo systemctl restart ssh ssh localhost "uname"
However, I’m getting permission issues:
Reading package lists... Building dependency tree... Reading state information... openssh-server is already the newest version (1:8.2p1-4ubuntu0.1). 0 upgraded, 0 newly installed, 0 to remove and 4 not upgraded. Synchronizing state of ssh.service with SysV service script with /lib/systemd/systemd-sysv-install. Executing: /lib/systemd/systemd-sysv-install enable ssh Permission denied, please try again. Permission denied, please try again. runner@localhost: Permission denied (publickey,password).
would you happen to know how to solve these issues?
At a glance, no. To get more information try running
ssh with the
-v option, and check
/var/log/auth.log (as in,
cat to the log or upload as artifact) for the server side.
Thanks @airtower-luna ! I’m not too good at reading the verbose output of ssh, but it seems to me that ssh wants to read a passphrase that I set to be empty:
debug1: Reading configuration data /etc/ssh/ssh_config debug1: /etc/ssh/ssh_config line 19: include /etc/ssh/ssh_config.d/*.conf matched no files debug1: /etc/ssh/ssh_config line 21: Applying options for * debug1: Connecting to localhost [::1] port 22. debug1: Connection established. debug1: identity file /home/runner/.ssh/id_rsa type 0 debug1: identity file /home/runner/.ssh/id_rsa-cert type -1 debug1: identity file /home/runner/.ssh/id_dsa type -1 debug1: identity file /home/runner/.ssh/id_dsa-cert type -1 debug1: identity file /home/runner/.ssh/id_ecdsa type -1 debug1: identity file /home/runner/.ssh/id_ecdsa-cert type -1 debug1: identity file /home/runner/.ssh/id_ecdsa_sk type -1 debug1: identity file /home/runner/.ssh/id_ecdsa_sk-cert type -1 debug1: identity file /home/runner/.ssh/id_ed25519 type -1 debug1: identity file /home/runner/.ssh/id_ed25519-cert type -1 debug1: identity file /home/runner/.ssh/id_ed25519_sk type -1 debug1: identity file /home/runner/.ssh/id_ed25519_sk-cert type -1 debug1: identity file /home/runner/.ssh/id_xmss type -1 debug1: identity file /home/runner/.ssh/id_xmss-cert type -1 debug1: Local version string SSH-2.0-OpenSSH_8.2p1 Ubuntu-4ubuntu0.1 debug1: Remote protocol version 2.0, remote software version OpenSSH_8.2p1 Ubuntu-4ubuntu0.1 debug1: match: OpenSSH_8.2p1 Ubuntu-4ubuntu0.1 pat OpenSSH* compat 0x04000000 debug1: Authenticating to localhost:22 as 'runner' debug1: SSH2_MSG_KEXINIT sent debug1: SSH2_MSG_KEXINIT received debug1: kex: algorithm: curve25519-sha256 debug1: kex: host key algorithm: ecdsa-sha2-nistp256 debug1: kex: server->client cipher: email@example.com MAC: <implicit> compression: none debug1: kex: client->server cipher: firstname.lastname@example.org MAC: <implicit> compression: none debug1: expecting SSH2_MSG_KEX_ECDH_REPLY debug1: Server host key: ecdsa-sha2-nistp256 SHA256:NFnWPH2boToKCX0yq1K33LY0K3EwK810f599LpwoXJI debug1: read_passphrase: can't open /dev/tty: No such device or address Host key verification failed.
This looks like the key issue, not the passphrase:
You need to either import the host key for localhost into
authorized_keys, or (if you’re only going to make test connections to localhost, nothing critical) you can write
StrictHostKeyChecking accept-new to automatically accept the new key.
Thanks once more @airtower-luna .
The thing that confuses me is that I did import the key:
ssh-keygen -t rsa -q -f "$HOME/.ssh/id_rsa" -N "" cat "$HOME/.ssh/id_rsa.pub" >> "$HOME/.ssh/authorized_keys"
and that it did find it:
debug1: identity file /home/runner/.ssh/id_rsa type 0
authorized_keys in the previous post was a mistake. The issue is with
known_hosts. The rest still applies, though. The key missing from
known_hosts is not your login key, but the host key, which the SSH client uses to ensure it’s talking to the right server.
Thanks! Indeed that was one issue in adding myself to
know_hosts. However, even with this fixed, ssh seems to really now want to take my
debug1: Offering public key: /home/runner/.ssh/id_rsa RSA SHA256:ivLPhVUx8LHGGeIQkIdDwBJVzp9wQBkRiFRkXXN5HwE agent debug1: Authentications that can continue: publickey,password debug1: Trying private key: /home/runner/.ssh/id_dsa
(Not to worry about publishing the key here, it is generated in a virtual machine in CI).
It looks like the SSH server rejected the key. To figure out why you’ll need to check
/var/log/auth.log as I mentioned above, it should contain information on login attempts.
Thanks for all your help. The solution was in the end very simple. My $HOME has permissions 777, which is too much for SSH. So what solved it was
chmod g-w $HOME chmod o-w $HOME
I have lost a lot of time debugging users ssh incidents only to find out it was a simple file permission. I wrote a few bash scripts that allow users and administrators to make sure that the ssh files and directory permissions are correct on each system. The script names are check-user-ssh.sh and check-host-ssh.sh which can be found at docker-security-infrastructure/ssh at master · BradleyA/docker-security-infrastructure · GitHub
Thanks nice @bradleya . Did you consider making this an GitHub Action?