Networking Essentials

From TCP/IP fundamentals to cloud networking, debugging tools, and production troubleshooting

Why Networking Matters for Modern Developers

In cloud-native and containerized environments, your code is only as good as your networking. Understanding how packets move, how names resolve, and how traffic is routed and balanced is essential for debugging slow APIs, fixing "connection refused" errors, configuring services, and building reliable, scalable systems.

IP Addressing & Subnetting Fundamentals

Every device on a network needs an IP address to communicate. Understanding IP addressing and subnetting is critical for designing cloud networks, configuring VPCs, and troubleshooting connectivity.

IPv4 Address Structure

IPv4 ADDRESS BREAKDOWN
192.168.1.100
│   │   │  │
│   │   │  └─ Host portion
│   │   └──── Third octet
│   └──────── Second octet
└──────────── First octet

Each octet: 0-255 (8 bits)
Total: 32 bits (4 bytes)
Format: Dotted decimal notation

Private vs Public IP Addresses

TypeRangeUse Case
Private (Class A)10.0.0.0/8
(10.0.0.0 - 10.255.255.255)
Large internal networks, AWS VPCs, enterprise LANs
Private (Class B)172.16.0.0/12
(172.16.0.0 - 172.31.255.255)
Docker default networks, medium networks
Private (Class C)192.168.0.0/16
(192.168.0.0 - 192.168.255.255)
Home networks, small office LANs
Loopback127.0.0.0/8localhost, testing (127.0.0.1)
PublicAll other addressesInternet-routable, assigned by ISPs/cloud providers

CIDR Notation Explained

CIDR (Classless Inter-Domain Routing) uses slash notation to specify how many bits are used for the network vs host portion.

10.0.0.0/24
        └─ /24 means first 24 bits are the network
           Last 8 bits (32-24) are for hosts

Subnet mask: 255.255.255.0
Available IPs: 2^8 = 256 addresses
Usable hosts: 254 (minus network & broadcast)

Examples:
/32 → 1 IP      (255.255.255.255) - Single host
/24 → 256 IPs   (255.255.255.0)   - Small subnet (AWS default)
/16 → 65,536    (255.255.0.0)     - Medium network
/8  → 16M IPs   (255.0.0.0)       - Large network (entire VPC)
Real-world example:
AWS VPC: 10.0.0.0/16 → 65,536 IPs
Public subnet: 10.0.1.0/24 → 256 IPs
Private subnet: 10.0.2.0/24 → 256 IPs
Database subnet: 10.0.3.0/24 → 256 IPs

Subnet Calculation Example

CIDRNetworkBroadcastFirst UsableLast UsableTotal Hosts
10.0.1.0/2410.0.1.010.0.1.25510.0.1.110.0.1.254254
10.0.0.0/1610.0.0.010.0.255.25510.0.0.110.0.255.25465,534
192.168.1.0/26192.168.1.0192.168.1.63192.168.1.1192.168.1.6262

TCP/IP Model & Core Protocols

The TCP/IP model defines how data travels across networks in layers. Each layer has specific responsibilities.

┌─────────────────────────────────────────────────────────────────┐
│  APPLICATION LAYER                                              │
│  (What users interact with)                                     │
│  HTTP, HTTPS, DNS, SSH, FTP, SMTP, gRPC, WebSocket              │
├─────────────────────────────────────────────────────────────────┤
│  TRANSPORT LAYER                                                │
│  (How data is delivered)                                        │
│  TCP (reliable, ordered) | UDP (fast, connectionless)           │
│  Ports: 0-65535                                                 │
├─────────────────────────────────────────────────────────────────┤
│  INTERNET LAYER                                                 │
│  (How packets are routed)                                       │
│  IP, ICMP (ping), routing                                       │
├─────────────────────────────────────────────────────────────────┤
│  LINK LAYER                                                     │
│  (Physical network)                                             │
│  Ethernet, Wi-Fi, MAC addresses                                 │
└─────────────────────────────────────────────────────────────────┘

Example: When you visit https://api.example.com
1. Application: HTTPS request created
2. Transport: TCP connection on port 443
3. Internet: IP routing to destination
4. Link: Ethernet/WiFi transmission

TCP vs UDP, When to Use Each

