Skip to content

Commit

Permalink
Merge pull request #2 from blazenetuk/ALERT
Browse files Browse the repository at this point in the history
ALERT - Auth Log and Event Reporting Tool
  • Loading branch information
blazenetuk authored Sep 20, 2024
2 parents 0aecb9a + 65c95f9 commit dddd4ce
Show file tree
Hide file tree
Showing 3 changed files with 370 additions and 0 deletions.
149 changes: 149 additions & 0 deletions HOWTO_Reports.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
# ALERT - Auth Log and Event Reporting Tool

This Branch provides the following -

### :basecampy: Auth Log Report
<!-- SPACE -->

<!-- SPACE -->
A script to generate a HTML report of the current server auth requests for the past 3 hours
Provides a regular report for the each 3 hours of the `auth.log` on the server to audit server
connection attempts and logins.
Can be run via the crontab to produce the html report
:star: a script snipplet is available to provide an admin with a copy of the `auth.log` from the
log file directory
<!-- SPACE -->
<br></br>
<!-- SPACE -->
### :basecampy: System Status Report
<!-- SPACE -->

<!-- SPACE -->
A script to generate a HTML report of the server stats for the administrator or operators
The html report generates includes the following information and can be run via the crontab
<!-- SPACE -->

<!-- SPACE -->
:star: Current Open Ports
:star: Current Connections
:star: System Log Entries from the past 2 hours
:star: System Critical Entry's (Priority 2)
:star: System Alert Entry's (Priority 1)
:star: System Emergency Entry's (Priority 0)
<!-- SPACE -->
<br></br>
### How To

To Use the Scripts

1. Upload them to the required server

2. Check you are happy with the settings by opening the script in an editor
for example; `$ nano authlog_report.sh`

3. Make the script executable with chmod `chmod u+x`
for example; `$ chmod u+x authlog_report.sh`

> [!CAUTION]
> We do not encourage you to use this from a system directory or set it up for the 'root' user on your system
> Please ensure you consult the correct documents for operating system
4. Test the script by by running it
for example; `$ ./authlog_report.sh`

6. Ensure the report has been generated and address any errors/software not installed as required.
You will receive the following message (if not commented out)

> HTML report generated: authlog.html


### Configuration

**authlog_report.sh**

Path/Directory to your log file 'authlog' file

> LOG_FILE=
Path/Directory and File name for the html report

> OUTPUT_HTML=
**sysstatus_report.sh**

Log file to analyze
This should be the same layout/format as the system
file 'authlog.log'

> LOG_FILE=
The filename to use for the html report

> OUTPUT_HTML=

### Requirements


This is a list of the programs that are current ran by each script to generate the report.

**authlog_report.sh**

- date
<sub> - Display date and time in the given FORMAT. </sub>
- hostname
<sub> - Hostname is the program that is used to either set or display the
current host, domain or node name of the system. These names are
used by many of the networking programs to identify the machine.
The domain name is also used by NIS/YP. </sub>
- awk
<sub> - The awk utility shall execute programs written in the awk
programming language, which is specialized for textual data
manipulation. An awk program is a sequence of patterns and
corresponding actions. When input is read that matches a pattern,
the action associated with that pattern is carried out.</sub>
- grep
<sub> - grep searches for PATTERNS in each FILE. PATTERNS is one or more
patterns separated by newline characters, and grep prints each
line that matches a pattern. Typically PATTERNS should be quoted
when grep is used in a shell command.</sub>
- cat
<sub> - concatenate files and print on the standard output.</sub>

**sysstatus_report.sh**

- date
<sub> - Display date and time in the given FORMAT. </sub>
- hostname
<sub> - Hostname is the program that is used to either set or display the
current host, domain or node name of the system. These names are
used by many of the networking programs to identify the machine.
The domain name is also used by NIS/YP. </sub>
- netstat
<sub> - Netstat prints information about the Linux networking subsystem.
The type of information printed is controlled by the first
argument</sub>
- tail
<sub> - Print the last 10 lines of each FILE to standard output. With
more than one FILE, precede each with a header giving the file
name. With no FILE, or when FILE is -, read standard input.</sub>
- grep
<sub> - grep searches for PATTERNS in each FILE. PATTERNS is one or more
patterns separated by newline characters, and grep prints each
line that matches a pattern. Typically PATTERNS should be quoted
when grep is used in a shell command.</sub>
- awk
<sub> - The awk utility shall execute programs written in the awk
programming language, which is specialized for textual data
manipulation. An awk program is a sequence of patterns and
corresponding actions. When input is read that matches a pattern,
the action associated with that pattern is carried out. </sub>
- journalctl
<sub> - journalctl is used to print the log entries stored in the journal
by systemd-journald.service(8) and
systemd-journal-remote.service(8).
If called without parameters, it will show the contents of the
journal accessible to the calling user, starting with the oldest
entry collected.</sub>

