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
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
| Type | Range | Use 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 |
| Loopback | 127.0.0.0/8 | localhost, testing (127.0.0.1) |
| Public | All other addresses | Internet-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)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
| CIDR | Network | Broadcast | First Usable | Last Usable | Total Hosts |
|---|---|---|---|---|---|
| 10.0.1.0/24 | 10.0.1.0 | 10.0.1.255 | 10.0.1.1 | 10.0.1.254 | 254 |
| 10.0.0.0/16 | 10.0.0.0 | 10.0.255.255 | 10.0.0.1 | 10.0.255.254 | 65,534 |
| 192.168.1.0/26 | 192.168.1.0 | 192.168.1.63 | 192.168.1.1 | 192.168.1.62 | 62 |
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
| Feature | TCP (Transmission Control Protocol) | UDP (User Datagram Protocol) |
|---|---|---|
| Connection | Connection-oriented (handshake required) | Connectionless (fire and forget) |
| Reliability | Guaranteed delivery, retransmits lost packets | No guarantee, packets can be lost |
| Ordering | Packets arrive in order | Packets may arrive out of order |
| Speed | Slower (overhead from reliability) | Faster (minimal overhead) |
| Use Cases | HTTP/HTTPS, SSH, databases, email, file transfer | DNS, streaming (video/audio), gaming, VoIP, monitoring |
| Error Checking | Extensive error checking & recovery | Basic 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
Port Numbers Explained
| Range | Type | Purpose | Examples |
|---|---|---|---|
| 0-1023 | Well-Known | Reserved for common services (requires root/admin) | 80 (HTTP), 443 (HTTPS), 22 (SSH), 53 (DNS) |
| 1024-49151 | Registered | Assigned to specific applications | 3306 (MySQL), 5432 (PostgreSQL), 6379 (Redis) |
| 49152-65535 | Ephemeral/Dynamic | Temporary ports for client connections | Your 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))- 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
| Type | Purpose | Example |
|---|---|---|
| A | Maps domain to IPv4 address | example.com → 93.184.216.34 |
| AAAA | Maps domain to IPv6 address | example.com → 2606:2800:220:1:: |
| CNAME | Alias to another domain | www.example.com → example.com |
| MX | Mail server for domain | example.com → mail.example.com |
| TXT | Text data (SPF, DKIM, verification) | "v=spf1 include:_spf.google.com ~all" |
| NS | Nameserver for domain | example.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)HTTP/HTTPS Fundamentals
HTTP (Hypertext Transfer Protocol) is the foundation of web communication. HTTPS adds encryption via SSL/TLS.
HTTP Request Methods
| Method | Purpose | Idempotent? | Use Case |
|---|---|---|---|
| GET | Retrieve data | ✅ Yes | Fetch user profile, list products |
| POST | Create new resource | ❌ No | Create user, submit form, upload file |
| PUT | Update/replace resource | ✅ Yes | Update entire user profile |
| PATCH | Partial update | ❌ No | Update user's email only |
| DELETE | Remove resource | ✅ Yes | Delete user account |
| OPTIONS | Check allowed methods | ✅ Yes | CORS 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
| Header | Purpose |
|---|---|
Content-Type | Media type of the body (application/json, text/html, image/png) |
Authorization | Authentication credentials (Bearer token, Basic auth) |
Accept | Client tells server what formats it can handle |
User-Agent | Client software (browser, curl, mobile app) |
Cache-Control | Caching directives (no-cache, max-age=3600) |
Cookie / Set-Cookie | Session 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.)
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
- 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
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.comnc (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
- 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.1Load 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, Web4Load Balancing Algorithms
| Algorithm | How It Works | Best For |
|---|---|---|
| Round Robin | Distributes requests sequentially (1→2→3→1→2→3...) | Servers with equal capacity, stateless apps |
| Least Connections | Sends to server with fewest active connections | Long-lived connections (WebSockets, database connections) |
| Least Response Time | Routes to server with lowest latency | Mixed server performance, geographically distributed |
| IP Hash | Uses client IP to determine server (same IP → same server) | Session persistence without sticky sessions |
| Weighted Round Robin | Distributes 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 UP1. 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 server1Sticky Sessions Trade-offs
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;
}
}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 dataPublic vs Private Subnets
| Type | Internet Access | Route Table | Use Cases |
|---|---|---|---|
| Public | ✅ Yes (via Internet Gateway) | 0.0.0.0/0 → igw-xxxxx | Load balancers, NAT gateways, bastion hosts |
| Private | ⚠️ Outbound only (via NAT Gateway) | 0.0.0.0/0 → nat-xxxxx | Application servers, worker nodes, APIs |
| Isolated | ❌ No internet access | Only VPC CIDR routes | Databases, 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 ✅
Security Groups vs Network ACLs
| Feature | Security Group (SG) | Network ACL (NACL) |
|---|---|---|
| Level | Instance level (firewall for EC2) | Subnet level (firewall for entire subnet) |
| Statefulness | Stateful, return traffic automatically allowed | Stateless, must explicitly allow both directions |
| Rules | Allow rules only (deny by default) | Allow AND deny rules (processed in order) |
| Evaluation | All rules evaluated before decision | Rules evaluated in number order (lowest first) |
| Default | Deny all inbound, allow all outbound | Allow all inbound and outbound |
| Use Case | Primary 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)
- 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
→
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