FeatureTCP (Transmission Control Protocol)UDP (User Datagram Protocol)
ConnectionConnection-oriented (handshake required)Connectionless (fire and forget)
ReliabilityGuaranteed delivery, retransmits lost packetsNo guarantee, packets can be lost
OrderingPackets arrive in orderPackets may arrive out of order
SpeedSlower (overhead from reliability)Faster (minimal overhead)
Use CasesHTTP/HTTPS, SSH, databases, email, file transferDNS, streaming (video/audio), gaming, VoIP, monitoring
Error CheckingExtensive error checking & recoveryBasic checksum only

TCP Three-Way Handshake

Before any data flows, TCP establishes a connection through a three-way handshake. Understanding this is critical for debugging connection timeouts.

CLIENT                                    SERVER
  │                                          │
  │────────── 1. SYN ──────────────────────▶ │  "Can we talk?"
  │         (SEQ=100)                        │
  │                                          │
  │◀──────── 2. SYN-ACK ──────────────────── │  "Yes! Ready when you are"
  │         (SEQ=300, ACK=101)               │
  │                                          │
  │────────── 3. ACK ──────────────────────▶ │  "Great, let's start"
  │         (ACK=301)                        │
  │                                          │
  │═══════ CONNECTION ESTABLISHED ══════════ │
  │                                          │
  │────────── HTTP GET / ──────────────────▶ │  Data transfer begins
  │                                          │

If SYN fails → Connection timeout (firewall blocking)
If SYN-ACK fails → Server not listening on port
If ACK fails → Client/network issue
Common Debugging: If you see "Connection timed out", the SYN packet never reached the server (firewall, wrong IP, or service not running).

Port Numbers Explained

RangeTypePurposeExamples
0-1023Well-KnownReserved for common services (requires root/admin)80 (HTTP), 443 (HTTPS), 22 (SSH), 53 (DNS)
1024-49151RegisteredAssigned to specific applications3306 (MySQL), 5432 (PostgreSQL), 6379 (Redis)
49152-65535Ephemeral/DynamicTemporary ports for client connectionsYour browser uses these when connecting to servers
# View which processes are listening on which ports
$ ss -tulnp | grep LISTEN

tcp   LISTEN  0  128   0.0.0.0:22        0.0.0.0:*     users:(("sshd",pid=1234))
tcp   LISTEN  0  128   127.0.0.1:3306    0.0.0.0:*     users:(("mysqld",pid=5678))
tcp   LISTEN  0  4096  0.0.0.0:80        0.0.0.0:*     users:(("nginx",pid=9012))
Security Check:
- SSH (22) on 0.0.0.0 → Accessible from anywhere (okay if secured)
- MySQL (3306) on 127.0.0.1 → Only accessible locally (secure!)
- Nginx (80) on 0.0.0.0 → Public web server (expected)

DNS, The Internet's Phonebook

DNS translates human-friendly domain names (like api.yourapp.com) into IP addresses machines understand. In cloud/container environments, DNS problems cause 40-60% of connectivity issues.

Common DNS Record Types

TypePurposeExample
AMaps domain to IPv4 addressexample.com → 93.184.216.34
AAAAMaps domain to IPv6 addressexample.com → 2606:2800:220:1::
CNAMEAlias to another domainwww.example.com → example.com
MXMail server for domainexample.com → mail.example.com
TXTText data (SPF, DKIM, verification)"v=spf1 include:_spf.google.com ~all"
NSNameserver for domainexample.com → ns1.cloudflare.com

Essential DNS Debugging Commands

dig +short

When to use: Fastest way to get just the IP(s), perfect for scripts, CI/CD, or quick checks.

$ dig +short api.example.com
34.120.145.67
35.190.87.12
dig @8.8.8.8

When to use: Your local DNS is broken or cached bad data, bypass it.

$ dig api.example.com @8.8.8.8 +short
34.120.145.67
dig +trace

When to use: New domain not resolving, weird intermittent failures, debugging delegated zones.

$ dig +trace api.newapp.com
.          518400  IN  NS  a.root-servers.net.
com.       172800  IN  NS  a.gtld-servers.net.
newapp.com. 172800 IN  NS  ns-cloud-a1.googledomains.com.
api.newapp.com. 300 IN  A   34.120.145.67
nslookup

