commit ea04e059e3741ff53ccbfbcfdda22c7325cacb3e Author: ducoterra Date: Tue Aug 18 19:36:46 2026 -0400 add initial 3 lessons diff --git a/lesson1.md b/lesson1.md new file mode 100644 index 0000000..3747301 --- /dev/null +++ b/lesson1.md @@ -0,0 +1,159 @@ +# Basic Linux Commands (Bash) + +Almost every software engineer, sysadmin, and DevOps person uses the terminal daily. +This lesson takes you from never having used Linux to being comfortable navigating +and managing files on a machine. You can practice on a Raspberry Pi, a cloud VM, +or any Linux distro — the commands are the same. + +## 1. What is a terminal? + +A terminal is a text window where you type a command and press Enter. The program +that reads your commands is called a **shell**. On most Linux systems (including +Raspberry Pi OS) it's **Bash**. + +To open one on the Pi, press `Ctrl+Alt+T` or find "Terminal" in the menu. + +Commands in this lesson go in code boxes. Type exactly what's in the box and press +Enter. Anything in a box by itself is a command; anything after `#` is a comment +explaining it — don't type that part. + +## 2. Your first commands + +Run these one by one and read the output: + +``` +whoami # prints your username +pwd # prints your current folder (your "address") +ls # lists the files in your current folder +date # prints the date and time +``` + +Linux organizes everything as files and folders in one big tree. The very top +folder is `/` (the root), and your personal folder (like `/home/pi`) is your home. + +## 3. Moving around + +``` +ls # what's in this folder +ls -la # everything, including hidden files, with details +cd downloads # go into a folder (no space between cd and the name) +cd .. # go up one level +cd ~ # go to your home folder (cd with no argument does the same) +``` + +Tip: type the first few letters of a folder name and press **Tab** — Linux +autocompletes it for you. Use Tab constantly. + +## 4. Files and folders + +``` +touch notes.txt # create an empty file +mkdir projects # create a folder +mkdir -p projects/web/app # create nested folders in one go +cp notes.txt backup.txt # copy a file +mv notes.txt projects/ # move a file (or rename it) +rm backup.txt # delete a file +rm -r projects # delete a folder and everything inside it +``` + +Warning: `rm` does not ask "are you sure?" and there is no trash bin. Deleted is +deleted. Read your command carefully before pressing Enter — especially `rm -rf`, +which deletes recursively without mercy. + +## 5. Looking at files + +``` +cat notes.txt # print the whole file +head notes.txt # first 10 lines +tail notes.txt # last 10 lines +less notes.txt # scroll through a big file (press q to quit) +``` + +## 6. Writing to files + +``` +echo "hello" > notes.txt # write (overwrites the file if it exists) +echo "second line" >> notes.txt # append (>> adds to the end) +``` + +## 7. Editing files: nano + +`nano` is the standard beginner editor. Open a file with: + +``` +nano notes.txt +``` + +Now you can edit. The keys you need are shown at the bottom of the screen: + +- `Ctrl+O` then `Enter` — save (it calls saving "Write Out") +- `Ctrl+X` — quit + +If it asks "Save modified buffer?" when you quit, press `y`, then `Enter`. + +## 8. Searching and pipes + +``` +grep "hello" notes.txt # print only the lines containing "hello" +ls | grep notes # list only files whose name contains "notes" +``` + +That `|` is called a **pipe**. It takes the output of the command on the left and +feeds it as input to the command on the right. Piping small tools together is one +of the core ideas of Linux — small commands that each do one thing, chained up. + +## 9. Getting help + +``` +ls --help # short summary of how to use a command +man ls # full manual page (press q to quit) +``` + +When you don't know a command, `man` is the first place to look. It's on the +machine itself, so it works even without internet. + +## 10. Installing software: apt + +On Raspberry Pi OS (and Ubuntu/Debian), software comes in packages managed by +`apt`. `sudo` means "run this as the administrator" and it will ask for your +password: + +``` +sudo apt update # refresh the list of available packages +sudo apt install -y curl # install a package (the -y means "yes to prompts") +sudo apt remove curl # remove a package +``` + +## 11. About your system + +``` +uname -a # what machine and kernel this is +df -h # how much disk space is left +free -h # how much memory is in use +history # everything you've typed so far +clear # clear the screen +``` + +## 12. Shortcuts that feel like magic + +- **Tab** — autocomplete a command or filename +- **Up/Down arrows** — cycle through your previous commands +- **Ctrl+C** — stop whatever is currently running +- **Ctrl+L** — clear the screen (same as `clear`) +- **Ctrl+R** — search your command history: start typing the old command, keep + pressing Ctrl+R to cycle through matches, Enter to run it + +## Practice + +Try these from memory (scroll up only when you're stuck): + +1. Create a folder called `lesson1` and go into it. +2. Create a file `hello.txt` containing the line `hello world`. +3. Append a second line: `second line`. +4. Print only the lines containing `hello`. +5. Copy `hello.txt` to `hello-backup.txt`, then delete the original. +6. Print the first line of `hello-backup.txt`. + +If you can do all six without looking, you know the essentials: `pwd`, `ls`, `cd`, +`touch`, `nano`, `cat`, `rm`, `cp`, `mv`, `grep`, and pipes. That's the toolkit +you'll reach for on any Linux machine. diff --git a/lesson2.md b/lesson2.md new file mode 100644 index 0000000..78cd514 --- /dev/null +++ b/lesson2.md @@ -0,0 +1,285 @@ +# Raspberry Pi VPN (Networking) + +In this lesson you'll build a personal VPN server on your Raspberry Pi using +**WireGuard** — the modern standard for VPNs. It gives you a private road into +your home network: when you're at school, at a friend's house, or on vacation, +you can reach devices on your home Wi-Fi — the Pi, a NAS, a media server, a smart +home dashboard — as if your phone were plugged into the house. + +As a side effect, the road is encrypted, so nobody in between can read what +you're accessing. + +## How it works + +A quick networking refresher so the steps make sense: + +- Devices on your home network get **local** IP addresses like + `192.168.1.42`. To the internet, your whole house appears as **one** public IP + address (the router's). +- By default the internet can only knock on the front door — the router. To reach + devices *inside* the house, we set up one exception: the Pi runs a VPN server, + and the router forwards that one port to it. +- A VPN creates an **encrypted tunnel** between your phone and the Pi. Inside the + tunnel we use our own private addresses: the Pi is `10.100.0.1`, your phone is + `10.100.0.2`. +- When you connect, your phone has two identities at once: it's on your carrier's + network *and* on your home network. Anything in your home range + (`192.168.1.x`) travels through the tunnel into the house. + +``` +phone --encrypted tunnel--> Pi --home network--> NAS, Pi, media server, ... +``` + +**Check your own network first:** find your Pi's local IP on the Pi with +`hostname -I`. This lesson assumes it looks like `192.168.1.42`, so the home +range is `192.168.1.0/24`. If your router uses a different range (some use +`192.168.0.x` or `10.0.0.x`), substitute yours everywhere. + +## What you need + +- A Raspberry Pi running Raspberry Pi OS, connected to your home network (wired + ethernet is best and easiest) +- Your phone, with the official **WireGuard** app (iOS or Android) +- Access to your router's admin page (usually `192.168.1.1` in a browser) + +## Step 1 — Install WireGuard on the Pi + +``` +sudo apt update +sudo apt install -y wireguard wireguard-tools nftables qrencode +``` + +(`qrencode` prints a scannable QR code; `nftables` handles the forwarding rules +later.) + +## Step 2 — Create the server's keys + +Every WireGuard device has a **private key** (a secret) and a **public key** +(safe to share). Think of them like a password and a public address. The Pi gets +its pair now: + +``` +sudo -i +cd /etc/wireguard +umask 077 +wg genkey | tee server.key | wg pubkey > server.pub +cat server.key +``` + +- `sudo -i` logs you in as the administrator account (root). Type `exit` at the + end of each root session to go back to your normal user. +- `umask 077` makes sure new files are only readable by you. +- Copy the long string from `cat server.key` — you'll paste it into the config in + the next step. **Never share your private key.** The public key (`server.pub`) + is fine to share. + +## Step 3 — Write the server config + +Still as root, open the config file: + +``` +nano /etc/wireguard/wg0.conf +``` + +Type this, replacing the last line with your server's private key: + +``` +[Interface] +Address = 10.100.0.1/24, fd08:4711::1/64 +ListenPort = 47111 +PrivateKey = PASTE_YOUR_SERVER_PRIVATE_KEY_HERE +``` + +Save (`Ctrl+O`, `Enter`) and quit (`Ctrl+X`). What the lines mean: + +- `Address` — the Pi's address inside the tunnel (`10.100.0.1`). +- `ListenPort` — the port clients connect to. `47111`, UDP. + +## Step 4 — Let the Pi forward traffic + +To send your phone's traffic on to other devices in the house, the Pi has to be +willing to pass packets through. Two things enable that: **IP forwarding** +(allow packets through) and **NAT** (let tunnel devices share the Pi's internet +connection — you'll want it if you ever tunnel more than just home access). + +First, edit `/etc/sysctl.d/99-sysctl.conf` (`nano /etc/sysctl.d/99-sysctl.conf`). +Make sure these two lines exist **without** a `#` in front of them (remove the `#` +if there is one): + +``` +net.ipv4.ip_forward = 1 +net.ipv6.conf.all.forwarding = 1 +``` + +Save and quit, then apply: + +``` +sysctl --system +``` + +Second, open the server config again (`nano /etc/wireguard/wg0.conf`) and add +these two lines inside the `[Interface]` section (paste them exactly as one line +each): + +``` +PostUp = nft add table ip wireguard; nft add chain ip wireguard wireguard_chain {type nat hook postrouting priority srcnat\; policy accept\;}; nft add rule ip wireguard wireguard_chain counter packets 0 bytes 0 masquerade; nft add table ip6 wireguard; nft add chain ip6 wireguard wireguard_chain {type nat hook postrouting priority srcnat\; policy accept\;}; nft add rule ip6 wireguard wireguard_chain counter packets 0 bytes 0 masquerade +PostDown = nft delete table ip wireguard; nft delete table ip6 wireguard +``` + +`PostUp`/`PostDown` are commands that run automatically when the tunnel starts and +stops — here they add and remove the NAT rule. Ugly-looking, but it's copy-paste +and it's what the official docs recommend. + +When you're done, type `exit` to leave root. + +## Step 5 — Start the VPN + +``` +sudo systemctl enable wg-quick@wg0 +sudo systemctl start wg-quick@wg0 +sudo wg +``` + +If `sudo wg` prints an interface called `wg0` with a public key and a listening +port, the server is up. `enable` makes it start automatically after every reboot, +so you only ever run the `start` command after changing the config. + +## Step 6 — Open a door in the router + +Your phone needs to reach the Pi through the internet. Two things in your router's +admin page: + +1. **Give the Pi a fixed local IP.** Find the current one on the Pi with + `hostname -I`, then add a **DHCP reservation** in the router (binds that IP to + the Pi's MAC address). If the Pi's IP ever changes, the port forward breaks. +2. **Add a port forward: UDP port `47111` → the Pi's local IP.** + +Also find your home's **public IP** — it's often shown on the router's front page +("WAN IP"), or open `https://ifconfig.co` on any device at home. You'll paste it +into the client config next. + +## Step 7 — Add your phone as a client + +WireGuard calls every connected device a **peer**. Back on the Pi: + +``` +sudo -i +cd /etc/wireguard +umask 077 +name=phone +wg genkey | tee ${name}.key | wg pubkey > ${name}.pub +wg genpsk > ${name}.psk +``` + +That created the phone's key pair plus a **preshared key** (an extra per-device +layer of encryption). + +Register the phone in the server config — this appends a `[Peer]` section to +`wg0.conf`: + +``` +echo "[Peer]" >> wg0.conf +echo "PublicKey = $(cat ${name}.pub)" >> wg0.conf +echo "PresharedKey = $(cat ${name}.psk)" >> wg0.conf +echo "AllowedIPs = 10.100.0.2/32, fd08:4711::2/128" >> wg0.conf +``` + +Then tell the running server about the change (this reloads the config without +kicking off connected clients): + +``` +wg syncconf wg0 <(wg-quick strip wg0) +``` + +Now build the config file the phone will use: + +``` +echo "[Interface]" > ${name}.conf +echo "Address = 10.100.0.2/32, fd08:4711::2/128" >> ${name}.conf +echo "PrivateKey = $(cat ${name}.key)" >> ${name}.conf +echo "" >> ${name}.conf +echo "[Peer]" >> ${name}.conf +echo "PublicKey = $(cat server.pub)" >> ${name}.conf +echo "PresharedKey = $(cat ${name}.psk)" >> ${name}.conf +echo "Endpoint = 203.0.113.10:47111" >> ${name}.conf +echo "AllowedIPs = 10.100.0.0/24, fd08:4711::/64, 192.168.1.0/24" >> ${name}.conf +echo "PersistentKeepalive = 25" >> ${name}.conf +``` + +Replace `203.0.113.10` with **your home's public IP**, and `192.168.1.0/24` with +**your home range** if it's different. What the important lines do: + +- `AllowedIPs` decides what travels through the tunnel. Here it's the tunnel + itself plus your whole home range — so home devices are reachable. Everything + else (normal web browsing, apps) goes over your carrier's network directly, + exactly as usual. + (If you ever want *everything* tunneled — e.g. to route it through a future + Pi-hole — you'd replace that line with `AllowedIPs = 0.0.0.0/0, ::/0`.) +- `PersistentKeepalive = 25` — phones sit behind carriers' NAT, so this sends a + small packet every 25 seconds to keep the tunnel's door open. + +## Step 8 — Connect your phone + +Still as root, print the config as a QR code: + +``` +qrencode -t ansiutf8 < ${name}.conf +``` + +On your phone: open the WireGuard app → tap the blue **+** → scan the QR code → +toggle the tunnel **on**. (If you're using the Pi over SSH from a laptop, the QR +code appears in your terminal window — just scan it with the phone.) Then `exit` +root. + +## Step 9 — Check it works + +The interesting test is from **outside** the house: turn your phone's Wi-Fi off +and use cellular data. + +1. On the Pi, run `sudo wg`. Your phone should appear with + `latest handshake: X seconds ago` and a transfer count. +2. Open your Pi's local address in your phone's browser — + `http://192.168.1.42` or `http://192.168.1.42/admin` (use your Pi's own local + IP). If the page loads from a school Wi-Fi network, your phone is effectively + sitting in your house. +3. Try SSH: `ssh YOUR_USER@192.168.1.42` from Termux (Android) or any SSH client + on iPhone. If you get a shell, remote access is fully working. + +## What you can do now + +Rule of thumb: anywhere you would have typed a `192.168.1.x` address while at +home, that same address now works from anywhere in the world. + +- Web interfaces: Pi-hole admin, your NAS, Home Assistant — open them in the + browser. +- SSH into any device in the house. +- Stream from a media server or download files from a NAS. + +One caveat: device **names** like `raspberrypi.local` only resolve *inside* the +house, so over the tunnel, use IP addresses. + +## Troubleshooting + +- **Phone never shows a handshake:** check the port forward is UDP (not TCP) on + port `47111` pointing at the Pi's current local IP; check the `Endpoint` line + has your *current* public IP (it can change — call your ISP for a static one if + it's changing often); check keys were copied without extra spaces. +- **Can't connect from home Wi-Fi, but cellular works:** common and often + unfixable — many routers can't loop a forwarded port back to devices already + inside the network (no "NAT loopback"). Test with cellular data. +- **Connected, but home devices are unreachable:** the `AllowedIPs` line in the + client config has the wrong home range — it must match your router's subnet, + the same range your Pi's IP lives in. Also make sure Step 4 (IP forwarding) is + done. +- **A device works at home but not over the tunnel:** use its IP address instead + of its name (see the caveat above), and double-check the device is actually on + your home network. + +## Security notes + +- Anyone with your phone's config file can walk into your home network. Treat it + like a password — don't screenshot it into a shared chat. +- Your Pi is now reachable from the internet. Keeping a firewall enabled (for + example with `ufw`) is a good next step. +- Lost a device? Delete its `[Peer]` section from `wg0.conf` and run + `wg syncconf wg0 <(wg-quick strip wg0)` again — its keys stop working. diff --git a/lesson3.md b/lesson3.md new file mode 100644 index 0000000..7e35def --- /dev/null +++ b/lesson3.md @@ -0,0 +1,157 @@ +# Raspberry Pi Pihole (DNS) + +In this lesson you'll turn your Raspberry Pi into a **Pi-hole**, a network-wide +ad and tracker blocker. Once it's running, every device on your Wi-Fi gets ads +blocked automatically — including devices you can't install anything on. + +## What is DNS? + +When you type `example.com` into a browser, your computer first asks a **DNS +server**: "what's the IP address of example.com?" DNS is the internet's phone +book. Computers only speak IP addresses. + +By default, the phone book is run by your internet provider (or whoever your +network uses). That means they can see every website you visit. Ad companies lean +on this: your devices look up ad servers *before* the ad loads, and those lookups +are how tracking works. + +Pi-hole is a DNS server you run on your own network. It checks every name lookup +against blocklists of ads and trackers. Bad lookups get a "nope" answer, so the +ad never loads. Everything else is forwarded to a real DNS server upstream. + +``` +phone / laptop / tablet + | "who is doubleclick.net?" + v +Pi (Pi-hole) --- "blocked" +Pi (Pi-hole) --- forwards good lookups to upstream DNS (e.g. 1.1.1.1) +``` + +## What you need + +- A Raspberry Pi running Raspberry Pi OS, connected to your network (wired + ethernet is best) +- Access to your router's admin page + +## Step 0 — Give the Pi a fixed IP + +Pi-hole needs an IP address that never changes, because every device on the +network will be pointed at it. + +1. On the Pi, find its current IP: + + ``` + hostname -I + ``` + +2. In your router's admin page, add a **DHCP reservation** for the Pi (this binds + that IP to the Pi's MAC address so the router always hands out the same one). + This is the simplest way to make the IP permanent. + +## Step 1 — Install Pi-hole + +``` +sudo apt update +curl -sSL https://install.pi-hole.net | bash +``` + +That downloads and runs Pi-hole's official installer. It walks you through a +few questions in the terminal: + +- Accept the defaults for everything (press Enter). +- If asked about the upstream/private DNS provider, keep the default unless you + have a specific one you want to use. + +When it finishes, it prints your **admin page URL** (it looks like +`http://192.168.1.42/admin`) and a **password**. Write both down. + +## Step 2 — Point your network at the Pi + +This is the step that makes it network-wide. In your router's admin page, set the +**DNS server for DHCP** to the Pi's IP address (the one from Step 0). + +From now on, every device that gets an address from your router automatically +asks the Pi for DNS. Phones, laptops, tablets, smart TVs — all covered, no setup +on each device. + +If your router doesn't let you change its DHCP DNS, Pi-hole has a built-in DHCP +server you can run instead (you'd turn the router's DHCP off first). As a last +resort, you can set the DNS address manually on individual devices — but the +router method is the one to use when you can. + +## Step 3 — Let the Pi use itself too + +By default, the Pi doesn't use Pi-hole for its own lookups. Two things to set up: + +``` +sudo usermod -aG pihole $USER +``` + +That adds your account to the `pihole` group so the command-line tools work +without asking for a password every time. Log out of the terminal and back in +(so the change takes effect). + +Optionally, make the Pi itself resolve through Pi-hole by adding this line to +`/etc/dhcpcd.conf`: + +``` +static domain_name_servers=127.0.0.1 +``` + +Be aware of the trade-off: if Pi-hole ever breaks, the Pi itself won't be able to +resolve names until you fix it — which can make fixing it annoying. + +## Step 4 — The admin dashboard + +Open `http://YOUR_PI_IP/admin` in a browser and log in with the password the +installer gave you. The pages that matter: + +- **Dashboard** — live stats. Watch the query counter climb and the red + "Blocked" numbers appear within a minute of your network using it. +- **Query Log** — every single name lookup your network made, and what Pi-hole + answered. Search it to see what a device looked up. +- **Domain Lists** — block or allow specific domains for the whole network. Type + a domain, add it, choose "Always deny", and that site is dead on every device. +- **Settings** — choose the upstream DNS provider Pi-hole forwards to, the + privacy level, and the blocking mode. "Allow only local requests" is a sensible + secure default. + +## Step 5 — Check it's actually blocking + +1. On your phone or laptop, visit a website you know is full of ads. The ads + should be gone or greatly reduced. +2. In the dashboard's Query Log, you should see blocked lookups marked in red. +3. On the Pi, confirm the service is healthy: + + ``` + pihole status + ``` + + It should say the DNS server is up and running. + +## Useful commands + +``` +pihole status # is everything running? +pihole -h # list all available commands +pihole update # update Pi-hole and its blocklists (run this now and then) +``` + +Blocklists grow stale, so run `pihole update` once in a while to keep blocking +current. + +## Where this goes next + +If you followed the VPN lesson, you can already reach the Pi from anywhere — so +once this is done, you can manage your whole house's ad-blocking from your phone +at school or on vacation, at `http://YOUR_PI_IP/admin` through the tunnel. + +If you want, the tunnel can also ask Pi-hole for names: add this line to the +`[Interface]` section of your client config, then regenerate and rescan the QR +code: + +``` +DNS = 10.100.0.1 +``` + +Now any name lookups the phone makes go through Pi-hole first.