Using IAP for TCP forwarding

This page explains how to use tunnel permissions and encrypted tunnels to control access to administrative services, like SSH and RDP, on your backends. Tunnel permissions let you control access through Cloud IAM, while encrypted tunnels let you control access through Identity-Aware Proxy (IAP) by routing TCP traffic through IAP before sending it to your Compute Engine instances.

You don't need a publicly routable IP address assigned to your instances to use IAP.

To learn more about how IAP handles TCP forwarding, see the TCP forwarding overview.

Before you begin

Before you begin, you need the following:

  • User or group names that you want to grant access to.
  • A firewall that allows connections from IAP's TCP forwarding IP addresses to the TCP port of your resource's admin service. To properly configure your firewall, adjust your firewall rules to allow access from IAP's TCP forwarding netblock, 35.235.240.0/20, on all ports of your machine. Note: If the default-allow-ssh and default-allow-rdp default rules are applied to ports used for SSH and RDP, you may not need to adjust your firewall rules.

    Open the Firewall Rules page

Configuring the OAuth consent screen

If you haven't configured your project's OAuth consent screen, you'll be prompted to do so. An email address and product name are required for the OAuth consent screen.

  1. Go to the OAuth consent screen.
    Configure consent screen
  2. Under Support email, select the email address you want to display as a public contact. This email address must be your email address, or a Google Group you own.
  3. Enter the Application name you want to display.
  4. Add any optional details you'd like.
  5. Click Save.

To change information on the OAuth consent screen later, such as the product name or email address, repeat the preceding steps to configure the consent screen.

Configuring access and permissions

Cloud Identity and Access Management (Cloud IAM) permissions let you manage access control when setting up TCP forwarding with IAP.

To set Cloud IAM permissions for IAP tunnels, complete the following steps:

Console

  1. View your SSH and TCP resources by going to the Identity-Aware Proxy page and selecting SSH and TCP Resources tab.

    Open the IAP admin page

  2. Update member permissions on resources by selecting the checkbox next to resources. This can be set per zone name or per whole project by selecting the region or All Tunnel Resources checkboxes.
  3. On the right side Info panel, click Add member.
  4. Specify which users and groups you want to grant access by adding them to the New members field.
  5. Grant the members access to the tunneled resources by opening the Select a role drop-down list and selecting Cloud IAP > IAP-Secured Tunnel User. Note that if a member has the Owner role, they have permission to use IAP for TCP forwarding.
  6. Optionally, add member restrictions by clicking Add condition and entering the condition Title and Expression.

    For example, by setting Expression to a CEL expression that uses destination.ip and destination.port Cloud IAM conditions, you can limit access to only members on port 22 or to members who have a private IP of 10.0.0.1:

    destination.ip == "10.0.0.1" || destination.port == 22
    

    Access levels can also be used to restrict access with the following CEL expression:

    "FULL_ACCESS_LEVEL_NAME" in request.auth.access_levels
    

    Where FULL_ACCESS_LEVEL_NAME is accessPolicies/POLICY_NAME/accessLevels/ACCESS_LEVEL_NAME.

    To find the full name of an access level:

    1. Open the Access Context Manager page.

      Open the Access Context Manager page

    2. Click on the name of the access level.

    The full Access level name is now displayed on the right side panel in the following format:

  7. Click Save.

gcloud

  1. Open the Cloud IAM policy for the app using the following gcloud command:

    gcloud projects get-iam-policy PROJECT_ID > policy.yaml

  2. Grant the iap.tunnelResourceAccessorrole to your members by modifying the Cloud IAM policy YAML file. Note that if a member has the Owner role, they have permission to use IAP for TCP forwarding.

    The following is an example of an edited policy.yaml file that binds the iap.tunnelResourceAccessor role to a group of VM instance admins, granting them access to IAP-secured tunnel resources.


    Example policy.yaml file

    ...
    - members:
      - group:instance-admins@example.com
      role: roles/iap.tunnelResourceAccessor
    ...

    Optionally, set access level conditions at the project level with Cloud IAM conditions. To use Cloud IAM conditions, join the Private Beta.

  3. Bind the policy to the app using the set-iam-policy command.

    gcloud projects set-iam-policy PROJECT_ID policy.yaml

To grant a member the iap.tunnelResouceAccessor role without editing the policy.yaml file, call the following command.

gcloud projects add-iam-policy-binding PROJECT_ID \
   --member=user:EXAMPLE_USER@EXAMPLE.COM \
   --role=roles/iap.tunnelResourceAccessor

API