114 changes: 114 additions & 0 deletions authlog_report.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
#!/usr/bin/bash

# Settings/Variable
LOG_FILE="/home/<some user>/auth.log" # Path/Directory to your log file 'authlog' file
OUTPUT_HTML="/home/<some user>/authlog.html" # Path/Directory and File name for the html report

# Get the current date and time
CURRENT_DATE=$(date +"%b %d %H:%M:%S")

# Get the date and time 3 hours ago
PAST_DATE=$(date --date="3 hours ago" +"%b %d %H:%M:%S")

# Defines the name of the server
MY_NAME=$(hostname)

# Start the HTML file with basic structure and styles
# Style color is RED
cat <<EOF > "$OUTPUT_HTML"
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Auth Log Report</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f8f8f8;
color: #333;
}
table {
width: 100%;
border-collapse: collapse;
margin: 20px 0;
}
table, th, td {
border: 1px solid #ddd;
}
th, td {
padding: 10px;
text-align: left;
}
th {
background-color: #b30000;
color: white;
}
tr:nth-child(even) {
background-color: #f2f2f2;
}
tr:hover {
background-color: #f5c6c6;
}
caption {
font-size: 1.5em;
margin-bottom: 10px;
color: #b30000;
}
</style>
</head>
<body>
<h1>Authentication Report for $MY_NAME</h1>
<table>
<caption>Connection Attempts</caption>
<tr>
<th>Timestamp</th>
<th>Username</th>
<th>IP Address</th>
</tr>
EOF

# Process the log file to extract entries from the past 3 hours
awk -v past_date="$PAST_DATE" -v current_date="$CURRENT_DATE" '
{
log_time = sprintf("%s %s %s", $1, $2, $3);
if (log_time >= past_date && log_time <= current_date) {
print $0;
}
}' "$LOG_FILE" | grep -E "Accepted|Failed password|session opened" | while read -r line; do
# Extract timestamp
timestamp=$(echo "$line" | awk '{print $1, $2, $3}')

# Extract username correctly (handles both "invalid user" and normal cases)
# or applies 'N/A' if unknown or not found
username=$(echo "$line" | grep -oP "for (invalid user |user )\K\w+" || echo "N/A")

# Extract IP address
ip=$(echo "$line" | grep -oP "(\d{1,3}\.){3}\d{1,3}")

# If the IP is blank, skip this entry
# prevents a lot of false entries
if [[ -z "$ip" ]]; then
continue
fi

# Append the details as a table row to the HTML file
echo " <tr>" >> "$OUTPUT_HTML"
echo " <td>$timestamp</td>" >> "$OUTPUT_HTML"
echo " <td>$username</td>" >> "$OUTPUT_HTML"
echo " <td>$ip</td>" >> "$OUTPUT_HTML"
echo " </tr>" >> "$OUTPUT_HTML"
done

# Close the HTML output
cat <<EOF >> "$OUTPUT_HTML"
</table>
</body>
</html>
EOF

# Print success message
# -- if running from crontab
# Please comment this out by putting
# '#' before the word 'echo'
echo "HTML report generated: $OUTPUT_HTML"
107 changes: 107 additions & 0 deletions sysstatus_report.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#!/usr/bin/bash

# Log file to analyze (replace with actual path if needed)
LOG_FILE="/home/<some user>/auth.log"

# The filename to use for the html report
OUTPUT_HTML="report.html"

# Get today's date in the format of the log system log file
TODAYS_DATE=$(date +"%b %d")

# Get the current time
CURRENT_TIME=$(date +"%H:%M")

# Get the time two hours ago
TWO_HOURS_AGO=$(date -d '2 hours ago' +"%H:%M")

# delete the old file as we will update
if [ -f $OUTPUT_HTML ]; then
rm $OUTPUT_HTML
fi

# Updated HTML Code for better email format
# The Color Scheme is currently BLUE

# Create or overwrite the HTML report file
echo "<html>" > $OUTPUT_HTML
echo "<head><title>System Report $(hostname)</title></head>" >> $OUTPUT_HTML

# Add inline CSS for email-friendly formatting
echo "<body style='font-family: Arial, sans-serif; background-color: #f4f4f9; color: #333;'>" >> $OUTPUT_HTML
echo "<h1 style='color: #0044cc;'>System Report</h1>" >> $OUTPUT_HTML

