add initial 3 lessons

This commit is contained in:
2026-08-18 19:36:46 -04:00
commit ea04e059e3
3 changed files with 601 additions and 0 deletions
+159
View File
@@ -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.
+285
View File
@@ -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.
+157
View File
@@ -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.