Home / OCI

OCIHow-toBeginner

OCI security lists vs network security groups: basics, defaults and a connection checklist

How OCI security lists and NSGs differ, how they combine, why stateless rules break replies, and a step-by-step checklist when you cannot reach an instance on SSH or an application port.

Deepak Bhardwaj4 min read

Applies toOCI Virtual Cloud Network, security lists, network security groups, OCI CLI 3.x

OCI gives you two virtual firewalls. Both can be used at once, and traffic is allowed if either allows it. Understanding that "union" rule is the key to most OCI connectivity puzzles.

Side by side

Security list Network security group (NSG)
Applies to Every VNIC in the subnet VNICs you add to it (instances, LBs, DBs)
Up to Several per subnet Several per VNIC
Source/destination CIDR, service CIDR CIDR, service, or another NSG
Stateful Per rule (default stateful) Per rule (default stateful)
Best for A broad subnet baseline Per-application rules

Both are allow-only. When a packet reaches a VNIC, OCI checks the union of all security lists on the subnet and all NSGs on the VNIC; if any rule allows it, it passes.

Tip

Oracle recommends NSGs for application rules because they follow the resource and can reference each other ("app NSG may talk to db NSG on 1521"), not IP ranges.

The default security list

A new VCN created with the wizard gets a default security list that typically allows:

  • Ingress TCP 22 from 0.0.0.0/0.
  • Ingress ICMP type 3 code 4 (path MTU) from anywhere, and ICMP type 3 from the VCN.
  • Egress all.

Remove the open SSH rule for production and use the Bastion service instead.

Create an NSG pair for a web and database tier

WEB_NSG=$(oci network nsg create --compartment-id $COMP --vcn-id $VCN --display-name nsg-web --query 'data.id' --raw-output)
DB_NSG=$(oci network nsg create --compartment-id $COMP --vcn-id $VCN --display-name nsg-db --query 'data.id' --raw-output)

cat > db-rules.json <<'EOF'
[{"direction":"INGRESS","protocol":"6","source":"NSG_WEB","sourceType":"NETWORK_SECURITY_GROUP",
  "tcpOptions":{"destinationPortRange":{"min":1521,"max":1521}},"isStateless":false,"description":"web to db"}]
EOF
sed -i "s|NSG_WEB|$WEB_NSG|" db-rules.json
oci network nsg rules add --nsg-id $DB_NSG --security-rules file://db-rules.json

Protocol numbers: 6 TCP, 17 UDP, 1 ICMP, all.

Add an instance's VNIC to the NSG:

VNIC=$(oci compute instance list-vnics --instance-id $INSTANCE --query 'data[0].id' --raw-output)
oci network vnic update --vnic-id $VNIC --nsg-ids "[\"$WEB_NSG\"]"

--nsg-ids replaces the list, so include any NSGs the VNIC already had.

Stateless rules and replies

Rules are stateful by default: replies are allowed automatically. A stateless rule (sometimes used for high-traffic load balancer subnets) needs a matching rule in the other direction for the return traffic, including ephemeral ports. Mixing them up gives "connects, then hangs" symptoms.

Checklist: I cannot reach my instance

  1. Instance running, and the service listening? Use the serial console or Run Command if you cannot SSH:
ss -tlnp | grep ':22\|:8080'
  1. OS firewall. Oracle Linux images ship with firewalld enabled; open the port there too:
sudo firewall-cmd --permanent --add-port=8080/tcp && sudo firewall-cmd --reload
  1. Security lists on the subnet allow ingress on the port from your source.
  2. NSGs on the VNIC (if the security list does not) allow it.
  3. Route table: public subnet routes 0.0.0.0/0 to an internet gateway; private subnet to a NAT gateway or DRG.
  4. Public IP assigned, if you connect from the internet.
  5. Your side: corporate firewall or VPN blocking the port.

Check rules from the CLI:

oci network security-list list --compartment-id $COMP --vcn-id $VCN \
  --query 'data[].{name:"display-name", ingress:"ingress-security-rules"[].{src:source, proto:protocol, port:"tcp-options"."destination-port-range".min}}'
oci network nsg rules list --nsg-id $WEB_NSG --output table

Network path analysis in Network Command Center > Network Path Analyzer traces a flow and names the rule or route that blocks it.

Symptom map

Symptom Usually
Timeout Security list / NSG / route / OS firewall
Connection refused Reached the host; nothing listening
Works by IP from inside VCN, not from internet No public IP, no IGW route, or rule only allows VCN CIDR
SSH works, app port does not firewalld on the instance

Prevent it next time

  • Keep the subnet security list minimal (ICMP, maybe Bastion), put application rules in NSGs.
  • Name NSGs by role; reference NSGs instead of IP ranges.
  • Enable VCN flow logs on production subnets so you can see dropped traffic.