> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# OCI Network Security Rules Should Not Allow All Ports

### More Info:

Network Security Groups should not have rules allowing all ports (1-65535) or all protocols. Such rules effectively disable network-level access control.

### Risk Level

Medium

### Address

Compliance, Security

### Compliance Standards

* APRA CPS 234 (Australia)
* BSI C5 (Germany)
* Brazil LGPD
* CCPA / CPRA (California)
* CIS Critical Security Controls v8
* CMMC 2.0
* CSA Cloud Controls Matrix v4
* DPDPA
* Digital Operational Resilience Act (EU)
* ISO/IEC 27017
* ISO/IEC 27018
* ISO/IEC 27701
* KSA PDPL
* MAS Technology Risk Management (Singapore)
* MITRE ATT\&CK (Cloud)
* NIS2 Directive
* NIST
* NIST SP 800-171
* NYDFS 23 NYCRR 500
* SWIFT Customer Security Controls Framework
* Sarbanes-Oxley IT General Controls
* Securities and Exchange Board of India (SEBI) - Cloud Security Adoption Framework
* UK NCSC Cyber Assessment Framework

### Triage and Remediation

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        To remediate “OCI Network Security Rules Should Not Allow All Ports” using the OCI Console, you need to find and fix any security list or NSG rule where the destination port is set to “all” (0–65535 or left blank).

        Below are the practical steps.

        ***

        ## 1. Identify non‑compliant rules

        ### A. From Cloud Guard (if you’re using it)

        1. In the OCI Console, open the **☰ menu**.
        2. Go to **Security → Cloud Guard**.
        3. Click **Detections** (or **Problems**).
        4. Filter by:
           * **Resource type**: *Security List* or *Network Security Group*
           * Or search text: `port`, `0-65535`, `all ports`, or similar.
        5. Open each problem to see:
           * Compartment
           * VCN
           * Security List or NSG name
           * Offending rule (protocol/ports/source/destination)

        ### B. Manually via Networking (if Cloud Guard not in use)

        1. Go to **☰ → Networking → Virtual Cloud Networks**.
        2. For each relevant **VCN**, check both:
           * **Security Lists**
           * **Network Security Groups**

        You’re looking for any rule where:

        * Protocol = `TCP`, `UDP`, or `All`, and
        * Destination port is a range like `0-65535`, `1-65535`, or left as “all”.

        ***

        ## 2. Fix Security List rules

        1. Go to **☰ → Networking → Virtual Cloud Networks**.
        2. Click the **VCN** that contains the bad rule.
        3. In the left pane, click **Security Lists**.
        4. Click the **Security List** name.
        5. Under:
           * **Ingress Rules**: to fix incoming rules.
           * **Egress Rules**: to fix outgoing rules.
        6. Click **Edit All Rules** (or **Add Ingress Rule / Add Egress Rule** as needed).

        For each non-compliant rule:

        * Note what it is being used for (SSH, HTTP, DB, etc.).
        * Decide the **specific port(s)** required (e.g., 22, 80, 443, 1521).

        Then either:

        * **Option 1 – Replace the rule (recommended):**
          1. Delete the “all ports” rule from the list.
          2. Add **one or more new rules** with:
             * **Source** (ingress) or **Destination** (egress) narrowed (CIDR or specific subnet).
             * **IP Protocol** = `TCP`/`UDP` (avoid `All` if not required).
             * **Destination Port Range** = the specific port or small port range (e.g., `22`, `443`, `1024-1040`).

        * **Option 2 – Narrow the port range:**
          * If you cannot yet fully restrict to single ports, change the **Destination Port Range** from `0-65535` to a minimal necessary range.

        7. Click **Save Changes**.

        Repeat for **each** security list with an all-ports rule.

        ***

        ## 3. Fix Network Security Group (NSG) rules

        1. Go to **☰ → Networking → Virtual Cloud Networks**.
        2. Click the **VCN**.
        3. Click **Network Security Groups**.
        4. Click the **NSG** name.
        5. Check:
           * **Ingress Rules**
           * **Egress Rules**

        For every rule with all ports open:

        1. Click the **Actions** menu (three dots) next to the rule and choose **Remove**.
        2. Click **Add Ingress Rule** or **Add Egress Rule** to re-create a restricted rule:
           * **Source Type/Destination Type**: CIDR, NSG, or Service.
           * **Source/Destination**: Narrow as much as possible.
           * **IP Protocol**: Prefer `TCP` or `UDP`, not `All`.
           * **Destination Port Range**: Enter the exact port or narrow range (e.g., `22`, `443`, `1433`, etc.).
        3. Click **Add Ingress Rule** / **Add Egress Rule** to save.

        Repeat for all NSGs with all-ports rules.

        ***

        ## 4. Validate using Monitoring / Cloud Guard

        1. If Cloud Guard is enabled:
           * Go to **☰ → Security → Cloud Guard → Detections**.
           * Confirm the earlier problems are now **Resolved** or in a non-failing state after the next evaluation cycle.

        2. Optionally, use:
           * **VCN Flow Logs** or **Network Monitoring** features to verify legitimate traffic still works.
           * Connectivity tests (SSH, HTTP, application checks).

        ***

        ## 5. General hardening tips (brief)

        * Never leave:
          * Ingress: `0.0.0.0/0` to `All Protocols` on `All Ports`.
          * Wide open egress rules to all destinations on all ports from sensitive subnets.
        * Use:
          * Minimal required ports.
          * Private CIDRs or specific NSGs as source/destination instead of public `0.0.0.0/0` where possible.
          * Separate NSGs per application tier (web, app, DB) to keep rules tight.

        If you share an example of an existing rule (source, protocol, current port range, and what it’s used for), I can give you an exact “before and after” rule set to apply in the console.
      </Accordion>

      <Accordion title="Using CLI">
        Below is a practical, CLI‑only way to **identify and remediate “allow all ports” rules** in OCI network security lists and NSGs.

        ***

        ## 1. Prerequisites

        * OCI CLI installed and configured (`oci setup config`)
        * Your **compartment OCID** handy: `ocid1.compartment.oc1...`

        Set a helper variable:

        ```bash theme={null}
        COMPARTMENT_ID="<your_compartment_ocid>"
        ```

        ***

        ## 2. Identify Problem Rules

        ### 2.1. Security Lists

        List all security lists in the compartment:

        ```bash theme={null}
        oci network security-list list \
          --compartment-id "$COMPARTMENT_ID" \
          --all
        ```

        For each security list OCID, inspect rules:

        ```bash theme={null}
        SEC_LIST_ID="<security_list_ocid>"

        oci network security-list get \
          --security-list-id "$SEC_LIST_ID" \
          --query 'data."ingress-security-rules"'
        ```

        You’re looking for rules with:

        * `0.0.0.0/0` or wide CIDR (e.g., `0.0.0.0/0`, `::/0`)
        * `protocol = "all"` **or** `tcpOptions` / `udpOptions` with:
          * `destination-port-range.min = 1` and `max = 65535` (or missing = all ports)

        Repeat with egress if required:

        ```bash theme={null}
        oci network security-list get \
          --security-list-id "$SEC_LIST_ID" \
          --query 'data."egress-security-rules"'
        ```

        ***

        ### 2.2. Network Security Groups (NSGs)

        List NSGs:

        ```bash theme={null}
        oci network nsg list \
          --compartment-id "$COMPARTMENT_ID" \
          --all
        ```

        For each NSG:

        ```bash theme={null}
        NSG_ID="<nsg_ocid>"

        oci network nsg rules list \
          --network-security-group-id "$NSG_ID" \
          --all
        ```

        Again, identify rules that:

        * Allow from `0.0.0.0/0` or `::/0`
        * Have `protocol = "all"` or full port ranges (1–65535)

        ***

        ## 3. Remediate Security List Rules (CLI)

        You **cannot partially edit a single rule** on security lists; you must update the list with a new JSON definition of rules.

        ### 3.1. Export Existing Security List

        ```bash theme={null}
        SEC_LIST_ID="<security_list_ocid>"

        oci network security-list get \
          --security-list-id "$SEC_LIST_ID" \
          --query 'data' > sec-list.json
        ```

        `sec-list.json` will look roughly like:

        ```json theme={null}
        {
          "id": "ocid1.securitylist.oc1....",
          "display-name": "my-security-list",
          "ingress-security-rules": [
            {
              "source": "0.0.0.0/0",
              "protocol": "6",
              "tcp-options": {
                "destination-port-range": {
                  "min": 1,
                  "max": 65535
                }
              }
            }
          ],
          "egress-security-rules": [
            {
              "destination": "0.0.0.0/0",
              "protocol": "all"
            }
          ],
          ...
        }
        ```

        ### 3.2. Edit the JSON Locally

        * **Remove** any “allow all ports” rules, or
        * **Narrow** to specific ports (e.g., 80 and 443) and/or CIDRs.

        Example corrected ingress rule for HTTP/HTTPS only:

        ```json theme={null}
        "ingress-security-rules": [
          {
            "source": "0.0.0.0/0",
            "protocol": "6",
            "tcp-options": {
              "destination-port-range": {
                "min": 80,
                "max": 80
              }
            }
          },
          {
            "source": "0.0.0.0/0",
            "protocol": "6",
            "tcp-options": {
              "destination-port-range": {
                "min": 443,
                "max": 443
              }
            }
          }
        ]
        ```

        When done, keep only fields expected by the update API. Safest: build a minimal JSON like:

        ```json theme={null}
        {
          "ingressSecurityRules": [
            {
              "source": "0.0.0.0/0",
              "protocol": "6",
              "tcpOptions": {
                "destinationPortRange": {
                  "min": 80,
                  "max": 80
                }
              }
            },
            {
              "source": "0.0.0.0/0",
              "protocol": "6",
              "tcpOptions": {
                "destinationPortRange": {
                  "min": 443,
                  "max": 443
                }
              }
            }
          ],
          "egressSecurityRules": [
            {
              "destination": "0.0.0.0/0",
              "protocol": "6",
              "tcpOptions": {
                "destinationPortRange": {
                  "min": 443,
                  "max": 443
                }
              }
            }
          ]
        }
        ```

        Save as `sec-list-update.json`.

        ### 3.3. Apply the Update

        ```bash theme={null}
        oci network security-list update \
          --security-list-id "$SEC_LIST_ID" \
          --from-json file://sec-list-update.json
        ```

        Repeat for each affected security list.

        ***

        ## 4. Remediate NSG Rules (CLI)

        With NSGs, you can **add or delete individual rules**.

        ### 4.1. Delete “Allow All Ports” Rule

        First list rules with OCIDs:

        ```bash theme={null}
        oci network nsg rules list \
          --network-security-group-id "$NSG_ID" \
          --all
        ```

        Find the offending rule, note its `id`:

        ```bash theme={null}
        RULE_ID="<nsg_rule_ocid>"

        oci network nsg rules delete \
          --network-security-group-id "$NSG_ID" \
          --security-rule-id "$RULE_ID" \
          --force
        ```

        ### 4.2. Add Restrictive Rule(s)

        Example: allow inbound TCP 22 from a specific admin subnet only:

        ```bash theme={null}
        oci network nsg rules add \
          --network-security-group-id "$NSG_ID" \
          --security-rules '[
            {
              "direction": "INGRESS",
              "protocol": "6",
              "source": "10.0.0.0/24",
              "isStateless": false,
              "tcpOptions": {
                "destinationPortRange": {
                  "min": 22,
                  "max": 22
                }
              }
            }
          ]'
        ```

        Adjust `source`, ports, and direction as needed.

        ***

        ## 5. Tie to Monitoring / Cloud Guard

        If this finding came from **Cloud Guard**:

        * After fixing rules, you can **re-evaluate** problems or wait for the next assessment.
        * Optionally, configure a **Responder Recipe** in Cloud Guard that:
          * Detects rules with `0.0.0.0/0` + all ports / all protocols.
          * Triggers a responder that removes or restricts those rules (if you want automation).

        This configuration is usually done via Console, but can also be managed with `oci cloud-guard` CLI commands if needed.

        ***

        If you paste one example of a current security list / NSG rule JSON, I can give you an exact before/after JSON and CLI line for that specific rule.
      </Accordion>

      <Accordion title="Using Python">
        Below is a practical way to **detect and remediate “allow all ports” rules in OCI Network Security** using Python and the OCI SDK.

        We’ll:

        1. Identify which objects to scan (Security Lists and/or Network Security Groups).
        2. Detect rules that allow “all ports”.
        3. Update them to a more restrictive configuration (or at least flag them).

        ***

        ## 0. Prerequisites

        1. Install the OCI Python SDK:

        ```bash theme={null}
        pip install oci
        ```

        2. Have your OCI config file in place (typically `~/.oci/config`) with a profile, e.g. `[DEFAULT]`.

        3. Know:
           * The **compartment OCID** you want to scan.
           * Whether you want to check **Security Lists**, **NSGs**, or both.

        ***

        ## 1. Logic to Detect “Allow All Ports” Rules

        In OCI, “allow all ports” is usually:

        * `tcp_options` or `udp_options`:
          * Either `destination_port_range` missing (means any port), or
          * `destination_port_range.min == 1` and `max == 65535` (or 0–65535 in older configs).
        * OR protocol == `"all"` / `"all"` in security lists.
        * Source CIDR often `"0.0.0.0/0"`, but even non-0.0.0.0/0 can be too broad depending on your policy.

        You may need to refine your **exact** detection criteria based on your security policy (e.g., only flag 0.0.0.0/0).

        ***

        ## 2. Python Script: Scan and Remediate Security Lists

        This example:

        * Lists all Security Lists in a compartment.
        * Finds ingress rules that:
          * Source is `0.0.0.0/0`, and
          * Protocol is `6` (TCP) or `17` (UDP) or `"all"`, and
          * Ports are unrestricted.
        * **Remediation example**: removes those rules or replaces them with a specific allowed port (e.g., 22).

        Adjust to your needs.

        ```python theme={null}
        import oci

        # CONFIG
        PROFILE = "DEFAULT"  # OCI CLI profile
        COMPARTMENT_ID = "<your_compartment_ocid>"
        DRY_RUN = True  # Set False to apply changes
        RESTRICT_TO_PORT = 22  # Example target port for remediation (SSH)

        config = oci.config.from_file("~/.oci/config", PROFILE)
        network_client = oci.core.VirtualNetworkClient(config)

        def is_all_ports_ingress(rule):
            """
            Determine if an ingress rule effectively allows all ports.
            Adjust logic per your policy.
            """
            # Only inspect 'ALLOW' rules
            if rule.action != "ALLOW":
                return False

            # Focus on public ingress from anywhere
            if rule.source != "0.0.0.0/0":
                return False

            # Protocol "all"
            if rule.protocol == "all":
                return True

            # TCP = 6, UDP = 17
            if rule.protocol not in ["6", "17"]:
                return False

            # Get tcp_options or udp_options
            opts = rule.tcp_options if rule.protocol == "6" else rule.udp_options

            # No options means all ports
            if not opts:
                return True

            if not opts.destination_port_range:
                return True

            min_port = opts.destination_port_range.min
            max_port = opts.destination_port_range.max

            # Heuristic: min 1, max 65535 => essentially all ports
            if min_port <= 1 and max_port >= 65535:
                return True

            return False

        def build_restricted_rule(rule, port):
            """
            Build a new rule restricted to a specific port.
            You can customize this to suit your needs.
            """
            # Clone the rule but constrain the port
            # For "all" protocol, we’ll restrict only TCP here, adjust as needed.
            if rule.protocol == "all" or rule.protocol == "6":
                proto = "6"
                tcp_options = oci.core.models.TcpOptions(
                    destination_port_range=oci.core.models.PortRange(
                        min=port,
                        max=port
                    )
                )
                udp_options = None
            elif rule.protocol == "17":
                proto = "17"
                tcp_options = None
                udp_options = oci.core.models.UdpOptions(
                    destination_port_range=oci.core.models.PortRange(
                        min=port,
                        max=port
                    )
                )
            else:
                # For other protocols, just return as is or skip
                return rule

            return oci.core.models.IngressSecurityRule(
                protocol=proto,
                source=rule.source,
                is_stateless=rule.is_stateless,
                source_type=rule.source_type,
                description=f"RESTRICTED: {rule.description or ''}".strip(),
                tcp_options=tcp_options,
                udp_options=udp_options
            )

        def remediate_security_lists():
            print(f"Scanning Security Lists in compartment: {COMPARTMENT_ID}")
            sls = oci.pagination.list_call_get_all_results(
                network_client.list_security_lists,
                compartment_id=COMPARTMENT_ID
            ).data

            for sl in sls:
                print(f"\nSecurity List: {sl.display_name} ({sl.id})")

                original_ingress = sl.ingress_security_rules or []
                bad_rules = [r for r in original_ingress if is_all_ports_ingress(r)]

                if not bad_rules:
                    print("  No 'allow all ports' ingress rules found.")
                    continue

                print(f"  Found {len(bad_rules)} overly permissive ingress rule(s).")

                # Create new ingress rules list without bad rules
                new_ingress = []
                for r in original_ingress:
                    if r in bad_rules:
                        print(f"    Will modify/remove rule: {r}")
                        # Example: restrict to a given port
                        new_rule = build_restricted_rule(r, RESTRICT_TO_PORT)
                        if new_rule:
                            new_ingress.append(new_rule)
                            print(f"      -> Replaced with restricted rule on port {RESTRICT_TO_PORT}")
                        # Or you could simply skip adding it to remove it
                        # (i.e., delete the rule entirely).
                    else:
                        new_ingress.append(r)

                if DRY_RUN:
                    print("  DRY_RUN enabled: not applying changes.")
                else:
                    print("  Updating security list...")
                    update_details = oci.core.models.UpdateSecurityListDetails(
                        ingress_security_rules=new_ingress,
                        egress_security_rules=sl.egress_security_rules
                    )
                    network_client.update_security_list(
                        security_list_id=sl.id,
                        update_security_list_details=update_details
                    )
                    print("  Update complete.")

        if __name__ == "__main__":
            remediate_security_lists()
        ```

        ***

        ## 3. Python Script: Scan and Remediate NSG Security Rules (Optional)

        If you’re using NSGs, similar logic applies, but using `NetworkSecurityGroupRulesClient`.

        Skeleton:

        ```python theme={null}
        from oci.core import VirtualNetworkClient, NetworkSecurityGroupRulesClient
        from oci.core.models import UpdateNetworkSecurityGroupSecurityRulesDetails

        config = oci.config.from_file("~/.oci/config", PROFILE)
        vcn_client = VirtualNetworkClient(config)
        nsg_rules_client = NetworkSecurityGroupRulesClient(config)

        def remediate_nsgs():
            nsgs = oci.pagination.list_call_get_all_results(
                vcn_client.list_network_security_groups,
                compartment_id=COMPARTMENT_ID
            ).data

            for nsg in nsgs:
                print(f"\nNSG: {nsg.display_name} ({nsg.id})")

                rules = oci.pagination.list_call_get_all_results(
                    nsg_rules_client.list_network_security_group_security_rules,
                    network_security_group_id=nsg.id
                ).data

                bad_rules = [r for r in rules if is_all_ports_ingress(r) and r.direction == "INGRESS"]
                if not bad_rules:
                    print("  No 'allow all ports' ingress rules found.")
                    continue

                print(f"  Found {len(bad_rules)} overly permissive ingress rule(s).")

                # Build patch: remove / replace the bad rules
                # NOTE: NSG rule updates use `UpdateNetworkSecurityGroupSecurityRulesDetails`
                # with `security_rules` list including all desired rules.
                new_rules = []
                for r in rules:
                    if r in bad_rules:
                        print(f"    Will modify/remove rule: {r.id}")
                        new_rule = build_restricted_rule(r, RESTRICT_TO_PORT)
                        if new_rule:
                            new_rules.append(new_rule)
                    else:
                        new_rules.append(r)

                if DRY_RUN:
                    print("  DRY_RUN enabled: not applying changes.")
                else:
                    print("  Updating NSG rules...")
                    update_details = UpdateNetworkSecurityGroupSecurityRulesDetails(
                        security_rules=new_rules
                    )
                    nsg_rules_client.update_network_security_group_security_rules(
                        network_security_group_id=nsg.id,
                        update_network_security_group_security_rules_details=update_details
                    )
                    print("  Update complete.")
        ```

        (You’ll need to slightly adapt `is_all_ports_ingress` and `build_restricted_rule` for NSG rule models, but the concepts are identical.)

        ***

        ## 4. Operationalizing as “Monitoring”

        To make this actual “monitoring” for OCI networking:

        1. **Run this script on a schedule**:
           * Use a cron job on a bastion/management host or
           * Use **OCI Functions + Events** (triggered on `CreateNetworkSecurityGroupSecurityRules`, `UpdateSecurityList`, etc.).
        2. Start with `DRY_RUN = True` to log-only.
        3. Send findings to:
           * OCI Logging,
           * Email (via OCI Notifications),
           * SIEM, etc.
        4. After validating, switch to `DRY_RUN = False` to auto-remediate.

        ***

        If you specify:

        * Exact allowed ports,
        * Whether to **delete** or **tighten** rules,
          I can tailor the code to your precise security policy.
      </Accordion>

      <Accordion title="Using Terraform">
        ```hcl theme={null}
        # Network Security Group
        resource "oci_core_network_security_group" "example_nsg" {
          compartment_id = VAR_COMPARTMENT_OCID   # replace with your compartment OCID
          vcn_id         = VAR_VCN_OCID           # replace with your VCN OCID
          display_name   = "example-nsg"
        }

        # INSECURE (do NOT use): allows all protocols / all ports
        # resource "oci_core_network_security_group_security_rule" "allow_all_inbound" {
        #   network_security_group_id = oci_core_network_security_group.example_nsg.id
        #   direction                 = "INGRESS"
        #   protocol                  = "all"                  # or "6" (TCP) with full port range 1-65535
        #   source                    = "0.0.0.0/0"
        # }

        # SECURE: restrict to required protocol and ports instead of all ports / all protocols
        resource "oci_core_network_security_group_security_rule" "allow_inbound_tcp_443" {
          network_security_group_id = oci_core_network_security_group.example_nsg.id

          direction = "INGRESS"
          protocol  = "6"                       # TCP

          source      = "ALLOWED_CIDR_BLOCK"    # replace with the specific CIDR (e.g., "203.0.113.0/24")
          source_type = "CIDR_BLOCK"

          tcp_options {
            destination_port_range {
              min = 443                         # replace with the required port
              max = 443
            }
          }

          stateless = false
        }

        # Example: restrict outbound as well, if you previously had an "allow all" egress rule
        resource "oci_core_network_security_group_security_rule" "allow_egress_tcp_443" {
          network_security_group_id = oci_core_network_security_group.example_nsg.id

          direction = "EGRESS"
          protocol  = "6"                       # TCP

          destination      = "ALLOWED_CIDR_BLOCK"  # replace with specific CIDR or service CIDR
          destination_type = "CIDR_BLOCK"

          tcp_options {
            destination_port_range {
              min = 443
              max = 443
            }
          }

          stateless = false
        }
        ```

        Changing `protocol = "all"` or a full `1-65535` port range to specific protocol/ports updates the security rule in place and does not force replacement of the NSG itself, but the rule resources will be modified and traffic not matching the new ports will be blocked.

        To verify, `terraform plan` should no longer show rules with `protocol = "all"` or TCP/UDP options spanning ports `1-65535`, and instead show updates (or creates/destroys) that narrow each rule to the required ports and CIDRs.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