# Netstat TCP Connections
echo "<h2 style='color: #0044cc;'>Netstat TCP Connections (-at)</h2>" >> $OUTPUT_HTML
echo "<table border='1' cellpadding='5' cellspacing='0' style='width: 100%; border-collapse: collapse;'>" >> $OUTPUT_HTML
echo "<tr style='background-color: #0044cc; color: white;'><th>Proto</th><th>Local Address</th><th>Foreign Address</th><th>State</th></tr>" >> $OUTPUT_HTML
netstat -at | tail -n +3 | while read proto local_addr foreign_addr state; do
echo "<tr><td style='border: 1px solid #ddd;'>$proto</td><td style='border: 1px solid #ddd;'>$local_addr</td><td style='border: 1px solid #ddd;'>$foreign_addr</td><td style='border: 1px solid #ddd;'>$state</td></tr>" >> $OUTPUT_HTML
done
echo "</table>" >> $OUTPUT_HTML

# Netstat UDP Connections
echo "<h2 style='color: #0044cc;'>Netstat UDP Connections (-au)</h2>" >> $OUTPUT_HTML
echo "<table border='1' cellpadding='5' cellspacing='0' style='width: 100%; border-collapse: collapse;'>" >> $OUTPUT_HTML
echo "<tr style='background-color: #0044cc; color: white;'><th>Proto</th><th>Local Address</th><th>Foreign Address</th></tr>" >> $OUTPUT_HTML
netstat -au | tail -n +3 | while read proto local_addr foreign_addr; do
echo "<tr><td style='border: 1px solid #ddd;'>$proto</td><td style='border: 1px solid #ddd;'>$local_addr</td><td style='border: 1px solid #ddd;'>$foreign_addr</td></tr>" >> $OUTPUT_HTML
done
echo "</table>" >> $OUTPUT_HTML

# Table of log entries by today's date only
echo "<h2 style='color: #0044cc;'>Log Entries (Past 2 hours)</h2>" >> $OUTPUT_HTML
echo "<table border='1' cellpadding='5' cellspacing='0' style='width: 100%; border-collapse: collapse;'>" >> $OUTPUT_HTML
echo "<tr style='background-color: #0044cc; color: white;'><th>Date</th><th>Message</th></tr>" >> $OUTPUT_HTML

# Filter logs by today's date and the last two hours
grep "$TODAYS_DATE" $LOG_FILE | awk -v current_time="$CURRENT_TIME" -v two_hours_ago="$TWO_HOURS_AGO" '
{
# Extract the time (hour:minute) from the log line (4th field)
log_time = substr($3, 1, 5)
# Check if the log time is between two_hours_ago and current_time
if (log_time >= two_hours_ago && log_time <= current_time) {
# Print log entry with date and message (cut off the first 5 fields for the message)
print "<tr><td style=\"border: 1px solid #ddd;\">" $1, $2, $3 "</td><td style=\"border: 1px solid #ddd;\">" substr($0, index($0,$6)) "</td></tr>"
}
}' >> $OUTPUT_HTML

echo "</table>" >> $OUTPUT_HTML

# Function to add journalctl output, check if "-- No entries --" is returned
add_journalctl_section() {
PRIORITY=$1
TITLE=$2

echo "<h2 style='color: #0044cc;'>Journalctl Output (Priority $PRIORITY - $TITLE)</h2>" >> $OUTPUT_HTML
echo "<table border='1' cellpadding='5' cellspacing='0' style='width: 100%; border-collapse: collapse;'>" >> $OUTPUT_HTML
echo "<tr style='background-color: #0044cc; color: white;'><th>Date</th><th>Time</th><th>Message</th></tr>" >> $OUTPUT_HTML

# Capture the journalctl output
JOURNAL_OUTPUT=$(journalctl -p $PRIORITY -n 5 --no-pager)

if [[ "$JOURNAL_OUTPUT" == *"-- No entries --"* ]]; then
echo "<tr><td colspan='3' style='text-align: center;'>No current issues logged</td></tr>" >> $OUTPUT_HTML
else
echo "$JOURNAL_OUTPUT" | while read date time message; do
echo "<tr><td style='border: 1px solid #ddd;'>$date</td><td style='border: 1px solid #ddd;'>$time</td><td style='border: 1px solid #ddd;'>$message</td></tr>" >> $OUTPUT_HTML
done
fi

echo "</table>" >> $OUTPUT_HTML
}

# Add sections for different journal priorities
add_journalctl_section 2 "Critical"
add_journalctl_section 1 "Alert"
add_journalctl_section 0 "Emergency"

# Close HTML tags
echo "</body></html>" >> $OUTPUT_HTML

# we are going to be running from crontab so don't confirm report generated
# Print completion message
# if you are running this from a crontab, you should
# comment this out with '#'
echo "Report generated: $OUTPUT_HTML"

0 comments on commit dddd4ce

Please sign in to comment.