When to use: Minimal containers (Alpine, distroless) where dig is not installed.

$ nslookup api.example.com 1.1.1.1
Server:    1.1.1.1
Address:   1.1.1.1#53
Name:      api.example.com
Address:   34.120.145.67

DNS Caching & TTL (Time To Live)

DNS records are cached at multiple levels. TTL determines how long a record is cached before re-querying.

$ dig api.example.com

;; ANSWER SECTION:
api.example.com.    300    IN    A    34.120.145.67
                    └─ TTL in seconds (5 minutes)

Caching layers:
1. Browser cache (Chrome, Firefox)
2. OS cache (systemd-resolved, dnsmasq)
3. Router/Gateway cache
4. ISP DNS cache
5. CDN/Recursive resolver (8.8.8.8, 1.1.1.1)
Production Tip: Before changing DNS records for production systems, lower TTL to 60-300 seconds a day ahead. This ensures fast propagation when you make the actual change.

HTTP/HTTPS Fundamentals

HTTP (Hypertext Transfer Protocol) is the foundation of web communication. HTTPS adds encryption via SSL/TLS.

HTTP Request Methods

MethodPurposeIdempotent?Use Case
GETRetrieve data✅ YesFetch user profile, list products
POSTCreate new resource❌ NoCreate user, submit form, upload file
PUTUpdate/replace resource✅ YesUpdate entire user profile
PATCHPartial update❌ NoUpdate user's email only
DELETERemove resource✅ YesDelete user account
OPTIONSCheck allowed methods✅ YesCORS preflight requests

HTTP Status Codes You'll See Every Day

2xx Success
  • 200 OK → Request succeeded
  • 201 Created → Resource created (POST)
  • 204 No Content → Success, no body returned
3xx Redirection
  • 301 Moved Permanently → Permanent redirect
  • 302 Found → Temporary redirect
  • 304 Not Modified → Use cached version
4xx Client Errors
  • 400 Bad Request → Invalid syntax
  • 401 Unauthorized → Authentication required
  • 403 Forbidden → Authenticated but no permission
  • 404 Not Found → Resource doesn't exist
  • 429 Too Many Requests → Rate limit exceeded
5xx Server Errors
  • 500 Internal Server Error → Generic server failure
  • 502 Bad Gateway → Upstream server issue
  • 503 Service Unavailable → Server overloaded/down
  • 504 Gateway Timeout → Upstream didn't respond

Essential HTTP Headers

HeaderPurpose
Content-TypeMedia type of the body (application/json, text/html, image/png)
AuthorizationAuthentication credentials (Bearer token, Basic auth)
AcceptClient tells server what formats it can handle
User-AgentClient software (browser, curl, mobile app)
Cache-ControlCaching directives (no-cache, max-age=3600)
Cookie / Set-CookieSession management, user tracking

HTTPS & SSL/TLS, Encryption Basics

HTTPS = HTTP + TLS (Transport Layer Security). All communication is encrypted between client and server.

TLS Handshake (simplified):

CLIENT                                    SERVER
  │                                          │
  │─────── 1. ClientHello ────────────────▶  │  "I support TLS 1.3, these ciphers"
  │                                          │
  │◀────── 2. ServerHello ─────────────────  │  "TLS 1.3 it is, here's my certificate"
  │        (Certificate with public key)     │
  │                                          │
  │─────── 3. Verify Certificate ──────────  │  Client checks cert is valid
  │        (Check CA signature, expiry)      │
  │                                          │
  │─────── 4. Generate Session Key ────────  │  Both create shared secret key
  │                                          │
  │═══════ ENCRYPTED CONNECTION ═══════════  │  All data now encrypted
  │                                          │

