Best practices for controlling SSH network access

This document describes best practices for controlling SSH network accessto Linux virtual machine (VM) instances.

To connect to a VM instance using SSH, a user needs network access to the VMinstance and valid SSH credentials. By default, Compute Engineuses a firewall rule thatdoesn't restrict SSH network access, but allows anybody on the internet toconnect to port22 of VM instances. While convenient for developers to getstarted quickly without considering network or security controls, allowing usersto connect from any device, network and location bears risks:

  • Users might connect from untrusted devices or networks.
  • Bad actors might launch brute force attacks and attempt to compromiseyour VM instances.
  • Bad actors with access to SSH credentials that were leaked or not revokedin time can use the credentials to access and sign in to a VM from any network.

The following sections describe how you can reduce risk by limiting the networks,locations, or devices from which users can establish SSH connection to your VMs:

The document focuses on practices that are either specific to Google Cloud orof particular relevance when using SSH on Google Cloud. The document doesn'tcover best practices for specific SSH client or server implementations.

Reduce network exposure

Allowing users to establish SSH connections from anywhere means that you arecompletely reliant on SSH authentication and authorization mechanisms to protectyour VMs. You can reduce risk and establish an additional layer of protection byreducing the network exposure of VMs.

There are multiple approaches to reducing the network exposure of your VMs.To identify the approach that's best suited to your environment, you must considera number of factors as illustrated by the following flowchart:

Reducing the network exposure

  • External access: The first factor to consider is whether the VM only needsto be accessible within the VPC network, or whether you need the VM to beaccessible externally too.

    If VPC-internal access is sufficient, then you don't need to assign an externalIP address to the VM, but you must still decide how to manage access.

  • Size of the internal network: If VPC-internal access is sufficient, thenthe second factor to consider is the size of your internal network.

    In smaller networks, it might be sufficient to use firewall rules that allowingress to port22 from internal addresses to help protect your VMs. Inlarger networks, relying on firewall rules alone might be too limiting:In such cases, you can benefit from usingIdentity-Aware Proxy TCP-forwardingto enforce context-aware access to VMs.

  • VPC Service Controls perimeter design: The next factor to consider is whether theVM instance is part of a VPC Service Controls perimeter.

    If the VM is part of a service perimeter, then any API access originatingfrom the VM is considered to originate from within the perimeter. When yougrant a user that's situated outside the perimeter SSH access to a VM insidethe perimeter, they can potentially copy data from the perimeter to theirlocal workstation, or the other way round – this can put the confidentiality andintegrity of your perimeter's data at risk.

    Whenever you need to grant SSH access to a VM instance that's part of aVPC Service Controls perimeter, useIAP TCP-forwarding.IAP detects whether the user's workstation is part of thesame VPC Service Controls perimeter and blocks access attempts from outsidethe service perimeter by default. To allow external access, useingress rules and configurethem toenforce context-aware access.

  • Management of client devices: The final factor to consider is how yourclient devices are managed, because that determines the ways in which you cancontrol context-aware access.

    Context-aware access is most effective whenAccess Context Managerhas access to a rich set of signals about a user, their device, and theirlocation and therefore works in conjunction with Chrome Enterprise Premium: If you useChrome Enterprise Premium to manage your devices, then you can set upaccess levels thatcontrol access based on device posture. You can then apply this access levelto SSH access by using IAP TCP-forwarding in combination withaccess bindingsorIAM conditions.

    If you don't control the configuration of a client device, you must considerit unmanaged and potentially untrusted.

    To allow access from unmanaged devices, you can also use IAPTCP-forwarding, but you can only manage access based on user's identity andthe device's IP address. Because Access Context Manager doesn't have access to anydevice signals, you won't be able to restrict access based on device posture.

Based on the factors and by using the flow-chart, you can identify which approach to reducenetwork exposure is best suited to your environment. The following sectionsdescribe these approaches in more detail.

