Adding files
This commit is contained in:
+57
-38
@@ -16,7 +16,7 @@ The repository is the source of truth for the project.
|
||||
|
||||
Read files in this order:
|
||||
|
||||
```text
|
||||
```
|
||||
1. README.md
|
||||
2. RECOVERY.md
|
||||
3. dotemacs
|
||||
@@ -35,13 +35,13 @@ The user’s `.emacs` setup already loads the Linux+ system.
|
||||
|
||||
The repository may contain a copy of that file named:
|
||||
|
||||
```text
|
||||
```
|
||||
dotemacs
|
||||
```
|
||||
|
||||
The relevant startup code is:
|
||||
|
||||
```elisp
|
||||
```
|
||||
;; Load custom Elisp
|
||||
(let ((dir "~/.emacs.d/lisp/linuxplus/"))
|
||||
(add-to-list 'load-path dir)
|
||||
@@ -51,13 +51,13 @@ The relevant startup code is:
|
||||
|
||||
Therefore, after saving new lesson or quiz files into:
|
||||
|
||||
```text
|
||||
```
|
||||
~/.emacs.d/lisp/linuxplus/
|
||||
```
|
||||
|
||||
the correct refresh step is:
|
||||
|
||||
```text
|
||||
```
|
||||
M-x linuxplus-load-all
|
||||
```
|
||||
|
||||
@@ -67,13 +67,13 @@ Do not tell the user to manually add the directory to `load-path`, manually load
|
||||
|
||||
The loader file is:
|
||||
|
||||
```text
|
||||
```
|
||||
linuxplus-load-all.el
|
||||
```
|
||||
|
||||
The function:
|
||||
|
||||
```text
|
||||
```
|
||||
linuxplus-load-all
|
||||
```
|
||||
|
||||
@@ -89,7 +89,7 @@ The current convention uses consecutive numbers for each lesson/quiz pair.
|
||||
|
||||
Example:
|
||||
|
||||
```text
|
||||
```
|
||||
102-user-management-lesson.el
|
||||
103-user-management-quiz.el
|
||||
```
|
||||
@@ -98,7 +98,7 @@ The next topic should use the next unused lesson number and the next unused quiz
|
||||
|
||||
Example:
|
||||
|
||||
```text
|
||||
```
|
||||
104-storage-lvm-quotas-lesson.el
|
||||
105-storage-lvm-quotas-quiz.el
|
||||
```
|
||||
@@ -120,13 +120,13 @@ A lesson file should:
|
||||
|
||||
Avoid this problem:
|
||||
|
||||
```elisp
|
||||
```
|
||||
explicit-shell-file-name
|
||||
```
|
||||
|
||||
Use a safer shell fallback pattern based on current repository style, such as:
|
||||
|
||||
```elisp
|
||||
```
|
||||
(or shell-file-name (getenv "SHELL") "/bin/sh")
|
||||
```
|
||||
|
||||
@@ -137,8 +137,11 @@ The exact buffer names and formatting should follow the highest-numbered current
|
||||
A quiz file should:
|
||||
|
||||
* use the established numbered filename format
|
||||
|
||||
* define one interactive quiz function
|
||||
|
||||
* call `linuxplus-start-quiz`
|
||||
|
||||
* pass exactly three arguments:
|
||||
|
||||
1. the lesson function symbol
|
||||
@@ -147,7 +150,7 @@ A quiz file should:
|
||||
|
||||
The expected call shape is:
|
||||
|
||||
```elisp
|
||||
```
|
||||
(linuxplus-start-quiz
|
||||
'linuxplus-NNN-topic-name-lesson
|
||||
'((:type true-false
|
||||
@@ -158,7 +161,7 @@ The expected call shape is:
|
||||
|
||||
Supported question types include:
|
||||
|
||||
```text
|
||||
```
|
||||
true-false
|
||||
yes-no
|
||||
multiple
|
||||
@@ -170,7 +173,7 @@ For multiple-choice questions, inspect `06-linuxplus-quiz-mode.el` and the highe
|
||||
|
||||
The user will maintain:
|
||||
|
||||
```text
|
||||
```
|
||||
STUDY.md
|
||||
```
|
||||
|
||||
@@ -182,7 +185,7 @@ Prefer paraphrased concepts over exact copyrighted question text.
|
||||
|
||||
Good format:
|
||||
|
||||
```text
|
||||
```
|
||||
Missed area: LVM volume groups
|
||||
Correct concept: vgcreate creates a volume group.
|
||||
Exam trap: lvcreate creates a logical volume, not a volume group.
|
||||
@@ -194,7 +197,7 @@ Future lessons should prioritize weak areas listed in `STUDY.md`.
|
||||
|
||||
Previously discussed weak areas included topics such as:
|
||||
|
||||
```text
|
||||
```
|
||||
systemd and PID 1
|
||||
GRUB2
|
||||
LVM
|
||||
@@ -231,29 +234,21 @@ To add a new topic:
|
||||
|
||||
4. Create a lesson file:
|
||||
|
||||
```text
|
||||
NNN-topic-name-lesson.el
|
||||
```
|
||||
|
||||
5. Create the matching quiz file:
|
||||
|
||||
```text
|
||||
NNN+1-topic-name-quiz.el
|
||||
```
|
||||
|
||||
6. Keep the lesson and quiz focused on one topic.
|
||||
|
||||
7. Save both files in:
|
||||
|
||||
```text
|
||||
~/.emacs.d/lisp/linuxplus/
|
||||
```
|
||||
|
||||
8. Tell the user to run:
|
||||
|
||||
```text
|
||||
M-x linuxplus-load-all
|
||||
```
|
||||
|
||||
9. Then tell the user to run the new lesson and quiz functions.
|
||||
|
||||
@@ -274,23 +269,47 @@ When helping with this project:
|
||||
## Goal
|
||||
|
||||
The goal is to help the user make steady Linux+ certification progress through targeted, topic-based, Emacs-integrated lessons and quizzes.
|
||||
|
||||
## RECOVERY maintenance update - 2026-07-09
|
||||
|
||||
Created a targeted review lesson pair based on missed Linux+ firewall
|
||||
book questions:
|
||||
Corrected the firewall review lesson pair to follow the repository numbering and loader conventions.
|
||||
|
||||
- `linuxplus-lesson-120.el`
|
||||
- `linuxplus-quiz-120.el`
|
||||
Remove these incorrectly named files:
|
||||
|
||||
Lesson 120 covers firewall ACLs, packet inspection, persistent
|
||||
configuration files, stateful firewall review points, firewalld runtime
|
||||
to permanent configuration, numbered UFW rules, simple UFW SSH blocking,
|
||||
DenyHosts, and Fail2Ban.
|
||||
* `linuxplus-lesson-120.el`
|
||||
* `linuxplus-quiz-120.el`
|
||||
|
||||
Quiz 120 uses only true/false, yes/no, and single-choice questions.
|
||||
The lesson keeps text above an `ansi-term` buffer and includes GNU
|
||||
Emacs on GNU/Linux audio practice with `espeak-ng` and `espeak`.
|
||||
Create these replacement files:
|
||||
|
||||
Include the book's expected wording, but preserve the real-world note
|
||||
that DenyHosts is strongly associated with `/etc/hosts.deny`, while
|
||||
Fail2Ban commonly blocks through firewall actions.
|
||||
* `104-firewall-review-lesson.el`
|
||||
* `105-firewall-review-quiz.el`
|
||||
|
||||
Reason for correction:
|
||||
|
||||
* `linuxplus-load-all.el` loads numbered Emacs Lisp files.
|
||||
* Lesson and quiz files use consecutive numbers.
|
||||
* The lesson file should be named `NNN-topic-name-lesson.el`.
|
||||
* The quiz file should be named `NNN+1-topic-name-quiz.el`.
|
||||
* Quiz files should call `linuxplus-start-quiz` instead of using their own `read-string` scoring loop.
|
||||
|
||||
The corrected lesson function is:
|
||||
|
||||
* `linuxplus-firewall-review-lesson`
|
||||
|
||||
The corrected quiz function is:
|
||||
|
||||
* `linuxplus-firewall-review-quiz`
|
||||
|
||||
Lesson content is based on missed Linux+ firewall book questions:
|
||||
|
||||
* firewall ACLs
|
||||
* packet inspection
|
||||
* persistent configuration files
|
||||
* stateful firewall review points
|
||||
* `firewall-cmd --runtime-to-permanent`
|
||||
* numbered UFW rules
|
||||
* simple UFW SSH blocking
|
||||
* DenyHosts
|
||||
* Fail2Ban
|
||||
|
||||
The lesson preserves the real-world note that DenyHosts is strongly associated with `/etc/hosts.deny`, while Fail2Ban commonly blocks through firewall actions. For the book question, memorize the book's expected wording.
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
;;; Linux+ Lesson 120: Firewall review
|
||||
;;;
|
||||
;;; Review firewall ACLs, stateful behavior, firewalld, UFW, and IDS.
|
||||
;;;
|
||||
;;; This file is part of the Linux+ Learning project.
|
||||
;;;
|
||||
;;; Copyright (c) 2026, Scott C. MacCallum (scm@sdf.org).
|
||||
;;;
|
||||
;;; This program is free software: you can redistribute it and/or modify
|
||||
;;; it under the terms of the GNU Affero General Public License as
|
||||
;;; published by the Free Software Foundation, either version 3 of the
|
||||
;;; License, or (at your option) any later version.
|
||||
;;;
|
||||
;;; This program is distributed in the hope that it will be useful,
|
||||
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;;; GNU Affero General Public License for more details.
|
||||
;;;
|
||||
;;; You should have received a copy of the GNU Affero General
|
||||
;;; Public License along with this program. If not, see
|
||||
;;; <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Run with:
|
||||
;;
|
||||
;; M-x linuxplus-lesson-120
|
||||
;;
|
||||
;; This lesson displays text above an ansi-term practice buffer.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'term)
|
||||
|
||||
(defun linuxplus-lesson-120 ()
|
||||
"Show Linux+ lesson 120 with a shell practice buffer."
|
||||
(interactive)
|
||||
(delete-other-windows)
|
||||
(let ((buffer (get-buffer-create "*Linux+ Lesson 120*")))
|
||||
(switch-to-buffer buffer)
|
||||
(read-only-mode -1)
|
||||
(erase-buffer)
|
||||
(insert "Linux+ Lesson 120: Firewall review\n\n")
|
||||
(insert "This lesson reviews firewall facts missed during book\n")
|
||||
(insert "practice. Treat this as Linux+ study wording.\n\n")
|
||||
(insert "Firewall basics:\n\n")
|
||||
(insert " Firewalls use ACLs, inspect network packets, and use\n")
|
||||
(insert " configuration files so rules can persist after restart.\n\n")
|
||||
(insert "ACL means access control list. An ACL is a list of rules\n")
|
||||
(insert "that allow or deny traffic based on details such as source,\n")
|
||||
(insert "destination, protocol, port, or interface.\n\n")
|
||||
(insert "Stateful firewall review:\n\n")
|
||||
(insert " A stateless firewall checks each packet by rule only.\n")
|
||||
(insert " A stateful firewall tracks connection state.\n")
|
||||
(insert " Your review answer associates stateful firewalls with\n")
|
||||
(insert " faster handling for established connections and with\n")
|
||||
(insert " detecting whether packets are fragmented.\n\n")
|
||||
(insert "firewalld runtime and permanent rules:\n\n")
|
||||
(insert " firewalld can have runtime rules and permanent rules.\n")
|
||||
(insert " Test changes at runtime first. After a successful test,\n")
|
||||
(insert " make them permanent with super user privileges:\n\n")
|
||||
(insert " sudo firewall-cmd --runtime-to-permanent\n\n")
|
||||
(insert "UFW review:\n\n")
|
||||
(insert " To view numbered UFW rules, use:\n\n")
|
||||
(insert " sudo ufw status numbered\n\n")
|
||||
(insert " Your review answer for blocking SSH is:\n\n")
|
||||
(insert " sudo ufw deny 22/tcp\n\n")
|
||||
(insert "IDS review:\n\n")
|
||||
(insert " For this book item, remember DenyHosts and Fail2Ban\n")
|
||||
(insert " as intrusion detection systems. The answer associates\n")
|
||||
(insert " them with modifying /etc/hosts.deny.\n\n")
|
||||
(insert "Real-world note: DenyHosts is strongly associated with\n")
|
||||
(insert "/etc/hosts.deny. Fail2Ban is commonly configured to block\n")
|
||||
(insert "attackers through firewall actions. For the book question,\n")
|
||||
(insert "memorize the book's expected wording.\n\n")
|
||||
(insert "Audio practice on GNU/Linux:\n\n")
|
||||
(insert " espeak-ng 'Use firewall cmd runtime to permanent.'\n")
|
||||
(insert " espeak 'Use sudo ufw status numbered.'\n")
|
||||
(insert " espeak-ng 'Use sudo ufw deny twenty two slash tcp.'\n\n")
|
||||
(insert "Practice below. Try sudo ufw status numbered if UFW is\n")
|
||||
(insert "installed, or review firewall-cmd --help if firewalld is\n")
|
||||
(insert "available on your system.\n")
|
||||
(goto-char (point-min))
|
||||
(read-only-mode 1)
|
||||
(split-window-below)
|
||||
(other-window 1)
|
||||
(ansi-term "/bin/bash")))
|
||||
|
||||
(provide 'linuxplus-lesson-120)
|
||||
|
||||
;;; linuxplus-lesson-120.el ends here
|
||||
@@ -1,95 +0,0 @@
|
||||
;;; Linux+ Quiz 120: Firewall review
|
||||
;;;
|
||||
;;; Review firewall ACLs, stateful behavior, firewalld, UFW, and IDS.
|
||||
;;;
|
||||
;;; This file is part of the Linux+ Learning project.
|
||||
;;;
|
||||
;;; Copyright (c) 2026, Scott C. MacCallum (scm@sdf.org).
|
||||
;;;
|
||||
;;; This program is free software: you can redistribute it and/or modify
|
||||
;;; it under the terms of the GNU Affero General Public License as
|
||||
;;; published by the Free Software Foundation, either version 3 of the
|
||||
;;; License, or (at your option) any later version.
|
||||
;;;
|
||||
;;; This program is distributed in the hope that it will be useful,
|
||||
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;;; GNU Affero General Public License for more details.
|
||||
;;;
|
||||
;;; You should have received a copy of the GNU Affero General
|
||||
;;; Public License along with this program. If not, see
|
||||
;;; <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Run with:
|
||||
;;
|
||||
;; M-x linuxplus-quiz-120
|
||||
;;
|
||||
;; Questions are true/false, yes/no, or single-choice only.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'subr-x)
|
||||
|
||||
(defvar linuxplus-quiz-120-score-file
|
||||
(expand-file-name "linuxplus-quiz-120-score.txt"
|
||||
user-emacs-directory)
|
||||
"File used to save the Linux+ quiz 120 score.")
|
||||
|
||||
(defun linuxplus-quiz-120--ask (prompt answer)
|
||||
"Ask PROMPT and compare the response to ANSWER."
|
||||
(string= (downcase (string-trim (read-string prompt)))
|
||||
answer))
|
||||
|
||||
(defun linuxplus-quiz-120 ()
|
||||
"Run Linux+ quiz 120 and save the score."
|
||||
(interactive)
|
||||
(let ((score 0)
|
||||
(total 8))
|
||||
(when (linuxplus-quiz-120--ask
|
||||
"True or false: Firewalls use ACLs. "
|
||||
"true")
|
||||
(setq score (1+ score)))
|
||||
(when (linuxplus-quiz-120--ask
|
||||
"Yes or no: Do firewalls inspect network packets? "
|
||||
"yes")
|
||||
(setq score (1+ score)))
|
||||
(when (linuxplus-quiz-120--ask
|
||||
"Which helps firewall rules persist? A) config files B) pwd "
|
||||
"a")
|
||||
(setq score (1+ score)))
|
||||
(when (linuxplus-quiz-120--ask
|
||||
"True or false: Stateful firewalls track connections. "
|
||||
"true")
|
||||
(setq score (1+ score)))
|
||||
(when (linuxplus-quiz-120--ask
|
||||
(concat "Which can be faster after a connection exists? "
|
||||
"A) stateful B) stateless ")
|
||||
"a")
|
||||
(setq score (1+ score)))
|
||||
(when (linuxplus-quiz-120--ask
|
||||
(concat "Which saves tested firewalld runtime rules? "
|
||||
"A) firewall-cmd --runtime-to-permanent "
|
||||
"B) ufw numbered ")
|
||||
"a")
|
||||
(setq score (1+ score)))
|
||||
(when (linuxplus-quiz-120--ask
|
||||
(concat "Which command views numbered UFW rules? "
|
||||
"A) sudo ufw status numbered "
|
||||
"B) sudo ufw list ")
|
||||
"a")
|
||||
(setq score (1+ score)))
|
||||
(when (linuxplus-quiz-120--ask
|
||||
(concat "Which simple command blocks SSH by port? "
|
||||
"A) sudo ufw deny 22/tcp "
|
||||
"B) sudo ufw allow 22/tcp ")
|
||||
"a")
|
||||
(setq score (1+ score)))
|
||||
(with-temp-file linuxplus-quiz-120-score-file
|
||||
(insert (format "Linux+ quiz 120 score: %d/%d\n" score total)))
|
||||
(message "Linux+ quiz 120 score: %d/%d" score total)))
|
||||
|
||||
(provide 'linuxplus-quiz-120)
|
||||
|
||||
;;; linuxplus-quiz-120.el ends here
|
||||
Reference in New Issue
Block a user