turbot/steampipe-mod-gcp-compliance

Control: 4.9 Ensure that Compute instances do not have public IP addresses

Description

Compute instances should not be configured to have external IP addresses.

To reduce your attack surface, Compute instances should not have public IP addresses. Instead, instances should be configured behind load balancers, to minimize the instance's exposure to the internet.

Remediation

To be able turn on Shielded VM on an instance, your instance must use an image with Shielded VM support.

From Console

  1. Login to VM instances.
  2. Click on the instance name to see its VM instance details page.
  3. Click EDIT
  4. For each Network interface, ensure that External IP is set to None.
  5. Click Done and then click Save.

From Command Line

  1. Describe the instance properties:
gcloud compute instances describe INSTANCE_NAME --zone=ZONE
  1. Identify the access config name that contains the external IP address. This access config appears in the following format:
networkInterfaces:
- accessConfigs:
- kind: compute#accessConfig
name: External NAT
natIP: 130.211.181.55
type: ONE_TO_ONE_NAT
  1. Delete the access config.
gcloud compute instances update INSTANCE_NAME --shielded-vm-secure-boot
  1. Restart the instance:
gcloud compute instances delete-access-config INSTANCE_NAME --zone=ZONE --access-config-name "ACCESS_CONFIG_NAME"

Note: In the above example, the ACCESS_CONFIG_NAME is External NAT. The name of your access config might be different.

Usage

Run the control in your terminal:

powerpipe control run gcp_compliance.control.cis_v120_4_9

Snapshot and share results via Turbot Pipes:

powerpipe login
powerpipe control run gcp_compliance.control.cis_v120_4_9 --share

SQL

This control uses a named query:

with instance_without_access_config as (
select
name
from
gcp_compute_instance,
jsonb_array_elements(network_interfaces) nic
where
nic ->> 'accessConfigs' is null
),
instance_with_access_config as (
select
name
from
gcp_compute_instance,
jsonb_array_elements(network_interfaces) nic,
jsonb_array_elements(nic -> 'accessConfigs') d
where
d ->> 'natIP' is null
)
select
self_link resource,
case
when name like 'gke-%' and labels ? 'goog-gke-node' then 'skip'
when name in (select name from instance_without_access_config) then 'ok'
when name in (select name from instance_with_access_config) then 'ok'
else 'alarm'
end as status,
case
when name like 'gke-%' and labels ? 'goog-gke-node'
then title || ' created by GKE.'
when name in (select name from instance_without_access_config) or name in (select name from instance_with_access_config)
then title || ' not associated with public IP addresses.'
else title || ' associated with public IP addresses.'
end as reason
, location as location, project as project
from
gcp_compute_instance;

Tags