IAP-based SSH access

The idea of this approach is to only allow SSH access throughIAP TCP-forwarding, and tolet IAP control access based on the user's identity.

We recommend this approach for VM instances for which the following applies:

  • The VM instance must be accessible externally or from a large internal network.
  • The VM isn't part of a VPC Service Controls perimeter.

By default, a VM instance with an external IP address allows SSH access becausedefault firewalls allow connections from the public internet to port 22, butthis is not a recommended approach. This approach can significantly increasethe risk that the VM becomes subject to attacks such as the following:

  • Usage of unrevoked credentials: Former employees whose access hasn't beenfully revoked might continue to access the VM.
  • Abuse of valid credentials: Bad actors in possession of stolen or leakedcredentials might use these to sign in.
  • Denial of service: Bad actors might attempt to exhaust the VM's resourcesby flooding it with requests.
Important: We don't recommend exposing SSH directly over the public internet.

A more secure way to enable external SSH access to a VM instance is to useIAP TCP-forwarding. Similar to a bastion host or reverse proxy,IAP TCP-forwarding acts as an intermediary between the clientdevice and the VM.

IAP TCP-forwarding performs the following four functions whena user attempts to establish an SSH connection:

  • Authentication: IAP verifies that the user possessesa valid Google credential.
  • Authorization: IAP checks IAM policiesto verify that the user has been granted permission to connect to the VMthrough IAP.
  • Context-aware access: Optionally, IAP can verify thatthe user, their device and location satisfies certain access levels.
  • Auditing: When data access logs are enabled, IAP logseach successful and failed attempt to connect to a VM instance.

By acting as an intermediary and performing these functions, IAPremoves the need to assign a external IP address to the VM and provides anadditional layer of security.

IAP-based context-aware SSH access

The idea of this approach is to only allow SSH access through IAPTCP forwarding, and to let IAP control access based on the user'sidentity and additional factors.

We recommend this approach for VM instances for which the following applies:

  • The VM instance must be accessible from outside the VPC and networks that areconnected to the VPC.
  • The VM isn't part of a VPC Service Controls perimeter.
  • The VM only needs to be accessible from certain devices, networks, or locations.

When you grant a user SSH access to a VM instance – whether directly or throughIAP – then, by default, they can access the VM instance from anydevice, network and location. While convenient for users, this level of accessincreases risks as users might be connecting from compromised devices oruntrusted networks.

To reduce risk, configure IAP TCP-forwarding so that users canonly access VM instances from certain devices or locations. You can configuresuch context-aware access in two ways:

  • Access bindings: You cancreate an access leveland assign it to a group by using anaccess binding.Access bindings are a form or identity-based policy and they apply to allresources that a user attempts to access – this includes IAP,but also other APIs and the Google Cloud console.

    Using access bindings works best if you want to ensure that context-aware accessis uniformly enforced across resources.

  • IAM conditions: You can create an access level and assignit to individual IAM role bindings by usingIAM conditions.

    Using IAM role bindings is a form of resource-based policyand the approach works best if you want to apply different policies todifferent sets of VMs.

Basic access levels let you limit access by network or geo-location. As aChrome Enterprise Premium subscriber, you can also limit access based on otherattributes such ascredential strength,the configuration of the browserthat's used for authentication, ordevice posture.

VPC Service Controls-based SSH access

The idea of this approach is to only allow SSH access through IAPTCP forwarding, and to configure the service perimeter to allow IAP ingress for certain identities our sources.

We recommend this approach for VM instances that are part of aVPC Service Controls perimeter.

Granting users external SSH access to a VM that's part of a service perimetercan be risky because it might allow users to undermine your VPC Service Controlsperimeter by exfiltrating data through SSH.

