Add network & containerisation
Build and deploy Docusaurus / build-and-deploy (push) Successful in 1m1s

This commit is contained in:
2026-03-10 20:31:37 +01:00
parent a63a0cdc3c
commit 42b8971744
11 changed files with 1102 additions and 52 deletions
+112
View File
@@ -0,0 +1,112 @@
# Containerisation Basics
Generic concepts behind containerisation, applicable to any runtime.
Related pages:
- [Containerisation / Docker Basics](./Docker/Basics.md)
---
## 1. What Is Containerisation?
Containerisation is a lightweight form of virtualisation. Instead of emulating hardware, it isolates applications at the operating-system level: each container runs in its own namespace but shares the host kernel.
Key benefits:
- **Portability** a container image packages the application and its dependencies together and runs the same way on any compatible host.
- **Isolation** processes inside a container cannot directly affect other containers or the host.
- **Efficiency** containers start in milliseconds and consume far less overhead than virtual machines.
- **Reproducibility** images are versioned and built from explicit definitions, making deployments predictable.
---
## 2. Containers vs Virtual Machines
| | Container | Virtual Machine |
|----------------|-----------------------------------------|--------------------------------------------------|
| Kernel | Shared with host | Separate (emulated or paravirtualised) |
| Startup time | Seconds or less | Seconds to minutes |
| Overhead | Very low | Higher (memory, CPU) |
| Isolation | Process-level | Hardware-level |
| Portability | Image-based, very portable | Depends on hypervisor |
Containers are generally chosen when the goal is to package and run applications efficiently. Virtual machines are preferred when stronger isolation or a different operating-system kernel is required.
---
## 3. Core Concepts
### 3.1 Image
An image is a read-only template used to create containers. It bundles:
- A base operating-system layer (for example a minimal Debian or Alpine image).
- Application binaries and their dependencies.
- Configuration and entrypoint instructions.
Images are built from a definition file (for Docker, a `Dockerfile`) and are composed of **layers**. Each layer represents a change on top of the previous one, and layers are cached and reused across images.
### 3.2 Container
A container is a running instance of an image. It is:
- Isolated from the host and other containers through Linux namespaces.
- Resource-limited using control groups (cgroups).
- Ephemeral by default its writable layer is discarded when the container is removed.
Persistent data must be stored outside the container lifecycle using **volumes** or **bind mounts**.
### 3.3 Registry
A registry is a server that stores and distributes container images. Common examples include:
- **Docker Hub** the default public registry.
- **GitHub Container Registry (GHCR)**.
- **Self-hosted** registries (for example Gitea's built-in package registry or a dedicated Harbor instance).
Images are referenced as `registry/name:tag`. The tag identifies a specific version.
### 3.4 Volume
A volume is a mechanism for persisting data independently of the container lifecycle. Two common forms:
- **Managed volumes** created and tracked by the container runtime; stored in a dedicated area on the host.
- **Bind mounts** a specific host directory exposed inside the container at a given path.
---
## 4. Linux Primitives Behind Containers
Containers rely on two core Linux kernel features.
### 4.1 Namespaces
Namespaces provide process-level isolation for system resources so that each container sees only its own view of the system:
- **PID namespace** containers see their own process tree.
- **Network namespace** each container gets its own network stack and interfaces.
- **Mount namespace** containers see their own filesystem tree.
- **UTS namespace** each container can have a distinct hostname.
- **User namespace** container user IDs can be remapped to different host IDs.
### 4.2 cgroups (control groups)
cgroups limit and account for resource consumption per process group:
- CPU usage.
- Memory limits.
- I/O bandwidth.
This prevents a single container from monopolising host resources.
---
## 5. Container Runtimes
Several implementations exist:
- **Docker** the most widely adopted; includes a CLI, a build system, and Docker Compose for multi-container setups. See [Docker / Basics](./Docker/Basics.md).
- **Podman** daemonless and Docker-compatible; supports rootless containers by default.
- **containerd** a lower-level runtime used by Kubernetes and sometimes by Docker as its engine backend.
- **LXC / LXD** older but still used for system containers, which behave more like lightweight virtual machines than application containers.
+176
View File
@@ -0,0 +1,176 @@
# Docker Basics
Docker-specific concepts: architecture, images, containers, volumes, networks, and Compose.
For generic containerisation concepts, see:
- [Containerisation / Basics](../Basics.md)
---
## 1. What Is Docker?
Docker is a platform built around Linux containers. It provides:
- A **container runtime** (`dockerd`, the Docker daemon).
- A **CLI** (`docker`) for building images, running containers, and managing the system.
- A **build system** based on `Dockerfile`.
- **Docker Compose** for defining and running multi-container applications from a single file.
Docker was the tool that popularised application containers and remains the most widely used runtime in self-hosted and production environments.
---
## 2. Architecture
Docker uses a clientserver model:
- **Docker client** (`docker`) the CLI used to issue commands.
- **Docker daemon** (`dockerd`) the background service that manages images, containers, networks, and volumes.
- **Registry** where images are stored and fetched (default: Docker Hub).
When you run `docker run nginx`, the client sends a request to the daemon, which pulls the image from the registry if not already present, then starts the container.
---
## 3. Images
### 3.1 Dockerfile
A `Dockerfile` is a plain text file that describes how to build an image step by step.
```dockerfile
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
```
Each instruction creates a new layer. Docker caches layers to speed up rebuilds only layers that change (and everything after them) are re-executed.
### 3.2 Building Images
Images are built with `docker build`. Common flags:
- `-t name:tag` assign a name and tag.
- `-f Dockerfile.custom` specify a non-default Dockerfile.
- `--no-cache` ignore cached layers and rebuild from scratch.
See [Docker / Commands](./Commands.md) for practical examples.
### 3.3 Image Tags
A tag identifies a specific version of an image: `nginx:1.25`, `nginx:stable`, or `nginx:latest`. Using explicit version tags is safer than `latest`, which always points to the most recent build and can change without notice.
---
## 4. Containers
### 4.1 Lifecycle
A container moves through several states:
- **Created** exists but has not started yet.
- **Running** the main process is active.
- **Paused** processes are suspended.
- **Stopped / Exited** the main process has ended.
- **Removed** the container is deleted; its writable layer is discarded.
Only data stored in volumes or bind mounts survives beyond the container's removal.
### 4.2 Common Run Flags
| Flag | Purpose |
|----------------------------|----------------------------------------------|
| `-d` | Detached mode (run in background) |
| `--name` | Assign a name to the container |
| `-p host:container` | Publish a port to the host |
| `-v host:container` | Bind mount a directory or attach a volume |
| `-e KEY=VALUE` | Set an environment variable |
| `--restart unless-stopped` | Restart policy (survives reboots) |
| `--network` | Attach to a specific Docker network |
---
## 5. Volumes and Bind Mounts
### 5.1 Named Volumes
Volumes are managed by Docker and stored under `/var/lib/docker/volumes/`. They persist across container restarts and removals (unless explicitly deleted with `docker volume rm`).
Use named volumes for data that must survive the container lifecycle: databases, application state, generated files.
### 5.2 Bind Mounts
Bind mounts surface a specific host path inside the container at a chosen mount point. They are suitable for:
- Configuration files managed on the host.
- Application data stored in a known host directory.
Unlike named volumes, bind mounts depend directly on the host filesystem layout and are not tracked by Docker.
---
## 6. Networks
Docker provides several network drivers:
- **bridge** (default) containers on the same bridge network can reach each other by container name. User-defined bridges (created explicitly) support automatic DNS resolution between containers.
- **host** the container shares the host's network stack directly; no network isolation is applied.
- **none** the container has no network access.
- **overlay** multi-host communication (Swarm/Kubernetes); not relevant for single-host setups.
Creating a dedicated user-defined bridge network for each application stack is the recommended approach; it avoids exposing containers to unrelated services.
---
## 7. Docker Compose
Docker Compose defines a multi-container application in a single `compose.yaml` (or `docker-compose.yml`) file.
A minimal example:
```yaml
services:
app:
image: myapp:latest
restart: unless-stopped
ports:
- "8080:80"
volumes:
- /host/appdata/myapp:/data
environment:
- APP_ENV=production
db:
image: postgres:16
restart: unless-stopped
volumes:
- db_data:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=secret
volumes:
db_data:
```
Key Compose concepts:
- **services** each service becomes one container.
- **volumes** named volumes declared here are managed by Docker.
- **networks** Compose creates a default user-defined bridge network per project; services reach each other by service name.
- **env_file** loads environment variables from a file; useful to keep secrets out of `compose.yaml`.
For Compose command examples, see [Docker / Commands](./Commands.md).
---
## 8. Relation to Other Documents
- [Containerisation / Basics](../Basics.md)
- [Docker / Commands](./Commands.md)
- [Home-Server / Docker Stacks](../../Home-Server/Containers/Stacks.md)
+183
View File
@@ -0,0 +1,183 @@
# Docker Commands
Practical Docker and Docker Compose command reference. Each block groups related commands with inline comments.
For the concepts behind these commands, see:
- [Docker / Basics](./Basics.md)
---
## 1. Images
```bash
# List local images
docker images
# Pull an image from a registry
docker pull nginx:stable
# Build an image from a Dockerfile in the current directory
docker build -t myapp:1.0 .
# Build with a custom Dockerfile
docker build -f Dockerfile.prod -t myapp:prod .
# Tag an existing image
docker tag myapp:1.0 myapp:latest
# Remove an image
docker rmi myapp:1.0
# Remove all unused images (dangling and unreferenced)
docker image prune -a
```
---
## 2. Container Lifecycle
```bash
# Run a container in detached mode
docker run -d --name myapp -p 8080:80 nginx:stable
# Run with a bind mount, environment variable, and restart policy
docker run -d \
--name myapp \
-v /host/data:/app/data \
-e APP_ENV=production \
--restart unless-stopped \
myapp:1.0
# Start / stop / restart a container
docker start myapp
docker stop myapp
docker restart myapp
# List running containers
docker ps
# List all containers (including stopped)
docker ps -a
# Remove a stopped container
docker rm myapp
# Stop and remove in one go
docker stop myapp && docker rm myapp
```
---
## 3. Logs and Inspection
```bash
# View container logs
docker logs myapp
# Follow logs in real time
docker logs -f myapp
# Show last 50 lines
docker logs --tail 50 myapp
# Execute a command inside a running container
docker exec -it myapp bash # interactive shell
docker exec myapp ls /app # one-off command
# Inspect container configuration and networking
docker inspect myapp
# Show live resource usage for all running containers
docker stats
```
---
## 4. Volumes
```bash
# List volumes
docker volume ls
# Create a named volume
docker volume create mydata
# Inspect a volume (shows mount path on host)
docker volume inspect mydata
# Remove a volume
docker volume rm mydata
# Remove all unused volumes
docker volume prune
```
---
## 5. Networks
```bash
# List networks
docker network ls
# Create a user-defined bridge network
docker network create mynet
# Connect a running container to a network
docker network connect mynet myapp
# Inspect a network (shows connected containers)
docker network inspect mynet
# Remove a network
docker network rm mynet
```
---
## 6. Docker Compose
```bash
# Start all services in detached mode
docker compose up -d
# Stop and remove containers (volumes are kept)
docker compose down
# Stop and remove containers AND named volumes
docker compose down -v
# Rebuild images before starting
docker compose up -d --build
# Restart a single service
docker compose restart app
# View logs for all services
docker compose logs -f
# View logs for one service
docker compose logs -f app
# List containers for the current project
docker compose ps
# Execute a command inside a service container
docker compose exec app bash
```
---
## 7. System Cleanup
```bash
# Show disk usage by Docker objects (images, containers, volumes, cache)
docker system df
# Remove all stopped containers, unused networks, dangling images, and build cache
docker system prune
# Same but also remove unused non-dangling images
docker system prune -a
```
+1 -1
View File
@@ -49,7 +49,7 @@ Docker runs on the Debian host and is my main way to deploy services.
- Typical services:
- Media: Komga (ebooks), Jellyfin (videos).
- Dev: Gitea + Postgres.
- Security: Vaultwarden.
- Password manager: Vaultwarden.
- Monitoring: Homepage, Uptime Kuma, Dozzle, Glances.
- Containers use `restart: unless-stopped` so they come back after reboot.
+111 -8
View File
@@ -1,16 +1,119 @@
# Network Basics
This page is for general networking concepts I reuse across projects.
Core networking concepts: IP addressing, subnets, ports, routing, and protocols.
At the end of each topic, I link to my home server implementation when it exists.
Related detailed pages:
Related pages:
- [Network / DNS](./DNS.md)
- [Network / VPN Basics](./VPN/Basics.md)
- [Network / Reverse Proxy](./ReverseProxy.md)
- [Network / SSH](./SSH.md)
- [Network / VPN Basics](./VPN/Basics.md)
- [Network / Firewall](./Firewall.md)
## TODO
---
- Add sections for IP addressing, routing, DNS, and HTTP(S).
- Link to home-server implementation pages from each section.
## 1. IP Addresses
Every device on a network is identified by an **IP address**. The most common version is IPv4, written as four numbers separated by dots: `192.168.1.18`. Each number is between 0 and 255, giving 4 bytes (32 bits) per address.
### 1.1 Private vs Public Addresses
Some ranges are reserved for private use — they are only valid inside a local network and are never routed on the public internet:
| Range | Example | Common use |
|-------------------|-----------------|------------------------------|
| `10.0.0.0/8` | `10.10.10.1` | VPNs, corporate networks |
| `172.16.0.0/12` | `172.16.0.1` | Docker default bridge |
| `192.168.0.0/16` | `192.168.1.18` | Home/office LANs |
Everything else is a **public** address, routable on the internet. Your internet box has one public IP assigned by your ISP.
### 1.2 Subnets and CIDR Notation
A subnet groups a range of IP addresses together. The size is expressed with **CIDR notation**: a `/` followed by the number of fixed bits.
- `/24` → first 24 bits are fixed → 256 addresses (`192.168.1.0` to `192.168.1.255`).
- `/32` → all 32 bits are fixed → exactly one address.
- `/16` → first 16 bits are fixed → 65 536 addresses.
The most common home network is a `/24`, for example `192.168.1.0/24`.
A **subnet mask** expresses the same thing differently: `/24``255.255.255.0`.
---
## 2. Ports
An IP address identifies a machine. A **port** identifies a specific service or application running on that machine. Ports are numbers from 0 to 65 535.
When two machines communicate they use an IP + port pair: `192.168.1.18:80`.
### 2.1 Why Ports Exist
A server typically runs several services at once — a web server, an SSH daemon, a database, etc. Ports allow the OS to route each incoming packet to the correct service.
- A packet arrives at `192.168.1.18:443` → the OS delivers it to the HTTPS server.
- A packet arrives at `192.168.1.18:22` → the OS delivers it to the SSH daemon.
When you "open a port", you are telling a firewall or router to allow traffic destined for that port number to pass through.
### 2.2 TCP vs UDP
| Protocol | Characteristics | Common uses |
|----------|--------------------------------------------------------------|-------------------------------------------|
| **TCP** | Connection-oriented, reliable, ordered delivery | HTTP/HTTPS, SSH, databases, email |
| **UDP** | Connectionless, no delivery guarantee, lower overhead | DNS, WireGuard, video streaming, QUIC |
TCP establishes a connection before transferring data and retransmits lost packets. UDP fires packets without verifying receipt — faster but not guaranteed.
### 2.3 Well-Known Ports
Ports 01023 are "well-known" — standardised assignments used by common services:
| Port | Protocol | Service |
|-------|----------|--------------------------|
| 22 | TCP | SSH |
| 53 | TCP/UDP | DNS |
| 80 | TCP | HTTP |
| 443 | TCP | HTTPS |
| 51820 | UDP | WireGuard (conventional) |
Ports 102449 151 are "registered". Ports 49 15265 535 are "dynamic" (used temporarily for outbound connections).
For filtering and controlling port access, see [Network / Firewall](./Firewall.md).
---
## 3. Routing
Routing is the process of forwarding packets from one network to another. At home this is mostly transparent:
1. Your device sends a packet.
2. If the destination is on the same subnet, it is delivered directly.
3. Otherwise it is sent to the **default gateway** (your router), which forwards it towards the internet.
The default gateway is normally the IP of your router on the local network (for example `192.168.1.1`).
---
## 4. HTTP and HTTPS
**HTTP** (HyperText Transfer Protocol) is the protocol used by web browsers and APIs. It is a request-response protocol over TCP:
- A client sends a request: `GET /page HTTP/1.1`
- A server responds with a status code and a body: `200 OK`
**HTTPS** is HTTP over a **TLS** (Transport Layer Security) encrypted connection. TLS:
- Encrypts traffic so it cannot be read in transit.
- Authenticates the server via a certificate.
Modern browsers require HTTPS. Self-signed certificates work for internal networks but require the client to explicitly trust the issuing CA.
For TLS and certificates in depth, see:
- [Security / Certificates](../Security/Certificates.md)
For HTTP routing via a reverse proxy, see:
- [Network / Reverse Proxy](./ReverseProxy.md)
+85 -10
View File
@@ -1,18 +1,93 @@
# DNS Basics
This page is for generic DNS concepts I reuse across projects.
How domain names are resolved to IP addresses, and how local DNS differs from public DNS.
## Scope
For generic networking concepts, see:
- What DNS does (names → IPs).
- Difference between public DNS and internal DNS.
- Common record types (A, AAAA, CNAME, etc.).
## Notes / TODO
- Add examples with public domains.
- Explain how internal `.lan` domains fit into this picture.
- [Network / Basics](./Basics.md)
For my concrete home server DNS setup, see:
- [Home-Server / dnsmasq implementation](../Home-Server/Implementations/DNS/dnsmasq.md)
---
## Scope
- What DNS does and why it exists.
- How a query is resolved step by step.
- Common record types.
- Public DNS vs internal / split DNS.
- TTL.
---
## 1. What DNS Does
DNS (Domain Name System) translates human-readable names like `google.com` into IP addresses like `142.250.74.46`. Without DNS, every user would need to memorise the IP of every service they use.
DNS is a globally distributed, hierarchical database. No single server knows all names — responsibility is delegated across thousands of authoritative name servers worldwide.
---
## 2. How a Query Is Resolved
When your browser wants to reach `www.example.com`:
1. **Local cache** — the OS checks if it already has a recent cached answer.
2. **Stub resolver** — the OS sends the query to its configured DNS server (usually the router or a public resolver).
3. **Recursive resolver** — if not cached, this server performs the full lookup:
- Asks a **root server**: *"Who handles `.com`?"*
- Asks the **.com TLD server**: *"Who handles `example.com`?"*
- Asks the **authoritative name server** for `example.com`: *"What is `www.example.com`?"*
4. The answer (an IP address) travels back and is cached at each level.
5. The OS delivers the IP to the browser, which opens a TCP connection.
This whole process typically takes a few milliseconds.
---
## 3. Common Record Types
| Type | Purpose | Example |
|---------|-------------------------------------------------------|--------------------------------------------|
| `A` | Maps a name to an IPv4 address | `example.com → 93.184.216.34` |
| `AAAA` | Maps a name to an IPv6 address | `example.com → 2606:2800:…` |
| `CNAME` | Alias: maps one name to another name | `www.example.com → example.com` |
| `MX` | Mail server for a domain | `@ → mail.example.com` |
| `TXT` | Arbitrary text; used for SPF, DKIM, domain ownership | `"v=spf1 include:…"` |
| `PTR` | Reverse lookup: IP → name | `34.216.184.93.in-addr.arpa → example.com` |
| `NS` | Authoritative name server(s) for a zone | `example.com → ns1.example.com` |
In practice, `A`, `CNAME`, and `TXT` are the records encountered most often.
---
## 4. Public DNS vs Internal DNS
### 4.1 Public DNS
Public resolvers answer queries for any registered domain on the internet. Common examples:
- `8.8.8.8` / `8.8.4.4` — Google DNS
- `1.1.1.1` / `1.0.0.1` — Cloudflare DNS
- `9.9.9.9` — Quad9
Your OS or router is configured to use one of these by default.
### 4.2 Internal / Local DNS
For names that only exist inside a private network (like `.lan` domains on a home server), you need an **internal DNS server**. It answers queries for private names and forwards everything else to a public resolver.
This is called **split DNS**: different names are resolved by different servers depending on which network you are on.
---
## 5. TTL (Time To Live)
Every DNS record has a **TTL** — a duration in seconds telling resolvers how long they may cache the answer.
- Short TTL (60300 s): changes propagate quickly, but more queries are made.
- Long TTL (360086400 s): reduces query load, but changes are slow to propagate everywhere.
When changing a record (for example updating an IP), it is common to lower the TTL beforehand to speed up propagation.
+99
View File
@@ -0,0 +1,99 @@
# Firewall Basics
What a firewall does, how packet filtering works, and the relationship between ports and rules.
For generic networking concepts, see:
- [Network / Basics](./Basics.md)
---
## Scope
- What a firewall is and why it matters.
- Stateless vs stateful filtering.
- Inbound vs outbound rules.
- How ports relate to firewall rules.
- Linux firewall tooling.
---
## 1. What Is a Firewall?
A **firewall** is a system that controls which network traffic is allowed to pass, based on a set of rules. It can run on a dedicated appliance, a router, or directly on the host OS.
Rules are evaluated against packet attributes:
- Source and destination IP address.
- Source and destination port.
- Protocol (TCP or UDP).
- Connection state.
Traffic that does not match any allow rule is typically **dropped** (silently discarded) or **rejected** (a "connection refused" response is sent back).
---
## 2. Stateless vs Stateful Filtering
### 2.1 Stateless
Each packet is evaluated independently. The firewall has no memory of previous packets.
Simple and fast, but incomplete: to allow a TCP connection, you would need to explicitly create rules in both directions, since the response packets are separate.
### 2.2 Stateful (Connection Tracking)
The firewall tracks the state of each connection. It knows whether a packet is:
- **NEW** — initiating a new connection.
- **ESTABLISHED** — part of an already-allowed connection.
- **RELATED** — related to an existing connection (for example an FTP data channel).
This makes rules much simpler: allow NEW connections matching certain criteria, and the return traffic (ESTABLISHED/RELATED) is automatically let through. Most modern host firewalls are stateful, including Linux `nftables` and `iptables`.
---
## 3. Inbound vs Outbound Rules
- **Inbound (ingress)** — traffic arriving at the machine from outside. This is where most filtering happens: blocking access to ports that should not be public.
- **Outbound (egress)** — traffic leaving the machine. Often unrestricted on home or personal servers, but can be tightened in high-security environments.
---
## 4. Ports and Firewall Rules
"Opening a port" means adding an inbound rule to allow traffic on that port number to reach the service listening on it.
Example rule set:
| Action | Protocol | Port | Source | Effect |
|--------|----------|-------|-------------------|-------------------------------------------|
| ALLOW | TCP | 443 | any | Anyone can reach the HTTPS reverse proxy |
| ALLOW | TCP | 80 | any | HTTP (redirect to HTTPS) |
| ALLOW | TCP | 22 | 192.168.1.0/24 | SSH only from the local network |
| ALLOW | UDP | 51820 | any | WireGuard peers can connect |
| DROP | TCP | 5432 | any | PostgreSQL is not accessible externally |
Good practice: only allow ports that are actively needed. Every exposed port is a potential attack surface.
---
## 5. Linux Firewall Tooling
Linux manages packet filtering through **Netfilter**, a subsystem built into the kernel. Several tools provide a user-space interface to it:
| Tool | Description |
|-------------|---------------------------------------------------------------------------------------|
| `iptables` | The classic interface to Netfilter. Still widely used, but being replaced by `nftables`. |
| `nftables` | The modern replacement for `iptables`. Cleaner syntax, better performance. |
| `ufw` | "Uncomplicated Firewall" — a simplified front-end for `iptables`. Good for basic setups. |
| `firewalld` | Dynamic firewall manager used on RHEL/Fedora systems. |
On Debian, `ufw` or direct `nftables` rules are the most common choices.
---
## Notes / TODO
- Document the actual firewall rules in use on the home server (ports 80, 443, 22, 51820).
- Create `Home-Server/Implementations/Firewall.md` once the setup is confirmed.
+85 -10
View File
@@ -1,18 +1,93 @@
# Reverse Proxy Basics
This page is for generic reverse-proxy concepts (HTTP, HTTPS, virtual hosts) without being tied to a specific tool.
What a reverse proxy does and why it sits in front of web services.
## Scope
For generic networking concepts, see:
- Role of a reverse proxy in front of services.
- Virtual hosts and routing by hostname.
- TLS termination and certificates.
## Notes / TODO
- Add a small diagram of client → reverse proxy → backend.
- Compare briefly Caddy / Nginx / Traefik.
- [Network / Basics](./Basics.md)
- [Security / Certificates](../Security/Certificates.md)
For my concrete Caddy setup on the home server, see:
- [Home-Server / Caddy implementation](../Home-Server/Implementations/DNS/Caddy.md)
---
## Scope
- What a reverse proxy is and how it differs from a forward proxy.
- Routing by hostname (virtual hosts).
- TLS termination.
- Brief comparison of common tools.
---
## 1. What Is a Reverse Proxy?
A **reverse proxy** is a server that sits in front of one or more backend services. Clients connect to the proxy, and the proxy forwards the request to the appropriate backend.
```
Client → Reverse Proxy → Backend service A
→ Backend service B
→ Backend service C
```
From the client's perspective there is only one entry point. The proxy hides the internal layout of services.
A **forward proxy** is the opposite: it sits in front of clients and forwards their requests to external servers (used to filter or log outbound internet traffic). What is described here is always the reverse variant.
---
## 2. Why Use One?
- **Single entry point** — all traffic enters on ports 80 and 443. Backends do not need to be exposed directly.
- **Hostname-based routing** — one IP can serve many services, each with its own domain name.
- **TLS termination** — HTTPS is handled once at the proxy; backends communicate over plain HTTP internally.
- **Centralised logging** — request logs are in one place.
- **Header manipulation** — add security headers, forward the real client IP, etc.
---
## 3. Hostname-Based Routing (Virtual Hosts)
HTTP/1.1 requires clients to send the target hostname in the `Host` header. HTTPS clients send it via **SNI** (Server Name Indication) during the TLS handshake.
The reverse proxy reads this and routes to the matching backend:
| Incoming host | Forwards to |
|---------------------|-----------------------|
| `jellyfin.lan` | `localhost:8096` |
| `vaultwarden.lan` | `localhost:8080` |
| `home.lan` | `localhost:3000` |
This is how a single machine with one IP can serve many services on the same port 443.
---
## 4. TLS Termination
**TLS termination** means the reverse proxy handles HTTPS encryption and decryption. Each client sees a valid HTTPS connection; the proxy communicates with backends over plain HTTP on the internal network.
This simplifies backends — they do not need to manage certificates themselves.
Two certificate scenarios:
- **Public domain + Let's Encrypt** — certificates are fetched automatically via the ACME protocol (HTTP-01 or DNS-01 challenge). Trusted by all browsers.
- **Internal network** — a private CA issues certificates. Browsers need to import and trust this CA's root certificate. Tools like Caddy automate this with `tls internal`.
For more on certificates and trust chains, see:
- [Security / Certificates](../Security/Certificates.md)
---
## 5. Common Tools
| Tool | Notable characteristics |
|-------------|-----------------------------------------------------------------------------------------------------|
| **Caddy** | Automatic HTTPS by default (Let's Encrypt + internal CA), simple `Caddyfile` syntax, minimal setup |
| **Nginx** | Very widely used, highly configurable, manual certificate management (or paired with Certbot) |
| **Traefik** | Docker-native, auto-discovers services via container labels, suited for dynamic environments |
| **HAProxy** | Focus on high-performance load balancing, lower-level than the others |
For a personal home server, Caddy or Traefik are the most convenient.
+124 -1
View File
@@ -1 +1,124 @@
## TODO
# SSH Basics
How SSH works, key-based authentication, the config file, and port forwarding.
For generic networking concepts, see:
- [Network / Basics](./Basics.md)
---
## 1. What Is SSH?
**SSH** (Secure Shell) is a protocol for opening an encrypted remote session on another machine. It is used primarily to:
- Open an interactive shell on a remote server.
- Transfer files securely (`scp`, `rsync over SSH`, `sftp`).
- Create encrypted tunnels for forwarding traffic.
SSH runs on port 22 by default (TCP). All communication is encrypted end to end.
---
## 2. Password vs Key-Based Authentication
### 2.1 Password Authentication
The simplest method: the client sends a username and password. The server verifies against its user database.
Drawbacks:
- Vulnerable to brute-force attacks.
- Must type a password every time.
- Commonly disabled on hardened servers.
### 2.2 Key-Based Authentication
The client holds a **private key** (kept secret). The server holds the corresponding **public key** in `~/.ssh/authorized_keys`.
Authentication process:
1. The server sends a challenge that can only be answered by the holder of the private key.
2. The client responds without ever transmitting the private key itself.
3. The server grants access.
This is the recommended method:
- No credential is transmitted over the network.
- Easy to revoke: just remove the public key from the server.
- The private key can be further protected by a local passphrase.
```bash
# Generate a key pair (ed25519 is the modern recommended algorithm)
ssh-keygen -t ed25519 -C "my-laptop"
# → creates ~/.ssh/id_ed25519 (private) and ~/.ssh/id_ed25519.pub (public)
# Copy the public key to a remote server
ssh-copy-id user@192.168.1.18
```
---
## 3. SSH Config File
The file `~/.ssh/config` lets you define shortcuts and options per host, so you don't have to type them every time.
```
Host homeserver
HostName 192.168.1.18
User myuser
IdentityFile ~/.ssh/id_ed25519
Port 22
```
With this, `ssh homeserver` expands to the full connection automatically.
| Option | Purpose |
|--------------------------|-------------------------------------------------------------|
| `HostName` | Real hostname or IP |
| `User` | Login username |
| `IdentityFile` | Path to the private key to use |
| `Port` | SSH port if non-standard |
| `ServerAliveInterval` | Send keepalive packets to avoid dropped idle connections |
---
## 4. Port Forwarding and Tunnels
SSH can forward network traffic through the encrypted connection, acting as a lightweight alternative to a VPN.
### 4.1 Local Forwarding
Makes a port on the remote machine accessible locally:
```bash
ssh -L 8080:localhost:8096 homeserver
# localhost:8080 on your machine now reaches the server's port 8096
```
Useful for accessing a service on a remote machine without exposing it publicly.
### 4.2 Reverse Forwarding
Makes a local port accessible on the remote machine. Useful for reaching a machine that is behind NAT and cannot accept inbound connections directly.
### 4.3 Dynamic / SOCKS Proxy
```bash
ssh -D 1080 homeserver
# Creates a local SOCKS5 proxy — configure your browser to route traffic through localhost:1080
```
All proxied traffic goes via the server. A basic VPN alternative for browser traffic.
---
## 5. Hardening Notes
Common practices for securing an SSH server:
- Disable password authentication (`PasswordAuthentication no` in `/etc/ssh/sshd_config`).
- Disable root login (`PermitRootLogin no`).
- Restrict to specific users with `AllowUsers myuser`.
- Use a firewall to limit which source IPs can reach port 22.
- Optionally move SSH to a non-standard port to reduce automated scanning noise (not a real security fix, but reduces log clutter).
+120 -4
View File
@@ -1,12 +1,128 @@
# VPN Basics
This page is for generic VPN concepts (tunnels, peers, routing, AllowedIPs) without being tied to a specific implementation.
What a VPN does, full tunnel vs split tunnel, and the key concepts behind WireGuard.
## TODO
For generic networking concepts, see:
- Summarise common patterns for split-tunnel vs full-tunnel.
- Explain the idea of "server" vs "peer" in WireGuard terms.
- [Network / Basics](../Basics.md)
For my concrete WireGuard setup on the home server, see:
- [Home-Server / WireGuard implementation](../../Home-Server/Implementations/VPN/WireGuard.md)
---
## 1. What Is a VPN?
A **VPN** (Virtual Private Network) creates an **encrypted tunnel** between two network endpoints. Any traffic sent through it is:
- **Encrypted** — cannot be read by anyone in between.
- **Encapsulated** — wrapped inside VPN packets so the underlying network only sees opaque data.
From the application's perspective, the other end of the tunnel behaves as if it were directly reachable on the local network.
Common use cases:
- Accessing services on a home network remotely.
- Encrypting traffic on untrusted networks (public Wi-Fi).
- Linking two separate networks together (site-to-site VPN).
---
## 2. Full Tunnel vs Split Tunnel
### 2.1 Full Tunnel
All traffic from the client goes through the VPN — including regular internet browsing. The VPN server becomes the client's internet gateway.
```
All traffic → VPN server → internet
```
Use case: strong privacy, hiding traffic from the local ISP. Slower because everything is routed via the server.
### 2.2 Split Tunnel
Only traffic to specific IP ranges goes through the VPN. Everything else uses the client's normal connection directly.
```
192.168.1.0/24 → VPN server → home network
10.10.10.0/24 → VPN server → VPN peers
Everything else → direct internet (no VPN)
```
Use case: accessing home services remotely while keeping normal internet performance. This is the typical choice for a home server VPN.
In WireGuard, this is controlled by the `AllowedIPs` field on the client — see section 3.3.
---
## 3. WireGuard Concepts
WireGuard is a modern VPN protocol built into the Linux kernel. It is simpler, faster, and uses more modern cryptography than OpenVPN or IPsec.
### 3.1 Interface and Peers
WireGuard creates a virtual network interface (for example `wg0`). You then define **peers** — the other endpoints allowed to communicate through it.
There is no hard "server vs client" distinction in the protocol. In practice, one machine (the home server) has a stable public address and acts as the hub. But cryptographically, every participant is just a peer.
### 3.2 Public/Private Key Pairs
Each WireGuard peer has a **key pair**:
- **Private key** — stays on the peer, never shared with anyone.
- **Public key** — shared with all peers that need to communicate with this one.
Authentication is purely cryptographic: no passwords, no certificates, no CA. Holding the private key matching a registered public key is sufficient.
```bash
# Generate a key pair
wg genkey | tee privatekey | wg pubkey > publickey
```
### 3.3 AllowedIPs
`AllowedIPs` is the most important WireGuard concept. It does two things simultaneously:
1. **Outbound routing** — tells the interface which destination IPs should be sent through this peer.
2. **Inbound access control** — only packets with a source IP inside `AllowedIPs` are accepted from this peer.
Example on the **server** side (describing a client peer):
```ini
[Peer]
PublicKey = <client-public-key>
AllowedIPs = 10.10.10.2/32 # only this specific client VPN IP is valid
```
Example on the **client** side (describing the server peer):
```ini
[Peer]
PublicKey = <server-public-key>
Endpoint = <server-public-ip>:51820
AllowedIPs = 10.10.10.0/24, 192.168.1.0/24 # split tunnel — only these ranges go through the VPN
```
Setting `AllowedIPs = 0.0.0.0/0` on the client is a full tunnel — all traffic goes through the server.
### 3.4 Endpoint
The `Endpoint` field specifies the real IP address and UDP port used to reach a peer. Only the server needs a stable, publicly reachable endpoint. Roaming clients can omit it — their endpoint is learned dynamically from the first packet they send.
WireGuard uses **UDP** (port 51820 by convention). This port must be open in the server's firewall.
### 3.5 PersistentKeepalive
Because WireGuard uses UDP, NAT routers may drop the session mapping if no packet is sent for a while. Setting `PersistentKeepalive = 25` on a client makes it send a small keepalive packet every 25 seconds to maintain the NAT entry.
---
## 4. WireGuard vs Other Protocols
| Protocol | Complexity | Performance | Notes |
|---------------|------------|-------------|-----------------------------------------------------|
| **WireGuard** | Low | Very high | In-kernel on Linux, ~4 000 lines of code, modern crypto |
| **OpenVPN** | Medium | Medium | Mature, widely supported, certificate-based |
| **IPsec** | High | High | Enterprise standard, very complex to configure |