🚧 Under construction — VoTechWorks is being built. A free tech program — complimentary, as our commitment to get America working.
voTechWorksGrade 13 · a vocational technology learning center, by urbanicity
newSchoolWorks.com › VoTechWorks › Technology & Design › Cybersecurity › Linux for Cybersecurity › Lesson 11
TEC-CYBE44-04 · Lesson 11 · 14.5 clock hours · lab

Introduction to Bash Scripting for Security Automation

Objective. Students write Bash scripts that automate common security-administration tasks including user auditing, log parsing, and system health checks.

⚠ Pending professional review

This lesson, its worked examples and its practice questions has not yet been verified by an industry-certified professional or by a certification or approval body. It is a study draft and may contain errors. Do not use it as instructions for work on a job site or on live equipment. Always follow your instructor, your supervising professional, and current official references and regulations.

VoTechWorks program approval and accreditation are still in progress. Credentials are issued only by the certifying bodies named in each program, after their own exams.

Why Automate Security Tasks with Bash?

Cybersecurity professionals spend significant time on repetitive tasks: auditing user accounts, scanning logs for threats, and checking system health. Bash scripting lets you encode those tasks once and run them reliably whenever needed. Because Bash is the default shell on most Linux distributions, your scripts run without installing additional software — an important advantage in locked-down enterprise environments. CompTIA CySA+ explicitly tests your ability to use scripting and automation to support security operations, so these skills map directly to your certification goals.

Shell Script Basics

A Bash script is a plain-text file that begins with a shebang line: `#!/bin/bash`. This tells the kernel which interpreter to use. Make the file executable with `chmod +x scriptname.sh`, then run it with `./scriptname.sh`.

Key constructs you will use in every security script:

Safe Scripting Practices

Poor scripting habits create security vulnerabilities. Follow these rules:

1. Always quote variables. Unquoted variables containing spaces or special characters cause unexpected behavior and can be exploited.

2. Validate input. If your script accepts arguments, check that the expected argument exists and is the correct type before using it: `if [ -z "$1" ]; then echo "Usage: $0 <logfile>"; exit 1; fi`.

3. Use `sudo` only where necessary. Reading `/etc/shadow` requires elevated privilege. Request it explicitly for that command rather than running the entire script as root.

4. Avoid storing credentials in scripts. Never hard-code passwords or API keys.

5. Restrict output file permissions. Reports containing account data are sensitive. Set permissions with `chmod 600 reportfile.txt` immediately after creation.

6. Test in a non-production VM. The lab machines for this course are isolated VMs. Never run untested scripts on production systems.

Auditing User Accounts

Three system files power user auditing:

Use `awk -F: '$3 == 0 {print $1}' /etc/passwd` to extract UID-0 accounts. Use `sudo awk -F: '$2 == "" {print $1}' /etc/shadow` to find accounts with no password hash.

Parsing Log Files

`/var/log/auth.log` (Debian/Ubuntu) records authentication events. Failed SSH logins appear as lines containing `Failed password`. The source IP address follows the word `from`.

Pipeline pattern:

```

grep "Failed password" "$LOGFILE" | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn

```

Breaking it down: `grep` filters matching lines; `awk` extracts the IP field (position varies by log format — verify against a real sample); `sort` prepares for deduplication; `uniq -c` counts consecutive identical lines; the final `sort -rn` ranks by count descending.

Accept the log path as `$1` so the script is reusable against any log file.

Conditional Firewall Actions

Extending the log parser to take action is the core of automated threat response. Set a threshold variable at the top of the script: `THRESHOLD=${2:-10}` (uses the second argument if provided, otherwise defaults to 10). After ranking, loop through results and compare each count to the threshold:

```bash

while read -r count ip; do

if [ "$count" -gt "$THRESHOLD" ]; then

sudo ufw deny from "$ip"

echo "$(date --iso-8601=seconds) BLOCKED $ip ($count attempts)" >> audit.log

fi

done

```

`ufw deny from` adds a firewall rule blocking all traffic from that IP. Logging the action with a timestamp creates an audit trail — essential for incident response documentation and compliance.