By only allowing SSH access through IAP TCP-forwarding, you canreduce this risk and ensure that all SSH access is subject to the configurationof your VPC Service Controls perimeter:

  • If a user attempts to connect from outside the service perimeter(as illustrated in the previous example), IAP TCP-forwardingnot only checks if the user is granted IAM access to the VM,but also checks if the request satisfies any of theperimeter's ingress rules.
  • If a user attempts to connect from inside the service perimeter, IAPTCP-forwarding also checks if the user is granted IAM accessto the VM, but ignores VPC Service Controls ingress rules.

    IAP considers a connection to originate from inside aservice perimeter if any of the following applies:

    • The source IP is the external IP address of a VM that's part ofthe service perimeter.
    • The connection is made through Private Google Access from a VM that'spart of the service perimeter.
    • The connection is made through a Private Service Connect access endpointthat's part of the service perimeter.

Firewall-controlled internal SSH access

The idea of this approach is to disallow all external access and to only allowVPC-internal SSH access.

You can use this approach for VM instances for which the following applies:

  • The VM instance doesn't need to be accessible externally.
  • The VM is connected to a small- to medium-sized internal network.
  • The VM isn't part of a VPC Service Controls perimeter.

To disallow all external access, you can do one of the following:

  • Deploy the VM instances without an external IP address.
  • Configure firewall rules so that ingress SSH trafficfrom IP ranges outside the VPC isn't allowed.

Disable serial console access

To troubleshoot malfunctioning VM instances, Compute Engine lets youconnect to an instance's serial port consolethrough an SSH gateway,ssh-serialport.googleapis.com.This gateway is publicly accessible over the internet.

The SSH gateway accesses the VM through the underlying hypervisor instead of theVPC network. Access to the serial console is therefore controlled byIAM policies and not by firewall rules.

Allowing users to access a VM serial console can unintentionally leave the VMoverexposed. To prevent this over-exposure, use thecompute.disableSerialPortAccessorganizational policy constraintto disable serial console access,and lift the constraint temporarily when you need emergency access to the VM's serial port.

Use a bastion VM if you need session recording

By acting as an intermediary between client devices and VMs, IAPTCP-forwarding performs functions that are commonly performed by bastion hosts orjump servers. These functions include:

  • Enforcing access policies in a centralized way
  • Auditing access

Unlike some bastion hosts, IAP TCP-forwarding doesn't terminateSSH connections: When you establish an SSH connection to a VM through IAPTCP-forwarding, the SSH connection is end-to-end encrypted between your clientand the VM. As a result of this end-to-end encryption, IAPTCP-forwarding can't inspect the contents of the SSH session, and doesn't providesession recording capabilities. The IAP audit logs containconnection metadata, but don't reveal any information about the contents of the session.

If you need session recording, use a bastion VM:

  • Configure the bastion VM so that it terminates SSH connections and recordsits contents. Make sure to restrict the use of SSH port forwarding as it mightundermine the effectiveness of session recording.
  • Set up firewall rules of target VMs so that SSH connections are only allowedfrom the bastion VM.
  • Allow access to the bastion VM through IAP TCP-forwarding only
Important: Bastion VMs that terminate SSH sessions can be a particularlyattractive target for bad actors, and you must secure the VM's configurationaccordingly.

Use firewall policies to restrict SSH exposure

After you determinewhich way to limit SSH exposureworks best for your environment, you must ensure that all VMs and projects areconfigured accordingly. In particular, you must ensure that all projects use aconsistent set of firewall rules that determine how SSH can be used.

To apply a set of firewall rules across multiple projects, usehierarchical firewall policies and applythem to folders in yourresource hierarchy.

For example, to help enforce that all SSH access is performed throughIAP TCP-forwarding, apply a firewall policy that includes thefollowing two custom rules (in order of priority):

  1. Allow ingress from35.235.240.0/20 to port 22 of selected VMs.35.235.240.0/20 is the IP range used by IAP TCP-forwarding.
  2. Deny ingress from0.0.0.0/0 to port 22 of all VMs.

What's next

Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2025-12-15 UTC.