Introduction

One of the more frequent problems on Stackoverflow is Compute Engine SSH. This article will dive into how SSH is configured on Compute Engine and how to connect using various SSH tools. I will also cover how to create SSH key pairs and install them on Compute Engine.

Note: I am in the process of writing this article. I decided to release the first part early for everyone’s benefit.

Last Update: February 10, 2020

Initial Setup

In this step, we will set some defaults to minimize the number of command parameters required.

I will be using the Windows Command Prompt syntax. To switch to Linux usually means change the line continuation character ^ to \ and modifying command line parameter quoting.

Set the default region to us-central1

gcloud config set compute/region us-central1

Se the default zone to us-central1-a

gcloud config set compute/zone us-central1-a

Double-check the default configuration

gcloud config list

Which displays on my system as:

[compute]
region = us-central1
zone = us-central1-a
[core]
account = john.hanley@example.com
disable_usage_reporting = False
project = fiery-stars-999999
show_structured_logs = always

I removed extra information. Check that the account and project are set correctly.

Check for existing Google SSH Key Pair

The CLI will use an existing Google SSH Key Pair if they already exist. On Windows, several files are stored in the directory c:\Users\username\.ssh. The Google Key Pair filenames are:

  • google_compute_engine – This is the private key.
  • google_compute_engine.ppk – This is the PuTTY file format containing both the private and public key.
  • google_compute_engine.pub – This is the public key.

Note: The private key contains everything required. The public key can be extracted from the private key. The PPK is just a different file format containing both the private and public keys.

If these files exist, create a backup directory and move these files there so you can follow along with this tutorial. Do a file move instead of copy/delete so that the file permissions are not changed.

SSH Configuration on a New Compute Engine VM Instance

Create a new instance using the CLI with the minimum number of parameters. Use this command as the basis for future commands. To keep costs low, specify the machine type as f1-micro instead of the default which is n1-standard-1. This article uses Ubuntu 18.04 (Bionic) as the VM instance operating system.

Fetch a list of machine types for a zone

gcloud compute machine-types list --zones=us-central1-a

A truncated list looks like this:

NAME             ZONE           CPUS  MEMORY_GB  DEPRECATED
f1-micro         us-central1-a  1     0.60
g1-small         us-central1-a  1     1.70
n1-standard-1    us-central1-a  1     3.75
n1-standard-2    us-central1-a  2     7.50

Create the first test instance

gcloud compute instances create ssh-test-1 ^
--machine-type=f1-micro ^
--image=ubuntu-1804-bionic-v20200129a ^
--image-project=ubuntu-os-cloud

The output from the command:

