Connecting to Linux VMs using advanced methods


In general, the best SSH connection methods are described in the Connecting to instances document. However, when you need to manage your own credentials, use third-party tools, or connect using alternative connection paths, the following advanced methods might fit your needs better than the standard methods. For information about how SSH connections work in Compute Engine, including SSH key configuration and storage, see SSH connections to Linux VMs.

There are several advanced methods that you can use to connect to Linux VMs:

Before you begin

Supported operating systems

These connection methods are supported for all Linux operating systems that are available on Compute Engine. For Fedora CoreOS, you must set up SSH access before you can use these methods.

Providing public SSH keys to instances

Normally, Compute Engine creates and manages SSH keys for you whenever you connect using the methods described in Connecting to instances.

However, if you need to use your own SSH keys (for example, when using third-party tools to connect), you must generate your own SSH key pair and provide your public SSH key file to the instance before you can connect.

If you are not familiar with how to generate your own SSH key, see Create SSH keys.

To provide your SSH key to the instance, use one of the following methods:

  • (Recommended) Enable OS Login. OS Login uses IAM roles to provide your public SSH key to the instance through your Google Account or a managed user account. For instructions, see Setting up OS Login.

    When setting up OS Login, ensure that you complete the step to Add keys to VMs that use OS Login. In this step you can add your public key to the user account that you want to use to connect to your VM.

    To learn more about the benefits of using this feature, see OS Login.

  • (Not recommended) Manually add and remove SSH keys by editing project or instance metadata. See Managing SSH keys in metadata. This method adds unnecessary risks and complexity and is not recommended unless the OS Login method above does not work for you. See Risks of manual key management.

  • If your instance is managed by someone else who already has access (such as a Systems Administrator in your organization), you can also provide your public SSH key file to them and ask them to manually configure it for you. Usually this involves them connecting to your instance, copying your public key file into your home directory on your instance, and changing the permissions on the file, but this depends on how your organization manages your instances.

Connecting to instances that do not have external IP addresses

If you have isolated instances that do not have an external IP address, you can still connect to those instances by using their internal IP addresses on a Google Cloud VPC network. For example, you can still connect to VMs that you intentionally isolate from external networks by using the following methods:

Connecting over a VPN connection

To use a Virtual Private Network (VPN) to connect to an instance without an external IP address:

  • You must use a computer that can reach the VM instance over a Cloud VPN tunnel.

    For example, you might have a VPN that your local on-premises network shares with your Google Cloud VPC. In that situation, connect to the instance using the Google Cloud CLI, SSH on Linux or macOS, or third-party SSH clients such as PuTTY on Windows.

See the following tabs for details:

gcloud

To connect to an instance without an external IP address, use the gcloud compute ssh command with the --internal-ip flag.

  1. In the Google Cloud console, go to the VM Instances page and find the internal IP address for the instance that you want to connect to.

    Go to VM Instances

  2. Connect to the instance.

    gcloud compute ssh INTERNAL_INSTANCE_NAME \
        --zone=ZONE \
        --internal-ip
    

    Replace the following:

    • INTERNAL_INSTANCE_NAME: the name of the instance that you want to connect to
    • ZONE: the name of the zone in which the instance is located
  3. After you connect, run commands on your instance using this terminal. When you finish, disconnect from the instance by running the exit command.

Linux and macOS

To connect to an instance without an external IP address from Linux or macOS workstations, do the following:

  1. Provide your public SSH key to an instance using one of the available options. You cannot proceed without this.

  2. On your local machine, start the ssh-agent to manage your SSH keys for you:

    eval ssh-agent $SHELL
    
  3. Use the ssh-add command to load your private SSH key from your local computer into the agent and use your private SSH key for authentication of all SSH commands. Replace PRIVATE_KEY with the filename of your private key file.

    ssh-add ~/.ssh/PRIVATE_KEY
    
  4. In the Google Cloud console, go to the VM Instances page and find the internal IP address for the instance that you want to connect to.

    Go to VM Instances

  5. In a local terminal, use the ssh command along with the username associated with your private SSH key and the internal IP address of the instance to connect to. For example:

    ssh USERNAME@INTERNAL_INSTANCE_IP_ADDRESS

    Replace the following:

    • USERNAME: the username of the user who is connecting to the instance. This must be the username you specified when you created the SSH key.
    • INTERNAL_INSTANCE_IP_ADDRESS: the internal IP address of the instance that you want to connect to.

After you connect, run commands on your instance using this terminal. When you finish, disconnect from the instance by running the exit command.

Windows (PuTTY)

To connect to an instance without an external IP address from Windows workstations:

  1. If you have not done so already, provide your public SSH key to an instance using one of the available options. You cannot proceed without this.

  2. In the Google Cloud console, go to the VM Instances page and find the internal IP address for the instance that you want to connect to.

    Go to VM Instances

  3. Follow the preceding steps to connect to an instance using PuTTY from Windows, but make the following change:

    • Where the steps instruct you to specify an external IP address, instead specify the internal address of the instance you want to connect to.

