turbot/steampipe-mod-oci-compliance

Control: 2.3 Ensure no network security groups allow ingress from 0.0.0.0/0 to port 22

Description

Network security groups provide stateful filtering of ingress/egress network traffic to OCI resources. It is recommended that no security group allows unrestricted ingress access to port 22.

Remediation

From Command Line

Execute the following command:

for region in `oci iam region list | jq -r '.data[] | .name'`;
do
for compid in `oci iam compartment list 2>/dev/null | jq -r '.data[] |
.id'`;
do
for nsgid in `oci network nsg list --compartment-id $compid -- region $region --all 2>/dev/null | jq -r '.data[] | .id'`
do
output=`oci network nsg rules list --nsg-id=$nsgid --all 2>/dev/null | jq -r '.data[] | select(.source == "0.0.0.0/0" and .direction == "INGRESS" and ((."tcp-options"."destination-port-range".max >= 22 and ."tcp-options"."destination-port-range".min <= 22) or ."tcpoptions"."destination-port-range" == null))'`
if [ ! -z "$output" ]; then echo "NSGID=", $nsgid, "Security Rules=", $output; fi
done
done
done
  • Remove the security rules
oci network nsg rules remove --nsg-id=<NSGID from audit output>

or

  • Update the security rules
oci network nsg rules update --nsg-id=<NSGID from audit output> --securityrules='[<updated security-rules JSON (without isValid and TimrCreated fields)>]'
eg:
oci network nsg rules update --nsgid=ocid1.networksecuritygroup.oc1.iad.xxxxxxxxxxxxxxxxxxxxxx --securityrules='[{ "description": null, "destination": null, "destination-type": null, "direction": "INGRESS", "icmp-options": null, "id": "709001", "is-stateless": null, "protocol": "6", "source": "140.238.154.0/24", "source-type": "CIDR_BLOCK", "tcp-options": { "destination-port-range": { "max": 22, "min": 22 }, "source-port-range": null }, "udp-options": null }]'

Usage

Run the control in your terminal:

powerpipe control run oci_compliance.control.cis_v110_2_3

Snapshot and share results via Turbot Pipes:

powerpipe login
powerpipe control run oci_compliance.control.cis_v110_2_3 --share

SQL

This control uses a named query:

with non_compliant_rules as (
select
id,
count(*) as num_noncompliant_rules
from
oci_core_network_security_group,
jsonb_array_elements(rules) as r
where
r ->> 'direction' = 'INGRESS'
and r ->> 'sourceType' = 'CIDR_BLOCK'
and r ->> 'source' = '0.0.0.0/0'
and (
r ->> 'protocol' = 'all'
or (
(r -> 'tcpOptions' -> 'destinationPortRange' ->> 'min')::integer <= 22
and (r -> 'tcpOptions' -> 'destinationPortRange' ->> 'max')::integer >= 22
)
)
group by id
)
select
nsg.id as resource,
case
when non_compliant_rules.id is null then 'ok'
else 'alarm'
end as status,
case
when non_compliant_rules.id is null then nsg.display_name || ' ingress restricted for SSH from 0.0.0.0/0.'
else nsg.display_name || ' contains ' || non_compliant_rules.num_noncompliant_rules || ' ingress rule(s) allowing SSH from 0.0.0.0/0.'
end as reason
, nsg.region as region, nsg.tenant_name as tenant
, coalesce(c.name, 'root') as compartment
from
oci_core_network_security_group as nsg
left join non_compliant_rules on non_compliant_rules.id = nsg.id
left join oci_identity_compartment c on c.id = nsg.compartment_id;

Tags