DNS, HTTP, TCP/IP, ports, TLS certificates, curl debugging, and load balancers — everything you need to understand what's happening between your code and the user, and how to debug it when it breaks.
ping host — can I reach it at all?nc -zv host 443 — is the port open?curl -v https://host — is the app responding?
api.app.com → 1.2.3.4www → app.com# dig (Linux/Mac/WSL2) — full detail dig google.com # Full DNS response dig google.com A # A records only dig google.com MX # Mail server records dig +short google.com # Just the IP(s) dig @8.8.8.8 google.com # Use Google's DNS server dig +trace google.com # Full resolution path # nslookup (works on all platforms) nslookup google.com nslookup -type=MX gmail.com nslookup google.com 8.8.8.8 # Query specific DNS server # Check /etc/hosts (local overrides) cat /etc/hosts # Linux/Mac/WSL2 # Windows PowerShell native DNS Resolve-DnsName google.com Resolve-DnsName google.com -Type MX Resolve-DnsName google.com -Server 8.8.8.8
dig +short google.com shows what your system sees. Check the TTL — if it's 3600, old record cached for 1 hour. Use dig @8.8.8.8 to bypass local cache and query directly.
# View listening ports (Linux/Mac/WSL2) netstat -tlnp # TCP listening, numeric, with PIDs ss -tlnp # Newer, faster alternative to netstat lsof -i :8080 # What process is using port 8080? # Test if a remote port is open nc -zv github.com 443 # netcat: port 443 open? nc -zv 10.0.0.5 5432 # DB port reachable? curl -s --connect-timeout 3 telnet://host:22 && echo "open" # Trace the network path traceroute google.com # Linux/Mac tracepath google.com # Alternative (no sudo) # Windows PowerShell equivalents netstat -an # All connections Test-NetConnection -ComputerName github.com -Port 443 Test-NetConnection github.com -Port 443 -InformationLevel Detailed tracert google.com # Windows traceroute
nc fails but the service is running, check cloud firewall rules — not the server.
-o /dev/null -s -w "%{http_code}" — print just the status code from curl# === Basic requests === curl https://api.github.com # GET request curl -I https://google.com # Headers only (HEAD) curl -v https://httpbin.org/get # Verbose — shows TLS + headers # === Common flags === curl -L url # Follow redirects curl -o file.json url # Save response to file curl -s url # Silent (no progress bar) curl --connect-timeout 5 url # Timeout after 5 seconds # === POST with JSON body === curl -X POST https://httpbin.org/post \ -H "Content-Type: application/json" \ -H "Authorization: Bearer mytoken" \ -d '{"name":"devops","env":"prod"}' # === Check status code only === curl -o /dev/null -s -w "%{http_code}" https://google.com # Output: 200 # === Timing breakdown === curl -w "\n\nDNS: %{time_namelookup}s\nConnect: %{time_connect}s\nTLS: %{time_appconnect}s\nTotal: %{time_total}s\n" \ -o /dev/null -s https://google.com # === Custom headers + auth === curl -H "X-API-Key: secret123" \ -H "Accept: application/json" \ https://api.example.com/users
Invoke-WebRequest https://google.comInvoke-WebRequest -Uri url -Method HEAD(Invoke-WebRequest url).StatusCodeInvoke-RestMethod https://api.url/endpoint (JSON)curl.exe -I https://google.com (real curl!)
curl -I url — get status + headers fastcurl -v url — see everything (TLS, redirects)curl -w "%{http_code}" -o /dev/null -s url — scripted status checkcurl --connect-timeout 3 url — diagnose timeouts
Authorization: Bearer <token> — API authContent-Type: application/json — request body typeX-Request-ID — trace a request through logsCache-Control — caching behaviour
# Check certificate expiry date echo | openssl s_client -connect google.com:443 -servername google.com 2>/dev/null \ | openssl x509 -noout -dates # notBefore=... notAfter=Dec 15 12:00:00 2025 GMT # Full cert details (subject, issuer, SANs) echo | openssl s_client -connect google.com:443 2>/dev/null \ | openssl x509 -noout -text | grep -A2 "Subject:\|Not After\|DNS:" # Quick expiry check with days remaining domain="google.com" expiry=$(echo | openssl s_client -connect $domain:443 -servername $domain 2>/dev/null \ | openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2) echo "Expires: $expiry" # Test TLS version + cipher curl -v --tls-max 1.2 https://google.com 2>&1 | grep "SSL connection" # Windows PowerShell $req = [Net.HttpWebRequest]::Create("https://google.com") $req.GetResponse() | Out-Null $req.ServicePoint.Certificate.GetExpirationDateString()
Sits in front of your app servers and:
Tools: nginx, HAProxy, Traefik, AWS ALB, Azure Application Gateway
upstream backend {
least_conn; # Algorithm: least connections
server 10.0.0.1:8080; # App server 1
server 10.0.0.2:8080; # App server 2
server 10.0.0.3:8080 backup; # Backup — only if others fail
}
server {
listen 443 ssl;
server_name api.example.com;
ssl_certificate /etc/ssl/certs/server.crt;
ssl_certificate_key /etc/ssl/private/server.key;
location / {
proxy_pass http://backend;
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;
# Health check
proxy_connect_timeout 3s;
proxy_read_timeout 30s;
}
}
# Health check endpoint (nginx checks this)
# If /health returns non-2xx: server removed from pool
GET /health) on each backend. If it returns non-2xx or times out, that server is removed from the pool until it recovers. This is how rolling deployments achieve zero downtime.
Use curl, dig, netstat, and openssl to diagnose real-world networking issues — on both Linux/Mac and Windows
dig google.com (Linux/Mac/WSL2) or Resolve-DnsName google.com (PowerShell). Note the A record IP, TTL value, and answer section.curl.exe (real curl) or Invoke-WebRequest.netstat -tlnp or ss -tlnp. Windows: netstat -an | findstr LISTEN. Identify which ports are open and what services are using them.google.com's cert expiry with openssl (Linux/Mac/WSL2). Then check github.com. Note the notAfter date and issuer.httpbin.org to trigger 404, 429, 500, 503 responses and observe what curl outputs. Commit a notes file to your lab repo with your findings.# === DNS === dig google.com A # A records dig +short google.com # Just IPs dig @8.8.8.8 google.com # via Google DNS nslookup github.com # Works on all platforms # === HTTP === curl -I https://httpbin.org/get curl -v https://httpbin.org/get 2>&1 | head -40 curl -o /dev/null -s -w "%{http_code}\n" https://google.com curl -w "\nDNS:%{time_namelookup}s Connect:%{time_connect}s TLS:%{time_appconnect}s Total:%{time_total}s\n" \ -o /dev/null -s https://github.com # === Ports === netstat -tlnp 2>/dev/null || ss -tlnp nc -zv github.com 443 && echo "Port 443 OPEN" # === TLS === echo | openssl s_client -connect google.com:443 -servername google.com 2>/dev/null \ | openssl x509 -noout -dates echo | openssl s_client -connect github.com:443 -servername github.com 2>/dev/null \ | openssl x509 -noout -dates # === HTTP Error Simulation === for code in 200 301 400 404 429 500 503; do result=$(curl -o /dev/null -s -w "%{http_code}" "https://httpbin.org/status/$code") echo "Requested $code → Got: $result" done
# === DNS === Resolve-DnsName google.com Resolve-DnsName google.com -Type A Resolve-DnsName -Name google.com -Server 8.8.8.8 nslookup github.com # works in PS too # === HTTP === Invoke-WebRequest https://httpbin.org/get (Invoke-WebRequest https://google.com).StatusCode curl.exe -I https://httpbin.org/get # real curl curl.exe -o NUL -s -w "%{http_code}" https://google.com # === Ports === netstat -an | Select-String "LISTEN" Test-NetConnection -ComputerName github.com -Port 443 Test-NetConnection github.com -Port 443 -InformationLevel Detailed # === TLS === $req = [Net.HttpWebRequest]::Create("https://google.com") $req.GetResponse() | Out-Null $req.ServicePoint.Certificate.GetExpirationDateString() # === HTTP errors === 200, 301, 404, 500 | ForEach-Object { $r = Invoke-WebRequest "https://httpbin.org/status/$_" -EA SilentlyContinue Write-Host "Status $_`: $($r.StatusCode)" }
notes/day5-networking.md in your lab repo. Note what each command output, the cert expiry dates, and any open ports you found. Commit with feat(day5): networking debug notes
| Task | 🐧 Linux/Mac/WSL2 | 🪟 PowerShell | 🪟 CMD / Windows |
|---|---|---|---|
| DNS lookup | dig domain.com | Resolve-DnsName domain.com | nslookup domain.com |
| Just the IP | dig +short domain.com | (Resolve-DnsName d.com).IPAddress | ping domain.com |
| Ping host | ping -c 4 host | ping host | ping host |
| Trace route | traceroute host | Test-NetConnection -TraceRoute host | tracert host |
| Test port open | nc -zv host port | Test-NetConnection host -Port port | telnet host port |
| Listening ports | ss -tlnp | netstat -an | sls LISTEN | netstat -an | find "LISTEN" |
| All connections | netstat -an | Get-NetTCPConnection | netstat -an |
| HTTP GET | curl https://url | Invoke-WebRequest url | curl.exe url |
| HTTP headers only | curl -I https://url | curl.exe -I url | curl.exe -I url |
| HTTP status code | curl -o /dev/null -s -w "%{http_code}" url | (Invoke-WebRequest url).StatusCode | — |
| TLS cert expiry | openssl s_client -connect h:443 | openssl x509 -noout -dates | $req.ServicePoint.Certificate.GetExpirationDateString() | — |
| Local IP address | ip addr show / ifconfig | ipconfig | ipconfig |
# Step 1: Verify the issue curl -o /dev/null -s -w "%{http_code}" https://api.example.com/health # → 502 # Step 2: Check DNS (is the domain resolving?) dig +short api.example.com # → 1.2.3.4 (DNS is fine) # Step 3: Is the load balancer port open? nc -zv api.example.com 443 && echo "LB port OPEN" # → open (load balancer is up) # Step 4: Is the backend app responding? curl http://10.0.0.1:8080/health # Direct to app server # → curl: (7) Failed to connect — APP SERVER IS DOWN # Step 5: Check app logs ssh app-server-1 sudo journalctl -u myapp --since "10 min ago" # → Out of memory! OOMKilled the process # Step 6: Restart app, verify sudo systemctl restart myapp curl -o /dev/null -s -w "%{http_code}" https://api.example.com/health # → 200 ✅
Always work through the layers:
3 questions · 5 minutes · DNS, HTTP codes, and TLS
curl flag shows only the HTTP response headers without downloading the response body?-v — verbose mode (shows everything)-I — sends a HEAD request, returns headers only-H — sets a request header-d — sends POST datanotes/day5-networking.md to your lab repo| Symptom | Most Likely Cause | First Command to Run |
|---|---|---|
| curl: (6) Could not resolve host | DNS failure — domain not resolving | dig +short domain.com |
| curl: (7) Failed to connect | Port closed, firewall blocking, app not running | nc -zv host port |
| curl: (28) Operation timed out | Firewall silently dropping packets, or very slow response | traceroute host |
| SSL: certificate verify failed | Expired cert, self-signed, or wrong domain | openssl s_client -connect h:443 |
| HTTP 502 Bad Gateway | Upstream app server crashed or returned garbage | curl http://appserver:8080/health |
| HTTP 503 Service Unavailable | Load balancer health check failing — app down | systemctl status myapp |
| HTTP 504 Gateway Timeout | App responds but too slowly (DB query, CPU spike) | top then check DB slow query log |
| HTTP 401 Unauthorized | Missing or invalid auth token/session | curl -H "Authorization: Bearer ..." url |
| HTTP 403 Forbidden | Auth OK but no permission — check RBAC/IAM | Check cloud IAM policies / K8s RBAC |
| HTTP 429 Too Many Requests | Rate limiting triggered | Check Retry-After header in response |
| DNS works but connection fails | Firewall blocking traffic at L4 | Test-NetConnection h -Port p |
| Works locally but fails from CI | Private DNS / VPN not configured in CI | Check CI environment network config |
# === Connectivity === ping google.com -n 4 # 4 pings tracert google.com # trace route Test-NetConnection google.com -Port 443 Test-NetConnection google.com -Port 443 -InformationLevel Detailed # === DNS === Resolve-DnsName google.com Resolve-DnsName -Name google.com -Type A Resolve-DnsName -Name google.com -Server 8.8.8.8 ipconfig /flushdns # clear DNS cache ipconfig /displaydns # show cached DNS # === Ports / Connections === netstat -an netstat -ano # with PID Get-NetTCPConnection -State Listen Get-NetTCPConnection | Where-Object LocalPort -eq 8080 # === HTTP (real curl on Win10+) === curl.exe -I https://google.com curl.exe -v https://httpbin.org/get curl.exe -o NUL -s -w "%{http_code}" https://google.com curl.exe -X POST https://httpbin.org/post -H "Content-Type: application/json" -d '{\"key\":\"val\"}' # === TLS Certificate === $r = [Net.HttpWebRequest]::Create("https://google.com") $r.GetResponse() | Out-Null Write-Host "Expires: $($r.ServicePoint.Certificate.GetExpirationDateString())" Write-Host "Issuer: $($r.ServicePoint.Certificate.Issuer)"
dig, curl, nc, openssl, ss, netstat, tracerouteGet-NetFirewallRule | Where-Object Enabled -eq True | Select-Object DisplayName, Direction, Action | Format-TableTest-NetConnection localhost -Port 8080
/etc/hosts:C:\Windows\System32\drivers\etc\hosts127.0.0.1 myapp.local
| Day | Topic | Key Skill Gained | Lab Output |
|---|---|---|---|
| Day 1 | What is DevOps? | CALMS, DORA metrics, Infinity Loop | DORA baseline document |
| Day 2 | DevOps Toolchain | Tool landscape, 3 stacks, toolkit setup | Git + Docker + VS Code installed |
| Day 3 | Agile + DevOps | Scrum, Kanban, DevOps "Done" definition | GitHub Project Kanban board |
| Day 4 | Linux for DevOps | 20 commands, permissions, shell scripting | sysinfo.sh script committed |
| Day 5 | Networking | DNS, HTTP codes, TLS, curl, netstat | Networking notes + debug commands |