After you connect, run commands on your instance using this terminal. When you finish, disconnect from the instance by running the exit command.

Connecting through a bastion host

Another method of connecting to an instance that does not have an external IP address is to connect through a bastion host. Using a bastion host also lets you connect to instances on other peered VPC networks.

To connect to an instance through a bastion host from Linux and macOS, use either the Google Cloud CLI or SSH. To connect from Windows, use a third-party SSH client such as PuTTY.

Connecting to other instances from a bastion host requires a private SSH key. There are several ways to manage this:

  • Install the Google Cloud CLI and configure it to manage your private keys for you.
  • Forward your private key to the bastion host instance by enabling agent forwarding in your ssh client.

See the following examples for complete steps:

gcloud

The Google Cloud CLI lets you connect to instances that don't have external IP addresses without forwarding your private SSH keys to the bastion host. To do this, install gcloud on both your local workstation and the bastion host instance, if you have not done so already.

To use the Google Cloud CLI to connect to an instance that does not have an external IP address:

  1. Set a read/write Compute Engine API access scope for the service account on your bastion host instance by including --scopes compute-rw in your command. For more information, see Changing the service account and access scopes for an instance.

  2. Grant the necessary IAM permissions to allow your bastion host to access your public SSH key by either using OS Login (recommended) or project metadata. Use one of the following procedures:

    The service account on your bastion host can now apply your public SSH key.

  3. Connect to the Linux bastion host instance. Replace EXTERNAL_INSTANCE_NAME with the name of the bastion host instance that you're using to gain access to the internal network.

    gcloud compute ssh EXTERNAL_INSTANCE_NAME
    
  4. From the Linux bastion host instance, use the gcloud compute ssh command with the --internal-ip flag to connect to instances using their internal IP addresses.

    gcloud compute ssh INTERNAL_INSTANCE_NAME --internal-ip
    

    Replace INTERNAL_INSTANCE_NAME with the name of the instance that you want to connect to.

After you connect, run commands on your instance using this terminal. When you finish, disconnect from the instance by running the exit command.

Linux and macOS

If you need to forward private keys to the bastion host instance, you must add your keys to the ssh-agent. Then, use either the gcloud compute ssh command or the ssh command to establish the initial connection to the bastion host and forward the keys in the SSH agent. This process works only on Linux and macOS workstations. If you need to forward private keys to a bastion host from a Windows workstation, follow the PuTTY instructions instead.

To connect to an instance without an external IP address from Linux or macOS workstations:

  1. Provide your public SSH key using one of the available options. Make sure you provide this public SSH key to both the Linux bastion host instance and the instance without an external IP address.

  2. On your local machine, start the ssh-agent to manage your SSH keys for you:

    eval ssh-agent $SHELL
    
  3. Use the ssh-add command to load your private SSH key from your local computer into the agent. Once added, SSH commands automatically use the private SSH key file for authentication.

    $ ssh-add ~/.ssh/PRIVATE_KEY
    

    Replace PRIVATE_KEY with the name of your private key file.

  4. In the Google Cloud console, go to the VM Instances page. In the External IP column, find the external IP address of the Linux bastion host instance. And in the Internal IP column, find the internal IP address of the internal instance that you want to connect to.

    Go to VM Instances

  5. Connect to the Linux bastion host instance using either ssh or gcloud compute ssh. For either option, include the -A argument to enable authentication agent forwarding.

    Connect to the Linux bastion host instance and forward your private keys with ssh:

    ssh -A USERNAME@BASTION_HOST_EXTERNAL_IP

    Replace the following:

    • USERNAME: the name attached to your SSH key.
    • BASTION_HOST_EXTERNAL_IP: the external IP address of the bastion host instance that you're using to gain access to the internal network.

    Alternatively, you can connect to the bastion host instance and forward your private keys using the gcloud compute ssh command. This option lets you connect to the bastion host instance using the Google Cloud CLI, and then use regular ssh with the forwarded credentials when you connect to internal IP addresses.

    gcloud compute ssh --ssh-flag="-A" BASTION_HOST_INSTANCE_NAME
    

    Replace BASTION_HOST_INSTANCE_NAME with the name of the bastion host instance that you're using to gain access to your internal network.

  6. From the Linux bastion host instance, use SSH to connect to the instance that doesn't have an external IP address:

    ssh USERNAME@INTERNAL_INSTANCE_IP_ADDRESS

    Replace the following:

    • USERNAME: the name attached to your SSH key.
    • INTERNAL_INSTANCE_IP_ADDRESS: the internal IP address of the instance that you want to connect to.

After you connect, run commands on your instance using this terminal. When you finish, disconnect from the instance by running the exit command.

Windows