Running and Verifying Scripts

After writing each script, test it with known data before using it on real systems. Your instructor supplies a sample `auth.log` designed to trigger specific outputs — use it to verify correctness. Check syntax without executing with `bash -n scriptname.sh`. Use `set -x` at the top during debugging to print each command as it runs, then remove it before submission.

Key terms9

ShebangThe first line of a script (`#!/bin/bash`) that tells the operating system which interpreter to use when executing the file.
Variable quotingSurrounding a variable reference in double quotes (`"$VAR"`) to prevent word-splitting and globbing, which can cause logic errors or security vulnerabilities.
UID 0The numeric user identifier 0, reserved for the root account; any other account possessing UID 0 has full administrative privileges and is a critical security finding.
/etc/shadowA root-readable Linux file that stores hashed passwords and account aging information for each user; an empty password field indicates no password is set.
lastlogA Linux command that reports the most recent login time for every account; accounts showing 'Never logged in' are candidates for removal or review.
uniq -cA command-line option that prefixes each unique line with a count of how many times it appeared consecutively in sorted input, commonly used to count log-event frequencies.
ufwUncomplicated Firewall, a front-end for iptables on Debian-based Linux systems; `ufw deny from <IP>` blocks all inbound traffic from the specified address.
Audit logA time-stamped record of actions taken by a script or system; in security automation, it documents every automated response for later review and compliance evidence.
Exit codeAn integer returned by every command when it finishes; 0 indicates success and any non-zero value indicates an error, allowing scripts to detect and handle failures.
In class: Write a Bash script that reads /etc/passwd, identifies all accounts with a UID of 0, accounts with no password hash in /etc/shadow (requires sudo), and accounts that have never logged in (using lastlog); output a formatted report to a text file. · Write a Bash script that accepts a log file path as an argument, parses it for failed authentication attempts, counts occurrences per IP address, and prints a ranked list to stdout — test it against a sample auth.log provided by the instructor. · Extend the log-parsing script with a conditional block: if any single IP appears more than a configurable threshold (default 10), append a ufw deny rule for that IP and log the action with a timestamp to a separate audit file; test the full pipeline end-to-end.
Materials: Linux VM, bash, text editor (nano/vim), sample auth.log provided by instructor, CompTIA CySA+ Study Guide (scripting and automation sections), GNU Bash Reference Manual
Check: Instructor runs each script against a reference test set and reviews the code for logic errors and safe variable quoting; pass = scripts produce correct output on all three test cases with no syntax errors.

Practice check8

Answer each question, then check it. Nothing is recorded; this is your own practice.

Security Operations / Scripting and Automation (CySA+)
1. Which shebang line correctly declares a Bash script?
Identity and Access Management (Security+)
2. A security analyst runs `awk -F: '$3 == 0 {print $1}' /etc/passwd` and sees two account names in the output. What does this finding indicate?
Security Operations / Scripting and Automation (CySA+)
3. Why should variables in a Bash script always be enclosed in double quotes when referenced?
Incident Response / Security Operations (CySA+)
4. A script parses auth.log and finds that IP 198.51.100.42 has 47 failed login attempts, well above the threshold of 10. The script runs `sudo ufw deny from 198.51.100.42`. What additional step does the script take to support incident response?
Security Operations / Scripting and Automation (CySA+)
5. Which command checks a Bash script for syntax errors without executing it?
Identity and Access Management (Security+)
6. A field in /etc/shadow shows `!!` as the password value for an account. What does this mean?
Security Operations / Log Analysis (CySA+)
7. In the log-parsing pipeline `grep "Failed password" auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn`, what is the purpose of `sort` before `uniq -c`?
General Security Concepts / Least Privilege (Security+, ISC2 CC)
8. When a Bash script writes a report containing user account data, which permission set is most appropriate for that output file to limit exposure?
Record this lesson on my transcript. Sign in with your key and enrollment email to record lessons (enroll free if you have no key). This page stays open to read and practise.