Skip to content

Instantly share code, notes, and snippets.

@espoelstra
Last active November 1, 2023 17:55
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save espoelstra/c910a8f5de6ba16d09fdb2014a5d843c to your computer and use it in GitHub Desktop.
Save espoelstra/c910a8f5de6ba16d09fdb2014a5d843c to your computer and use it in GitHub Desktop.
Access ChromeOS Crosh shell via ssh to localhost using Secure Shell and a Yubikey for passwordless auth

Why oh why

I want to develop some scripts for things like Chrx, Chromebrew, MrChromebox scripts etc and I don't want to register a new SSH key to my account every time I need to powerwash or use recovery on one of my Chromebooks because I messed it up. I already use my Yubikey for GPG/FIDO/U2F/SSH on all the other systems I develop on, and I only needed the SSH portion to work for this particular use case. I also didn't want to deal with using Crouton or Crostini since that requires additional downloads and more configuration and complexity.

Challenges

Since the Crosh userland doesn't have scdaemon or pcscd for talking to the smart card, I had to come up with another way to access the Yubikey and make the SSH key available. I ended up trying a few different things to make it work, but overall the solution ended up being brilliantly straightforward. Originally I tried using Chromebrew to install one of the smartcard access/manager packages, but the dependency chain ended up pulling in Gnome keyring and a bunch of other crazy things that I didn't need at all. I ended up breaking Chromebrew a few different ways trying to uninstall all those packages without just nuking /usr/local/ since I had some other stuff installed there from dev_install and my other scripts.

Victory

I had run across some instructions in the ChromiumOS (ChromeOS) source code that I ended up being able to utilize to make this super easy and still very secure.

TL;DR to expound on later

# Open a Crosh shell via Ctrl+Alt+T or Crosh window app then typing `shell`
# Create host keys (only needs to be done once).
sudo su - # or sudo -i
mkdir -p /mnt/stateful_partition/etc/ssh
ssh-keygen -f /mnt/stateful_partition/etc/ssh/ssh_host_rsa_key -N '' -t rsa
ssh-keygen -f /mnt/stateful_partition/etc/ssh/ssh_host_ed25519_key -N '' -t ed25519

# We don't need to do the iptables portion if we are only accessing via localhost
# Open firewall and start sshd (must be done on every boot).
#  iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# You need to start the daemon temporarily in foreground mode so that you can get your Yubikey's public key
/usr/sbin/sshd -D


# Open Secure Shell
# Create a connection for chronos@localhost
# Add --ssh-agent=gsc for the Relay Options and -A for SSH Arguments
# Attempt the connection, you may get prompted to allow the Smart Card Connector/Secure Shell to talk
# You may get prompted to trust the host, you can do so
# Then you will get a password prompt because it doesn't know our key yet
# press Ctrl+Shift+J to view the ssh-rsa or ssh-ecdsa key
# copy the key starting with ssh- to the last character of ==


# Back in the Crosh shell
# Ctrl+C to kill sshd
exit # leave root shell
mkdir -p ~/.ssh/
TRUSTED_SSH_KEY='<paste your ssh-rsa key here>'
echo "$TRUSTED_SSH_KEY" >> ~/.ssh/authorized_keys
# Note we removed the -D so it will run in the background
sudo /usr/sbin/sshd -oAuthorizedKeysFile=/home/chronos/user/.ssh/authorized_keys

# Back in Secure Shell
# Hit enter on the password prompt (it should fail/stop prompting because we killed the sshd it was talking to)
## Otherwise if you accidentally ran sshd without -D keep
## pressing Enter each time you are prompted for the password until it fails
## run `sudo kill $(pgrep sshd)` and then run the sshd line above again
# When it gives you the option to reconnect, accept the offer by pressing R
# You should get prompted for the PIN for your GPG/SSH key from the Yubikey
# If you enter your key correctly you will be prompted to cache the PIN
# Choose yes and you won't be prompted for your PIN each time the SSH key is used
# Choose no and you will get prompted, this is a GREAT thing for remote shared systems

References

https://chromium.googlesource.com/chromiumos/overlays/chromiumos-overlay/+/master/chromeos-base/chromeos-sshd-init/files/openssh-server.conf.README

Google Groups (hterm)

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