Created [https://www.googleapis.com/compute/v1/projects/fiery-stars-999999/zones/us-central1-a/instances/ssh-test-1].
NAME        ZONE           MACHINE_TYPE  PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP      STATUS
ssh-test-1  us-central1-a  f1-micro                   10.128.0.5   104.155.169.104  RUNNING

Connect to the instance

gcloud compute ssh ssh-test-1

The output from the command:

{"version": "0.0.1", "verbosity": "WARNING", "timestamp": "2020-02-11T00:27:37.532Z", "message": "The PuTTY PPK SSH key file for gcloud does not exist."}
{"version": "0.0.1", "verbosity": "WARNING", "timestamp": "2020-02-11T00:27:37.534Z", "message": "The public SSH key file for gcloud does not exist."}
{"version": "0.0.1", "verbosity": "WARNING", "timestamp": "2020-02-11T00:27:37.535Z", "message": "The private SSH key file for gcloud does not exist."}
{"version": "0.0.1", "verbosity": "WARNING", "timestamp": "2020-02-11T00:27:37.536Z", "message": "You do not have an SSH key for gcloud."}
{"version": "0.0.1", "verbosity": "WARNING", "timestamp": "2020-02-11T00:27:37.537Z", "message": "SSH keygen will be executed to generate a key."}
Updating project ssh metadata...\Updated [https://www.googleapis.com/compute/v1/projects/fiery-stars-999999].
Updating project ssh metadata...done.
Waiting for SSH key to propagate.
WARNING - POTENTIAL SECURITY BREACH!
The server's host key does not match the one PuTTY has
cached in the registry. This means that either the
server administrator has changed the host key, or you
have actually connected to another computer pretending
to be the server.
The new ssh-ed25519 key fingerprint is:
ssh-ed25519 255 b8:6c:96:c6:91:df:96:e4:d1:5e:a3:89:61:84:ee:b1
If you were expecting this change and trust the new key,
enter "y" to update PuTTY's cache and continue connecting.
If you want to carry on connecting but without updating
the cache, enter "n".
If you want to abandon the connection completely, press
Return to cancel. Pressing Return is the ONLY guaranteed
safe choice.
Update cached key? (y/n, Return cancels connection)

On Windows, this command launches a PuTTY SSH terminal window. You will either think this is normal or if you know SSH well, magical. For some clouds, the first SSH connection setup is complicated. Now let’s investigate what really happened.

To connect to a system via SSH, three items are necessary:

  • username
  • SSH private key on the client computer
  • SSH public key on the remote computer setup with the SSH server

This means that the CLI did something on both the local computer and the Compute Engine VM instance.

In the PuTTY SSH terminal window type this command:

cat ~/.ssh/authorized_keys

The output will look like this:

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC/NkM3YA3Sabq0l0KrN/xxmNrBaLz5U6WS6dZyxvWjb3svMHvfjm7CegBO43vkbNwLIO0irzDpB+AjaCPlAGTqep8fIrjt9xuQso0sihDShm+uAMceEwn/7xrksANSdJKfPRV676RPVGMvMx35cDEIxzGEjvMZeCeJ/Wu7uTmZQfaLpU5Uj9bMo7vgLwTc49eudeV0JEMVd16VUG3DW2i0wz52ne+IRDjqOT7MhBjIlMJjMpHgmLJ16rz1J7whN+s2Thbop/YcufoaJrxWrq+Xno4AS6oEiuNnWgRPMEka3DzYGKhtFfNeOssAhEEQM7r1vf/1E0kp+oR5hFzNLuPB john.hanley@DESKTOP

Notice a few items about the format:

  • Begins with the string “ssh-rsa”. This is the key type.
  • PEM-encoded data starting with “AAAAB3N”.
  • A comment at the end which happens to be the username/computer-name of my system.

For the previous command, I specified the ~ directory. This is the home directory for the logged-in user. What user is that? How did the CLI choose the username?

Get the logged-in username

In the PuTTY SSH terminal window type this command:

whoami

On my system, this results in:

john.hanley

How did the CLI choose the username?

In the output from gcloud config list one of the lines is account = john.hanley@example.com. The CLI uses the username part of the email address for the Linux username.

This means that if you use different Google Cloud credentials to SSH into an instance, you will log in as different users.

Specify the username

Maybe I prefer to use the username john instead of john.hanley. To do that specify the username in front of the instance name in the format username@instance_name.

gcloud compute ssh john@ssh-test-1

Where does the CLI store the SSH key pair?

The CLI will generate a new Google SSH Key Pair if they do not already exist. On Windows, several files are stored in the directory c:\Users\username\.ssh. The Google Key Pair filenames are:

  • google_compute_engine – This is the private key.
  • google_compute_engine.ppk – This is the PuTTY file format containing both the private and public key.
  • google_compute_engine.pub – This is the public key.

Note: The key pair private key contains everything required. The public key can be extracted from the private key. The PPK is just a different file format containing both the private and public keys.

The CLI will reuse the existing key pair when creating a new instance. The public key is set up on the remote instance.

Delete the test instance

We are now finished with this test instance. Delete it so that we can go to the next step.

gcloud compute instances delete ssh-test-1

Improving Google Compute Engine SSH security

Host Keys

A host key is a key pair that identifies a remote system. The host key is used to verify that you are connecting to the intended system and to prevent man-in-the-middle (MITM) attacks.

SSH host keys are stored as guest attributes. If guest attributes are enabled on the initial boot, Compute Engine stores the generated host keys as guest attributes. To enable guest attributes, add the command line parameter --metadata enable-guest-attributes=TRUE.

Create a new test VM instance

gcloud compute instances create ssh-test-1 ^
--machine-type=f1-micro ^
--image=ubuntu-1804-bionic-v20200129a ^
--image-project=ubuntu-os-cloud ^
--metadata enable-guest-attributes=TRUE

Read the VM instance host keys

gcloud compute instances get-guest-attributes ssh-test-1 ^
--query-path "hostkeys/"

Command output:

NAMESPACE  KEY                  VALUE
hostkeys   ecdsa-sha2-nistp256  AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBC0MpMPASbd+rPllL0LpM34a70VLYomo/d4T59wx73ZBeigCRVhfPhsmF2W+oDQw8S/lramFUIUw43j+09Y89NU=
hostkeys   ssh-ed25519          AAAAC3NzaC1lZDI1NTE5AAAAIDOgXOdySmE6WZPOnlQTl/KHeNtT9XCP9tOYsbABxqxz
hostkeys   ssh-rsa              AAAAB3NzaC1yc2EAAAADAQABAAABAQDKnc0jZ+o6klGNxLWlQ3Z1EPcfAzTsHgK+z9Y3QNFOgppk+gf3CDxIvu7fUBi8SksP5WdOrwlsVXIeF0mAbw7pk/niTwyTQXZji2E3hkxzQsbrJZIKm/gdsLMCV8E0KzYKLnDWZEPsW0Nq9nBGw3W4/LAT5hYl37ldk55m9JsZ9z4G96XyJrYV/L4IwfCQUpsiUlJHvHQ65BmyFROb+2Ck7TLluf74eXEnstY9CyP9xv7CpQChLprPkW5R2ZC1NGZeH0v32EovOVx1Aw+2sXwVW3Ph+O3Io6Aa6QKUPKMU2rXQfgmyQ+e5LfdKwbxNZ01H0BoHh29T6W5hjMgRtcYf

Connect to the instance

gcloud compute ssh ssh-test-1

The output from the command:

Writing 3 keys to C:\Users\john.hanley\.ssh\google_compute_known_hosts

Enable project-wide guest attributes

 

gcloud compute project-info add-metadata ^
--metadata enable-guest-attributes=TRUE

Display project info

The output includes guest attributes and remembered SSH public keys.

gcloud compute project-info describe

 

 

Summary

 

More Information

Credits

I write free articles about technology. Recently, I learned about Pexels.com which provides free images. The image in this article is courtesy of Piet Bakker at Pexels.