kitestacks-homelab/homelab-mastery/concepts/networking.md
kenpat 0d3fc4051c merge: add homelab-mastery as subdir
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>
2026-06-19 00:33:54 -05:00

8.4 KiB
Raw Blame History

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 0255 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 (065535) 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:

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.comhttp://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.

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."