Moved homelab-mastery repo content into homelab-mastery/ subdirectory. Covers architecture, concepts, certifications, interview-prep, and learning-path. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
187 lines
8.4 KiB
Markdown
187 lines
8.4 KiB
Markdown
# Networking — The Foundation of Everything
|
||
|
||
This is the most important concept to master. Every other technology in this homelab is built on networking fundamentals. CCNA will teach this deeply — this is the overview.
|
||
|
||
---
|
||
|
||
## IP Addresses
|
||
|
||
Every device on a network has an IP address — a unique identifier.
|
||
|
||
**IPv4:** Four numbers 0–255 separated by dots: `192.168.1.205`
|
||
|
||
**Private ranges** (not routable on the internet, only on local networks):
|
||
- `192.168.x.x` — home networks (your router assigns these)
|
||
- `172.16.x.x – 172.31.x.x` — Docker bridge networks use this range
|
||
- `10.x.x.x` — corporate networks often use this
|
||
|
||
**Public IPs:** Routable on the internet. Your home has one (assigned by ISP). kscloud1 has one (assigned by Hetzner).
|
||
|
||
**Tailscale IPs:** `100.x.x.x` — a special private range used by Tailscale for its overlay network.
|
||
|
||
---
|
||
|
||
## Subnets and CIDR Notation
|
||
|
||
A subnet is a range of IP addresses. CIDR notation describes the range:
|
||
- `192.168.1.0/24` — all addresses from `192.168.1.0` to `192.168.1.255` (256 addresses)
|
||
- `172.16.0.0/12` — a large range covering all Docker bridge networks
|
||
- `/32` — a single IP address
|
||
|
||
The number after `/` is the prefix length — how many bits are fixed. The remaining bits define the host range.
|
||
|
||
In this homelab: `ufw allow from 172.16.0.0/12` allows traffic from any Docker container to the host. That `/12` covers all possible Docker bridge subnet addresses.
|
||
|
||
---
|
||
|
||
## Ports
|
||
|
||
A port is a number (0–65535) that identifies a specific service on a host. Think of the IP address as the building, and the port as the apartment number.
|
||
|
||
**Well-known ports:**
|
||
- 22 — SSH
|
||
- 80 — HTTP
|
||
- 443 — HTTPS
|
||
- 3306 — MySQL/MariaDB
|
||
- 5432 — PostgreSQL
|
||
- 6379 — Redis
|
||
|
||
**Your homelab ports** (just examples — you know yours):
|
||
- Each service binds to a port inside the container
|
||
- Docker maps host ports to container ports: `3006:3000`
|
||
|
||
When a service "listens on a port," it's waiting for TCP/UDP connections on that port. When cloudflared connects to `http://grafana:3000`, it's connecting to IP of the `grafana` container on port 3000.
|
||
|
||
---
|
||
|
||
## DNS — How Names Become IPs
|
||
|
||
DNS (Domain Name System) translates human-readable names to IP addresses.
|
||
|
||
```
|
||
www.kitestacks.com → DNS lookup → Cloudflare's IP address
|
||
grafana → Docker DNS → 172.x.x.x (container IP)
|
||
100.123.x.x → Tailscale DNS → kscloud1
|
||
```
|
||
|
||
**Cloudflare DNS:** You configured NS records to point `kitestacks.com` to Cloudflare's nameservers. Cloudflare then controls all DNS for that domain. The A record for `www.kitestacks.com` points to Cloudflare's anycast IP, not your home IP.
|
||
|
||
**Docker DNS:** Inside the `kitestacks` Docker network, Docker runs an internal DNS server at `127.0.0.11`. When cloudflared looks up `homepage`, Docker DNS returns the container's IP on the bridge network.
|
||
|
||
**How to check DNS:**
|
||
```bash
|
||
dig www.kitestacks.com # what does the public DNS say?
|
||
nslookup grafana # from inside a container
|
||
```
|
||
|
||
---
|
||
|
||
## HTTP vs HTTPS
|
||
|
||
**HTTP (HyperText Transfer Protocol):** Data is sent in plain text. Anyone who can see the network traffic can read it.
|
||
|
||
**HTTPS:** HTTP + TLS encryption. Data is encrypted in transit.
|
||
|
||
**TLS (Transport Layer Security):** A cryptographic protocol. Requires a certificate proving the server is who it claims to be.
|
||
|
||
In this homelab:
|
||
- All internal Docker network traffic is HTTP — it never leaves the host, so encryption isn't needed
|
||
- All public traffic goes through Cloudflare, which handles TLS — Cloudflare terminates HTTPS at the edge
|
||
- Between Cloudflare and cloudflared (the tunnel itself), traffic is encrypted by the tunnel protocol
|
||
|
||
**Certificates:** Cloudflare manages TLS certificates for `*.kitestacks.com` automatically — you don't need to configure Let's Encrypt or buy a certificate.
|
||
|
||
---
|
||
|
||
## Reverse Proxy
|
||
|
||
A reverse proxy sits in front of services and routes requests to them.
|
||
|
||
```
|
||
Client → Reverse Proxy → Service A
|
||
↘ Service B
|
||
↘ Service C
|
||
```
|
||
|
||
In this homelab, Cloudflare + cloudflared acts as the reverse proxy:
|
||
- Receives all inbound HTTPS traffic
|
||
- Decrypts TLS
|
||
- Reads the `Host` header (`www.kitestacks.com`, `grafana.kitestacks.com`, etc.)
|
||
- Routes to the correct container based on the hostname rules you configured
|
||
|
||
nginx (the portal container) is also a reverse proxy — it forwards `/api/*` requests to the metrics API running on the host.
|
||
|
||
---
|
||
|
||
## Cloudflare Tunnel — Deep Dive
|
||
|
||
The tunnel replaces the need for port forwarding. Here's exactly what happens:
|
||
|
||
**Setup (happens once when you start cloudflared):**
|
||
1. cloudflared reads the TUNNEL_TOKEN
|
||
2. It makes an outbound HTTPS connection to Cloudflare's edge servers (`region1.argotunnel.com`)
|
||
3. It authenticates and registers as a connector
|
||
4. Cloudflare keeps this connection open (persistent, long-lived)
|
||
|
||
**When a request comes in:**
|
||
1. User's browser connects to Cloudflare's edge (the public IP in DNS)
|
||
2. Cloudflare sees the Host header: `grafana.kitestacks.com`
|
||
3. Cloudflare looks up the tunnel configuration — `grafana.kitestacks.com` → `http://grafana:3000`
|
||
4. Cloudflare sends the request over the existing tunnel connection to cloudflared
|
||
5. cloudflared resolves `grafana` via Docker DNS → gets container IP
|
||
6. cloudflared forwards the request to the grafana container
|
||
7. Response goes back through the tunnel to Cloudflare → to the user
|
||
|
||
**The key insight:** All of this happens over a single outbound connection from cloudflared. No inbound ports. Your home router doesn't know any of this is happening.
|
||
|
||
---
|
||
|
||
## Tailscale — Overlay Network
|
||
|
||
Tailscale creates a WireGuard mesh between devices. Each device gets a `100.x.x.x` IP that works regardless of physical location or network.
|
||
|
||
**Under the hood:**
|
||
- WireGuard: a modern VPN protocol, UDP-based, very fast, cryptographically simple
|
||
- Tailscale coordinates key exchange via their servers, but actual traffic is peer-to-peer
|
||
- Works behind NAT via UDP hole-punching (most of the time)
|
||
- Falls back to relay servers (DERP) if direct connection isn't possible
|
||
|
||
**Why this matters for the homelab:**
|
||
- kscloud1's Postgres and Redis bind to `100.123.x.x` (Tailscale IP), not `0.0.0.0`
|
||
- Even though kscloud1 has a public IP, the database is unreachable from the internet
|
||
- Only devices on the tailnet can connect to it
|
||
- Monk's Authentik connects to `100.123.x.x:5432` — traffic goes through the encrypted Tailscale tunnel
|
||
|
||
---
|
||
|
||
## Firewall Basics (ufw)
|
||
|
||
ufw (Uncomplicated Firewall) manages Linux's netfilter/iptables rules.
|
||
|
||
```bash
|
||
ufw default deny incoming # block all inbound by default
|
||
ufw allow ssh # allow SSH (port 22)
|
||
ufw allow from 172.16.0.0/12 to any port 8000 # Docker containers → metrics API
|
||
```
|
||
|
||
On kscloud1: ufw blocks everything by default. The exception for `172.16.0.0/12` allows containers (which use 172.x.x.x addresses) to reach port 8000 on the host (where the metrics API runs in host network mode).
|
||
|
||
Without that rule: the homepage container calls `host.docker.internal:8000` → kernel sees source `172.x.x.x` → ufw blocks it → System Status widget shows "Offline."
|
||
|
||
---
|
||
|
||
## What to Know Cold for CCNA
|
||
|
||
- **Subnetting:** Practice calculating subnets. `/24`, `/25`, `/26`, `/27` etc. — know the host ranges by heart.
|
||
- **OSI Model:** 7 layers. Know what each layer does and what protocols live there.
|
||
- **TCP vs UDP:** TCP is reliable (handshake, acknowledgements). UDP is fast (no handshake, fire and forget). HTTP uses TCP. DNS uses UDP (mostly).
|
||
- **The TCP 3-way handshake:** SYN → SYN-ACK → ACK. This is how every TCP connection starts.
|
||
- **ARP:** How a device finds the MAC address for an IP on the same subnet.
|
||
- **Default gateway:** The router. Packets destined for outside the local subnet go to the default gateway.
|
||
- **NAT:** Network Address Translation. How your home router lets multiple devices share one public IP. Crucial to understand — it's why cloudflared uses outbound connections.
|
||
|
||
---
|
||
|
||
## What to Say About Networking
|
||
|
||
> *"The homelab uses Cloudflare Tunnel for all inbound traffic, which means no ports are open on the home router. All nine public subdomains have DNS pointing to Cloudflare, and a cloudflared connector on each host maintains a persistent outbound tunnel. Internally, services communicate over a Docker bridge network using container DNS. A Tailscale overlay network connects monk and kscloud1 for private database access — the shared Authentik Postgres is bound only to the Tailscale interface so it's never exposed to the public internet."*
|