Back to Checks
oraclecloud

Subnet has VCN flow logging enabled

network_vcn_subnet_flow_logs_enabled
Service: networkSeverity: medium
OfficialBuilt-inVerified
Categories:loggingforensics-ready
Resource Type:Subnet

OCI subnets in a VCN have network flow logging configured. Evaluation considers an active flowlogs configuration targeting the VCN or the specific subnet in the same region and associated with a log group.

Risk

Without flow logs, east-west and ingress/egress traffic is opaque, weakening detection and forensics. Scans, data exfiltration, and lateral movement can go unnoticed, undermining confidentiality and integrity, and delaying response to availability threats like DDoS.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler oraclecloud --checks network_vcn_subnet_flow_logs_enabled

Recommendation

Enable VCN flow logs for all subnets-prefer VCN-wide enablement for complete coverage-and route to centralized log groups. Enforce least privilege on log access, set retention, and integrate with a SIEM. Use capture filters and sampling to control volume. Review logs to support defense-in-depth.

Remediation

Terraform

# Enable VCN flow logs (covers all subnets in the VCN)
resource "oci_logging_log" "<example_resource_name>" {
  display_name = "<example_resource_name>"
  log_group_id = "<example_resource_id>"          # Existing Log Group OCID
  log_type     = "SERVICE"
  is_enabled   = true

  configuration {
    source {
      source_type = "OCISERVICE"
      service     = "flowlogs"                     # CRITICAL: enables VCN/Subnet flow logging
      resource    = "<example_resource_id>"       # CRITICAL: VCN OCID (use subnet OCID if enabling per-subnet)
      category    = "vcn"                          # CRITICAL: set to "vcn" (or "subnet" for subnet-level)
      parameters  = { capture_filter = "<example_resource_id>" }  # Capture Filter OCID
    }
  }
}

Other

1In OCI Console, go to Networking > Flow logs
2Click Enable flow logs
3Select a Log group (or create one) and a Capture filter (or create one)
4Click Next, then Add enablement points
5Choose Virtual cloud network and select your VCN (or choose Subnet and select the subnet)
6Click Add enablement points, then Next, then Enable flow logs

Check Code

"""Check Ensure VCN flow logging is enabled for all subnets."""

from prowler.lib.check.models import Check, Check_Report_OCI
from prowler.providers.oraclecloud.services.logging.logging_client import logging_client
from prowler.providers.oraclecloud.services.network.network_client import network_client


class network_vcn_subnet_flow_logs_enabled(Check):
    """Check Ensure VCN flow logging is enabled for all subnets."""

    def execute(self) -> Check_Report_OCI:
        """Execute the network_vcn_subnet_flow_logs_enabled check."""
        findings = []

        for subnet in network_client.subnets:
            report = Check_Report_OCI(
                metadata=self.metadata(),
                resource=subnet,
                region=subnet.region,
                resource_name=subnet.display_name,
                resource_id=subnet.id,
                compartment_id=subnet.compartment_id,
            )

            # Check if subnet has flow logs enabled (either at VCN or subnet level)
            has_flow_logs = False

            # Check for VCN-level flow logs
            for log in logging_client.logs:
                if (
                    log.source_service == "flowlogs"
                    and log.source_resource
                    and subnet.vcn_id in log.source_resource
                    and log.region == subnet.region
                    and log.is_enabled
                ):
                    has_flow_logs = True
                    break

            # If no VCN-level logs, check for subnet-level flow logs
            if not has_flow_logs:
                for log in logging_client.logs:
                    if (
                        log.source_service == "flowlogs"
                        and log.source_resource
                        and subnet.id in log.source_resource
                        and log.region == subnet.region
                        and log.is_enabled
                    ):
                        has_flow_logs = True
                        break

            if has_flow_logs:
                report.status = "PASS"
                report.status_extended = (
                    f"Subnet {subnet.display_name} has flow logging enabled."
                )
            else:
                report.status = "FAIL"
                report.status_extended = (
                    f"Subnet {subnet.display_name} does not have flow logging enabled."
                )

            findings.append(report)

        return findings