diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..1791cdc --- /dev/null +++ b/LICENSE.md @@ -0,0 +1 @@ +Lab content © 2025 Meyi Cloud Solutions Pvt. Ltd. Licensed under CC BY-NC-ND 4.0. diff --git a/README.md b/README.md new file mode 100644 index 0000000..ead3772 --- /dev/null +++ b/README.md @@ -0,0 +1,68 @@ +# Linux Essentials — Detailed Lab Overview + +## Duration +**2 Hours (12 Steps)** + +## Audience +This lab is designed for **complete beginners** (equivalent to 10th grade students) who are learning Linux and the terminal for the first time. +No prior Linux knowledge is assumed. Each instruction is step-by-step and written in simple language. + +## Lab Format +- **Instruction Lab**: You will be guided through commands and concepts directly. +- **Hands-On Practice**: You will type commands into the terminal and observe outputs. +- **Validation Tasks**: At the end, optional tasks (Git & Networking) include helper files and validation scripts. + +## Learning Objectives +By the end of this lab, you will be able to: +1. Open and use the Linux terminal effectively. +2. Navigate the filesystem and perform file operations. +3. View, search, and filter text files. +4. Manage processes and jobs (foreground/background). +5. Understand file permissions and change them with `chmod` and `chown`. +6. Gather system information (disk, memory, uptime). +7. Perform basic networking commands (ping, DNS lookups, open ports). +8. Archive and compress files using `tar` and `gzip`. +9. Use the package manager (`apt`) to install and remove software. +10. Write and run simple shell scripts. +11. Initialize and commit code to a Git repository. +12. Troubleshoot connectivity and DNS resolution. + +## Structure +- **Steps 1–10**: Core Linux skills (approx. 100 minutes). +- **Steps 11–12**: Validation tasks with helpers (approx. 20 minutes). +- Each step is **10 minutes** on average, but you may take longer as you practice. + +## Requirements +- **Operating System**: Ubuntu 24 (or similar Linux distribution). +- **Tools**: Terminal application (bash shell). +- **Network**: Internet connection for package installation and DNS tests. +- **Permissions**: Some tasks require `sudo` access (administrator rights). + +## Key Skills Practiced +- Working with the Linux command line +- Creating and organizing files and directories +- Redirecting and searching text output +- Managing processes and monitoring system usage +- Adjusting permissions for files and directories +- Compressing and archiving data +- Installing/removing software with APT +- Writing and running bash scripts +- Using Git for version control +- Troubleshooting basic networking issues + +## Suggested Workflow +1. **Follow each step in order.** Each builds on the previous one. +2. **Type commands manually.** Avoid copy-paste to build muscle memory. +3. **Observe the output carefully.** Compare it with expected results. +4. **Repeat tasks** if something doesn’t work — troubleshooting is part of learning. +5. **Try variations** (e.g., different filenames, directories) to deepen your understanding. + +## Completion Criteria +- You have successfully completed all 10 instructional steps. +- You optionally attempted Steps 11 and 12 and passed the provided validation scripts. +- You are comfortable using the Linux terminal for basic daily tasks. + +--- + +**Next Steps:** +After completing this lab, you are ready to explore more advanced topics such as user management, shell scripting with conditionals/loops, and networking security. diff --git a/docs/.DS_Store b/docs/.DS_Store new file mode 100644 index 0000000..5008ddf Binary files /dev/null and b/docs/.DS_Store differ diff --git a/docs/00_overview.md b/docs/00_overview.md index 4bba659..92a184a 100644 --- a/docs/00_overview.md +++ b/docs/00_overview.md @@ -1 +1,68 @@ -# Overview \ No newline at end of file +# Linux Essentials — Detailed Lab Overview + +## Duration +**3 Hours (12 Steps)** + +## Audience +This lab is designed for **complete beginners** (equivalent to 10th grade students) who are learning Linux and the terminal for the first time. +No prior Linux knowledge is assumed. Each instruction is step-by-step and written in simple language. + +## Lab Format +- **Instruction Lab**: You will be guided through commands and concepts directly. +- **Hands-On Practice**: You will type commands into the terminal and observe outputs. +- **Validation Tasks**: At the end, optional tasks (Git & Networking) include helper files and validation scripts. + +## Learning Objectives +By the end of this lab, you will be able to: +1. Open and use the Linux terminal effectively. +2. Navigate the filesystem and perform file operations. +3. View, search, and filter text files. +4. Manage processes and jobs (foreground/background). +5. Understand file permissions and change them with `chmod` and `chown`. +6. Gather system information (disk, memory, uptime). +7. Perform basic networking commands (ping, DNS lookups, open ports). +8. Archive and compress files using `tar` and `gzip`. +9. Use the package manager (`apt`) to install and remove software. +10. Write and run simple shell scripts. +11. Permissions Challenge. +12. Troubleshoot connectivity and DNS resolution. + +## Structure +- **Steps 1–10**: Core Linux skills (approx. 200 minutes). +- **Steps 11–12**: Validation tasks with helpers (approx. 30 minutes). +- Each step is **10 minutes** on average, but you may take longer as you practice. + +## Requirements +- **Operating System**: Ubuntu 24 (or similar Linux distribution). +- **Tools**: Terminal application (bash shell). +- **Network**: Internet connection for package installation and DNS tests. +- **Permissions**: Some tasks require `sudo` access (administrator rights). + +## Key Skills Practiced +- Working with the Linux command line +- Creating and organizing files and directories +- Redirecting and searching text output +- Managing processes and monitoring system usage +- Adjusting permissions for files and directories +- Compressing and archiving data +- Installing/removing software with APT +- Writing and running bash scripts +- Using Git for version control +- Troubleshooting basic networking issues + +## Suggested Workflow +1. **Follow each step in order.** Each builds on the previous one. +2. **Type commands manually.** Avoid copy-paste to build muscle memory. +3. **Observe the output carefully.** Compare it with expected results. +4. **Repeat tasks** if something doesn’t work — troubleshooting is part of learning. +5. **Try variations** (e.g., different filenames, directories) to deepen your understanding. + +## Completion Criteria +- You have successfully completed all 10 instructional steps. +- You optionally attempted Steps 11 and 12 and passed the provided validation scripts. +- You are comfortable using the Linux terminal for basic daily tasks. + +--- + +**Next Steps:** +After completing this lab, you are ready to explore more advanced topics such as user management, shell scripting with conditionals/loops, and networking security. \ No newline at end of file diff --git a/docs/01_task.md b/docs/01_task.md deleted file mode 100644 index 17014e0..0000000 --- a/docs/01_task.md +++ /dev/null @@ -1 +0,0 @@ -## Initial task \ No newline at end of file diff --git a/docs/01_terminal_basics.md b/docs/01_terminal_basics.md new file mode 100644 index 0000000..7bc5bb8 --- /dev/null +++ b/docs/01_terminal_basics.md @@ -0,0 +1,196 @@ +# Step 1 — Terminal Basics (Ubuntu 24) + +> **Type along** exactly as shown. This step is written for absolute beginners and assumes no prior Linux experience. +> **Estimated time:** ~10–15 minutes + +--- + +## What you’ll learn +- What the *terminal* and the *shell* are +- How to open and close a terminal +- How to find your current shell and username +- How to run basic commands safely +- How to read the command prompt and use helpful keyboard shortcuts + +This expands the original brief step (“Open terminal → echo $SHELL → whoami → exit”) into a guided mini-lesson with checks, expected outputs, and troubleshooting. + +--- + +## Prerequisites +- Ubuntu 24 (or a similar Linux distribution) +- A keyboard and mouse (no admin/sudo needed for this step) +- Willingness to try and make small mistakes (that’s normal!) + +--- + +## 1) Open the Terminal + +You can open the terminal in **three** easy ways — choose the one you like: + +1. Press **Ctrl + Alt + T** (keyboard shortcut). +2. Click **Activities** (top-left) → type `terminal` → click **Terminal**. +3. Open **Applications** menu → **Terminal** (or **GNOME Terminal**). + +**Expected view:** A window with a prompt like: +``` +yourname@your-computer:~$ +``` +- `yourname` is your **username** (who you are) +- `your-computer` is the **hostname** (your machine’s name) +- `~` means your **home** directory (e.g., `/home/yourname`) +- `$` is the standard prompt for regular users (a `#` indicates the root/admin shell — you won’t use root here) + +> If your prompt looks a bit different, that’s okay—Linux allows customization. The ideas are the same. + +--- + +## 2) Meet Your Shell + +The **shell** is a program that reads your commands and runs them. In Ubuntu it’s usually **Bash**. + +**Find which shell you are using:** +```bash +echo $SHELL +``` +**Expected output (typical):** +``` +/bin/bash +``` +- `echo` prints text +- `$SHELL` is an **environment variable** that stores the path to your current shell + +**Alternative cross-check (nice to know):** +```bash +ps -p $$ -o comm= +``` +- Prints the name of the program running your current shell (`bash`, `zsh`, etc.) + +> Tip: Commands are **case-sensitive**. `Echo` or `ECHO` won’t work; use `echo` in lowercase. + +--- + +## 3) Who Am I? Where Am I? + +**Show your login name:** +```bash +whoami +``` +**Expected output** (your actual username): +``` +yourname +``` + +**Show your current folder (directory):** +```bash +pwd +``` +**Expected output** (your home): +``` +/home/yourname +``` + +> Remember: `~` is a shortcut for your home directory. `cd ~` and `cd` (with no arguments) both take you home. + +--- + +## 4) Try a Few Safe Commands + +Type each command and press **Enter**. Don’t worry—these are read-only. + +```bash +date # shows the current date and time +ls # lists files/folders in the current directory +ls -la # lists everything in long form, including hidden “dotfiles” +clear # clears your screen (or press Ctrl+L) +``` + +If you want to see *what* a command does: +```bash +man ls # the manual for ls (press q to quit) +ls --help # quick built-in help for ls +help echo # help for bash built-in command "echo" +``` + +> **How to read errors**: If you see a line like `command not found`, check your spelling and spaces. Linux cares about lowercase vs uppercase. + +--- + +## 5) Keyboard Superpowers (Optional but Very Useful) + +- **↑ / ↓**: browse history (commands you already typed) +- **Tab**: auto-complete file/command names (press twice to list options) +- **Ctrl + A**: jump to start of line +- **Ctrl + E**: jump to end of line +- **Ctrl + U**: clear from cursor *back* to start +- **Ctrl + K**: clear from cursor *forward* to end +- **Ctrl + W**: delete the previous word +- **Ctrl + L**: clear screen (same as `clear`) +- **Ctrl + C**: cancel/interrupt a running command (do not use while saving in editors) + +**Try it:** Type `ec` then press **Tab** — if `echo` is the only match, your shell completes the word for you. + +--- + +## 6) Practice: Your First Echo + +`echo` prints whatever you give it. Try these: + +```bash +echo Hello, Linux! +echo "Quoting keeps words together like this: two words" +echo $HOME # prints your home directory path +echo $USER # prints your username (same as whoami) +``` + +**What happened?** +- Without quotes, the shell splits by spaces +- With quotes `"..."`, the shell treats the content as one unit +- `$` means “expand this variable” (`$HOME`, `$USER`, `$SHELL`, `$PATH` are common ones) + +--- + +## 7) Close the Terminal (Two Safe Ways) + +1) Type: +```bash +exit +``` +2) Or press **Ctrl + D** (sends “end-of-input”, which ends the shell) + +If you had any running programs in the foreground, the shell will usually warn you. + +--- + +## Troubleshooting + +**Q: I typed `WhoAmI` and got “command not found.”** +A: Commands are case-sensitive. Type `whoami` (all lowercase). + +**Q: I see `Permission denied`.** +A: You tried to access something you don’t have rights to. In this step, just practice with safe commands (`echo`, `whoami`, `pwd`). + +**Q: My terminal is “stuck.”** +A: A command might still be running. Press **Ctrl + C** to cancel. If that doesn’t work, close the terminal window. + +**Q: My prompt ends with `#`. Is that bad?** +A: That means you’re in a **root** (administrator) shell. Close the terminal and open a new one. For learning, stay as a regular user (`$` prompt). + +--- + +## Quick Quiz (1 minute) + +- What does `$SHELL` store? +- How do you show your username? +- What does `~` represent? +- Which key shows your previous command? +- Two ways to exit the terminal? + +**Answers** (hover/select to reveal): `$SHELL` is your shell path; `whoami`; `~` = home directory; Up Arrow; `exit` and `Ctrl + D`. + +--- + +## Next Step + +You’re ready for **Step 2 — Navigation & File Operations**. +Keep this terminal open; we’ll continue in the same window. + diff --git a/docs/02_navigation_file_ops.md b/docs/02_navigation_file_ops.md new file mode 100644 index 0000000..9c834da --- /dev/null +++ b/docs/02_navigation_file_ops.md @@ -0,0 +1,298 @@ +# Step 2 — Navigation & File Operations (Ubuntu 24) + +> **Type along** exactly as shown. This step is written for absolute beginners and assumes no prior Linux experience. +> **Estimated time:** ~10–15 minutes + +--- + +## What you’ll learn +- What a *path* is (absolute vs. relative) +- How to **move around** with `cd` +- How to **create**, **inspect**, **copy**, **move/rename**, and **delete** files and folders +- How to work safely (confirmation prompts), and handle names with **spaces** +- How to verify your actions with `ls -l` + +This expands the original brief step (pwd → mkdir → cd → create file → ls -l) into a guided mini-lesson with checks, expected outputs, and troubleshooting. + +--- + +## 0) Setup (recommended) + +Create a clean practice area so you don’t accidentally change other files: + +```bash +mkdir -p ~/playground && cd ~/playground +``` + +- `~` is your **home** directory (e.g., `/home/yourname`). +- `mkdir -p` creates all missing parent folders safely. +- `cd` changes your current working directory. + +If something goes wrong, you can reset this folder later: +```bash +cd ~ && rm -rf ~/playground && mkdir -p ~/playground && cd ~/playground +``` + +--- + +## 1) Where am I? (Print Working Directory) + +```bash +pwd +``` + +**Expected output:** the full path of your current directory (e.g., `/home/yourname/playground`). +This is called an **absolute path** (it starts with `/`). + +--- + +## 2) Create folders (directories) + +Create a single folder: +```bash +mkdir projects +``` + +Create a **nested** folder tree in one go: +```bash +mkdir -p projects/alpha +``` + +Verify: +```bash +ls -la +``` + +- `-l` = long list (permissions, owner, size, date) +- `-a` = include hidden items (names starting with a dot) + +> Hidden files often store settings and are called **dotfiles** (e.g., `.bashrc`). + +--- + +## 3) Move around with `cd` + +Change into the new folder: +```bash +cd projects +pwd +``` + +Go **down** another level: +```bash +cd alpha +pwd +``` + +Go **up** one level: +```bash +cd .. +pwd +``` + +Jump **home** quickly: +```bash +cd ~ +pwd +``` + +Return to your last directory: +```bash +cd - +``` + +> Think of `cd` as “change directory” — just like opening folders in a file explorer. + +--- + +## 4) Create files (3 common ways) + +Make sure you’re inside `~/playground` (use `pwd` to check), then: + +**A) Create with content (overwrite if exists):** +```bash +echo "Hello Linux" > hello.txt +``` + +**B) Append more content (keeps existing lines):** +```bash +echo "Second line" >> hello.txt +``` + +**C) Create an empty file:** +```bash +touch empty.txt +``` + +**D) Create and edit with a text editor (nano):** +```bash +nano notes.txt +# Type: My first notes line. +# Save: Ctrl+O, Enter. Exit: Ctrl+X +``` + +Check what you made: +```bash +ls -l +cat hello.txt +``` + +> `>` writes/overwrites; `>>` appends. `touch` creates an empty file or updates the timestamp if it already exists. + +--- + +## 5) Inspect details with `ls` + +List files with extra info: +```bash +ls -l +``` + +You’ll see lines like: +``` +-rw-r--r-- 1 yourname yourname 12 Sep 8 10:00 hello.txt +``` +- `-rw-r--r--` → **permissions** +- first `yourname` → **owner** +- second `yourname` → **group** +- `12` → file size in bytes +- `hello.txt` → file name + +Try human-readable sizes: +```bash +ls -lh +``` + +Show hidden files too: +```bash +ls -la +``` + +--- + +## 6) Copy, move/rename, and delete files + +**Copy a file:** +```bash +cp hello.txt hello.bak +ls -l hello* +``` + +**Move/rename a file (same command):** +```bash +mv hello.bak projects/alpha/ +mv empty.txt empty-renamed.txt +ls -l projects/alpha +ls -l empty-renamed.txt +``` + +**Delete a file (interactive/safe):** +```bash +rm -i empty-renamed.txt +``` + +> `-i` asks **“remove regular file…?”** before deleting — excellent for beginners. + +**Delete a folder tree (careful!):** +```bash +rm -r projects/alpha +mkdir -p projects/alpha # recreate it for the next step +``` + +> `rm -r` removes directories **recursively** (everything inside). Use with caution. + +--- + +## 7) Names with spaces + +Two safe methods: + +**Quotes:** +```bash +mkdir "my notes" +echo "a line" > "my notes/file with space.txt" +ls -l "my notes" +``` + +**Escaping spaces with backslashes:** +```bash +echo "another line" > my\ notes/another\ file.txt +ls -l my\ notes +``` + +> If you forget quotes/backslashes, the shell will think you’re typing **multiple arguments** and show an error like “No such file or directory”. + +--- + +## 8) Wildcards (globbing) + +List all `.txt` files: +```bash +ls -l *.txt +``` + +List everything that starts with `he`: +```bash +ls -l he* +``` + +> If a wildcard matches nothing, the shell may pass the literal pattern to the command (e.g., `ls: cannot access '*.txt': No such file or directory`). That’s normal. + +--- + +## 9) Verify what you did (mini-checklist) + +- Where are you? + ```bash + pwd + ``` +- Do you see the files you created? + ```bash + ls -la + ``` +- Do you see the content you wrote? + ```bash + cat hello.txt + ``` +- Is there a copy in `projects/alpha/`? + ```bash + ls -l projects/alpha + ``` + +--- + +## 10) Cleanup (optional) + +If you want to start fresh: +```bash +cd ~ && rm -rf ~/playground && mkdir -p ~/playground && cd ~/playground +``` + +--- + +## Troubleshooting + +**Q: `Permission denied` when creating files?** +A: Ensure you’re working inside your home (e.g., `~/playground`) where you have write permission. + +**Q: `No such file or directory` when using spaces?** +A: Use quotes `"like this"` or escape spaces: `my\ notes/that\ file.txt`. + +**Q: I ran `rm -r` in the wrong place!** +A: This is why we practice in `~/playground`. In real life, **double-check** paths before you press Enter. + +--- + +## Quick Quiz (1 minute) +- How do you print the current directory path? +- What’s the difference between `>` and `>>`? +- Which command *renames* a file? +- Show a long listing including hidden files—what options do you use? +- Two ways to handle file names with spaces? + +**Answers:** `pwd`; `>` overwrites, `>>` appends; `mv`; `ls -la`; quotes or backslashes. + +--- + +## Next Step +Continue to **Step 3 — Searching & Text Viewing** to learn `grep`, `find`, `less`, and more! diff --git a/docs/03_searching_text.md b/docs/03_searching_text.md new file mode 100644 index 0000000..2395357 --- /dev/null +++ b/docs/03_searching_text.md @@ -0,0 +1,239 @@ +# Step 3 — Searching & Text Viewing (Ubuntu 24) + +> **Type along** exactly as shown. This step is written for absolute beginners and assumes no prior Linux experience. +> **Estimated time:** ~10–15 minutes + +--- + +## What you’ll learn +- How to **view** text files (`cat`, `less`, `head`, `tail`) +- How to **search inside** files with `grep` +- How to **find files/folders** anywhere with `find` +- How to chain commands together with the **pipe** (`|`) for quick analysis +- How to avoid common mistakes (case, spaces, patterns) + +This expands the original brief step to include **practical variations**, **safety notes**, and **troubleshooting**. + +> **Setup:** Continue using your practice area from previous steps (recommended): +> ```bash +> mkdir -p ~/playground && cd ~/playground +> ``` + +--- + +## 0) Create some sample files to search + +We’ll set up a few files so your searches have something to find. + +```bash +cd ~/playground +echo "Hello Linux" > hello.txt +echo "hello again" >> hello.txt +echo "Linux is powerful" > notes.txt +echo "HELLO CAPS" > caps.txt +mkdir -p logs +printf "alpha\nbeta\ngamma\nBeta\nGamma\n" > logs/mixed.txt +``` + +Verify: +```bash +ls -l +ls -l logs +``` + +--- + +## 1) View files quickly (`cat`) and with scrolling (`less`) + +**A) View entire file now:** +```bash +cat hello.txt +``` +- `cat` prints the file to your screen immediately (great for short files). + +**B) Scroll through long files:** +```bash +less notes.txt +``` +- **Keys:** Up/Down or PageUp/PageDown to move; `/word` to search; `n` for next match; `q` to quit. +- `less` doesn’t load the whole file at once — it’s ideal for big files and logfiles. + +**C) Peek at the top/bottom only (useful for logs):** +```bash +head -n 3 hello.txt # first 3 lines +tail -n 3 hello.txt # last 3 lines +tail -f hello.txt # follow new lines live; press Ctrl+C to stop +``` + +> **Tip:** Use `tail -f` while another process writes to a log to watch updates in real time. + +--- + +## 2) Search inside files with `grep` + +`grep` finds lines **containing** a pattern. + +**A) Basic search (case-sensitive by default):** +```bash +grep "Hello" hello.txt +``` +- Matches `Hello` but **not** `hello`. + +**B) Case-insensitive search:** +```bash +grep -i "hello" hello.txt +``` + +**C) Show line numbers with matches:** +```bash +grep -n "hello" hello.txt +``` + +**D) Search multiple files at once:** +```bash +grep -n "linux" *.txt +``` +- Matches lines containing `linux` in any `.txt` file (case-sensitive). + +**E) Recursive search (search through folders):** +```bash +grep -Rni "beta" . +``` +- `-R` = recursive, `-n` = show line numbers, `-i` = ignore case + +**F) Show only the filenames that match:** +```bash +grep -Rl "hello" . +``` + +**G) Regex (advanced but useful):** +Match `Hello` or `HELLO` or `hello` without `-i`, using an **extended** regex: +```bash +grep -En "(?i)hello" *.txt 2>/dev/null || grep -En "(H|h)ELLO|Hello|hello" *.txt 2>/dev/null +``` +> Note: The `(?i)` flag is not supported in all `grep` versions; the fallback demonstrates alternation with `-E`. Beginners can skip this for now. + +**H) Invert match (show lines that **do not** match):** +```bash +grep -v "hello" hello.txt +``` + +--- + +## 3) Find files/folders anywhere with `find` + +`find` walks directories and lets you filter by **name**, **type**, **size**, **time**, and more. + +**A) Find by name:** +```bash +find . -name "hello.txt" +find . -name "*.txt" +``` + +**B) Only files vs. only directories:** +```bash +find . -type f -name "*.txt" +find . -type d -name "logs" +``` + +**C) Limit depth to current folder only:** +```bash +find . -maxdepth 1 -type f -name "*.txt" +``` + +**D) Find by size (files larger than 1 megabyte):** +```bash +find . -type f -size +1M +``` + +**E) Find by modified time (edited within last 1 day):** +```bash +find . -type f -mtime -1 +``` + +**F) Do something with each result (`-exec`):** +Show file sizes for all `.txt` files: +```bash +find . -type f -name "*.txt" -exec wc -l {} \; +``` +> `wc -l` counts lines; `{}` is replaced by each found file; `\;` ends the `-exec` command. + +**G) Safer piping with null terminators (handles spaces in filenames):** +```bash +find . -type f -name "*.txt" -print0 | xargs -0 grep -n "hello" +``` +- This combination searches **all** `.txt` files for `hello`, even if filenames contain spaces. + +--- + +## 4) Combine tools with the pipe `|` + +**A) Quick counts (how many matches?):** +```bash +grep -Rni "hello" . | wc -l +``` +- `wc -l` counts how many **matching lines** were found. + +**B) Sort and unique (e.g., see unique matching filenames):** +```bash +grep -Rl "hello" . | sort | uniq +``` + +**C) Show the 5 most common words in a file (simple demo):** +```bash +tr -cs '[:alnum:]' '\n' < hello.txt | tr '[:upper:]' '[:lower:]' | sort | uniq -c | sort -nr | head -n 5 +``` +- Splits text into words, lowercases, counts, and shows top 5. + +> **Note:** The above is a mini data-processing pipeline — not required for beginners but fun to see what’s possible. + +--- + +## 5) Practice tasks (do them now) + +1) Show the **first** 2 lines of `logs/mixed.txt`. +2) Show only the lines that contain “Gamma” (any case) in `logs/mixed.txt`. +3) Find all `.txt` files **in this folder only** (not subfolders). +4) Count how many lines in **all** `.txt` files mention “hello” (any case). +5) Show the **filenames only** that contain the word “Linux” (case-insensitive) anywhere under the current folder. + +**Hints:** +```bash +head -n 2 logs/mixed.txt +grep -i "gamma" logs/mixed.txt +find . -maxdepth 1 -type f -name "*.txt" +grep -Rni "hello" . | wc -l +grep -Rli "linux" . +``` + +--- + +## Troubleshooting + +**Q: `grep: *.txt: No such file or directory`** +A: Wildcards expand before grep runs. If nothing matches `*.txt`, your shell might pass the literal string. Make sure you’re in the right folder and that `.txt` files exist. + +**Q: My search is case-sensitive, but I need any case.** +A: Add `-i` to `grep` (e.g., `grep -i "hello"`). + +**Q: `find` prints “Permission denied”.** +A: You’re walking directories you don’t own (outside your home). For practice, stay inside `~/playground`. + +**Q: `less` won’t quit.** +A: Press `q` to exit `less`. + +--- + +## Quick Quiz (1 minute) +- Which command opens a scrollable viewer? +- How do you search recursively and ignore case with `grep`? +- How do you show only filenames that match? +- Which `find` option restricts search to current directory only? +- What does `wc -l` do when piped after `grep`? + +**Answers:** `less`; `grep -Rni "term" .`; `grep -Rl "term" .`; `-maxdepth 1`; counts matching lines. + +--- + +## Next Step +Continue to **Step 4 — Process Management** to learn how to view, sort, and control running programs. diff --git a/docs/04_process_management.md b/docs/04_process_management.md new file mode 100644 index 0000000..3109092 --- /dev/null +++ b/docs/04_process_management.md @@ -0,0 +1,215 @@ +# Step 4 — Process Management (Ubuntu 24) + +> **Type along** exactly as shown. This step is written for absolute beginners and assumes no prior Linux experience. +> **Estimated time:** ~10–15 minutes + +--- + +## What you’ll learn +- What a **process** is and how to list them +- How to watch the system in real time with **top** +- How to start programs in the **background** and bring them to the **foreground** +- How to **stop/kill** a process safely +- How to view **PIDs** (Process IDs) and understand **signals** +- (Optional) How to adjust priority with **nice/renice** + +This expands the original brief step (ps/top/background jobs/kill) into a guided mini-lesson with checks, expected outputs, and troubleshooting. + +> **Setup:** Continue using your practice area from previous steps (recommended): +> ```bash +> mkdir -p ~/playground && cd ~/playground +> ``` + +--- + +## 0) What’s a “process”? + +A **process** is a running program (like the terminal, a text editor, a web browser tab, or a background task). +Linux gives every process a unique number called a **PID** (Process ID). You use the PID to control the process (e.g., to stop it). + +--- + +## 1) List processes with `ps` + +Show the first few running processes (system-wide view): +```bash +ps aux | head -n 15 +``` +- `a` = show processes for **all** users +- `u` = show the user/owner +- `x` = include processes without a controlling terminal + +**More readable columns (top 10 by PID):** +```bash +ps -o pid,ppid,user,%cpu,%mem,stat,cmd --sort=pid | head -n 10 +``` +- `pid` = Process ID +- `ppid` = Parent Process ID +- `%cpu`, `%mem` = CPU and memory usage +- `stat` = state (e.g., `S` sleeping, `R` running, `T` stopped) +- `cmd` = the command used to start the process + +--- + +## 2) Real-time view with `top` + +Open an updating view of processes: +```bash +top +``` +**Keys you can try inside `top`:** +- `P` = sort by CPU +- `M` = sort by memory +- `1` = show all CPU cores +- `q` = quit + +> Optional: Install **htop** (`sudo apt install -y htop`) for a friendlier view. Launch with `htop`, quit with `q`. + +--- + +## 3) Create a background process and manage jobs + +Start a harmless background job: +```bash +sleep 300 & +``` +- `sleep 300` waits for 300 seconds (5 minutes). The `&` runs it **in the background** so you get your prompt back. + +List your jobs: +```bash +jobs +``` + +Bring the job to the **foreground** (if there’s one job, it’s usually `%1`): +```bash +fg %1 +``` +Now your terminal is “busy” waiting for `sleep` to finish. Press **Ctrl + C** to stop it. + +Start it again in the background and **suspend**, **resume** flow: +```bash +sleep 300 & # start in background +jobs +fg %1 # bring to foreground +# Press Ctrl+Z # suspend the foreground job +bg %1 # resume it in the background +jobs +``` + +> **Ctrl+Z** = “pause” the foreground process. +> **bg** = continue a paused job in the background. +> **fg** = bring a background job to the foreground. + +--- + +## 4) Find PIDs and kill a process safely + +Create a background process to practice on: +```bash +sleep 400 & +``` + +Find its PID(s): +```bash +pgrep sleep +``` +You’ll see one or more numbers (PIDs). + +**Ask a process to exit nicely (SIGTERM 15):** +```bash +kill 15 +``` +If it doesn’t exit after a few seconds, you can **force** it (SIGKILL 9): +```bash +kill -9 +``` +> Use `-9` only if normal signals fail; it doesn’t let programs clean up. + +**Alternative: kill by name (use carefully):** +```bash +pkill sleep # stops all 'sleep' processes you own +# or +killall sleep +``` + +Confirm it’s gone: +```bash +pgrep sleep || echo "No sleep process found" +``` + +--- + +## 5) (Optional) Priority: nice and renice + +Every process has a **priority** (niceness). Higher nice values (e.g., `+10`) = **lower** priority (more “polite”). +Lower nice values (e.g., `-5`) = **higher** priority (less “polite”). Negative values may require `sudo`. + +Start a nice process: +```bash +nice -n 10 sleep 200 & +``` +Check niceness (NI column): +```bash +ps -o pid,ni,cmd -p $(pgrep -n sleep) +``` +Change niceness of a running process to be **more polite** (higher number): +```bash +renice +15 -p +ps -o pid,ni,cmd -p +``` +> To set a **negative** niceness (higher priority), you typically need `sudo`. + +Stop leftover sleep processes: +```bash +pkill sleep +``` + +--- + +## 6) Practice tasks (do them now) + +1) Start `sleep 180 &`. Then show your jobs, bring it to the foreground, suspend it, and resume it in the background. +2) Use `pgrep sleep` to find the PID and then terminate the process **politely**. Verify it’s gone. +3) Launch a “polite” (low-priority) task with `nice` and confirm the NI column shows the expected value. +4) Open `top`, press `P` to sort by CPU and `M` to sort by memory. Quit `top`. + +**Hints:** +```bash +sleep 180 &; jobs; fg %1; # then Ctrl+Z +bg %1; jobs +pgrep sleep; kill 15 ; pgrep sleep || echo "done" +nice -n 10 sleep 120 &; ps -o pid,ni,cmd -p $(pgrep -n sleep) +top # then P, M, q +``` + +--- + +## Troubleshooting + +**Q: I lost my job number. How do I get the PID?** +A: Use `pgrep ` (e.g., `pgrep sleep`). Then use `kill` with the PID. + +**Q: `kill` didn’t stop the process.** +A: Try `kill 15 ` again, wait a moment, then `kill -9 ` as a last resort. + +**Q: I see “Operation not permitted” with `renice`.** +A: Negative nice values (higher priority) generally require `sudo`. Increasing the niceness (e.g., `+10`, `+15`) is allowed. + +**Q: `top` won’t exit.** +A: Press `q` to quit `top`. + +--- + +## Quick Quiz (1 minute) +- What command shows an updating, real-time view of processes? +- Which key in `top` sorts by CPU usage? +- How do you start a command in the background? +- How do you bring job `%1` to the foreground? +- What’s the difference between `kill 15 ` and `kill -9 `? + +**Answers:** `top`; `P`; add `&` at the end; `fg %1`; `15` asks nicely, `-9` forces. + +--- + +## Next Step +Continue to **Step 5 — Permissions & Ownership** to learn how to read and change file permissions and ownership safely. diff --git a/docs/05_permissions.md b/docs/05_permissions.md new file mode 100644 index 0000000..345a861 --- /dev/null +++ b/docs/05_permissions.md @@ -0,0 +1,265 @@ +# Step 5 — Permissions & Ownership (Ubuntu 24) + +> **Type along** exactly as shown. This step is written for absolute beginners and assumes no prior Linux experience. +> **Estimated time:** ~10–15 minutes + +--- + +## What you’ll learn +- How to **read** Linux permissions and ownership +- How to **change** permissions with `chmod` (symbolic & octal) +- How to change **owner** and **group** with `chown` / `chgrp` +- How **directory** permissions differ from **file** permissions +- How **umask** affects default permissions +- (Optional) What **setuid**, **setgid**, and **sticky** bits do +- (Optional) How to use **ACLs** for fine‑grained access + +> **Setup:** Continue using your practice area (recommended): +> ```bash +> mkdir -p ~/playground && cd ~/playground +> ``` + +--- + +## 0) Primer: Users, Groups, and the `rwx` model +Linux tracks access for three classes: +- **u** (user/owner) — typically who created the file +- **g** (group) — collaborators who share a group +- **o** (others) — everyone else + +Each class can have: +- **r** (read) +- **w** (write) +- **x** (execute for files / *enter* for directories) + +**Example:** +``` +-rw-r----- 1 alice devs 42 Sep 8 12:00 notes.txt +``` +- Leading `-` = regular **file** (use `d` for directory) +- `rw-` (user), `r--` (group), `---` (others) +- Owner = `alice`, Group = `devs` + +> **Tip:** For **directories**, `x` means you can *enter* the directory and access filenames inside. Without `x`, even if you have `r`, you can list names but may not open files. + +--- + +## 1) View permissions & ownership +Create a couple of files and a directory: +```bash +printf 'hello\n' > hello.txt +printf '#!/usr/bin/env bash\necho hi\n' > hello.sh +mkdir project +``` +Show long listing: +```bash +ls -l hello.txt hello.sh project +``` +Show numeric (octal) permissions and type: +```bash +stat -c '%A %a %U:%G %n' hello.txt hello.sh project +``` +See your user and groups: +```bash +id +# or +groups +``` + +**Expected:** You’ll see owner = your username, group = your primary group, and default perms (e.g., `644` for files, `755` for new directories on many systems). + +--- + +## 2) Change permissions with `chmod` +`chmod` can use **symbolic** or **octal** modes. + +### A) Symbolic mode +Add **execute** for owner on the script, remove execute for others: +```bash +chmod u+x,o-x hello.sh +ls -l hello.sh +``` +Set **exact** bits (owner `rw`, group `r`, others `-`): +```bash +chmod u=rw,g=r,o= hello.txt +ls -l hello.txt +``` +Give **group** write on directory for collaboration: +```bash +chmod g+w project +ls -ld project +``` + +### B) Octal mode +- `r=4`, `w=2`, `x=1` → Sum them per class: `u g o` + +Make a common script mode `755` (rwx r-x r-x): +```bash +chmod 755 hello.sh +stat -c '%A %a %n' hello.sh +``` +Set a private file `600` (rw- --- ---): +```bash +chmod 600 hello.txt +stat -c '%A %a %n' hello.txt +``` + +### C) Recurse (be careful!) +Apply to all items beneath a directory: +```bash +mkdir -p project/sub +touch project/sub/todo.txt +chmod -R g+rw project +``` +> **Warning:** Recursive changes can break apps. Prefer targeted changes. + +--- + +## 3) Ownership: `chown` and `chgrp` +Ownership is stored as **user:group**. + +Change owner (requires privileges if not your own): +```bash +# Example only; may require sudo depending on target user +sudo chown $USER:$USER hello.txt +``` +Change **group** when collaborating: +```bash +# switch group ownership to e.g. `devs` (must be a group you’re in) +sudo chgrp devs project || echo "Try a group you belong to" +ls -ld project +``` +Change owner:group recursively (careful): +```bash +# Example – change group across a tree +sudo chown -R :devs project +``` + +> **Rule of thumb:** Use `chgrp` to hand a folder to a **team group**, then use directory permissions to control access. + +--- + +## 4) Executable scripts: shebang & run +Make sure the script starts with a **shebang** line and is executable: +```bash +head -n1 hello.sh +chmod u+x hello.sh +./hello.sh +``` +If you see `Permission denied`, check `ls -l hello.sh` and ensure the containing directory has `x`. + +--- + +## 5) Defaults with `umask` +`umask` subtracts permissions from new files/directories. + +Show current umask: +```bash +umask +``` +Make a new file/dir and check modes: +```bash +printf 'tmp\n' > new.txt +mkdir newdir +stat -c '%a %n' new.txt newdir +``` +Temporarily set a stricter umask for this shell (e.g., disallow “others”): +```bash +umask 007 +printf 'secret\n' > secret.txt +stat -c '%a %n' secret.txt +``` +> **Typical defaults:** Files start from `666` (rw rw rw) and directories from `777` (rwx rwx rwx), then your `umask` removes bits. + +--- + +## 6) Special bits (advanced) +### setuid (`4xxx` on files) +- Executed with the file **owner’s** privileges. +- Common on system tools like `passwd`. +> **Don’t set setuid on your own scripts**; it’s risky and often ignored for scripts. + +### setgid (`2xxx` on files/dirs) +- On **directories**, new files inherit the directory’s **group**, improving collaboration. + +Enable setgid on a shared project folder: +```bash +sudo chgrp devs project +sudo chmod g+ws project # the 's' shows setgid on the group bit +ls -ld project +``` +New files in `project/` will have group `devs` automatically. + +### sticky bit (`1xxx` on dirs) +- On directories like `/tmp`, users can only delete **their own** files even if the dir is world-writable. + +Add sticky to a shared drop folder: +```bash +mkdir -p shared_drop +chmod 1777 shared_drop +ls -ld shared_drop +``` + +--- + +## 7) ACLs (Access Control Lists) — optional +ACLs allow per‑user or per‑group overrides beyond the basic `u/g/o` model. + +Inspect ACLs: +```bash +getfacl hello.txt || echo "Install acl package if missing" +``` +Grant **alice** read/write: +```bash +setfacl -m u:alice:rw hello.txt +getfacl hello.txt | sed -n '1,20p' +``` +Set a **default ACL** on a directory (applies to new files): +```bash +setfacl -m d:u:alice:rwx project +getfacl project | sed -n '1,50p' +``` +Remove an entry or clear all: +```bash +setfacl -x u:alice hello.txt +setfacl -b hello.txt # wipe all ACLs +``` +> **Note:** On Ubuntu, ACL support is usually enabled by default. If commands are missing: `sudo apt update && sudo apt install -y acl`. + +--- + +## 8) Practice tasks (do these now) +1) Make `hello.sh` executable for **owner only**, and run it. + *Hint:* `chmod 700 hello.sh` +2) Make `hello.txt` readable by **group**, but **no access** for others. Verify with `stat`. +3) Create `project/docs/` and ensure the **group** keeps inheriting on new files. + *Hint:* `chmod g+ws project` and set group ownership. +4) Create a shared `shared_drop/` so **anyone** can write but only delete their own files. + *Hint:* `chmod 1777 shared_drop` +5) (Optional) Give a specific teammate **rw** on `hello.txt` using **ACLs**, then remove it. + +--- + +## Troubleshooting +- **Permission denied**: Check both the **file** and its **directory** for execute (`x`) where needed. +- **Operation not permitted**: Ownership changes or privileged bits may require `sudo`. +- **Script won’t run**: Ensure `#!/usr/bin/env bash` shebang and `chmod +x`. Also check the mount isn’t `noexec`. +- **Group changes don’t “stick”**: Use **setgid** on the directory and correct group ownership. +- **ACLs ignored?** Ensure filesystem supports ACLs and the tools are installed. + +--- + +## Quick Quiz (1 minute) +- What does the **x** bit mean on a **directory**? +- Translate `-rwxr-x---` to octal. +- Which command changes just the **group** of a file? +- What does **setgid** on a directory do? +- How does `umask` affect new files? + +**Answers:** enter/traverse; `750`; `chgrp`; new files inherit the directory’s group; it subtracts bits from default perms. + +--- + +## Next Step +Continue to **Step 6 — System Info & Monitoring** to learn how to inspect CPU, memory, disk, and logs effectively. + diff --git a/docs/06_system_info.md b/docs/06_system_info.md new file mode 100644 index 0000000..610b40f --- /dev/null +++ b/docs/06_system_info.md @@ -0,0 +1,269 @@ +# Step 6 — System Info & Monitoring (Ubuntu 24) + +> **Type along** exactly as shown. Safe to run on your machine; nothing here makes persistent config changes (a few optional installs use `apt`). +> **Estimated time:** ~15–20 minutes + +--- + +## What you’ll learn +- Identify OS, kernel, uptime, and hardware at a glance +- Inspect **CPU**, **memory**, **disks/partitions**, and **network** +- Watch processes and system load with `top`/`htop`, `ps`, and `vmstat` +- Check running **services** with `systemd` (`systemctl`) and view **logs** (`journalctl`) +- Measure disk/CPU/IO hot spots with `iostat`, `pidstat`, `iotop` +- Run a quick “health sweep” to triage performance issues + +> **Setup:** Use your lab folder: +> ```bash +> mkdir -p ~/playground && cd ~/playground +> ``` + +--- + +## 0) Snapshot: who, what, where +Start with the fastest high‑level checks. +```bash +whoami +hostnamectl # hostname, OS, kernel +uname -rsm # kernel: release + machine arch +cat /etc/os-release # distro details +uptime -p # human-friendly uptime +uptime # load averages (1/5/15 min) +date # current time (TZ matters!) +``` + +> **Load average rule of thumb:** On a 4‑core machine, a 1‑minute load of ~4 means “fully busy”; much higher means queued work. + +--- + +## 1) CPU & memory +### CPU facts +```bash +lscpu # sockets, cores, threads, flags +nproc # logical CPU count +cat /proc/cpuinfo | grep -m1 'model name' +``` + +### Memory / swap +```bash +free -h # Mem/Swap usage (human units) +vmstat -s | head -20 # memory counters summary +swapon --show # active swap areas +cat /proc/meminfo | sed -n '1,10p' +``` + +> **Tip:** High `si/so` (swap‑in/out) in `vmstat 1` output usually correlates with memory pressure. + +--- + +## 2) Processes, load, and scheduling +### `top` basics (built‑in) +```bash +top +``` +Useful keys inside **top**: +- `1`: show per‑CPU cores +- `M`: sort by memory; `P`: sort by CPU; `T`: by time +- `k`: kill a process (enter PID, then signal like `15`) +- `Shift+E`: change units (KiB/MiB) +- `q`: quit + +### `htop` (nicer UI) +```bash +sudo apt update && sudo apt install -y htop +htop +``` + +### Point-in-time listings with `ps` +```bash +ps aux --sort=-%cpu | head -15 +ps aux --sort=-%mem | head -15 +pstree -a | head -40 || echo 'Install: sudo apt install -y psmisc' +``` + +### Niceness & signals (be careful) +```bash +nice -n 10 sleep 60 & # start lower priority +pid=$! +renice +5 -p "$pid" # increase niceness (lower priority) +kill -15 "$pid" # graceful +# kill -9 "$pid" # last resort (commented) +``` + +--- + +## 3) Disks, partitions, and filesystem usage +### Layout & mounts +```bash +lsblk -f # devices, filesystems, labels +mount | column -t | head -20 +findmnt -t ext4,xfs # mounted FS by type +``` + +### Space usage +```bash +df -hT # size, used, type per mount +# top 20 heavy dirs under / +sudo du -xh / | sort -h | tail -20 +# top 10 heavy dirs under /var (faster) +sudo du -h -d1 /var | sort -h | tail -10 +# inode pressure +df -i +``` + +> **When a disk looks full but `df -h` shows space free:** check **inodes** with `df -i`. Lots of tiny files can exhaust inodes. + +### Disk performance (optional) +```bash +sudo apt install -y sysstat iotop +# per-disk stats, queue, utilization +iostat -xz 1 3 +# per-process IO (press 'o' to filter active) +sudo iotop -oPa +``` + +--- + +## 4) Network quick checks +```bash +ip -br a # brief addresses +ip r # routing table +hostname -I # IPs only +resolvectl status | sed -n '1,40p' # DNS view +``` +Listening ports and sockets: +```bash +ss -tulpn | head -30 # TCP/UDP listeners with PIDs +ss -s # socket summary +``` +Connectivity basics: +```bash +ping -c 3 8.8.8.8 +ping -c 3 google.com +sudo apt install -y mtr-tiny dnsutils +mtr -rwbzc 50 google.com # quick route quality report +dig +short google.com +curl -I https://example.com +``` + +> **If DNS is flaky:** try `dig @1.1.1.1 example.com` to bypass local resolvers. + +--- + +## 5) Services with systemd +List running services and check status: +```bash +systemctl list-units --type=service --state=running | head -30 +systemctl status ssh +systemctl is-enabled ssh +``` +Restart a service (requires sudo): +```bash +sudo systemctl restart ssh +``` +See boot performance & failures: +```bash +systemd-analyze time +systemd-analyze blame | head -20 +systemctl --failed +``` + +--- + +## 6) Logs: journald and friends +Live/system logs: +```bash +journalctl -n 200 --no-pager # last 200 lines +journalctl -f # follow +journalctl -p warning --since '1 hour ago' +``` +Service-specific logs: +```bash +journalctl -u ssh --since 'today' --no-pager +``` +Kernel messages and last boot: +```bash +journalctl -k --since '1 hour ago' +journalctl -b -1 --no-pager # previous boot +``` +Legacy file logs (some distros still write to these): +```bash +sudo tail -n 200 /var/log/syslog +sudo grep -i 'oom' /var/log/kern.log || true +``` + +> **Tip:** Use `-g PATTERN` to grep inside `journalctl`, e.g., `journalctl -g "Out of memory" -k`. + +--- + +## 7) Resource pressure signals (advanced but handy) +Linux exposes PSI (Pressure Stall Information): +```bash +cat /proc/pressure/{cpu,io,memory} +``` +If you see sustained **some**/**full** memory or IO pressure, correlate with `iostat`, `vmstat`, and logs (possible OOMs or slow disks). + +OOM killer evidence: +```bash +journalctl -k -g 'Out of memory' --since '1 day ago' +dmesg -T | grep -i 'killed process' | tail -n 10 +``` + +--- + +## 8) Quick health sweep (copy/paste) +Run this as a one‑shot collection for triage (prints to screen): +```bash +{ echo '=== SNAPSHOT ==='; + date; hostnamectl | sed -n '1,8p'; uname -rsm; uptime; echo; + echo '=== CPU/MEM ==='; lscpu | sed -n '1,8p'; free -h; vmstat 1 3; echo; + echo '=== DISK ==='; df -hT; iostat -xz 1 2 2>/dev/null || true; echo; + echo '=== TOP PROCS ==='; ps aux --sort=-%cpu | head -10; ps aux --sort=-%mem | head -10; echo; + echo '=== NET ==='; ip -br a; ss -tulpn | head -20; echo; + echo '=== SERVICES ==='; systemctl --failed || true; systemd-analyze time || true; echo; + echo '=== LOGS (last 50) ==='; journalctl -n 50 --no-pager; +} | sed 's/\x1b\[[0-9;]*m//g' +``` +> **Note:** Some parts need packages (`sysstat`) or privileges; missing tools will be gracefully skipped. + +--- + +## 9) Practice tasks (do these now) +1) Find your CPU core/thread count and current load. + *Hint:* `lscpu`, `uptime`, `top` (`1` key). +2) Identify the **top 5** memory‑hungry processes and the **top 5** CPU‑hungry processes. + *Hint:* `ps aux --sort=-%mem` / `--sort=-%cpu`. +3) Determine which directory under `/var` consumes the most space. + *Hint:* `sudo du -h -d1 /var | sort -h | tail -5`. +4) List all listening TCP sockets with owning PIDs. + *Hint:* `ss -tulpn`. +5) Check logs for **ssh** in the last hour and restart the service. + *Hint:* `journalctl -u ssh --since '1 hour ago'`, then `sudo systemctl restart ssh`. +6) (Optional) Install `sysstat` and run `iostat -xz 1 3`; identify any device >90% util. + +--- + +## 10) Troubleshooting quick guide +- **High load avg with low CPU** → usually **IO wait** or many blocked procs. Check `iostat -xz`, `ps` with `STAT` column (`D` = uninterruptible IO sleep). +- **Memory spikes / OOM** → check `journalctl -k -g 'Out of memory'`, watch `free -h`, consider which process grew via `ps --sort=-rss`. +- **Disk full** → use `df -hT`; then `du` to find culprits; also check **inodes** (`df -i`). +- **Service down** → `systemctl status ` then `_journalctl -u _` to see the why; look for ExecStart errors, missing ports. +- **No DNS resolution** → `resolvectl status`, try `dig @1.1.1.1 example.com`; if that works, local resolver is suspect. +- **Network seems fine but web fails** → check outbound firewall/proxy, test raw IP `curl -I http://1.1.1.1`. + +--- + +## 11) Quick quiz (1 minute) +- What do the **three** numbers in `uptime` represent? +- Which tool shows **per‑disk** queue and utilization quickly? +- How do you list services that **failed** on boot? +- One command to show **listening** sockets with PIDs? +- Where do you look for **OOM killer** events? + +**Answers:** 1/5/15‑min load avgs; `iostat -xz`; `systemctl --failed`; `ss -tulpn`; `journalctl -k -g 'Out of memory'` (or `dmesg`). + +--- + +## Next Step +Proceed to **Step 7 — Users & Authentication** to manage local users, groups, passwords, and SSH hardening. + diff --git a/docs/07_networking.md b/docs/07_networking.md new file mode 100644 index 0000000..c9294e5 --- /dev/null +++ b/docs/07_networking.md @@ -0,0 +1,252 @@ +# Step 7 — Networking Basics (Ubuntu 24) + +> **Type along** exactly as shown. These are safe, read‑mostly commands. Optional tools will prompt for `sudo apt install`. +> **Estimated time:** ~20–25 minutes + +--- + +## What you’ll learn +- Read your **IP configuration**, MAC, and default route +- Test connectivity at each layer: **link → IP → DNS → TCP/UDP → app** +- Inspect **listening ports** and active connections with `ss` +- Use **DNS tools** (`resolvectl`, `dig`) effectively +- Trace paths and check packet loss with **`mtr`/`traceroute`** +- Do quick HTTP checks with **`curl`** and simple servers (Python, `nc`) +- (Optional) Basics of **firewall** (`ufw`) and **packet capture** (`tcpdump`) + +> **Setup:** Use your lab folder: +> ```bash +> mkdir -p ~/playground && cd ~/playground +> ``` + +--- + +## 0) A quick model: test from low → high +1) **Link up?** (interface present, carrier) +2) **IP/route OK?** (address/gateway) +3) **DNS OK?** (names resolve) +4) **Transport OK?** (TCP/UDP reach port) +5) **App OK?** (HTTP responds, SSH banner, etc.) + +You’ll follow this order every time; it prevents wild goose chases. + +--- + +## 1) Interfaces & addresses +### See links and addresses +```bash +ip -br link # link names + state (brief) +ip -br a # addresses (IPv4/IPv6) per interface +hostname -I # IPs only (no names) +``` +Show details for your primary interface (replace `eth0`/`ens3`/`enp0s3` with yours): +```bash +ip addr show enp0s3 | sed -n '1,30p' +``` + +### MAC address & media info (optional) +```bash +sudo apt update && sudo apt install -y ethtool +sudo ethtool -P enp0s3 # permanent MAC +sudo ethtool enp0s3 | sed -n '1,25p' # speed/duplex/link +``` + +> **Tip:** Interface names vary across platforms (e.g., `wlp3s0` for Wi‑Fi). Use `ip -br link` to discover yours. + +--- + +## 2) Routing: where packets go +Show routes and default gateway: +```bash +ip route +ip r get 8.8.8.8 # which interface/gateway would handle this dest? +``` +See neighbors/ARP cache: +```bash +ip neigh | head -10 +``` + +> **Rule of thumb:** If `ip r get 8.8.8.8` errors or returns the wrong interface, your default route or subnet mask is wrong. + +--- + +## 3) How you got an IP: DHCP or static (read‑only) +### On servers (systemd‑networkd) +```bash +networkctl +networkctl status -a | sed -n '1,80p' +``` +### On desktops (NetworkManager) +```bash +nmcli device status +nmcli device show enp0s3 | sed -n '1,80p' +``` +View netplan config (do **not** edit during the lab): +```bash +sudo ls /etc/netplan/ +sudo sed -n '1,120p' /etc/netplan/*.yaml 2>/dev/null || true +``` + +--- + +## 4) Connectivity tests +### Ping (ICMP) +```bash +ping -c 3 1.1.1.1 # raw IP – tests routing only +ping -c 3 google.com # adds DNS to the chain +ping -6 -c 3 google.com # IPv6, if available +``` +If ping to hostname fails but IP works, it’s a **DNS** issue, not routing. + +### Trace the path (prefer `mtr`) +```bash +sudo apt install -y mtr-tiny +mtr -rwbzc 50 8.8.8.8 # summarize 50 pings across the route +mtr -rwbzc 50 google.com # includes DNS + any CDN hops +``` + +--- + +## 5) Name resolution like a pro +### System view (resolvectl) +```bash +resolvectl status | sed -n '1,80p' +resolvectl query example.com +``` +### Query types with `dig` +```bash +sudo apt install -y dnsutils +# A/AAAA +dig +short A example.com +dig +short AAAA example.com +# MX/NS/CNAME +dig +short MX example.com +dig +short NS example.com +# Bypass local DNS to test upstream directly +dig @1.1.1.1 +short A example.com +``` +Hosts database (rare but handy): +```bash +getent hosts localhost example.com | sed -n '1,10p' +``` + +--- + +## 6) Sockets & ports: who’s listening? +List listeners by protocol with owning PIDs: +```bash +ss -tulpn | head -30 # TCP/UDP listeners +ss -s # socket summary +``` +Filter for a specific port/service: +```bash +ss -tlpn 'sport = :22' # who owns TCP port 22 +``` + +### Mini lab: create a test port and connect +Start a listener (background): +```bash +nc -lv 127.0.0.1 9000 & echo $! > /tmp/nc9000.pid +sleep 1 +ss -tlpn 'sport = :9000' +``` +Connect to it: +```bash +printf 'hello from client\n' | nc -v 127.0.0.1 9000 +``` +Clean up: +```bash +kill "$(cat /tmp/nc9000.pid)" 2>/dev/null || true +rm -f /tmp/nc9000.pid +``` + +> **Why this matters:** When an app “won’t start,” check whether the port is already taken (`ss -tulpn`). + +--- + +## 7) Quick HTTP checks +Spin up a tiny web server (Python 3’s stdlib): +```bash +python3 -m http.server 8080 --bind 127.0.0.1 & echo $! > /tmp/http8080.pid +sleep 1 +ss -tlpn 'sport = :8080' +``` +Probe it with `curl`: +```bash +curl -I http://127.0.0.1:8080/ +``` +Stop the server: +```bash +kill "$(cat /tmp/http8080.pid)" 2>/dev/null || true +rm -f /tmp/http8080.pid +``` + +> **TLS tip:** To inspect certificates/handshakes: `openssl s_client -connect example.com:443 -servername example.com -brief`. + +--- + +## 8) Firewalls (optional, lab VM only) +Ubuntu ships **UFW** as a front‑end to `nftables`. +```bash +sudo ufw status verbose +``` +Allow a temporary lab port and verify: +```bash +sudo ufw allow 8080/tcp +sudo ufw status numbered +ss -tlpn 'sport = :8080' +# cleanup +sudo ufw delete allow 8080/tcp +``` +> **Caution:** Don’t enable/alter firewalls on production hosts without change control. In the lab it’s fine. + +--- + +## 9) Packet capture (optional but powerful) +```bash +sudo apt install -y tcpdump +# watch ICMP for a few packets +sudo tcpdump -n -c 5 icmp +# capture just port 8080 traffic (run while your test server is up) +sudo tcpdump -n -i any 'tcp port 8080' -c 10 +``` +> **Privacy note:** Packet captures can include sensitive data. Only capture on systems and networks you own or have permission to test. + +--- + +## 10) Common gotchas & fixes +- **No network**: `ip -br link` shows `DOWN` → `sudo ip link set enp0s3 up` (or ensure VM NIC attached). +- **Can ping IP but not hostname**: DNS issue → `resolvectl status`, `dig @1.1.1.1 example.com`. +- **Service won’t bind**: Port already in use → `ss -tulpn | grep :PORT`, stop the conflicting process. +- **Intermittent timeouts**: Check path with `mtr`; look for loss on the last 2–3 hops; also check host load (`top`) and disk (`iostat -xz`). +- **Works locally, not remotely**: Local firewall/NAT/security groups. Verify `ufw`, cloud SGs, and that service binds to the **right address** (0.0.0.0 vs 127.0.0.1). + +--- + +## 11) Practice tasks (do these now) +1) Identify your **primary interface**, IPv4/IPv6 addresses, and default gateway. + *Hint:* `ip -br a`, `ip route`. +2) Show the exact route used to reach **1.1.1.1** and **google.com**. + *Hint:* `ip r get`, `mtr -rwbc 30`. +3) Resolve `example.com` to A and AAAA records using **your** resolver and **1.1.1.1**. + *Hint:* `dig +short`, `dig @1.1.1.1`. +4) Start the Python HTTP server on port **8080**, verify with `ss` and `curl`, then stop it. +5) Create a local TCP listener on **9000** with `nc`, send a line of text from a client, confirm it appears, and clean up. +6) (Optional) Add a temporary UFW rule for **8080/tcp**, verify access, then remove it. + +--- + +## 12) Quick quiz (1 minute) +- Which command shows **listening sockets with PIDs**? +- Which tool gives you **route plus packet loss** over time? +- Name two commands to test **DNS** quickly. +- If a hostname fails but an IP succeeds, which layer is broken? +- What does `ip r get 8.8.8.8` tell you? + +**Answers:** `ss -tulpn`; `mtr` (or `traceroute` for path only); `resolvectl`, `dig` (also `getent hosts`); DNS; which interface/gateway will carry traffic to that destination. + +--- + +## Next Step +Proceed to **Step 8 — Users & Authentication** (local users, groups, passwords, SSH basics). If your curriculum orders topics differently, adjust the previous step’s “Next Step” pointer to match this page. + diff --git a/docs/08_archiving.md b/docs/08_archiving.md new file mode 100644 index 0000000..1f784fd --- /dev/null +++ b/docs/08_archiving.md @@ -0,0 +1,278 @@ +# Step 8 — Archiving & Compression (Ubuntu 24) + +> **Type along** exactly as shown. Nothing here alters system config. Optional installs use `apt`. +> **Estimated time:** ~20–25 minutes + +--- + +## What you’ll learn +- The difference between **archiving** (tar) and **compressing** (gzip/xz/zstd/zip/7z) +- Create, list, verify, extract **tar** archives with and without compression +- Choose the right compressor for **speed** vs **size** (gzip, xz, zstd) +- Include/exclude paths, preserve ownership/permissions, and handle **symlinks** and **sparse files** +- Stream archives via **pipes** and **SSH**; split and rejoin large archives +- Verify integrity with `tar -tvf`/`-W` and `sha256sum` + +> **Setup:** Work in a safe playground: +> ```bash +> mkdir -p ~/playground/arch && cd ~/playground/arch +> ``` + +--- + +## 0) Prepare sample data +Create a small tree with different file types: +```bash +mkdir -p src dirA/dirB +printf 'hello\n' > src/hello.txt +head -c 1M src/random.bin +ln -s ../src hello_link # symlink +# create a sparse file (looks big, uses little disk) +truncate -s 500M src/sparse.img +# hidden file, and a file to exclude later +printf 'secret\n' > .env +printf 'ignore me\n' > src/tmp.log +``` +Confirm structure: +```bash +find . -maxdepth 3 -printf '%M %u:%g %8s %p\n' | sed -n '1,40p' +``` + +--- + +## 1) Archiving 101 — `tar` without compression +Create an archive of **src/** and **dirA/**: +```bash +# c=create, v=verbose, f=filename + tar -cvf lab.tar src dirA + ls -lh lab.tar +``` +List contents without extracting: +```bash + tar -tvf lab.tar | head -20 +``` +Extract into a new folder and compare: +```bash + mkdir extract && tar -xvf lab.tar -C extract + diff -qr src extract/src && echo 'src matches extract/src' +``` +> **Note:** `tar` stores paths relative to where you run it; use `-C` to control base paths. + +--- + +## 2) Compressors quick tour +Install common tools: +```bash +sudo apt update && sudo apt install -y zstd xz-utils gzip zip unzip p7zip-full +``` +Single‑file compression (no tar): +```bash +# gzip (fast, widespread) +gzip -k src/hello.txt # keeps original with -k +ls -lh src/hello.txt* +# xz (smallest, slower) +xz -k src/random.bin +# zstd (balanced, very fast; levels 1–19; -T0 = all cores) +zstd -k -T0 src/random.bin +``` +Inspect compression ratios: +```bash +gzip -l src/hello.txt.gz +xz -l src/random.bin.xz +zstd -lv src/random.bin.zst +``` +> **Rule of thumb:** `zstd` is great default for speed; `xz` for maximum shrink (archives) when time is okay; `gzip` for legacy compatibility. + +--- + +## 3) Tar + compression combos +### Easiest: let `tar` drive the compressor +```bash +# gzip + tar -czvf lab.tar.gz src dirA +# xz + tar -cJvf lab.tar.xz src dirA +# zstd (modern) + tar --zstd -cvf lab.tar.zst src dirA +``` +**List** without extracting: +```bash + tar -tvf lab.tar.gz | head -10 + tar -tvf lab.tar.xz | head -10 + tar -tvf lab.tar.zst | head -10 +``` + +### Custom compressor flags with `-I` +```bash +# zstd level 19, all cores + tar -I 'zstd -T0 -19' -cvf lab-max.tar.zst src dirA +# parallel gzip if `pigz` is installed +# sudo apt install -y pigz + tar -I pigz -cvf lab.tar.gz src dirA +``` + +--- + +## 4) Extracting safely +Basic extraction into a target directory: +```bash +mkdir -p /tmp/lab_extract +sudo tar -xvpf lab.tar.zst --zstd -C /tmp/lab_extract +``` +Flags used: +- `x` extract, `v` verbose, `p` **preserve perms**, `f` filename +- `--same-owner` (root only) to preserve ownership exactly + +Strip leading path components (handy when archive contains a top‑level folder): +```bash +mkdir clean && tar -xvf lab.tar.gz --strip-components=1 -C clean +``` +Extract **one** item: +```bash +tar -xvf lab.tar.zst --zstd src/hello.txt -C extract_one +``` + +--- + +## 5) Excludes, includes, and quoting +Create an archive but **exclude** logs and hidden files: +```bash + tar --exclude='*.log' --exclude='.*' -cvf lab_nohidden.tar src dirA + tar -tvf lab_nohidden.tar | grep -E '\.log|/\.' || echo 'No logs/hidden files included' +``` +Use an **exclude‑from** file (one pattern per line): +```bash +printf '*.log\n.env\n*.tmp\n' > exclude.txt + tar --exclude-from=exclude.txt -cvf lab_filtered.tar src dirA +``` +> **Quoting tip:** Quote globs (`'*.log'`) so your shell doesn’t expand them before `tar` sees them. + +--- + +## 6) Sparse files & symlinks +The sample `src/sparse.img` is **sparse**. Use `--sparse` to store holes efficiently: +```bash + tar --sparse -cvf sparse.tar src/sparse.img + ls -lh sparse.tar +``` +Control how symlinks are handled: +```bash +# default: store symlink as link (recommended) + tar -cvf links.tar hello_link +# follow symlinks (stores target content) + tar -h -cvf links_follow.tar hello_link + tar -tvf links_follow.tar | head -3 +``` + +--- + +## 7) Streaming: pipes & SSH +Create and compress on the fly, no temp file: +```bash + tar -c src | zstd -T0 -19 -o src.tar.zst +``` +Send to a remote host over SSH (requires SSH access): +```bash +# on local machine + tar -c src | ssh user@remote 'tar -x -C /tmp' +# or with compression on the wire + tar -c src | zstd -T0 | ssh user@remote 'zstd -d | tar -x -C /tmp' +``` + +--- + +## 8) Integrity: list, verify, checksum +**List** is your first sanity check: +```bash + tar -tvf lab.tar.zst --zstd | head -5 +``` +Ask `tar` to **verify** after writing (`-W`): +```bash + tar --zstd -cvWf lab_verify.tar.zst src dirA +``` +Create a strong **checksum** alongside the archive: +```bash +sha256sum lab_verify.tar.zst > lab_verify.tar.zst.sha256 +sha256sum -c lab_verify.tar.zst.sha256 # verify later +``` + +--- + +## 9) Split & rejoin large archives +Split into ~200 MiB parts: +```bash + tar --zstd -cvf big.tar.zst src dirA + split -b 200M big.tar.zst big.tar.zst.part- + ls -lh big.tar.zst.part-* +``` +Rejoin and verify: +```bash + cat big.tar.zst.part-* > big.rejoined.tar.zst + cmp big.tar.zst big.rejoined.tar.zst && echo 'Parts rejoined OK' +``` + +--- + +## 10) `zip` and `7z` (cross‑platform) +### zip +```bash +zip -r lab.zip src dirA . -x '*.log' .env +unzip -l lab.zip | head -10 +unzip lab.zip -d unzip_out +``` +### 7‑Zip / 7z (high ratio, solid archives) +```bash +7z a -t7z -m0=lzma2 -mx=9 lab.7z src dirA +7z l lab.7z | head -15 +7z x lab.7z -o7z_out -y +``` + +--- + +## 11) Ownership, perms, and umask +- `tar` records **modes, owners, groups, times**. Extraction as non‑root maps owners to **your** user unless you use `sudo` + `--same-owner`. +- Use `-p` to **preserve permissions** even if your `umask` would change them. +- For shared/team archives, consider setting a consistent `umask` before creating, e.g., `umask 022`. + +--- + +## 12) Clean up (optional) +```bash +rm -rf extract extract_one clean unzip_out 7z_out *.tar* *.gz *.xz *.zst *.zip *.7z *.sha256 big.rejoined.tar.zst src dirA hello_link exclude.txt .env +``` + +--- + +## 13) Practice tasks (do these now) +1) Create `proj.tar.zst` from `src/` **excluding** `*.log` and hidden files. List its contents. +2) Extract only `src/hello.txt` into `~/playground/arch/single/` and verify checksum with `sha256sum`. +3) Make a **sparse** 1 GiB file and build a space‑efficient archive of it; compare `.tar` size with and without `--sparse`. +4) Stream‑extract `src/` to `/tmp/arch_stream/` without creating a local archive file. +5) Split `proj.tar.zst` into 100 MiB parts, rejoin, and verify with `cmp`. +6) (Optional) Create `lab.zip` and `lab.7z`, list both, extract to separate folders, and compare with the original tree using `diff -qr`. + +--- + +## 14) Troubleshooting +- **“file changed as we read it”** during tar: the file mutated mid‑archive; rerun when idle, or snapshot first. +- **Permissions wrong after extract**: add `-p` and (if root) `--same-owner`; check `umask`. +- **Symlinks unexpectedly dereferenced**: you probably used `-h`; remove it to store links as links. +- **Archive too slow**: use `zstd -T0` (multi‑threaded) or `pigz` for gzip; avoid `xz` for huge trees if you care about speed. +- **Disk full**: prefer streaming (`tar | zstd -o /mnt/big/…`) or `-C` to write on a larger filesystem; check free space with `df -h`. + +--- + +## 15) Quick quiz (1 minute) +- Does `tar` compress by default? +- Which compressor is fastest on multi‑core systems at decent ratios? +- Which `tar` option keeps original file modes on extract? +- How do you exclude all hidden files? +- What’s the safest way to copy to a remote host without writing a local archive file? + +**Answers:** No, `tar` only archives unless you add a compressor; `zstd -T0`; `-p` (and `--same-owner` when root); `--exclude='.*'`; `tar -c dir | ssh host 'tar -x -C /dest'` (optionally compress in the middle). + +--- + +## Next Step +Proceed to **Step 9 — Users & Authentication** (local users, groups, passwords, SSH basics). If your curriculum orders differ, update the previous step’s “Next Step” pointer to this page. + diff --git a/docs/09_package_mgmt.md b/docs/09_package_mgmt.md new file mode 100644 index 0000000..1b4c0cc --- /dev/null +++ b/docs/09_package_mgmt.md @@ -0,0 +1,266 @@ +# Step 9 — Package Management (Ubuntu 24) + +> **Type along** exactly as shown. Focuses on APT (Debian/Ubuntu). Optional bits cover `snap` and `flatpak`. +> **Estimated time:** ~25–30 minutes + +--- + +## What you’ll learn +- Discover, install, remove, and upgrade software with **APT** +- Inspect package **metadata**, **versions**, **deps**, and **files** +- Roll back to a **specific version**, **hold** packages, and clean cache +- Diagnose broken packages and locks; read APT/DPKG **logs** +- (Optional) Add third‑party **repositories** safely with modern **keyrings** +- (Optional) Use **snap** and **flatpak** where appropriate + +> **Setup:** Use a lab VM or a machine where you can install harmless utilities like `cowsay`, `sl`, `tree`. Production hosts should follow change control. + +--- + +## 0) Refresh indexes & basic system hygiene +```bash +sudo apt update # refresh package lists +apt list --upgradable # see pending upgrades (no sudo needed) +sudo apt upgrade -y # safe upgrade of installed packages +sudo apt autoremove -y # remove unused deps +sudo apt clean # drop cached .deb files +``` +> **Tip:** Use `sudo apt full-upgrade` (aka `dist-upgrade`) to allow kernel or dependency changes that add/remove packages. + +--- + +## 1) Find packages +Search by name/description: +```bash +apt search htop | sed -n '1,20p' # quick text search +``` +Show detailed metadata: +```bash +apt show htop | sed -n '1,40p' +``` +See available versions & repository **origin**: +```bash +apt policy htop +``` +List reverse deps (who depends on whom): +```bash +apt-cache rdepends --installed bash | sed -n '1,20p' +``` + +--- + +## 2) Install & remove packages +Install with confirmation and see what else will be pulled in: +```bash +sudo apt install -y htop tree +``` +Remove software but keep config files: +```bash +sudo apt remove -y tree +``` +Remove **and** purge config files: +```bash +sudo apt purge -y tree +``` + +### Verify installation contents +Which files did a package install? +```bash +dpkg -L htop | sed -n '1,40p' # list files owned by installed package +``` +Which package owns a file path? +```bash +dpkg -S /usr/bin/htop +``` +Find package **for an uninstalled** file path (requires apt-file): +```bash +sudo apt install -y apt-file +sudo apt-file update +apt-file search bin/ncdu | head -10 +``` + +--- + +## 3) Versions: pin, hold, and roll back +See available versions across repos: +```bash +apt policy openssh-server +``` +Install a **specific version**: +```bash +sudo apt install openssh-server=1:9.6p1-3ubuntu13 # example; use a version shown by `apt policy` +``` +Temporarily **hold** at current version (don’t upgrade): +```bash +sudo apt-mark hold openssh-server +apt-mark showhold +# later, unhold +sudo apt-mark unhold openssh-server +``` + +### Advanced: pin priority (optional) +Create a pin to prefer Ubuntu main over a PPA for a package (edit safely): +```bash +sudo mkdir -p /etc/apt/preferences.d +sudo tee /etc/apt/preferences.d/openssh.pref >/dev/null <<'EOF' +Package: openssh-server +Pin: release a=noble +Pin-Priority: 600 +EOF +``` +> **Rules of thumb:** Priority >1000 forces downgrade if needed; 500 is default; 600 prefers that source. + +--- + +## 4) Inspect dependencies & health +Show dependencies: +```bash +apt-cache depends htop | sed -n '1,40p' +``` +Simulate an install (no changes): +```bash +sudo apt -s install ncdu +``` +Check package status (installed?, config state): +```bash +dpkg -s htop | sed -n '1,40p' +``` + +--- + +## 5) Fix common issues +### Broken dependencies / interrupted dpkg +```bash +sudo dpkg --configure -a # finish interrupted installs +sudo apt -f install # attempt to fix broken deps +``` +### Lock is held +If another process is using APT/DPKG (GUI updater, unattended‑upgrades): +```bash +ps aux | egrep 'apt|dpkg|unattended' | egrep -v 'egrep' +# Wait for it to finish or stop the offending process if safe. +``` +### Stuck half‑installed package +```bash +sudo apt purge -y +sudo apt install -y +``` +### Where to read logs +```bash +sudo tail -n 100 /var/log/apt/history.log +sudo tail -n 100 /var/log/dpkg.log +``` + +--- + +## 6) Repositories the **right** way (modern keyrings) — optional +> Avoid legacy `apt-key`. Use per‑repo **keyrings** and `signed-by=`. + +Example: add a vendor repo safely (replace placeholders with a real vendor’s URLs): +```bash +sudo mkdir -p /etc/apt/keyrings +curl -fsSL https://vendor.example.com/keys/repo.gpg | \ + sudo gpg --dearmor -o /etc/apt/keyrings/vendor.gpg + +# Add source list (adjust codename e.g., noble, jammy) +. /etc/os-release +echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/vendor.gpg] \ +https://vendor.example.com/apt $VERSION_CODENAME main" | \ + sudo tee /etc/apt/sources.list.d/vendor.list >/dev/null + +sudo apt update +apt policy vendor-package-name +``` +Remove the repo cleanly later: +```bash +sudo rm -f /etc/apt/sources.list.d/vendor.list /etc/apt/keyrings/vendor.gpg +sudo apt update +``` + +### PPAs (Launchpad) — optional +```bash +sudo apt install -y software-properties-common +sudo add-apt-repository -y ppa:graphics-drivers/ppa +sudo apt update +``` +Remove: +```bash +sudo add-apt-repository -r ppa:graphics-drivers/ppa +sudo apt update +``` + +--- + +## 7) Kernel & reboot awareness +List kernels and check if a reboot is pending: +```bash +dpkg -l 'linux-image*' | sed -n '1,20p' +[ -f /var/run/reboot-required ] && echo 'Reboot required' || echo 'No reboot pending' +``` + +--- + +## 8) Snap & Flatpak (optional) +### Snap +```bash +snap list +snap find jq | head -10 +sudo snap install jq +sudo snap remove jq +``` +### Flatpak +```bash +sudo apt install -y flatpak +sudo flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo +flatpak search org.gnome.Calculator | head -5 +sudo flatpak install -y flathub org.gnome.Calculator +flatpak list +sudo flatpak uninstall -y org.gnome.Calculator +``` +> **When to use:** Prefer APT for system packages; `snap/flatpak` for sandboxed desktop apps or when newer versions are only available there. + +--- + +## 9) Cleanup & space management +```bash +sudo apt autoremove --purge -y +sudo apt clean +sudo du -h /var/cache/apt/archives | tail -1 +``` + +--- + +## 10) Practice tasks (do these now) +1) **Search** for `ncdu`, inspect details (`apt show`), and install it. +2) Use `dpkg -L ncdu` to list files; find which package owns `/usr/bin/ncdu` (`dpkg -S`). +3) Install `jq` at a **specific version** if multiple are available (`apt policy`, then `apt install jq=…`). +4) **Hold** `jq`, show holds, then **unhold** it. +5) Install `apt-file`, search which package provides `bin/htop`. +6) (Optional) Add a PPA, install a package from it, then remove the PPA and revert using pins or by installing the Ubuntu version. +7) Read the last 50 lines of both APT and DPKG logs. + +--- + +## 11) Troubleshooting quick guide +- **Broken deps** → `sudo dpkg --configure -a`, `sudo apt -f install`, then inspect `/var/log/apt/history.log`. +- **Held or pinned versions** blocking upgrades → check `apt-mark showhold`, and files under `/etc/apt/preferences.d`. +- **Repo GPG errors** → ensure you used keyrings + `signed-by=…`; check permissions on `/etc/apt/keyrings/*.gpg` (0644). +- **“Package not found”** → verify `apt update`, correct **codename** in source (`noble`, `jammy`), and architecture matches. +- **Lock files busy** → another process is running (`unattended-upgrades`, GUI), or left stale lock after crash. Confirm with `ps` and wait/kill cautiously. + +--- + +## 12) Quick quiz (1 minute) +- Which command shows all **available versions** for a package and where they come from? +- What’s the difference between `remove` and `purge`? +- How do you **prevent** a package from upgrading? +- Which logs help you reconstruct what APT did recently? +- Why is `apt-key` deprecated and what should you use instead? + +**Answers:** `apt policy`; `remove` keeps config files, `purge` deletes them; `apt-mark hold` (and pins for repo preference); `/var/log/apt/history.log` and `/var/log/dpkg.log`; use per‑repo **keyrings** with `signed-by=`. + +--- + +## Next Step +Proceed to **Step 10 — Users & Authentication** (local users, groups, passwords, SSH basics). If your curriculum orders differ, update the previous step’s “Next Step” pointers accordingly. + diff --git a/docs/10_scripting.md b/docs/10_scripting.md new file mode 100644 index 0000000..1135cf8 --- /dev/null +++ b/docs/10_scripting.md @@ -0,0 +1,365 @@ +# Step 10 — Basic Scripting (Bash on Ubuntu 24) + +> **Type along** exactly as shown. We’ll use **Bash** throughout. Nothing here modifies system config unless stated. +> **Estimated time:** ~30–40 minutes + +--- + +## What you’ll learn +- Write and run your first **Bash** scripts safely +- Use variables, quoting, arithmetic, and **exit codes** +- Branching (`if`), loops (`for`, `while`), and **functions** +- Handle **arguments** (`$1…`, `"$@"`, `getopts`), and **I/O** (stdin/stdout/stderr) +- Robust practices: shebangs, `set -Eeuo pipefail`, `trap`, `ShellCheck` +- Read files line‑by‑line, use pipes, and compose small utilities + +> **Setup:** +> ```bash +> mkdir -p ~/playground/scripting && cd ~/playground/scripting +> ``` + +--- + +## 0) Shebang, permissions, and running +Create a minimal script and execute it. +```bash +cat > hello.sh <<'EOF' +#!/usr/bin/env bash +# Minimal script +printf 'Hello, %s!\n' "${1:-world}" +EOF + +chmod +x hello.sh +./hello.sh +./hello.sh Raghu +``` + +**Notes** +- `#!/usr/bin/env bash` finds Bash via `$PATH`. +- `chmod +x` makes it executable. +- Use `./script.sh` or full path; **don’t** rely on `.` being in `$PATH`. + +--- + +## 1) Safer defaults for real scripts +Create a template with error handling. +```bash +cat > template.sh <<'EOF' +#!/usr/bin/env bash +set -Eeuo pipefail +# ^ E: trap ERR on subshells, e: exit on error, u: unset var error, o pipefail: pipeline fails early +IFS=$'\n\t' + +# --- globals --- +SCRIPT_NAME=${0##*/} +VERSION=1.0.0 + +# --- cleanup & error handling --- +cleanup() { + # runs on EXIT; delete temp files here + : +} +trap cleanup EXIT + +err() { + local code=$? + printf 'ERROR(%s): command failed (exit=%d)\n' "$SCRIPT_NAME" "$code" >&2 +} +trap err ERR + +usage() { + cat <&2; exit 2 ;; + \?) usage; exit 2 ;; + esac +done +shift $((OPTIND-1)) + +printf 'Hello, %s!\n' "$name" +EOF + +chmod +x template.sh +./template.sh -n Labzy +./template.sh -v +``` + +> **Reality check:** `set -e` can surprise you with commands that legally return non‑zero (e.g., `grep` no matches). Either guard them (`grep ... || true`) or test conditionally (`if grep -q ...; then ... fi`). + +--- + +## 2) Variables, quoting, and arithmetic +```bash +name=Raghu # no spaces around = +num=5 +msg="Hi $name" # double quotes expand variables +printf '%s (%d)\n' "$msg" "$num" + +# arithmetic +((sum = num + 10)) +printf 'sum=%d\n' "$sum" +((sum++)) + +# command substitution +now=$(date +%F) +printf 'Today: %s\n' "$now" + +# arrays (indexed) +fruits=(apple banana cherry) +printf '%s\n' "${fruits[@]}" + +# associative arrays (bash >= 4) +declare -A ages=([alice]=30 [bob]=27) +printf 'Alice=%s Bob=%s\n' "${ages[alice]}" "${ages[bob]}" +``` + +**Quoting rules you’ll actually use** +- Always **double‑quote** variables: `"$var"` (prevents word splitting & globbing) +- Prefer `"${arr[@]}"` to expand arrays safely +- Use single quotes for **literal** strings: `'*.log'` + +--- + +## 3) Conditions and loops +```bash +# if/elif/else +x=7 +if (( x > 10 )); then + echo 'big' +elif (( x == 7 )); then + echo 'lucky' +else + echo 'small' +fi + +# string tests and files +f='hello.sh' +if [[ -f $f && -x $f ]]; then echo 'script is executable'; fi + +# case +case "$1" in + start) echo starting ;; + stop) echo stopping ;; + *) echo usage: $0 '{start|stop}' ;; +esac + +# for loop (files) +for p in *.sh; do + printf 'script: %s\n' "$p" +done + +# while read loop (robust) +printf 'a\nb\nc\n' > lines.txt +while IFS= read -r line; do + printf 'line=[%s]\n' "$line" +done < lines.txt +``` + +--- + +## 4) Functions, returns, and exit codes +```bash +is_port_open() { + local host=$1 port=$2 + (echo > /dev/tcp/$host/$port) >/dev/null 2>&1 +} + +if is_port_open 127.0.0.1 22; then + echo 'ssh seems open' +else + echo 'ssh closed' +fi + +# explicit exit codes +some_check() { + [[ -d $1 ]] || return 2 # custom non-zero means a specific failure +} + +some_check /nope || echo "some_check failed with: $?" +``` + +> **Guideline:** exit codes: `0=success`, `1=generic`, `2=bad usage`, `>2` command‑specific. + +--- + +## 5) Stdout vs stderr, pipes, and redirection +```bash +# send normal output to a file +./hello.sh > output.txt +# send errors to a file +./template.sh -z 2> errors.log || true +# merge stderr into stdout +./template.sh -z > all.log 2>&1 || true +# pipelines +seq 1 10 | paste -sd+ - | bc +``` + +**Here‑docs and here‑strings** +```bash +cat <<'TXT' > note.txt +multi-line text +with $variables left alone +TXT + +# here-string passes a single line as stdin +read -r first <<< "$(head -n1 note.txt)" +``` + +--- + +## 6) Mini project: a tiny backup script +Create directories and a script that tars + compresses a folder with date stamps. +```bash +mkdir -p data backups +printf 'demo\n' > data/file1.txt + +cat > backup.sh <<'EOF' +#!/usr/bin/env bash +set -Eeuo pipefail +shopt -s nullglob +SRC=${1:-data} +OUT=${2:-backups} +mkdir -p "$OUT" +stamp=$(date +%Y%m%d-%H%M%S) +archive="$OUT/${SRC##*/}-$stamp.tar.zst" + +# require tar and zstd +command -v tar >/dev/null || { echo 'tar missing' >&2; exit 127; } +command -v zstd >/dev/null || { echo 'zstd missing: sudo apt install zstd' >&2; exit 127; } + +tar --zstd -cvf "$archive" "$SRC" >/dev/null +printf 'Created %s (%s)\n' "$archive" "$(du -h "$archive" | cut -f1)" +EOF + +chmod +x backup.sh +./backup.sh data backups +ls -lh backups | tail -n +1 +``` + +**Restore one archive** +```bash +mkdir -p restore +latest=$(ls -1 backups/*.tar.zst | tail -n1) +tar --zstd -xvf "$latest" -C restore +``` + +--- + +## 7) Argument parsing with `getopts` +```bash +cat > args_demo.sh <<'EOF' +#!/usr/bin/env bash +set -Eeuo pipefail +usage() { echo "Usage: $0 [-c COUNT] [-o OUTDIR] file"; } +count=1; out=out +while getopts ':c:o:h' opt; do + case "$opt" in + c) count=$OPTARG ;; + o) out=$OPTARG ;; + h) usage; exit 0 ;; + :) echo "Option -$OPTARG needs an argument" >&2; exit 2 ;; + \?) usage; exit 2 ;; + esac +done +shift $((OPTIND-1)) +file=${1:-} +[[ -n $file ]] || { usage; exit 2; } +mkdir -p "$out" +for i in $(seq 1 "$count"); do + cp -a "$file" "$out/${file##*/}.$i" +done +echo "Wrote $count copies to $out" +EOF + +chmod +x args_demo.sh +./args_demo.sh -c 3 -o copies hello.sh +ls -l copies +``` + +--- + +## 8) Reusable helpers and style +Create a tiny **lib** and reuse it. +```bash +cat > lib.sh <<'EOF' +#!/usr/bin/env bash +set -Eeu -o pipefail +log() { printf '[%(%F %T)T] %s\n' -1 "$*"; } +require() { command -v "$1" >/dev/null || { log "need $1"; exit 127; }; } +EOF + +cat > use_lib.sh <<'EOF' +#!/usr/bin/env bash +set -Eeuo pipefail +. ./lib.sh +require curl +log "Fetching example.com headers" +curl -I https://example.com >/dev/null +log done +EOF + +chmod +x use_lib.sh +./use_lib.sh +``` + +**Lint your scripts** (highly recommended): +```bash +sudo apt update && sudo apt install -y shellcheck +shellcheck hello.sh template.sh backup.sh args_demo.sh use_lib.sh +``` + +--- + +## 9) Cron and scheduling (optional) +Run a script every day at 02:15. +```bash +crontab -e +# add the line below, save & exit +15 2 * * * /home/$USER/playground/scripting/backup.sh /home/$USER/data /home/$USER/backups >>/home/$USER/backup.log 2>&1 +``` +Check logs or output files to confirm it ran. + +--- + +## 10) Practice tasks (do these now) +1) Add a `-d`/`--dry-run` option to `backup.sh` that prints what would be archived but doesn’t create a file. +2) Modify `args_demo.sh` to accept `-p PREFIX` and include it in the output filenames. +3) Write `checksum.sh` that prints a SHA256 for each file passed as arguments; exit `2` if any file doesn’t exist. +4) Create `filter.sh` that reads stdin and prints only lines containing a supplied pattern (case‑insensitive) – use `grep -i` properly with `set -e`. +5) (Optional) Write `netcheck.sh host port` that returns `0` if TCP is open using the `/dev/tcp` trick; otherwise `1`. + +--- + +## 11) Troubleshooting quick guide +- **Permission denied** → forgot `chmod +x`; or directory lacks `+x` for traversal. +- **`command not found`** → incorrect shebang; missing dependency (use `require` helper). +- **Script exits early with `set -e`** → a command returned non‑zero; handle expected failures with `|| true` or `if` guards. +- **Arguments with spaces break** → missing quotes; always use `"$var"` and `"$@"`. +- **Cron works manually but not via cron** → PATH/env differences; use absolute paths and redirect stderr. + +--- + +## 12) Quick quiz (1 minute) +- Why prefer `#!/usr/bin/env bash` over `#!/bin/bash`? +- What does `set -Eeuo pipefail` do in plain English? +- How do you safely loop over lines in a file? +- What’s the difference between `$*` and `"$@"`? +- Which tool flags common Bash mistakes automatically? + +**Answers:** Finds Bash via PATH (portable across distros); stricter error handling and earlier failure; `while IFS= read -r line; do …; done < file`; `$*` joins words (unsafe), `"$@"` preserves argument boundaries; **ShellCheck**. + +--- + +## Next Step +Proceed to **Step 11 — Users & Authentication** (or the next topic in your curriculum). Update previous steps’ “Next Step” pointers if needed. + diff --git a/docs/11_permissions_task.md b/docs/11_permissions_task.md new file mode 100644 index 0000000..89977bf --- /dev/null +++ b/docs/11_permissions_task.md @@ -0,0 +1,46 @@ +# Step 11 — Permissions Challenge (Validation Task) + +> **Goal:** Configure secure permissions for a small project so only the owner can read “secret” files, while a public folder stays readable by others. +> **Type:** Task with validator (solution is **not** in this doc). Use the helper if you’re stuck. + +## Scenario +Your team stores notes in a project called `secure-project`. You must: +- Create the directories and files +- Apply **correct permissions** so secrets are private and public readme is world‑readable +- Run the validator to confirm + +## Requirements + +1) Create folders (under your home practice area): + - `~/playground/secure-project/secrets` + - `~/playground/secure-project/public` + +2) Create files with exact contents: + - `~/playground/secure-project/secrets/plan.txt` containing: `TOP SECRET` + - `~/playground/secure-project/public/readme.txt` containing: `Welcome to the project` + +3) Set permissions **exactly**: + - Directory `secrets`: `700` + - File `secrets/plan.txt`: `600` + - Directory `public`: `755` + - File `public/readme.txt`: `644` + +4) Optional (nice to have, not required for pass): + - Show octal + owner/group using: `stat -c "%A %a %U %G %n" ` + +## Hints (partial) +- Create folders: `mkdir -p ...` +- Create files: `echo "TEXT" > file` +- Set directory perms: `chmod 700 DIR` (owner `rwx`, others none) +- Set file perms: `chmod 600 FILE` (owner `rw`, others none) +- Public readable directory: `chmod 755 DIR` +- Public readable file: `chmod 644 FILE` + +## How to validate +From your terminal, run the validator: + +```bash +bash validate/11_permissions_task.sh +``` + +If everything is correct, it will print **PASS**. Otherwise it prints a helpful **FAIL** message so you can adjust and re‑run. diff --git a/docs/12_network_troubleshooting.md b/docs/12_network_troubleshooting.md new file mode 100644 index 0000000..5beb96d --- /dev/null +++ b/docs/12_network_troubleshooting.md @@ -0,0 +1,7 @@ +# Step 12: Networking Troubleshooting (Validation Task) + +1. Ping localhost: `ping -c 2 127.0.0.1` +2. Ping remote: `ping -c 2 example.com` +3. Trace route: `traceroute example.com` +4. DNS check: `dig example.com` + diff --git a/helpers/.DS_Store b/helpers/.DS_Store new file mode 100644 index 0000000..5008ddf Binary files /dev/null and b/helpers/.DS_Store differ diff --git a/helpers/11_permissions_task.md b/helpers/11_permissions_task.md new file mode 100644 index 0000000..380180c --- /dev/null +++ b/helpers/11_permissions_task.md @@ -0,0 +1,22 @@ +### Helper — Step 11: Permissions Challenge (Exact Commands) + +> Use this only if you’re stuck. These commands implement the required state exactly. + +```bash +# 1) Workspace +mkdir -p ~/playground/secure-project/{secrets,public} + +# 2) Files with exact content +echo "TOP SECRET" > ~/playground/secure-project/secrets/plan.txt +echo "Welcome to the project" > ~/playground/secure-project/public/readme.txt + +# 3) Permissions +chmod 700 ~/playground/secure-project/secrets +chmod 600 ~/playground/secure-project/secrets/plan.txt +chmod 755 ~/playground/secure-project/public +chmod 644 ~/playground/secure-project/public/readme.txt + +# 4) (Optional) Inspect +stat -c "%A %a %U %G %n" ~/playground/secure-project/secrets ~/playground/secure-project/secrets/plan.txt +stat -c "%A %a %U %G %n" ~/playground/secure-project/public ~/playground/secure-project/public/readme.txt +``` diff --git a/helpers/12_network_troubleshooting.md b/helpers/12_network_troubleshooting.md new file mode 100644 index 0000000..9ddb70d --- /dev/null +++ b/helpers/12_network_troubleshooting.md @@ -0,0 +1,6 @@ +### Helper for Step 12: Networking Troubleshooting + +- `ping 127.0.0.1` → local test +- `ping example.com` → remote test +- `traceroute` → shows path +- `dig example.com` → DNS lookup diff --git a/lab.yaml b/lab.yaml index 9086837..872be0a 100644 --- a/lab.yaml +++ b/lab.yaml @@ -1,16 +1,68 @@ -title: labzy -version: 1.0.0 -description: Descrition for tasks . -overview_path: docs/00_overview.md +title: "Linux Essentials — Instruction Lab (Ubuntu 24)" +version: "1.0.0" +description: "Beginner-friendly Linux lab covering 12 steps with optional validation tasks for Git and Networking." +overview_path: "docs/00_overview.md" + sections: - title: Instructions + title: "Instructions" items: - - id: 1 - title: Task 1 - path: docs/01_task.md - estimated_minutes: 7 - dependencies: [] + - id: 1 + title: "Terminal Basics" + path: "docs/01_terminal_basics.md" + estimated_minutes: 20 + - id: 2 + title: "Navigation & File Operations" + path: "docs/02_navigation_file_ops.md" + estimated_minutes: 20 + - id: 3 + title: "Searching & Text Viewing" + path: "docs/03_searching_text.md" + estimated_minutes: 20 + - id: 4 + title: "Process Management" + path: "docs/04_process_management.md" + estimated_minutes: 20 + - id: 5 + title: "Permissions & Ownership" + path: "docs/05_permissions.md" + estimated_minutes: 15 + - id: 6 + title: "System Info & Monitoring" + path: "docs/06_system_info.md" + estimated_minutes: 20 + - id: 7 + title: "Networking Basics" + path: "docs/07_networking.md" + estimated_minutes: 25 + - id: 8 + title: "Archiving & Compression" + path: "docs/08_archiving.md" + estimated_minutes: 25 + - id: 9 + title: "Package Management" + path: "docs/09_package_mgmt.md" + estimated_minutes: 30 + - id: 10 + title: "Basic Scripting" + path: "docs/10_scripting.md" + estimated_minutes: 30 + - id: 11 + title: "Permissions Challenge (Validation Task)" + path: "docs/11_permissions_task.md" + helper_path: "helpers/11_permissions_task.md" + validation_script: "validate/11_permissions_task.sh" + estimated_minutes: 20 + - id: 12 + title: "Networking Troubleshooting (Validation Task)" + path: "docs/12_network_troubleshooting.md" + helper_path: "helpers/12_network_troubleshooting.md" + validation_script: "validate/12_network_troubleshooting.sh" + estimated_minutes: 10 + ui: default_open_section_id: 1 show_toc: true - collapsible_sections: true \ No newline at end of file + collapsible_sections: true + +license: + path: "/LICENSE.md" diff --git a/validate/.DS_Store b/validate/.DS_Store new file mode 100644 index 0000000..5008ddf Binary files /dev/null and b/validate/.DS_Store differ diff --git a/validate/11_permissions_task.sh b/validate/11_permissions_task.sh new file mode 100644 index 0000000..e68c12f --- /dev/null +++ b/validate/11_permissions_task.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +set -euo pipefail + +fail() { echo "FAIL: $1" >&2; exit 1; } +pass() { echo "PASS: Permissions Challenge completed successfully"; exit 0; } + +ROOT="$HOME/playground/secure-project" + +# 1) Check structure +[ -d "$ROOT/secrets" ] || fail "Missing directory: $ROOT/secrets" +[ -d "$ROOT/public" ] || fail "Missing directory: $ROOT/public" +[ -f "$ROOT/secrets/plan.txt" ] || fail "Missing file: $ROOT/secrets/plan.txt" +[ -f "$ROOT/public/readme.txt" ] || fail "Missing file: $ROOT/public/readme.txt" + +# 2) Check contents +grep -qx "TOP SECRET" "$ROOT/secrets/plan.txt" || fail "plan.txt content must be exactly: TOP SECRET" +grep -qx "Welcome to the project" "$ROOT/public/readme.txt" || fail "readme.txt content must be exactly: Welcome to the project" + +# 3) Check permissions (octal) +perm_dir_secrets=$(stat -c "%a" "$ROOT/secrets") +[ "$perm_dir_secrets" = "700" ] || fail "secrets directory should be 700 (got $perm_dir_secrets)" + +perm_plan=$(stat -c "%a" "$ROOT/secrets/plan.txt") +[ "$perm_plan" = "600" ] || fail "secrets/plan.txt should be 600 (got $perm_plan)" + +perm_dir_public=$(stat -c "%a" "$ROOT/public") +[ "$perm_dir_public" = "755" ] || fail "public directory should be 755 (got $perm_dir_public)" + +perm_readme=$(stat -c "%a" "$ROOT/public/readme.txt") +[ "$perm_readme" = "644" ] || fail "public/readme.txt should be 644 (got $perm_readme)" + +pass diff --git a/validate/12_network_troubleshooting.sh b/validate/12_network_troubleshooting.sh new file mode 100644 index 0000000..7965056 --- /dev/null +++ b/validate/12_network_troubleshooting.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +set -e +ping -c 1 127.0.0.1 >/dev/null || { echo "FAIL: Localhost ping failed"; exit 1; } +(getent hosts example.com || dig +short example.com) >/dev/null || { echo "FAIL: DNS failed"; exit 1; } +echo "PASS: Networking Troubleshooting Completed"