682bd69cf8
QA scan found 4 library files with functions that weren't exported, making them unavailable in subshells and nested calls. Added export statements for: - lib/attack-signatures.sh: 3 functions - lib/http-attack-analyzer.sh: 5 functions - lib/email-functions.sh: 18 functions - lib/rate-anomaly-detector.sh: 9 functions Total: 35 functions now properly exported This ensures functions are available when libraries are sourced by scripts that spawn subshells or use process substitution.
314 lines
8.0 KiB
Bash
Executable File
314 lines
8.0 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
################################################################################
|
|
# Email Functions Library
|
|
################################################################################
|
|
# Shared functions for email troubleshooting modules
|
|
################################################################################
|
|
|
|
# Detect MTA (Mail Transfer Agent)
|
|
detect_mta() {
|
|
if command -v exim &>/dev/null; then
|
|
echo "exim"
|
|
elif command -v postfix &>/dev/null || [ -f /etc/postfix/main.cf ]; then
|
|
echo "postfix"
|
|
elif command -v sendmail &>/dev/null; then
|
|
echo "sendmail"
|
|
else
|
|
echo "unknown"
|
|
fi
|
|
}
|
|
|
|
# Get mail log path based on system
|
|
get_mail_log_path() {
|
|
local control_panel=$(detect_control_panel 2>/dev/null || echo "unknown")
|
|
|
|
# Try common log locations in order of likelihood
|
|
if [ "$control_panel" = "cpanel" ]; then
|
|
if [ -f /var/log/exim_mainlog ]; then
|
|
echo "/var/log/exim_mainlog"
|
|
elif [ -f /var/log/exim/mainlog ]; then
|
|
echo "/var/log/exim/mainlog"
|
|
fi
|
|
elif [ "$control_panel" = "plesk" ]; then
|
|
if [ -f /var/log/maillog ]; then
|
|
echo "/var/log/maillog"
|
|
fi
|
|
else
|
|
# Standalone or other
|
|
if [ -f /var/log/mail.log ]; then
|
|
echo "/var/log/mail.log"
|
|
elif [ -f /var/log/maillog ]; then
|
|
echo "/var/log/maillog"
|
|
elif [ -f /var/log/exim_mainlog ]; then
|
|
echo "/var/log/exim_mainlog"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# Get mailbox base path
|
|
get_mailbox_base_path() {
|
|
local control_panel=$(detect_control_panel 2>/dev/null || echo "unknown")
|
|
|
|
case "$control_panel" in
|
|
cpanel)
|
|
echo "/home"
|
|
;;
|
|
plesk)
|
|
echo "/var/qmail/mailnames"
|
|
;;
|
|
*)
|
|
# Try common locations
|
|
if [ -d /home/vmail ]; then
|
|
echo "/home/vmail"
|
|
elif [ -d /var/mail ]; then
|
|
echo "/var/mail"
|
|
else
|
|
echo "/home"
|
|
fi
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# Validate email address format
|
|
validate_email() {
|
|
local email="$1"
|
|
if [[ "$email" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Extract domain from email address
|
|
get_email_domain() {
|
|
local email="$1"
|
|
echo "${email##*@}"
|
|
}
|
|
|
|
# Extract local part from email address
|
|
get_email_local() {
|
|
local email="$1"
|
|
echo "${email%%@*}"
|
|
}
|
|
|
|
# Convert bytes to human-readable format
|
|
format_size() {
|
|
local bytes="$1"
|
|
|
|
if [ "$bytes" -lt 1024 ]; then
|
|
echo "${bytes}B"
|
|
elif [ "$bytes" -lt 1048576 ]; then
|
|
echo "$((bytes / 1024))KB"
|
|
elif [ "$bytes" -lt 1073741824 ]; then
|
|
echo "$((bytes / 1048576))MB"
|
|
else
|
|
echo "$((bytes / 1073741824))GB"
|
|
fi
|
|
}
|
|
|
|
# Check if MTA service is running
|
|
check_mta_running() {
|
|
local mta=$(detect_mta)
|
|
|
|
case "$mta" in
|
|
exim)
|
|
if systemctl is-active --quiet exim 2>/dev/null || service exim status &>/dev/null; then
|
|
return 0
|
|
fi
|
|
;;
|
|
postfix)
|
|
if systemctl is-active --quiet postfix 2>/dev/null || service postfix status &>/dev/null; then
|
|
return 0
|
|
fi
|
|
;;
|
|
sendmail)
|
|
if systemctl is-active --quiet sendmail 2>/dev/null || service sendmail status &>/dev/null; then
|
|
return 0
|
|
fi
|
|
;;
|
|
esac
|
|
|
|
return 1
|
|
}
|
|
|
|
# Get MTA version
|
|
get_mta_version() {
|
|
local mta=$(detect_mta)
|
|
|
|
case "$mta" in
|
|
exim)
|
|
exim -bV 2>/dev/null | head -1 | awk '{print $3}'
|
|
;;
|
|
postfix)
|
|
postconf mail_version 2>/dev/null | awk '{print $3}'
|
|
;;
|
|
sendmail)
|
|
sendmail -d0.1 2>&1 | head -1 | awk '{print $2}'
|
|
;;
|
|
*)
|
|
echo "unknown"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# Get mail queue count
|
|
get_queue_count() {
|
|
local mta=$(detect_mta)
|
|
|
|
case "$mta" in
|
|
exim)
|
|
exim -bpc 2>/dev/null || echo "0"
|
|
;;
|
|
postfix)
|
|
postqueue -p 2>/dev/null | tail -1 | awk '{print $5}' | tr -d '(' | tr -d ')'
|
|
;;
|
|
*)
|
|
echo "0"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# Check DNS record
|
|
check_dns_record() {
|
|
local domain="$1"
|
|
local record_type="$2" # A, MX, TXT, etc.
|
|
|
|
if command -v dig &>/dev/null; then
|
|
dig +short "$domain" "$record_type" 2>/dev/null
|
|
elif command -v host &>/dev/null; then
|
|
host -t "$record_type" "$domain" 2>/dev/null | grep -v "has no" | awk '{print $NF}'
|
|
elif command -v nslookup &>/dev/null; then
|
|
nslookup -type="$record_type" "$domain" 2>/dev/null | grep -A10 "answer:" | grep -v "answer:"
|
|
fi
|
|
}
|
|
|
|
# Get server's primary IP
|
|
get_primary_ip() {
|
|
# Try multiple methods
|
|
local ip=""
|
|
|
|
# Method 1: hostname -i
|
|
ip=$(hostname -I 2>/dev/null | awk '{print $1}')
|
|
|
|
# Method 2: ip route
|
|
if [ -z "$ip" ]; then
|
|
ip=$(ip route get 8.8.8.8 2>/dev/null | awk '{print $7; exit}')
|
|
fi
|
|
|
|
# Method 3: ifconfig
|
|
if [ -z "$ip" ]; then
|
|
ip=$(ifconfig 2>/dev/null | grep 'inet ' | grep -v '127.0.0.1' | head -1 | awk '{print $2}' | cut -d: -f2)
|
|
fi
|
|
|
|
echo "$ip"
|
|
}
|
|
|
|
# Check if IP is valid format
|
|
is_valid_ip() {
|
|
local ip="$1"
|
|
if [[ "$ip" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Get reverse DNS (PTR) for IP
|
|
get_reverse_dns() {
|
|
local ip="$1"
|
|
|
|
if command -v dig &>/dev/null; then
|
|
dig +short -x "$ip" 2>/dev/null | sed 's/\.$//'
|
|
elif command -v host &>/dev/null; then
|
|
host "$ip" 2>/dev/null | grep "pointer" | awk '{print $NF}' | sed 's/\.$//'
|
|
fi
|
|
}
|
|
|
|
# Send test email
|
|
send_test_email() {
|
|
local to="$1"
|
|
local subject="${2:-Test Email from Server Toolkit}"
|
|
local body="${3:-This is a test email sent from the Server Toolkit.}"
|
|
local from="${4:-root@$(hostname)}"
|
|
|
|
if command -v mail &>/dev/null; then
|
|
echo "$body" | mail -s "$subject" -r "$from" "$to"
|
|
return $?
|
|
elif command -v sendmail &>/dev/null; then
|
|
{
|
|
echo "From: $from"
|
|
echo "To: $to"
|
|
echo "Subject: $subject"
|
|
echo ""
|
|
echo "$body"
|
|
} | sendmail -t
|
|
return $?
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Parse email from Exim log line
|
|
parse_exim_email() {
|
|
local log_line="$1"
|
|
# Extract email addresses from various Exim log formats
|
|
echo "$log_line" | grep -oE '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}' | head -1
|
|
}
|
|
|
|
# Get date range for log analysis (default: last 24 hours)
|
|
get_log_date_range() {
|
|
local hours="${1:-24}"
|
|
date -d "$hours hours ago" "+%Y-%m-%d %H:%M:%S"
|
|
}
|
|
|
|
# Count messages by sender
|
|
count_by_sender() {
|
|
local log_file="$1"
|
|
local min_date="${2:-}"
|
|
|
|
if [ -n "$min_date" ]; then
|
|
awk -v min_date="$min_date" '$0 >= min_date' "$log_file" | \
|
|
grep "<=" | \
|
|
grep -oE '\<[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}\>' | \
|
|
sort | uniq -c | sort -rn
|
|
else
|
|
grep "<=" "$log_file" | \
|
|
grep -oE '\<[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}\>' | \
|
|
sort | uniq -c | sort -rn
|
|
fi
|
|
}
|
|
|
|
# Export to detect_control_panel if not already available
|
|
if ! type detect_control_panel &>/dev/null; then
|
|
detect_control_panel() {
|
|
if [ -f /usr/local/cpanel/version ]; then
|
|
echo "cpanel"
|
|
elif [ -f /usr/local/psa/version ]; then
|
|
echo "plesk"
|
|
else
|
|
echo "standalone"
|
|
fi
|
|
}
|
|
fi
|
|
|
|
# Export functions for use in subshells
|
|
export -f detect_mta
|
|
export -f get_mail_log_path
|
|
export -f get_mailbox_base_path
|
|
export -f validate_email
|
|
export -f get_email_domain
|
|
export -f get_email_local
|
|
export -f format_size
|
|
export -f check_mta_running
|
|
export -f get_mta_version
|
|
export -f get_queue_count
|
|
export -f check_dns_record
|
|
export -f get_primary_ip
|
|
export -f is_valid_ip
|
|
export -f get_reverse_dns
|
|
export -f send_test_email
|
|
export -f parse_exim_email
|
|
export -f get_log_date_range
|
|
export -f count_by_sender
|