To connect to an instance without an external IP address from Windows workstations:

  1. Provide your public SSH key using one of the available options. Make sure you provide this public SSH key to both the Linux bastion host instance and the instance without an external IP address.

  2. In the Google Cloud console, go to the VM Instances page. In the External IP column, find the external IP address of the Linux bastion host instance. And in the Internal IP column, find the internal IP address of the internal instance that you want to connect to.

    Go to VM Instances

  3. Connect to the Linux bastion host instance by using PuTTY. To pass your private SSH key to the bastion host, enable the Allow agent forwarding setting, as shown in the following screenshot:

    Allowing agent forwarding for the instance that you are connecting to.

  4. From the Linux bastion host instance, use SSH to connect to the instance that doesn't have an external IP address:

    ssh USERNAME@INTERNAL_IP_ADDRESS
    

    Replace the following:

    • USERNAME: the username of the user connecting to the instance. This must be the username you specified when you created the SSH key.
    • INTERNAL_IP_ADDRESS: the internal IP address of the instance that you want to connect to.

    After you connect, run commands on your instance using this terminal. When you finish, disconnect from the instance by running the exit command.

Connecting through Identity-Aware Proxy (IAP) for TCP

You can enable IAP TCP forwarding to establish an encrypted tunnel over which you can forward SSH connections to the VM.

To enable IAP TCP forwarding for VMs, do the following:

  1. Create a firewall rule to enable connections from IAP.
  2. Grant the required IAM permissions to enable IAP TCP forwarding.

To connect to VMs with IAP TCP forwarding enabled, tunnel SSH connections.

Connecting to instances as the root user

By default, public images and most common operating systems don't allow root login with a password over SSH. If a user requires root permissions, they can get those permissions by running commands through sudo.

In Compute Engine VMs, the /etc/ssh/sshd_config SSH configuration file has the PermitRootLogin parameter set to prohibit-password or no. When PermitRootLogin=prohibit-password, you can't connect to a VM as root, unless you specify an SSH key for root in your project or instance metadata. When PermitRootLogin=no, you can't connect even if you specify an SSH key for root in your project or instance metadata.

You can modify the PermitRootLogin parameter, however, we recommend running commands through sudo instead.

If you configured an instance to allow SSH as the root user and configure an SSH key for the root user on that instance, you can connect as root using the gcloud compute ssh command with root@ specified before the instance name:

gcloud compute ssh \
    --project=PROJECT_ID \
    --zone=ZONE \
    root@INSTANCE_NAME

Replace the following:

  • PROJECT_ID: the ID of the project that contains the instance
  • ZONE: the name of the zone in which the instance is located
  • INSTANCE_NAME: the name of the instance

Manually connecting between instances as a service account

In some situations, you might want to connect to instances and run commands as if you were the service account associated with that instance. The gcloud compute ssh command lets you use the SSH credentials of a service account to connect from one instance to another, letting you run commands on the second instance as the service account.

The Google Cloud CLI automatically generates an SSH key pair and associates it with the service account on your instance. After you connect to another instance as the service account, you can run additional gcloud commands using the service account's IAM permissions.

For this example, assume that you have the following environment:

  • Instance A:
    • Instance A has a service account associated with it.
    • The service account associated with Instance A has the necessary OS Login roles configured either at the project level or specifically for the Instance B resource.
    • The service account has the https://www.googleapis.com/auth/cloud-platform platform-wide scope on Instance A.
  • Instance B:
    • Instance B runs either on the same internal network as Instance A or on a network with firewall rules that allow SSH connections from Instance A.
    • The OS Login feature is enabled on your project or specifically on Instance B.
  • Your personal user account:
    • Your account has the roles/iam.serviceAccountUser role for the service account associated with Instance A.
    • Your account has SSH access specifically to Instance A.
    • Your account has no access to Instance B. The service account is the only account with OS Login roles necessary to connect to Instance B.

Connect to Instance A and execute commands as that service account. This step requires that you have the roles/iam.serviceAccountUser role for that service account:

  1. Connect to Instance A as the user with the roles/iam.serviceAccountUser role. For example, you can use the Google Cloud CLI to establish this first SSH connection:

    gcloud compute ssh instance-a --project=PROJECT_ID --zone=ZONE
  2. As long as you have the roles/iam.serviceAccountUser role, after you use SSH to connect to Instance A, you can execute commands as if you were the service account. In this example, run the gcloud CLI on Instance A to create a chain-SSH connection to Instance B. The gcloud CLI identifies that Instance B is enabled to use OS Login and also identifies that the service account has the necessary IAM roles for using SSH to connect to Instance B.

    gcloud compute ssh instance-b --project=PROJECT_ID --zone=ZONE

    The output is similar to the following:

    WARNING: Using OS Login user [sa_113491385848438711199] instead of default user [my-username]
    Linux instance-b 4.9.0-8-amd64 #1 SMP Debian 4.9.110-3+deb9u6 (2018-10-08) x86_64
    ⋮
    
  3. You are now connected to Instance B as the service account, and can execute commands as that service account—for example:

    sa_113491385848438711199@instance-b:~$ uname -a
    
    Linux instance-b 4.9.0-8-amd64 #1 SMP Debian 4.9.110-3+deb9u6 (2018-10-08) x86_64 GNU/Linux
    

What's next