Certificate contains:
- Domain name (example.com)
- Public key
- Expiration date
- Issuer (Let's Encrypt, DigiCert, etc.)
Why HTTPS matters: Without it, passwords, API keys, and session tokens are sent in plain text. Always use HTTPS in production. Let's Encrypt provides free certificates.

Network Debugging Tools, Your Daily Toolkit

When things break, these tools help you diagnose where packets are failing.

ping, Basic Connectivity Test

Uses ICMP (Internet Control Message Protocol) to test if a host is reachable. The most fundamental network tool.

$ ping -c 4 google.com

PING google.com (142.250.80.46): 56 data bytes
64 bytes from 142.250.80.46: icmp_seq=0 ttl=116 time=12.4 ms
64 bytes from 142.250.80.46: icmp_seq=1 ttl=116 time=11.8 ms
64 bytes from 142.250.80.46: icmp_seq=2 ttl=116 time=12.1 ms
64 bytes from 142.250.80.46: icmp_seq=3 ttl=116 time=12.3 ms

--- google.com ping statistics ---
4 packets transmitted, 4 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 11.8/12.2/12.4/0.2 ms
What this tells you:
- Host is reachable (not blocked by firewall)
- Average latency: ~12ms (good for internet)
- No packet loss (stable connection)
- TTL=116 suggests ~12-15 router hops
Common Scenarios
Request timeout → Firewall blocking ICMP or host down
100% packet loss → Network/routing issue
High latency (>100ms) → Network congestion or geographic distance
Ping works but app doesn't → Firewall allows ICMP but blocks application port

curl, HTTP/HTTPS Testing

# Basic GET request with verbose output
$ curl -v https://api.example.com/health

*   Trying 34.120.145.67:443...
* Connected to api.example.com (34.120.145.67) port 443
* TLS handshake succeeded
> GET /health HTTP/2
> Host: api.example.com
> User-Agent: curl/8.1.2
> Accept: */*
> 
< HTTP/2 200 
< content-type: application/json
< content-length: 27
< 
{"status":"healthy"}

# POST with JSON body
$ curl -X POST https://api.example.com/users \
  -H "Content-Type: application/json" \
  -d '{"name":"Alice","email":"alice@example.com"}'

# Follow redirects
$ curl -L https://example.com

# Save response headers
$ curl -I https://api.example.com

# Test with specific timeout
$ curl --connect-timeout 5 --max-time 10 https://slow-api.com

nc (netcat), Port Connectivity Test

# Check if port 5432 (PostgreSQL) is open
$ nc -zv database.internal 5432
Connection to database.internal 5432 port [tcp/postgresql] succeeded!

# Test multiple ports
$ nc -zv api.example.com 80 443
Connection to api.example.com 80 port [tcp/http] succeeded!
Connection to api.example.com 443 port [tcp/https] succeeded!

# If connection fails:
$ nc -zv private-db.local 3306
nc: connect to private-db.local port 3306 (tcp) failed: Connection refused
# → Service not running OR firewall blocking

traceroute, Path Analysis

Shows the route packets take to reach a destination. Useful for identifying where network latency or failures occur.

$ traceroute api.example.com

traceroute to api.example.com (34.120.145.67), 30 hops max, 60 byte packets
 1  router.local (192.168.1.1)         0.8 ms   0.6 ms   0.5 ms
 2  10.0.0.1                            1.2 ms   1.1 ms   1.0 ms
 3  isp-gateway.net (72.14.212.1)      8.4 ms   8.2 ms   8.1 ms
 4  * * *  (timeout - firewall blocking ICMP)
 5  google-peering.net (108.170.252.1) 12.1 ms  11.9 ms  12.0 ms
 6  34.120.145.67                      12.8 ms  12.6 ms  12.7 ms
Reading traceroute:
- Each line = one network hop (router)
- Three time values = three probe packets
- *** = Timeout (router not responding to probes)
- Sudden latency increase = bottleneck point

mtr, Better traceroute

Combines ping and traceroute. Shows packet loss and latency for each hop in real-time.

$ mtr api.example.com

                        Packets               Pings
 Host                    Loss%   Sent   Last   Avg  Best  Wrst
 1. router.local         0.0%     50    0.5   0.6   0.4   1.2
 2. 10.0.0.1             0.0%     50    1.1   1.2   1.0   2.1
 3. isp-gateway.net      0.0%     50    8.2   8.4   7.9  12.1
 4. ???                100.0%     50    0.0   0.0   0.0   0.0
 5. google-peering.net   2.0%     50   12.1  12.3  11.8  15.2
 6. 34.120.145.67        0.0%     50   12.7  12.9  12.4  14.1
Why mtr is better: Shows packet loss percentage per hop. In this example, hop 5 has 2% loss, potential issue point.

Load Balancers, Distributing Traffic

A load balancer distributes incoming network traffic across multiple backend servers to ensure no single server is overwhelmed. Critical for scalability, high availability, and fault tolerance.

                    INTERNET
                       │
                       ▼
              ┌────────────────┐
              │ LOAD BALANCER  │  ← Single entry point
              │  (10.0.1.100)  │     Health checks enabled
              └────────────────┘
                   │   │   │
        ┌──────────┼───┼───┼──────────┐
        │          │   │   │          │
        ▼          ▼   ▼   ▼          ▼
    ┌─────┐    ┌─────┐ ┌─────┐    ┌─────┐
    │ Web1│    │ Web2│ │ Web3│    │ Web4│  ← Backend pool
    │:8080│    │:8080│ │:8080│    │:8080│     Auto-scaled
    └─────┘    └─────┘ └─────┘    └─────┘

If Web2 fails → LB automatically removes it from pool
Traffic redistributed to Web1, Web3, Web4

Load Balancing Algorithms

AlgorithmHow It WorksBest For
Round RobinDistributes requests sequentially (1→2→3→1→2→3...)Servers with equal capacity, stateless apps
Least ConnectionsSends to server with fewest active connectionsLong-lived connections (WebSockets, database connections)
Least Response TimeRoutes to server with lowest latencyMixed server performance, geographically distributed
IP HashUses client IP to determine server (same IP → same server)Session persistence without sticky sessions
Weighted Round RobinDistributes based on server capacity (powerful servers get more)Heterogeneous server pool (different CPU/RAM)

Layer 4 vs Layer 7 Load Balancing

Layer 4 (Transport)

Routes based on: IP address + Port

  • Faster (doesn't inspect packet contents)
  • Works with any protocol (TCP/UDP)
  • Lower latency
  • Simple routing decisions

Examples: AWS NLB, HAProxy (TCP mode)

Layer 7 (Application)

Routes based on: URLs, Headers, Cookies, Content

  • Intelligent routing (/api → API servers)
  • SSL termination
  • Request modification
  • Content-based decisions

Examples: AWS ALB, NGINX, Traefik

Health Checks, Automatic Failover

# HAProxy health check config
backend api_servers
    balance roundrobin
    
    # Health check every 2 seconds
    option httpchk GET /health HTTP/1.1
    
    server api1 10.0.1.10:3000 check inter 2s fall 3 rise 2
    server api2 10.0.1.11:3000 check inter 2s fall 3 rise 2
    server api3 10.0.1.12:3000 check inter 2s fall 3 rise 2
    
# inter 2s  → Check every 2 seconds
# fall 3    → 3 failed checks = mark as DOWN
# rise 2    → 2 successful checks = mark as UP
How it works:
1. LB sends GET /health every 2 seconds
2. If server returns 200 OK → healthy
3. If 3 consecutive failures → remove from pool
4. When server recovers (2 successful checks) → add back to pool

Sticky Sessions (Session Persistence)

Ensures the same user always hits the same backend server. Useful for stateful applications but reduces flexibility.

# Cookie-based sticky session (NGINX)
upstream backend {
    ip_hash;  # OR use sticky cookie
    server 10.0.1.10:3000;
    server 10.0.1.11:3000;
    server 10.0.1.12:3000;
}

# User's first request → routed to server1
# LB sets cookie: SERVERID=server1
# All subsequent requests with this cookie → always go to server1
Sticky Sessions Trade-offs
Pros: Simpler app code, no distributed session storage needed
Cons: Uneven load distribution, harder to scale, server failure = session loss
Better approach: Use Redis/Memcached for session storage (truly stateless)

Reverse Proxies, Traffic Gatekeepers

A reverse proxy sits between clients and your backend applications, forwarding client requests while adding a layer of control, optimization, and security.

Forward Proxy vs Reverse Proxy

FORWARD PROXY (protects clients)
─────────────────────────────────
CLIENT → FORWARD PROXY → INTERNET → SERVER
         (hides client)

Examples: Corporate proxy, VPN, Squid
Use: Content filtering, anonymity, caching

Client knows about proxy
Server doesn't know real client IP


REVERSE PROXY (protects servers)
────────────────────────────────
CLIENT → INTERNET → REVERSE PROXY → BACKEND SERVERS
                    (hides servers)

Examples: NGINX, Traefik, HAProxy, Cloudflare
Use: Load balancing, SSL termination, caching

Client doesn't know about backend servers
Server sees proxy IP (use X-Forwarded-For header)

Reverse Proxy Capabilities

Core Features
  • SSL/TLS termination
  • Caching static content
  • Compression (gzip, brotli)
  • Path-based routing
  • Request/response modification
  • Rate limiting
Security Features
  • Hide backend IPs/architecture
  • WAF (Web Application Firewall)
  • DDoS protection
  • Security headers injection
  • Certificate management
  • Access control

NGINX Reverse Proxy Configuration

# /etc/nginx/sites-available/myapp
# Rate limiting zone (must be in http context, outside server block)
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;

server {
    listen 80;
    server_name api.yourapp.com;

    # Redirect HTTP to HTTPS
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name api.yourapp.com;

    # SSL Configuration
    ssl_certificate /etc/letsencrypt/live/api.yourapp.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.yourapp.com/privkey.pem;

    # Security headers
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";
    add_header X-XSS-Protection "1; mode=block";

    # Rate limiting (10 requests/second per IP)
    limit_req zone=api_limit burst=20;
    
    # Path-based routing
    location /api/users {
        proxy_pass http://user-service:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
    
    location /api/payments {
        proxy_pass http://payment-service:4000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
    
    # Cache static assets
    location ~* .(jpg|jpeg|png|gif|css|js)$ {
        proxy_pass http://frontend:8080;
        proxy_cache my_cache;
        proxy_cache_valid 200 1h;
        add_header X-Cache-Status $upstream_cache_status;
    }
}
What this config does:
1. Forces HTTPS (redirects HTTP to HTTPS)
2. Terminates SSL (backends use plain HTTP)
3. Routes /api/users → user-service
4. Routes /api/payments → payment-service
5. Caches static files for 1 hour
6. Rate limits to 10 req/s per IP
7. Adds security headers

Cloud Networking, AWS VPC Fundamentals

AWS Virtual Private Cloud (VPC) is your own isolated network in the cloud. Understanding VPCs is critical for deploying secure, scalable applications on AWS.

VPC (10.0.0.0/16),  Your private cloud network
│
├── PUBLIC SUBNET (10.0.1.0/24)
│   ├── Internet Gateway attached → Can reach internet
│   ├── Route: 0.0.0.0/0 → Internet Gateway
│   └── Resources: Load Balancers, Bastion Hosts
│
├── PRIVATE SUBNET (10.0.2.0/24)
│   ├── NO direct internet access
│   ├── Route: 0.0.0.0/0 → NAT Gateway (in public subnet)
│   └── Resources: Application Servers, Databases
│
└── ISOLATED SUBNET (10.0.3.0/24)
    ├── NO internet access at all
    ├── Only VPC-internal communication
    └── Resources: Critical databases, compliance data

Public vs Private Subnets

TypeInternet AccessRoute TableUse Cases
Public✅ Yes (via Internet Gateway)0.0.0.0/0 → igw-xxxxxLoad balancers, NAT gateways, bastion hosts
Private⚠️ Outbound only (via NAT Gateway)0.0.0.0/0 → nat-xxxxxApplication servers, worker nodes, APIs
Isolated❌ No internet accessOnly VPC CIDR routesDatabases, sensitive data storage

NAT Gateway, Private Subnet Internet Access

NAT (Network Address Translation) Gateway allows instances in private subnets to reach the internet (for updates, API calls) while preventing inbound internet traffic.

Flow: Private Instance → Internet (Outbound)
─────────────────────────────────────────────
1. EC2 in private subnet (10.0.2.50) makes request to api.github.com
2. Route table: 0.0.0.0/0 → NAT Gateway (in public subnet)
3. NAT Gateway translates private IP → its own public IP
4. Request goes through Internet Gateway
5. Response comes back through same path
6. NAT Gateway translates back to 10.0.2.50

Inbound from internet? BLOCKED ❌
Only outbound connections allowed ✅
Cost note: NAT Gateways cost ~$0.045/hour + data transfer fees. For development, consider using a NAT instance (cheaper) or VPC endpoints for AWS services.

Security Groups vs Network ACLs

FeatureSecurity Group (SG)Network ACL (NACL)
LevelInstance level (firewall for EC2)Subnet level (firewall for entire subnet)
StatefulnessStateful, return traffic automatically allowedStateless, must explicitly allow both directions
RulesAllow rules only (deny by default)Allow AND deny rules (processed in order)
EvaluationAll rules evaluated before decisionRules evaluated in number order (lowest first)
DefaultDeny all inbound, allow all outboundAllow all inbound and outbound
Use CasePrimary security layer (recommended)Additional subnet-level defense (optional)
# Web Server Security Group
INBOUND RULES:
Type       Protocol  Port Range  Source
HTTP       TCP       80          0.0.0.0/0        (Allow from anywhere)
HTTPS      TCP       443         0.0.0.0/0        (Allow from anywhere)
SSH        TCP       22          203.0.113.0/24   (Only from office IP)

OUTBOUND RULES:
All traffic   All   All   0.0.0.0/0   (Allow to anywhere)

# Stateful means: if you allow port 80 inbound, the response
# automatically goes back out,  no outbound rule needed for HTTP responses

Route Tables, Traffic Direction

# Public Subnet Route Table
Destination      Target
10.0.0.0/16      local         (VPC internal traffic stays in VPC)
0.0.0.0/0        igw-abc123    (All other traffic → Internet Gateway)
# Private Subnet Route Table
Destination      Target
10.0.0.0/16      local         (VPC internal traffic)
0.0.0.0/0        nat-xyz789    (Outbound internet → NAT Gateway)
Reading route tables:
- Most specific route wins (10.0.0.0/16 more specific than 0.0.0.0/0)
- "local" = stays within VPC
- 0.0.0.0/0 = default route (catch-all for everything else)

Common Network Issues & Troubleshooting

A systematic approach to debugging network problems in production.

Network Debugging Workflow
1. Can you reach the host at all?
ping target.com
✅ Success → Move to step 2
❌ Timeout → DNS issue OR network routing problem

2. Does the DNS resolve correctly?
dig +short target.com
✅ Returns IP → DNS works, move to step 3
❌ No answer → DNS misconfiguration

3. Is the port open?
nc -zv target.com 443
✅ Connection succeeded → Port is open, move to step 4
❌ Connection refused → Service not running OR firewall blocking

4. Can you make an HTTP request?
curl -v https://target.com
✅ 200 OK → Service works!
❌ Timeout/Error → Application issue or SSL problem

5. Check logs and traces
→ Application logs, LB logs, VPC Flow Logs

Common Error Messages Decoded

❌ Connection refused

Meaning: You reached the host, but nothing is listening on that port.
Causes: Service not running, wrong port, firewall blocking
Debug: ss -tulnp | grep PORT on server to check if service is listening

❌ Connection timed out

Meaning: Packets sent but no response received.
Causes: Firewall blocking, wrong IP, host down, routing problem
Debug: traceroute target.com to see where packets stop

❌ Name or service not known (DNS failure)

Meaning: DNS couldn't resolve the domain name.
Causes: Typo in domain, DNS server down, record doesn't exist
Debug: dig +short domain.com @8.8.8.8 to bypass local DNS

❌ No route to host

Meaning: Network path to destination doesn't exist.
Causes: Routing misconfiguration, interface down, wrong subnet
Debug: Check route tables, verify IP is in correct subnet

❌ SSL certificate problem

Meaning: Certificate validation failed.
Causes: Expired cert, wrong domain, self-signed cert, clock skew
Debug: curl -vk https://domain.com (-k to skip verification) or check with openssl s_client -connect domain.com:443

Key Takeaways

  • IP & Subnetting: Understand CIDR notation, private IP ranges, and subnet design
  • TCP/IP Model: Know the 4 layers and when to use TCP vs UDP
  • DNS: Master dig, understand caching/TTL, and DNS record types
  • HTTP/HTTPS: Know status codes, methods, headers, and SSL/TLS basics
  • Debugging Tools: ping, curl, nc, traceroute, mtr are your daily drivers
  • Load Balancers: Understand algorithms, L4 vs L7, health checks, and sticky sessions
  • Reverse Proxies: SSL termination, caching, routing, and security headers
  • AWS VPC: Public/private subnets, NAT Gateways, Security Groups vs NACLs, route tables
  • Troubleshooting: Systematic debugging from DNS → connectivity → application