22_2 ‐ Single Private VNet with no internet, having all other services connected like blob storage - SanjeevOCI/Study GitHub Wiki

22_1 – Single Private VNet (no inbound internet) + Blob via Private Endpoint + NAT Gateway for Updates

Architecture

  • VNet: 10.10.0.0/16
  • Private Subnet (workloads): 10.10.1.0/24 (no public IPs)
  • NAT Gateway: outbound-only SNAT for OS/package updates
  • Private Endpoint (PE): Blob/Azure Files (Private Link) for storage without internet
  • Admin access: Azure Bastion / VPN / ExpressRoute (no public inbound)
  • Goal: Keep workloads private while allowing:
    • Private access to storage via PE
    • Optional outbound internet (via NAT GW) for OS updates/repos
    • No inbound internet access

1) Steps

1. Create Resource Group, VNet, and Private Subnet

  • Resource Group: Logical container for resources.
  • VNet: CIDR 10.10.0.0/16 (non-overlapping).
  • Private Subnet: CIDR 10.10.1.0/24, no public IPs assigned to VMs.

2. Create VM in Private Subnet

  • No public IP.
  • Can access:
    • Azure Managed Disks (block storage equivalent)
    • Azure Blob Storage / Azure Files via Private Endpoint
    • External repos (only if NAT Gateway is configured)

3. Create Private Endpoint

  • For Blob Storage (or Azure Files, Key Vault, etc.).
  • Placed in the Private Subnet (or a dedicated PE Subnet).
  • Use Private DNS Zone for privatelink.blob.core.windows.net and link to the VNet.
  • Validate:
    nslookup <account>.blob.core.windows.net → private IP from VNet.

4. NAT Gateway (Optional)

  • Create NAT Gateway and assign a Public IP or Public IP Prefix.
  • Associate NAT GW with the Private Subnet.
  • Required only if outbound internet is needed for:
    • OS updates
    • External package repos
  • If not required, skip to ensure no internet connectivity.

2) Route Table (UDR) – Private Subnet

Address Prefix Next Hop Type Next Hop Purpose
0.0.0.0/0 NAT Gateway <NATGW> Outbound internet via NAT GW (egress only)
(Disable internet alternative) None Blackhole route to drop all outbound internet traffic
(Blob PE traffic) No explicit route needed — PE is reached via DNS to its private IP

Attach this Route Table to the Private Subnet in VNet settings.


3) NSG – Private Subnet (workloads)

Outbound (Egress)

Priority Name Source Destination Protocol Port(s) Action Purpose
100 Allow-BlobPE-HTTPS VirtualNetwork Storage (Service Tag) TCP 443 Allow Blob/Azure Files via Private Endpoint
110 Allow-NATGW-HTTPS VirtualNetwork 0.0.0.0/0 TCP 443 Allow Outbound to internet via NAT GW for updates/repos
4000 Deny-All-Outbound * 0.0.0.0/0 Any * Deny Block all other outbound

Inbound (Ingress)

Priority Name Source Destination Protocol Port(s) Action Purpose
100 Allow-Admin Bastion/VPN Subnet or VirtualNetwork VirtualNetwork TCP 22,3389 Allow Admin via Bastion/VPN only
4096 Deny-All-Inbound * * Any * Deny Block all inbound from internet

4) Subtle Azure Networking Points (Interview Gold)

  • Default internet route:
    Every subnet has a system route 0.0.0.0/0 → Internet.

    • If VM has a Public IP → inbound/outbound possible (NSG permitting).
    • If VM has no Public IP → outbound still possible via Azure-provided SNAT (until Sept 2025 changes).
    • To block, create a custom UDR replacing 0.0.0.0/0 with Next hop: None (blackhole) or point to NVA/Azure Firewall.
  • NAT Gateway vs default SNAT:

    • NAT GW = dedicated outbound IP(s), scales better, avoids ephemeral SNAT port exhaustion.
    • Default SNAT shares ephemeral ports → can cause outbound connection failures at scale.
  • Private Endpoint (PE) traffic:

    • Always stays on Microsoft backbone.
    • With Private DNS Zone linked, PE overrides public DNS → no public internet path.
  • Service Tags in NSG rules:

    • Using Storage avoids hardcoding changing IP ranges.
  • DNS dependency for PE:

    • Without Private DNS Zone, your VM may resolve storage to a public IP, bypassing PE.
    • Validate: nslookup <storageaccount>.blob.core.windows.net → private IP.
  • NAT Gateway scope:

    • NAT GW is subnet-level in Azure (unlike OCI’s VCN-level NAT).
    • Any VM in the associated subnet without a public IP uses that NAT for outbound.
  • PE works without internet:

    • Even if you blackhole 0.0.0.0/0, PE still works — Azure injects a /32 route for the PE IP.
  • Effective routes:

    • Always check NIC → Effective routes to confirm NAT GW and PE routes are present.

5) Hardening & Best Practices

  • Prefer Azure Bastion for admin — removes need for jump hosts with public IPs.
  • To restrict updates to specific domains, insert Azure Firewall and use FQDN rules (NSGs can’t filter by FQDN).
  • Explicitly add Deny-All-Inbound & Deny-All-Outbound at low priority for clarity.
  • Enable NSG Flow Logs for audit and troubleshooting.
  • Use static NAT GW public IPs for allow-listing with external services.
  • At scale, separate PE subnets for policy isolation.

6) Quick Validation

  • DNS: nslookup <acct>.blob.core.windows.net → private IP (privatelink).
  • Outbound IP: curl https://ifconfig.io → shows NAT GW public IP.
  • Blob Access: azcopy/SDK calls succeed via PE.
  • Blocked test: curl http://example.com:80 fails (NSG deny).
  • Effective routes: NIC shows 0.0.0.0/0 → NAT GW and /32 to PE.

7) Flow Diagram

[ VM (Private Subnet) ] | (TCP 443) v [ Private Endpoint: Blob ] ---> Microsoft Backbone ---> [ Azure Storage ] | | (TCP 443 via UDR) v [ NAT Gateway ] ---> Internet (Outbound only)

  • Blob traffic → PE private IP (DNS via Private DNS Zone), stays private.
  • Updates/repos → NAT Gateway → Internet (no inbound allowed).
⚠️ **GitHub.com Fallback** ⚠️