diff --git a/.github/workflows/task5-users-privileges-report.yml b/.github/workflows/task5-users-privileges-report.yml new file mode 100644 index 0000000..511ca5e --- /dev/null +++ b/.github/workflows/task5-users-privileges-report.yml @@ -0,0 +1,24 @@ +name: Task 5 - Users, permissions and sudo report +on: + workflow_dispatch: + push: + paths: + - '.github/workflows/task5-users-privileges-report.yml' + - 'scripts/task5_users_privileges_report.sh' + - 'scripts/build_pdf_report.py' + - 'scripts/text_to_png.py' +jobs: + build-report-task5: + runs-on: ubuntu-latest + env: + REPORT_AUTHOR: Миленькова Ивана + steps: + - uses: actions/checkout@v4 + - run: | + sudo apt-get update + sudo apt-get install -y python3-pil sudo tcpdump + - run: bash scripts/task5_users_privileges_report.sh + - uses: actions/upload-artifact@v4 + with: + name: task5-report-pdf + path: reports/task5/report.pdf diff --git a/.github/workflows/task6-crontab-backup-report.yml b/.github/workflows/task6-crontab-backup-report.yml new file mode 100644 index 0000000..6a3e17d --- /dev/null +++ b/.github/workflows/task6-crontab-backup-report.yml @@ -0,0 +1,24 @@ +name: Task 6 - Crontab backup report +on: + workflow_dispatch: + push: + paths: + - '.github/workflows/task6-crontab-backup-report.yml' + - 'scripts/task6_crontab_backup_report.sh' + - 'scripts/build_pdf_report.py' + - 'scripts/text_to_png.py' +jobs: + build-report-task6: + runs-on: ubuntu-latest + env: + REPORT_AUTHOR: Миленькова Ивана + steps: + - uses: actions/checkout@v4 + - run: | + sudo apt-get update + sudo apt-get install -y python3-pil + - run: bash scripts/task6_crontab_backup_report.sh + - uses: actions/upload-artifact@v4 + with: + name: task6-report-pdf + path: reports/task6/report.pdf diff --git a/.github/workflows/task7-process-signals-report.yml b/.github/workflows/task7-process-signals-report.yml new file mode 100644 index 0000000..b5f67fc --- /dev/null +++ b/.github/workflows/task7-process-signals-report.yml @@ -0,0 +1,24 @@ +name: Task 7 - Process signals report +on: + workflow_dispatch: + push: + paths: + - '.github/workflows/task7-process-signals-report.yml' + - 'scripts/task7_process_signals_report.sh' + - 'scripts/build_pdf_report.py' + - 'scripts/text_to_png.py' +jobs: + build-report-task7: + runs-on: ubuntu-latest + env: + REPORT_AUTHOR: Миленькова Ивана + steps: + - uses: actions/checkout@v4 + - run: | + sudo apt-get update + sudo apt-get install -y python3-pil procps + - run: bash scripts/task7_process_signals_report.sh + - uses: actions/upload-artifact@v4 + with: + name: task7-report-pdf + path: reports/task7/report.pdf diff --git a/.github/workflows/task8-journal-report.yml b/.github/workflows/task8-journal-report.yml new file mode 100644 index 0000000..19a2a15 --- /dev/null +++ b/.github/workflows/task8-journal-report.yml @@ -0,0 +1,24 @@ +name: Task 8 - Journalctl report +on: + workflow_dispatch: + push: + paths: + - '.github/workflows/task8-journal-report.yml' + - 'scripts/task8_journal_report.sh' + - 'scripts/build_pdf_report.py' + - 'scripts/text_to_png.py' +jobs: + build-report-task8: + runs-on: ubuntu-latest + env: + REPORT_AUTHOR: Миленькова Ивана + steps: + - uses: actions/checkout@v4 + - run: | + sudo apt-get update + sudo apt-get install -y python3-pil systemd + - run: bash scripts/task8_journal_report.sh + - uses: actions/upload-artifact@v4 + with: + name: task8-report-pdf + path: reports/task8/report.pdf diff --git a/README.md b/README.md index 2eb6806..3748ce2 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,15 @@ # Автоматические отчёты по заданиям (GitHub Actions) -В репозитории настроены **4 отдельных workflow** (по одному на каждую практическую работу): +В репозитории настроены **8 отдельных workflow** (по одному на каждую практическую работу): 1. `Task 1 - VM and Linux install report` 2. `Task 2 - Terminal commands report` 3. `Task 3 - Filesystem image report` 4. `Task 4 - SSH and RDP remote access report` +5. `Task 5 - Users, permissions and sudo report` +6. `Task 6 - Crontab backup report` +7. `Task 7 - Process signals report` +8. `Task 8 - Journalctl report` Каждый workflow: - запускается вручную (`workflow_dispatch`), diff --git a/scripts/task5_users_privileges_report.sh b/scripts/task5_users_privileges_report.sh new file mode 100755 index 0000000..d76d186 --- /dev/null +++ b/scripts/task5_users_privileges_report.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +set -euo pipefail + +REPORT_AUTHOR="${REPORT_AUTHOR:-Миленькова Ивана}" +ROOT="reports/task5" +LOG_DIR="$ROOT/logs" +IMG_DIR="$ROOT/images" +mkdir -p "$LOG_DIR" "$IMG_DIR" + +NEW_USER="${NEW_USER:-studentnew}" +OLD_USER="${OLD_USER:-$(id -un)}" +NEW_GROUP="${NEW_GROUP:-pktcap}" + +run_capture() { + local key="$1"; shift + { echo "$ $*"; bash -lc "$*"; } >"$LOG_DIR/${key}.txt" 2>&1 || true + python3 scripts/text_to_png.py "$LOG_DIR/${key}.txt" "$IMG_DIR/${key}.png" --title "$key" +} + +run_capture 01_useradd "sudo useradd -m -s /bin/bash '${NEW_USER}' && id '${NEW_USER}' && getent passwd '${NEW_USER}'" +run_capture 02_first_file "sudo -u '${NEW_USER}' bash -lc 'echo first_owned_by_new_user > ~/first' && sudo install -o '${NEW_USER}' -g '${NEW_USER}' -m 600 ~'${NEW_USER}'/first /tmp/first && ls -l /tmp/first" +run_capture 03_second_file "echo second_owned_by_old_user > /tmp/second && sudo chown '${OLD_USER}:${OLD_USER}' /tmp/second && sudo chmod 600 /tmp/second && ls -l /tmp/second" +run_capture 04_sudoers_pkgmgr "sudo sh -c \"printf '%s\\n' '${OLD_USER} ALL=(ALL) NOPASSWD: /usr/bin/apt, /usr/bin/apt-get, /usr/bin/dnf, /usr/bin/yum, /usr/bin/pacman' > /etc/sudoers.d/90-${OLD_USER}-pkgmgr\" && sudo chmod 440 /etc/sudoers.d/90-${OLD_USER}-pkgmgr && sudo visudo -cf /etc/sudoers.d/90-${OLD_USER}-pkgmgr" +run_capture 05_pkgmgr_vs_tcpdump "sudo -n apt-get -v || sudo -n dnf --version || sudo -n yum --version || sudo -n pacman --version; sudo -n tcpdump -D" +run_capture 06_new_user_denied_pkgmgr "sudo -u '${NEW_USER}' sudo -n apt-get -v || sudo -u '${NEW_USER}' sudo -n dnf --version || sudo -u '${NEW_USER}' sudo -n yum --version || sudo -u '${NEW_USER}' sudo -n pacman --version" +run_capture 07_groupadd_and_tcpdump "sudo groupadd -f '${NEW_GROUP}' && sudo usermod -aG '${NEW_GROUP}' '${OLD_USER}' && sudo usermod -aG '${NEW_GROUP}' '${NEW_USER}' && sudo sh -c \"printf '%%%s ALL=(ALL) NOPASSWD: /usr/sbin/tcpdump\\n' '${NEW_GROUP}' > /etc/sudoers.d/91-${NEW_GROUP}-tcpdump\" && sudo chmod 440 /etc/sudoers.d/91-${NEW_GROUP}-tcpdump && sudo visudo -cf /etc/sudoers.d/91-${NEW_GROUP}-tcpdump && getent group '${NEW_GROUP}'" +run_capture 08_tcpdump_both_users "sudo -n tcpdump -D ; sudo -u '${NEW_USER}' bash -lc 'id && sudo -n tcpdump -D'" + +cat > "$ROOT/report.json" <"$LOG_DIR/$k.txt" 2>&1 || true; python3 scripts/text_to_png.py "$LOG_DIR/$k.txt" "$IMG_DIR/$k.png" --title "$k"; } +note_capture(){ local k="$1" t="$2" b="$3"; printf '%s\n' "$b" >"$LOG_DIR/$k.txt"; python3 scripts/text_to_png.py "$LOG_DIR/$k.txt" "$IMG_DIR/$k.png" --title "$t"; } +note_capture 01_script cron_script "#!/usr/bin/env bash +set -euo pipefail +TS=\$(date +%F_%H-%M-%S) +mkdir -p /var/backups/home +tar -czf /var/backups/home/home_backup_\${TS}.tar.gz \"$HOME\"" +run_capture 02_install "sudo install -m 755 /dev/stdin /usr/local/bin/weekly_home_backup.sh <<'EOS' +#!/usr/bin/env bash +set -euo pipefail +TS=\$(date +%F_%H-%M-%S) +mkdir -p /var/backups/home +tar -czf /var/backups/home/home_backup_\${TS}.tar.gz /home +EOS +sudo sed -i '/weekly_home_backup.sh/d' /etc/crontab; echo '0 0 * * 0 root /usr/local/bin/weekly_home_backup.sh' | sudo tee -a /etc/crontab; tail -n 8 /etc/crontab" +cat > "$ROOT/report.json" <"$LOG_DIR/$k.txt" 2>&1 || true; python3 scripts/text_to_png.py "$LOG_DIR/$k.txt" "$IMG_DIR/$k.png" --title "$k"; } +run_capture 01_start "nohup bash -lc 'while :; do :; done' >/tmp/cpu_stress.log 2>&1 & echo \$! > /tmp/stress.pid; cat /tmp/stress.pid" +run_capture 02_find_pid "ps -eo pid,ppid,user,cmd | grep -E 'while :; do :; done|cpu_stress' | grep -v grep" +run_capture 03_top "PID=\$(cat /tmp/stress.pid); top -b -n 1 -p \"\$PID\"" +run_capture 04_ps_before "ps -fp \"\$(cat /tmp/stress.pid)\"" +run_capture 05_term_kill "PID=\$(cat /tmp/stress.pid); kill -TERM \"\$PID\"; sleep 1; ps -p \"\$PID\" || true; if ps -p \"\$PID\" >/dev/null; then kill -KILL \"\$PID\"; fi" +run_capture 06_ps_after "ps -p \"\$(cat /tmp/stress.pid)\" || true" +cat > "$ROOT/report.json" <"$LOG_DIR/$k.txt" 2>&1 || true; python3 scripts/text_to_png.py "$LOG_DIR/$k.txt" "$IMG_DIR/$k.png" --title "$k"; } +run_capture 01_last20 "journalctl -n 20 --no-pager" +run_capture 02_ssh "journalctl -u ssh -u sshd --no-pager | tail -n 50" +run_capture 03_enable_ssh "sudo systemctl enable ssh || sudo systemctl enable sshd; sudo systemctl restart ssh || sudo systemctl restart sshd; systemctl is-enabled ssh || systemctl is-enabled sshd" +run_capture 04_hour "journalctl --since '1 hour ago' --no-pager | tail -n 80" +run_capture 05_boot_file "journalctl -b --no-pager > '$ROOT/last_boot.log' && wc -l '$ROOT/last_boot.log' && tail -n 20 '$ROOT/last_boot.log'" +run_capture 06_errors "grep -i 'error' '$ROOT/last_boot.log' | tail -n 50 || true" +cat > "$ROOT/report.json" <