To edit your application's policy.json file, follow the process below. See Managing access to IAP-secured resources for more information about using the Cloud IAM API to manage access policies.

  1. Download the credentials file for your service account.

    1. Go to the Service accounts page.
      Go to the service accounts page

    2. Click the email address of your service account.

    3. Click Edit.

    4. Click Create key.

    5. Select JSON as your key type.

    6. Create a new key by clicking Create and closing the confirmation window that appears.

    Your JSON credentials file has now been downloaded.

  2. Export the following variables.

    export IAP_BASE_URL=https://iap.googleapis.com/v1/projects/PROJECT_NUMBER/iap_tunnel
    # Replace with the path to your local service account's downloaded JSON file
    export JSON_CREDS=EXAMPLE.IAM.GSERVICEACCOUNT.COM.JSON
    # Replace POLICY_FILE.JSON with the name of JSON file to use for setIamPolicy
    export JSON_NEW_POLICY=POLICY_FILE.JSON
    

  3. Convert your service account credentials JSON file into an OAuth access token using Oauth2l by running the following command:

    oauth2l header --json ${JSON_CREDS} cloud-platform

  4. If this is your first time running the above command, when prompted:

    1. Get the verification code by clicking the displayed link and copying the code.
    2. Paste the verification code into your app prompt.
    3. Copy the returned bearer token.
    4. Export a new variable that's assigned to the value of your returned bearer token.
      export CLOUD_OAUTH_TOKEN=AUTHORIZATION_BEARER_TOKEN
  5. If you've run this command before, export the following variable.

    export CLOUD_OAUTH_TOKEN="$(oauth2l header --json ${JSON_CREDS} cloud-platform)"

  6. Get the Cloud IAM policy for the Compute Engine instance using the getIamPolicy method. The empty data bit at the end turns the curl request into POST instead of GET.

    curl -i -H "${CLOUD_OAUTH_TOKEN}" \
         ${IAP_BASE_URL}/zones/ZONE_NAME/instances/INSTANCE_ID or INSTANCE_NAME:getIamPolicy \
         -d ''

  7. Grant the iap.tunnelResourceAccessor role to your members by modifying the Cloud IAM policy JSON file.

  8. Optionally, add member restrictions based on Cloud IAM Conditions and access levels.

    The following is an example of an edited policy.json file that binds the iap.tunnelResourceAccessor role to a group of VM instance admins, granting them access to IAP-secured tunnel resources. A Cloud IAM condition has been added to make the resources accessible only to members in the VM instance admins group with a private IP address of 10.0.0.1 on port 22 using the destination.ip and destination.port Cloud IAM Conditions. They must also meet the requirements of the ACCESS_LEVEL_NAME access level.

    Note that if a member has the Owner role, they have permission to use IAP for TCP forwarding.


    Example policy.json file

    {
      "policy": {
        "bindings": [
          {
            "role": "roles/iap.tunnelResourceAccessor",
            "members": ["group:instance-admins@example.com"],
            "condition": {
              "expression": "\"accessPolicies/POLICY_NAME/accessLevels/ACCESS_LEVEL_NAME\" in request.auth.access_levels && destination.ip == \"10.0.0.1\" && destination.port == 22",
              "title": "CONDITION_NAME"
            }
          }
        ]
      }
    }

    To find a policy name , call accessPolicies.list:

    GET https://accesscontextmanager.googleapis.com/v1/accessPolicies
    
  9. Set your new policy.json file using the setIamPolicy method.

    curl -i -H "Content-Type:application/json" \
         -H "$(oauth2l header --json ${JSON_CREDS} cloud-platform)" \
         ${IAP_BASE_URL}/zones/ZONE_NAME/instances/INSTANCE_ID or INSTANCE_NAME:setIamPolicy \
         -d @${JSON_NEW_POLICY}
    

Tunneling

Create encrypted tunnels to forward TCP traffic through IAP, traffic you to apply IAP access controls to the traffic.

General TCP tunneling

IAP's TCP forwarding feature handles TCP traffic by allocating a local port. The local port tunnels data traffic from the local machine to the remote machine in an HTTPS stream. IAP then receives the data, applies access controls, and forwards the unwrapped data to the remote port. Conversely, any data from the remote port is also wrapped before it's sent to the local port where it's then unwrapped.

The command below creates an encrypted tunnel between the local machine and the remote resource, specified by its instance name. The command also prompts IAP's TCP forwarding feature to listen for connections on localhost:LOCAL_PORT. Remove the local-host-port flag from the command if you want a random local port selected.

gcloud compute start-iap-tunnel INSTANCE_NAME INSTANCE_PORT \
  --local-host-port=localhost:LOCAL_PORT

Where:

  • INSTANCE_NAME is the name of the instance to operate on.
  • INSTANCE_PORT is the name or number of the instance's port to connect to.
  • LOCAL_PORT is the port to which the proxy is bound.

Tunneling with SSH

Using SSH with IAP's TCP forwarding feature doesn't require the mapping of a local port. The SSH connection is instead directly wrapped inside HTTPS and sent by IAP's TCP forwarding to the remote instance. This feature lets you connect to instances that don't have a public IP address.

Console

To connect to your instance, use the SSH button in the Cloud Console. Your instance's access configuration must allow TCP tunneling through IAP.

gcloud

To connect to your instance, use the gcloud compute ssh command. Your instance's access configuration must allow TCP tunneling through IAP.

gcloud beta compute ssh INSTANCE_NAME

Where:

  • INSTANCE_NAME is the name of the instance to SSH into.

If the instance doesn't have a public IP address, the connection automatically uses IAP TCP tunneling. If the instance does have a public IP address, the connection uses the public IP address instead of IAP TCP tunneling.

If you specify the --tunnel-through-iap flag, gcloud compute ssh will always use IAP TCP tunneling.

If you specify the --internal-ip flag, gcloud compute ssh will never use IAP TCP tunneling.

Known limitations

Bandwidth: IAP's TCP forwarding feature isn't intended for bulk transfer of data. IAP reserves the right to rate-limit users abusing this service.

Connection length: IAP doesn't disconnect active sessions unless required for maintenance. We recommend having logic in your applications to handle reestablishing a tunnel when it becomes disconnected.

Next steps

Was this page helpful? Let us know how we did:

Send feedback about...

Identity-Aware Proxy Documentation