Update : full
This commit is contained in:
parent
e83894e30e
commit
5991764110
158
test/common.sh
Normal file
158
test/common.sh
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# =============================================================================
|
||||||
|
# Common functions and variables for security hardening
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# Colors for output
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[0;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
PURPLE='\033[0;35m'
|
||||||
|
CYAN='\033[0;36m'
|
||||||
|
GRAY='\033[0;37m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# Date format
|
||||||
|
DATE_FORMAT=$(date +"%Y-%m-%d")
|
||||||
|
TIMESTAMP_FORMAT=$(date +"%Y-%m-%d %H:%M:%S")
|
||||||
|
|
||||||
|
# Log file
|
||||||
|
LOG_FILE="/var/log/security-hardening.log"
|
||||||
|
|
||||||
|
# Backup directory
|
||||||
|
BACKUP_DIR="/root/security-backup-${DATE_FORMAT}"
|
||||||
|
|
||||||
|
# Function to create necessary directories
|
||||||
|
create_directories() {
|
||||||
|
mkdir -p "$BACKUP_DIR"
|
||||||
|
touch "$LOG_FILE"
|
||||||
|
chmod 600 "$LOG_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to log MESSAGEs
|
||||||
|
log_message() {
|
||||||
|
local LEVEL="$1"
|
||||||
|
local MESSAGE="$2"
|
||||||
|
local TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
|
||||||
|
|
||||||
|
# Log to file
|
||||||
|
echo "$TIMESTAMP [$LEVEL] $MESSAGE" >> "$LOG_FILE"
|
||||||
|
|
||||||
|
# Display to console with colors
|
||||||
|
case "$LEVEL" in
|
||||||
|
"INFO")
|
||||||
|
echo -e "${BLUE}[$LEVEL]${NC} $MESSAGE"
|
||||||
|
;;
|
||||||
|
"WARNING")
|
||||||
|
echo ""
|
||||||
|
echo -e "${YELLOW}[$LEVEL]${NC} $MESSAGE"
|
||||||
|
echo
|
||||||
|
;;
|
||||||
|
"ERROR")
|
||||||
|
echo ""
|
||||||
|
echo -e "${RED}[$LEVEL]${NC} $MESSAGE"
|
||||||
|
echo
|
||||||
|
;;
|
||||||
|
"SUCCESS")
|
||||||
|
echo ""
|
||||||
|
echo -e "${GREEN}[$LEVEL]${NC} $MESSAGE"
|
||||||
|
echo
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "[$LEVEL] $MESSAGE"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to back up a file before modifying
|
||||||
|
backup_file() {
|
||||||
|
local FILE="$1"
|
||||||
|
|
||||||
|
if [ -f "$FILE" ]; then
|
||||||
|
local BACKUP_PATH="$BACKUP_DIR$(dirname "$FILE")"
|
||||||
|
mkdir -p "$BACKUP_PATH"
|
||||||
|
cp -p "$FILE" "$BACKUP_PATH/" 2>/dev/null
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
log_message "INFO" "Backed up $FILE to $BACKUP_PATH/"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
log_message "ERROR" "Failed to back up $FILE"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log_message "WARNING" "File $FILE does not exist, no backup needed"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to display a progress bar
|
||||||
|
show_progress() {
|
||||||
|
local CURRENT="$1"
|
||||||
|
local TOTAL="$2"
|
||||||
|
local PERCENTAGE=$((current * 100 / total))
|
||||||
|
local PROGRESS=$((percentage / 2))
|
||||||
|
|
||||||
|
printf "\r[%-50s] %d%%" "$(printf '%0.s#' $(seq 1 $PROGRESS))" "$PERCENTAGE"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to run a module
|
||||||
|
run_module() {
|
||||||
|
local MODULE="$1"
|
||||||
|
local DESCRIPTION="$2"
|
||||||
|
|
||||||
|
# Increment step counter
|
||||||
|
((CURRENT_STEP++))
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo -e "${PURPLE}[$CURRENT_STEP/$TOTAL_STEPS] ${CYAN}$DESCRIPTION${NC}"
|
||||||
|
echo -e "${GRAY}$(printf '=%.0s' $(seq 1 80))${NC}"
|
||||||
|
|
||||||
|
# Source and run the module
|
||||||
|
if [ -f "$SCRIPT_DIR/modules/$MODULE.sh" ]; then
|
||||||
|
source "$SCRIPT_DIR/modules/$MODULE.sh"
|
||||||
|
show_progress "$CURRENT_STEP" "$TOTAL_STEPS"
|
||||||
|
else
|
||||||
|
log_MESSAGE "ERROR" "Module $module.sh not found"
|
||||||
|
show_progress "$CURRENT_STEP" "$TOTAL_STEPS"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to display a banner
|
||||||
|
display_banner() {
|
||||||
|
clear
|
||||||
|
echo -e "${GREEN}"
|
||||||
|
echo " _ _ _ _ _ "
|
||||||
|
echo " | | (_)_ __ _ ___ _ | |__ __ _ _ __| |_ ___ _ __ (_)_ __ __ _ "
|
||||||
|
echo " | | | | '_ \| | | \ \/ / | '_ \ / _ \| '__| __/ _ \ '_ \| | '_ \ / _ \`| "
|
||||||
|
echo " | |___| | | | | |_| |> < | | | | (_| | | | || __/ | | | | | | | (_| | "
|
||||||
|
echo " |_____|_|_| |_|\__,_/_/\_\ |_| |_|\__,_|_| \__\___|_| |_|_|_| |_|\__, | "
|
||||||
|
echo " |___/ "
|
||||||
|
echo -e "${NC}"
|
||||||
|
echo -e "${CYAN}Security Hardening Script for Debian/Ubuntu Systems${NC}"
|
||||||
|
echo -e "${CYAN}Version: ${VERSION}${NC}"
|
||||||
|
echo -e "${GRAY}$(printf '=%.0s' $(seq 1 80))${NC}"
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to display OS information
|
||||||
|
display_os_info() {
|
||||||
|
local OS_NAME=$(grep -E "^NAME=" /etc/os-release | cut -d= -f2 | tr -d '"')
|
||||||
|
local OS_VERSION=$(grep -E "^VERSION=" /etc/os-release | cut -d= -f2 | tr -d '"')
|
||||||
|
local KERNEL_VERSION=$(uname -r)
|
||||||
|
|
||||||
|
log_message "INFO" "Operating System: $OS_NAME $OS_VERSION"
|
||||||
|
log_message "INFO" "Kernel Version: $KERNEL_VERSION"
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to check if command exists
|
||||||
|
command_exists() {
|
||||||
|
command -v "$1" >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to check if package is installed
|
||||||
|
is_package_installed() {
|
||||||
|
dpkg -l "$1" | grep -q "^ii" >/dev/null 2>&1
|
||||||
|
}
|
96
test/main.sh
Normal file
96
test/main.sh
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# =============================================================================
|
||||||
|
# Linux Security Hardening Script for Debian/Ubuntu
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# Script version
|
||||||
|
VERSION="1.0.0"
|
||||||
|
|
||||||
|
# Set script directory
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
# Source common functions and variables
|
||||||
|
source "$SCRIPT_DIR/common.sh"
|
||||||
|
|
||||||
|
# Ensure the script is run as root
|
||||||
|
if [ "$EUID" -ne 0 ]; then
|
||||||
|
echo " * This script must be run with sudo privileges."
|
||||||
|
echo " * Please run it again using: sudo $0"
|
||||||
|
echo
|
||||||
|
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if the system is Debian or Ubuntu
|
||||||
|
if ! grep -q -E "Debian|Ubuntu" /etc/issue && ! grep -q -E "Debian|Ubuntu" /etc/os-release; then
|
||||||
|
echo "This script is designed for Debian or Ubuntu systems only."
|
||||||
|
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create necessary directories
|
||||||
|
create_directories
|
||||||
|
|
||||||
|
# Display banner
|
||||||
|
display_banner
|
||||||
|
|
||||||
|
# Display OS information
|
||||||
|
display_os_info
|
||||||
|
|
||||||
|
# Main execution
|
||||||
|
log_message "INFO" "Starting security hardening process"
|
||||||
|
|
||||||
|
# Initialize progress
|
||||||
|
TOTAL_STEPS=14
|
||||||
|
CURRENT_STEP=0
|
||||||
|
|
||||||
|
# Update and configure package management
|
||||||
|
$SCRIPT_DIR/modules/package_management.sh "Configuring package management"
|
||||||
|
|
||||||
|
# Configure SSH
|
||||||
|
$SCRIPT_DIR/modules/ssh_hardening.sh "Hardening SSH configuration"
|
||||||
|
|
||||||
|
# Configure firewall
|
||||||
|
$SCRIPT_DIR/modules/firewall.sh "Configuring firewall rules"
|
||||||
|
|
||||||
|
# Setup fail2ban
|
||||||
|
$SCRIPT_DIR/modules/fail2ban.sh "Setting up fail2ban"
|
||||||
|
|
||||||
|
# Configure system auditing
|
||||||
|
$SCRIPT_DIR/modules/auditing.sh "Configuring system auditing"
|
||||||
|
|
||||||
|
# Setup DNS
|
||||||
|
$SCRIPT_DIR/modules/dns_config.sh "Configuring DNS settings"
|
||||||
|
|
||||||
|
# Configure NTP
|
||||||
|
$SCRIPT_DIR/modules/ntp.sh "Configuring NTP"
|
||||||
|
|
||||||
|
# Setup automatic updates
|
||||||
|
$SCRIPT_DIR/modules/auto_updates.sh "Setting up automatic updates"
|
||||||
|
|
||||||
|
# Install and configure ClamAV
|
||||||
|
$SCRIPT_DIR/modules/antivirus.sh "Installing and configuring ClamAV"
|
||||||
|
|
||||||
|
# Setup custom prompt
|
||||||
|
$SCRIPT_DIR/modules/custom_prompt.sh "Setting up custom system prompt"
|
||||||
|
|
||||||
|
# Install GLPI agent
|
||||||
|
$SCRIPT_DIR/modules/glpi_agent.sh "Installing GLPI agent"
|
||||||
|
|
||||||
|
# Install Wazuh agent
|
||||||
|
$SCRIPT_DIR/modules/wazuh_agent.sh "Installing Wazuh agent"
|
||||||
|
|
||||||
|
# Setup monitoring (SNMP and NRPE)
|
||||||
|
$SCRIPT_DIR/modules/monitoring.sh "Setting up monitoring services"
|
||||||
|
|
||||||
|
# Apply additional security measures
|
||||||
|
$SCRIPT_DIR/modules/additional_hardening.sh "Applying additional security measures"
|
||||||
|
|
||||||
|
# Display completion message
|
||||||
|
echo
|
||||||
|
log_message "SUCCESS" "Security hardening completed successfully!"
|
||||||
|
echo "Log file available at: $LOG_FILE"
|
||||||
|
echo "System backup files stored at: $BACKUP_DIR"
|
||||||
|
echo
|
||||||
|
|
||||||
|
exit 0
|
344
test/modules/additional_hardening.sh
Normal file
344
test/modules/additional_hardening.sh
Normal file
@ -0,0 +1,344 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# =============================================================================
|
||||||
|
# Additional security hardening module
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# Set script directory
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
# Source common functions and variables
|
||||||
|
source "./common.sh"
|
||||||
|
|
||||||
|
# Function to harden system settings
|
||||||
|
harden_system_settings() {
|
||||||
|
log_message "INFO" "Applying additional system hardening measures"
|
||||||
|
|
||||||
|
# Backup sysctl.conf
|
||||||
|
backup_file "/etc/sysctl.conf"
|
||||||
|
|
||||||
|
# Create custom sysctl security settings
|
||||||
|
local sysctl_security="/etc/sysctl.d/10-security-hardening.conf"
|
||||||
|
|
||||||
|
log_message "INFO" "Creating security sysctl configuration"
|
||||||
|
|
||||||
|
cat > "$sysctl_security" << EOF
|
||||||
|
# Security hardening sysctl settings
|
||||||
|
# Generated by security hardening script
|
||||||
|
|
||||||
|
# IP Spoofing protection
|
||||||
|
net.ipv4.conf.all.rp_filter = 1
|
||||||
|
net.ipv4.conf.default.rp_filter = 1
|
||||||
|
|
||||||
|
# Ignore ICMP broadcast requests
|
||||||
|
net.ipv4.icmp_echo_ignore_broadcasts = 1
|
||||||
|
|
||||||
|
# Disable source packet routing
|
||||||
|
net.ipv4.conf.all.accept_source_route = 0
|
||||||
|
net.ipv4.conf.default.accept_source_route = 0
|
||||||
|
net.ipv6.conf.all.accept_source_route = 0
|
||||||
|
net.ipv6.conf.default.accept_source_route = 0
|
||||||
|
|
||||||
|
# Ignore send redirects
|
||||||
|
net.ipv4.conf.all.send_redirects = 0
|
||||||
|
net.ipv4.conf.default.send_redirects = 0
|
||||||
|
|
||||||
|
# Block SYN attacks
|
||||||
|
net.ipv4.tcp_syncookies = 1
|
||||||
|
net.ipv4.tcp_syn_retries = 5
|
||||||
|
net.ipv4.tcp_synack_retries = 2
|
||||||
|
net.ipv4.tcp_max_syn_backlog = 4096
|
||||||
|
|
||||||
|
# Log Martians
|
||||||
|
net.ipv4.conf.all.log_martians = 1
|
||||||
|
net.ipv4.conf.default.log_martians = 1
|
||||||
|
|
||||||
|
# Ignore ICMP redirects
|
||||||
|
net.ipv4.conf.all.accept_redirects = 0
|
||||||
|
net.ipv4.conf.default.accept_redirects = 0
|
||||||
|
net.ipv6.conf.all.accept_redirects = 0
|
||||||
|
net.ipv6.conf.default.accept_redirects = 0
|
||||||
|
|
||||||
|
# Ignore Directed pings
|
||||||
|
net.ipv4.icmp_echo_ignore_all = 0
|
||||||
|
|
||||||
|
# Protect against time-wait assassination
|
||||||
|
net.ipv4.tcp_rfc1337 = 1
|
||||||
|
|
||||||
|
# Increase system file descriptor limit
|
||||||
|
fs.file-max = 65535
|
||||||
|
|
||||||
|
# Increase system IP port limits
|
||||||
|
net.ipv4.ip_local_port_range = 2000 65000
|
||||||
|
|
||||||
|
# Protect against kernel memory exposure
|
||||||
|
kernel.kptr_restrict = 2
|
||||||
|
|
||||||
|
# Restrict dmesg access
|
||||||
|
kernel.dmesg_restrict = 1
|
||||||
|
|
||||||
|
# Restrict access to kernel pointers
|
||||||
|
kernel.kptr_restrict = 2
|
||||||
|
|
||||||
|
# Restrict kernel performance events
|
||||||
|
kernel.perf_event_paranoid = 3
|
||||||
|
|
||||||
|
# Protect against ptrace process attach
|
||||||
|
kernel.yama.ptrace_scope = 1
|
||||||
|
|
||||||
|
# Protect against SUID process core dumps
|
||||||
|
fs.suid_dumpable = 0
|
||||||
|
|
||||||
|
# Protect against core dumps
|
||||||
|
kernel.core_pattern = |/bin/false
|
||||||
|
|
||||||
|
# Disable IPv6 if not needed
|
||||||
|
# net.ipv6.conf.all.disable_ipv6 = 1
|
||||||
|
# net.ipv6.conf.default.disable_ipv6 = 1
|
||||||
|
# net.ipv6.conf.lo.disable_ipv6 = 1
|
||||||
|
EOF
|
||||||
|
|
||||||
|
log_message "SUCCESS" "Security sysctl configuration created at $sysctl_security"
|
||||||
|
|
||||||
|
# Apply sysctl settings
|
||||||
|
log_message "INFO" "Applying sysctl settings"
|
||||||
|
sysctl -p "$sysctl_security"
|
||||||
|
|
||||||
|
# Harden PAM configuration
|
||||||
|
log_message "INFO" "Hardening PAM configuration"
|
||||||
|
|
||||||
|
# Configure password policies
|
||||||
|
local pwquality_conf="/etc/security/pwquality.conf"
|
||||||
|
|
||||||
|
backup_file "$pwquality_conf"
|
||||||
|
|
||||||
|
cat > "$pwquality_conf" << EOF
|
||||||
|
# Password quality configuration
|
||||||
|
# Generated by security hardening script
|
||||||
|
|
||||||
|
# Minimum password length
|
||||||
|
minlen = 12
|
||||||
|
|
||||||
|
# Require at least one uppercase letter
|
||||||
|
ucredit = -1
|
||||||
|
|
||||||
|
# Require at least one lowercase letter
|
||||||
|
lcredit = -1
|
||||||
|
|
||||||
|
# Require at least one digit
|
||||||
|
dcredit = -1
|
||||||
|
|
||||||
|
# Require at least one special character
|
||||||
|
ocredit = -1
|
||||||
|
|
||||||
|
# Enforce password history (remember last 5 passwords)
|
||||||
|
enforce_for_root
|
||||||
|
remember = 5
|
||||||
|
|
||||||
|
# Maximum number of allowed consecutive characters
|
||||||
|
maxrepeat = 3
|
||||||
|
|
||||||
|
# Minimum number of character classes
|
||||||
|
minclass = 3
|
||||||
|
|
||||||
|
# Check for dictionary words
|
||||||
|
dictcheck = 1
|
||||||
|
|
||||||
|
# Reject passwords shorter than 8 chars even with sufficient credit
|
||||||
|
minlen = 8
|
||||||
|
EOF
|
||||||
|
|
||||||
|
log_message "SUCCESS" "Password quality configuration created at $pwquality_conf"
|
||||||
|
|
||||||
|
# Configure common-password
|
||||||
|
local common_password="/etc/pam.d/common-password"
|
||||||
|
|
||||||
|
backup_file "$common_password"
|
||||||
|
|
||||||
|
# Add pam_pwquality to common-password if not already present
|
||||||
|
if ! grep -q "pam_pwquality.so" "$common_password"; then
|
||||||
|
sed -i 's/pam_unix.so/pam_pwquality.so retry=3\npassword\t[success=1 default=ignore]\tpam_unix.so/' "$common_password"
|
||||||
|
log_message "SUCCESS" "Added pam_pwquality to $common_password"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Configure login.defs for password aging
|
||||||
|
local login_defs="/etc/login.defs"
|
||||||
|
|
||||||
|
backup_file "$login_defs"
|
||||||
|
|
||||||
|
# Update password expiration settings
|
||||||
|
sed -i 's/^PASS_MAX_DAYS.*/PASS_MAX_DAYS 90/' "$login_defs"
|
||||||
|
sed -i 's/^PASS_MIN_DAYS.*/PASS_MIN_DAYS 1/' "$login_defs"
|
||||||
|
sed -i 's/^PASS_WARN_AGE.*/PASS_WARN_AGE 7/' "$login_defs"
|
||||||
|
|
||||||
|
log_message "SUCCESS" "Updated password aging configuration in $login_defs"
|
||||||
|
|
||||||
|
# Secure /tmp directory
|
||||||
|
log_message "INFO" "Securing temporary directories"
|
||||||
|
|
||||||
|
# Create entries for mounting /tmp, /var/tmp, and /dev/shm with security options
|
||||||
|
local mount_options="defaults,nodev,nosuid,noexec"
|
||||||
|
|
||||||
|
# Add entries to fstab if they don't already exist
|
||||||
|
if ! grep -q "tmpfs /tmp" /etc/fstab; then
|
||||||
|
echo "tmpfs /tmp tmpfs $mount_options 0 0" >> /etc/fstab
|
||||||
|
log_message "SUCCESS" "Added secure /tmp mount to fstab"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! grep -q "tmpfs /dev/shm" /etc/fstab; then
|
||||||
|
echo "tmpfs /dev/shm tmpfs $mount_options 0 0" >> /etc/fstab
|
||||||
|
log_message "SUCCESS" "Added secure /dev/shm mount to fstab"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! grep -q "/tmp /var/tmp" /etc/fstab; then
|
||||||
|
echo "/tmp /var/tmp none bind 0 0" >> /etc/fstab
|
||||||
|
log_message "SUCCESS" "Added /var/tmp bind mount to fstab"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Disable uncommon network protocols
|
||||||
|
log_message "INFO" "Disabling uncommon network protocols"
|
||||||
|
|
||||||
|
local disabled_modules="/etc/modprobe.d/disablemod.conf"
|
||||||
|
|
||||||
|
cat > "$disabled_modules" << EOF
|
||||||
|
# Disable uncommon network protocols
|
||||||
|
# Generated by security hardening script
|
||||||
|
|
||||||
|
# Disable uncommon protocols
|
||||||
|
install dccp /bin/false
|
||||||
|
install sctp /bin/false
|
||||||
|
install rds /bin/false
|
||||||
|
install tipc /bin/false
|
||||||
|
install cramfs /bin/false
|
||||||
|
install freevxfs /bin/false
|
||||||
|
install jffs2 /bin/false
|
||||||
|
install hfs /bin/false
|
||||||
|
install hfsplus /bin/false
|
||||||
|
install squashfs /bin/false
|
||||||
|
install udf /bin/false
|
||||||
|
EOF
|
||||||
|
|
||||||
|
log_message "SUCCESS" "Disabled uncommon network protocols in $disabled_modules"
|
||||||
|
|
||||||
|
# Configure process accounting
|
||||||
|
log_message "INFO" "Configuring process accounting"
|
||||||
|
|
||||||
|
if ! is_package_installed "acct"; then
|
||||||
|
apt-get install -y acct
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
systemctl enable acct
|
||||||
|
systemctl start acct
|
||||||
|
log_message "SUCCESS" "Process accounting (acct) installed and enabled"
|
||||||
|
else
|
||||||
|
log_message "ERROR" "Failed to install process accounting (acct)"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log_message "INFO" "Process accounting (acct) is already installed"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Configure system logging
|
||||||
|
log_message "INFO" "Configuring system logging"
|
||||||
|
|
||||||
|
# Ensure rsyslog is installed
|
||||||
|
if ! is_package_installed "rsyslog"; then
|
||||||
|
apt-get install -y rsyslog
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
log_message "ERROR" "Failed to install rsyslog"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Configure rsyslog
|
||||||
|
local rsyslog_security="/etc/rsyslog.d/50-security.conf"
|
||||||
|
|
||||||
|
cat > "$rsyslog_security" << EOF
|
||||||
|
# Security logging configuration
|
||||||
|
# Generated by security hardening script
|
||||||
|
|
||||||
|
# Log auth messages to a separate file
|
||||||
|
auth,authpriv.* /var/log/auth.log
|
||||||
|
|
||||||
|
# Log kernel messages to a separate file
|
||||||
|
kern.* /var/log/kern.log
|
||||||
|
|
||||||
|
# Log system warnings and errors
|
||||||
|
*.warn;*.err /var/log/syslog
|
||||||
|
*.crit /var/log/critical
|
||||||
|
|
||||||
|
# Log all failed login attempts
|
||||||
|
auth,authpriv.warn /var/log/faillog
|
||||||
|
|
||||||
|
# Log sudo usage
|
||||||
|
local2.* /var/log/sudo.log
|
||||||
|
|
||||||
|
# Remote logging - uncomment and set your log server
|
||||||
|
#*.* @logserver.example.com:514
|
||||||
|
EOF
|
||||||
|
|
||||||
|
log_message "SUCCESS" "Rsyslog security configuration created at $rsyslog_security"
|
||||||
|
|
||||||
|
# Restart rsyslog
|
||||||
|
systemctl restart rsyslog
|
||||||
|
|
||||||
|
# Configure log rotation
|
||||||
|
local logrotate_conf="/etc/logrotate.d/rsyslog-security"
|
||||||
|
|
||||||
|
cat > "$logrotate_conf" << EOF
|
||||||
|
# Log rotation for security logs
|
||||||
|
# Generated by security hardening script
|
||||||
|
|
||||||
|
/var/log/auth.log
|
||||||
|
/var/log/kern.log
|
||||||
|
/var/log/syslog
|
||||||
|
/var/log/critical
|
||||||
|
/var/log/faillog
|
||||||
|
/var/log/sudo.log
|
||||||
|
{
|
||||||
|
rotate 14
|
||||||
|
daily
|
||||||
|
missingok
|
||||||
|
notifempty
|
||||||
|
compress
|
||||||
|
delaycompress
|
||||||
|
sharedscripts
|
||||||
|
postrotate
|
||||||
|
/usr/lib/rsyslog/rsyslog-rotate
|
||||||
|
endscript
|
||||||
|
create 0640 syslog adm
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
log_message "SUCCESS" "Log rotation configuration created at $logrotate_conf"
|
||||||
|
|
||||||
|
# Set secure file permissions
|
||||||
|
log_message "INFO" "Setting secure file permissions"
|
||||||
|
|
||||||
|
# Secure /etc/shadow
|
||||||
|
chmod 0600 /etc/shadow
|
||||||
|
|
||||||
|
# Secure SSH keys
|
||||||
|
if [ -d "/etc/ssh" ]; then
|
||||||
|
chmod 0700 /etc/ssh
|
||||||
|
chmod 0600 /etc/ssh/*key
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Remove unused accounts
|
||||||
|
log_message "INFO" "Checking for unused accounts"
|
||||||
|
|
||||||
|
local system_accounts="games gnats irc list news sync uucp"
|
||||||
|
|
||||||
|
for account in $system_accounts; do
|
||||||
|
if id "$account" &>/dev/null; then
|
||||||
|
log_message "INFO" "Locking unused account: $account"
|
||||||
|
passwd -l "$account"
|
||||||
|
usermod -s /usr/sbin/nologin "$account"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
log_message "SUCCESS" "System accounts secured"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main execution for additional hardening
|
||||||
|
harden_system_settings
|
||||||
|
|
||||||
|
log_message "SUCCESS" "Additional hardening measures completed"
|
116
test/modules/antivirus.sh
Normal file
116
test/modules/antivirus.sh
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# =============================================================================
|
||||||
|
# Antivirus configuration module
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# Set script directory
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
# Source common functions and variables
|
||||||
|
source "./common.sh"
|
||||||
|
|
||||||
|
# Function to install and configure ClamAV
|
||||||
|
configure_clamav() {
|
||||||
|
log_message "INFO" "Installing and configuring ClamAV antivirus"
|
||||||
|
|
||||||
|
# Install ClamAV if not already installed
|
||||||
|
if ! is_package_installed "clamav" || ! is_package_installed "clamav-daemon"; then
|
||||||
|
log_message "INFO" "Installing ClamAV and related packages"
|
||||||
|
apt-get install -y clamav clamav-daemon clamav-freshclam
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
log_message "ERROR" "Failed to install ClamAV"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log_message "INFO" "ClamAV is already installed"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Configure ClamAV
|
||||||
|
local freshclam_conf="/etc/clamav/freshclam.conf"
|
||||||
|
|
||||||
|
log_message "INFO" "Configuring ClamAV"
|
||||||
|
backup_file "$freshclam_conf"
|
||||||
|
|
||||||
|
# Stop ClamAV services to update configuration
|
||||||
|
systemctl stop clamav-freshclam
|
||||||
|
systemctl stop clamav-daemon
|
||||||
|
|
||||||
|
# Configure freshclam (virus database updater)
|
||||||
|
sed -i 's/^Example/#Example/' "$freshclam_conf"
|
||||||
|
sed -i 's/^Checks.*/Checks 24/' "$freshclam_conf"
|
||||||
|
sed -i 's/^DatabaseMirror.*/DatabaseMirror db.local.clamav.net/' "$freshclam_conf"
|
||||||
|
|
||||||
|
log_message "SUCCESS" "ClamAV freshclam configuration updated"
|
||||||
|
|
||||||
|
# Create a daily scan script
|
||||||
|
local scan_script="/etc/cron.daily/clamscan"
|
||||||
|
|
||||||
|
log_message "INFO" "Creating daily scan script"
|
||||||
|
|
||||||
|
cat > "$scan_script" << 'EOF'
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# ClamAV daily scan script
|
||||||
|
# Generated by security hardening script
|
||||||
|
|
||||||
|
# Set log file
|
||||||
|
LOG_FILE="/var/log/clamav/daily_scan.log"
|
||||||
|
SCAN_DIR="/"
|
||||||
|
EXCLUDE_DIRS=("/sys" "/proc" "/dev" "/media" "/mnt" "/run" "/var/lib/clamav")
|
||||||
|
|
||||||
|
# Create log directory if it doesn't exist
|
||||||
|
mkdir -p /var/log/clamav
|
||||||
|
|
||||||
|
# Start log
|
||||||
|
echo "ClamAV daily scan started at $(date)" > "$LOG_FILE"
|
||||||
|
|
||||||
|
# Build exclude parameters
|
||||||
|
EXCLUDES=""
|
||||||
|
for dir in "${EXCLUDE_DIRS[@]}"; do
|
||||||
|
EXCLUDES="$EXCLUDES --exclude-dir=$dir"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Run scan
|
||||||
|
clamscan -r $EXCLUDES --infected --detect-pua=yes --log="$LOG_FILE" --append "$SCAN_DIR"
|
||||||
|
|
||||||
|
# Email report if infected files found
|
||||||
|
INFECTED=$(grep -c "Infected files" "$LOG_FILE")
|
||||||
|
if [ "$INFECTED" -gt 0 ]; then
|
||||||
|
echo "Virus detected! See log at $LOG_FILE" | mail -s "ClamAV Virus Alert" root
|
||||||
|
fi
|
||||||
|
|
||||||
|
# End log
|
||||||
|
echo "ClamAV daily scan completed at $(date)" >> "$LOG_FILE"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
chmod +x "$scan_script"
|
||||||
|
log_message "SUCCESS" "ClamAV daily scan script created at $scan_script"
|
||||||
|
|
||||||
|
# Restart ClamAV services
|
||||||
|
log_message "INFO" "Starting ClamAV services"
|
||||||
|
systemctl start clamav-freshclam
|
||||||
|
systemctl start clamav-daemon
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
log_message "SUCCESS" "ClamAV services started successfully"
|
||||||
|
else
|
||||||
|
log_message "ERROR" "Failed to start ClamAV services"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Update virus database
|
||||||
|
log_message "INFO" "Updating ClamAV virus database"
|
||||||
|
freshclam
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
log_message "SUCCESS" "ClamAV virus database updated successfully"
|
||||||
|
else
|
||||||
|
log_message "WARNING" "ClamAV virus database update encountered issues"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main execution for antivirus
|
||||||
|
configure_clamav
|
||||||
|
|
||||||
|
log_message "SUCCESS" "Antivirus configuration completed"
|
126
test/modules/auditing.sh
Normal file
126
test/modules/auditing.sh
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# =============================================================================
|
||||||
|
# System auditing configuration module
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# Set script directory
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
# Source common functions and variables
|
||||||
|
source "./common.sh"
|
||||||
|
|
||||||
|
# Function to install and configure auditd
|
||||||
|
configure_auditd() {
|
||||||
|
log_message "INFO" "Installing and configuring auditd"
|
||||||
|
|
||||||
|
# Install auditd if not already installed
|
||||||
|
if ! is_package_installed "auditd"; then
|
||||||
|
apt-get install -y auditd audispd-plugins
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
log_message "ERROR" "Failed to install auditd"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log_message "INFO" "auditd is already installed"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Configure auditd
|
||||||
|
local audit_rules="/etc/audit/rules.d/audit.rules"
|
||||||
|
|
||||||
|
log_message "INFO" "Creating audit rules"
|
||||||
|
backup_file "$audit_rules"
|
||||||
|
|
||||||
|
cat > "$audit_rules" << 'EOF'
|
||||||
|
# Audit configuration
|
||||||
|
# Hardened audit rules
|
||||||
|
|
||||||
|
# Delete all existing rules
|
||||||
|
-D
|
||||||
|
|
||||||
|
# Set buffer size
|
||||||
|
-b 8192
|
||||||
|
|
||||||
|
# Failure mode: 1=silent, 2=printk
|
||||||
|
-f 1
|
||||||
|
|
||||||
|
# Enable kernel auditing
|
||||||
|
-e 1
|
||||||
|
|
||||||
|
# Authentication and authorization
|
||||||
|
-w /etc/pam.d/ -p wa -k pam
|
||||||
|
-w /etc/nsswitch.conf -p wa -k nsswitch
|
||||||
|
-w /etc/shadow -p wa -k shadow
|
||||||
|
-w /etc/passwd -p wa -k passwd
|
||||||
|
-w /etc/group -p wa -k group
|
||||||
|
-w /etc/sudoers -p wa -k sudoers
|
||||||
|
-w /etc/sudoers.d/ -p wa -k sudoers
|
||||||
|
|
||||||
|
# System startup and shutdown
|
||||||
|
-w /sbin/shutdown -p x -k power
|
||||||
|
-w /sbin/reboot -p x -k power
|
||||||
|
-w /sbin/halt -p x -k power
|
||||||
|
|
||||||
|
# Kernel modules
|
||||||
|
-w /sbin/insmod -p x -k modules
|
||||||
|
-w /sbin/rmmod -p x -k modules
|
||||||
|
-w /sbin/modprobe -p x -k modules
|
||||||
|
|
||||||
|
# User, group, password modifications
|
||||||
|
-w /usr/sbin/useradd -p x -k user_modification
|
||||||
|
-w /usr/sbin/userdel -p x -k user_modification
|
||||||
|
-w /usr/sbin/usermod -p x -k user_modification
|
||||||
|
-w /usr/sbin/groupadd -p x -k group_modification
|
||||||
|
-w /usr/sbin/groupdel -p x -k group_modification
|
||||||
|
-w /usr/sbin/groupmod -p x -k group_modification
|
||||||
|
-w /usr/bin/passwd -p x -k password_modification
|
||||||
|
|
||||||
|
# Network configuration
|
||||||
|
-w /etc/network/ -p wa -k network
|
||||||
|
-w /etc/sysconfig/network -p wa -k network
|
||||||
|
-w /etc/hosts -p wa -k hosts
|
||||||
|
-w /etc/hostname -p wa -k hostname
|
||||||
|
|
||||||
|
# System time changes
|
||||||
|
-a always,exit -F arch=b64 -S settimeofday -S adjtimex -S clock_settime -k time-change
|
||||||
|
-a always,exit -F arch=b32 -S settimeofday -S adjtimex -S clock_settime -k time-change
|
||||||
|
|
||||||
|
# Suspicious activities
|
||||||
|
-w /usr/bin/wget -p x -k suspicious_activity
|
||||||
|
-w /usr/bin/curl -p x -k suspicious_activity
|
||||||
|
-w /usr/bin/base64 -p x -k suspicious_activity
|
||||||
|
-w /bin/nc -p x -k suspicious_activity
|
||||||
|
-w /bin/netcat -p x -k suspicious_activity
|
||||||
|
-w /usr/bin/ncat -p x -k suspicious_activity
|
||||||
|
-w /usr/bin/ssh -p x -k suspicious_activity
|
||||||
|
-w /usr/bin/socat -p x -k suspicious_activity
|
||||||
|
-w /usr/bin/wireshark -p x -k suspicious_activity
|
||||||
|
-w /usr/bin/tshark -p x -k suspicious_activity
|
||||||
|
|
||||||
|
# Command execution
|
||||||
|
-a always,exit -F arch=b64 -S execve -k exec
|
||||||
|
-a always,exit -F arch=b32 -S execve -k exec
|
||||||
|
|
||||||
|
# Privilege escalation
|
||||||
|
-a always,exit -F arch=b64 -S setuid -S setgid -k privilege_escalation
|
||||||
|
-a always,exit -F arch=b32 -S setuid -S setgid -k privilege_escalation
|
||||||
|
EOF
|
||||||
|
|
||||||
|
log_message "SUCCESS" "Audit rules created at $audit_rules"
|
||||||
|
|
||||||
|
# Restart auditd service
|
||||||
|
log_message "INFO" "Restarting auditd service"
|
||||||
|
service auditd restart
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
log_message "SUCCESS" "auditd service restarted successfully"
|
||||||
|
else
|
||||||
|
log_message "ERROR" "Failed to restart auditd service"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main execution for auditing
|
||||||
|
configure_auditd
|
||||||
|
|
||||||
|
log_message "SUCCESS" "System auditing configuration completed"
|
142
test/modules/auto_updates.sh
Normal file
142
test/modules/auto_updates.sh
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# =============================================================================
|
||||||
|
# Automatic updates configuration module
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# Set script directory
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
# Source common functions and variables
|
||||||
|
source "./common.sh"
|
||||||
|
|
||||||
|
# Function to configure unattended-upgrades
|
||||||
|
configure_auto_updates() {
|
||||||
|
log_message "INFO" "Configuring automatic security updates"
|
||||||
|
|
||||||
|
# Install unattended-upgrades if not already installed
|
||||||
|
if ! is_package_installed "unattended-upgrades"; then
|
||||||
|
log_message "INFO" "Installing unattended-upgrades"
|
||||||
|
apt-get install -y unattended-upgrades apt-listchanges
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
log_message "ERROR" "Failed to install unattended-upgrades"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log_message "INFO" "unattended-upgrades is already installed"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Configure unattended-upgrades
|
||||||
|
local unattended_conf="/etc/apt/apt.conf.d/50unattended-upgrades"
|
||||||
|
|
||||||
|
log_message "INFO" "Creating unattended-upgrades configuration"
|
||||||
|
backup_file "$unattended_conf"
|
||||||
|
|
||||||
|
cat > "$unattended_conf" << EOF
|
||||||
|
// Unattended-Upgrades configuration
|
||||||
|
// Generated by security hardening script
|
||||||
|
|
||||||
|
// Automatically upgrade packages from these (origin:archive) pairs
|
||||||
|
Unattended-Upgrade::Allowed-Origins {
|
||||||
|
"\${distro_id}:\${distro_codename}";
|
||||||
|
"\${distro_id}:\${distro_codename}-security";
|
||||||
|
"\${distro_id}ESMApps:\${distro_codename}-apps-security";
|
||||||
|
"\${distro_id}ESM:\${distro_codename}-infra-security";
|
||||||
|
"\${distro_id}:\${distro_codename}-updates";
|
||||||
|
};
|
||||||
|
|
||||||
|
// Package blacklist - packages that should never be automatically upgraded
|
||||||
|
Unattended-Upgrade::Package-Blacklist {
|
||||||
|
// "vim";
|
||||||
|
// "libc6";
|
||||||
|
// "libc6-dev";
|
||||||
|
// "libc6-i686";
|
||||||
|
};
|
||||||
|
|
||||||
|
// Split the upgrade into smaller chunks to minimize downtime
|
||||||
|
Unattended-Upgrade::MinimalSteps "true";
|
||||||
|
|
||||||
|
// Install security updates automatically
|
||||||
|
Unattended-Upgrade::DevRelease "false";
|
||||||
|
|
||||||
|
// Automatically reboot if necessary
|
||||||
|
Unattended-Upgrade::Automatic-Reboot "true";
|
||||||
|
|
||||||
|
// Reboot time
|
||||||
|
Unattended-Upgrade::Automatic-Reboot-Time "02:00";
|
||||||
|
|
||||||
|
// Send email notifications if available
|
||||||
|
Unattended-Upgrade::Mail "";
|
||||||
|
|
||||||
|
// Only send mail on errors
|
||||||
|
Unattended-Upgrade::MailOnlyOnError "true";
|
||||||
|
|
||||||
|
// Remove unused kernel packages
|
||||||
|
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
|
||||||
|
|
||||||
|
// Remove unused dependencies
|
||||||
|
Unattended-Upgrade::Remove-Unused-Dependencies "true";
|
||||||
|
|
||||||
|
// Verbose logging
|
||||||
|
Unattended-Upgrade::Verbose "true";
|
||||||
|
|
||||||
|
// Enable automatic updates
|
||||||
|
APT::Periodic::Update-Package-Lists "1";
|
||||||
|
APT::Periodic::Download-Upgradeable-Packages "1";
|
||||||
|
APT::Periodic::AutocleanInterval "7";
|
||||||
|
APT::Periodic::Unattended-Upgrade "1";
|
||||||
|
EOF
|
||||||
|
|
||||||
|
log_message "SUCCESS" "unattended-upgrades configuration created at $unattended_conf"
|
||||||
|
|
||||||
|
# Create a configuration file to enable automatic updates
|
||||||
|
local auto_upgrades="/etc/apt/apt.conf.d/20auto-upgrades"
|
||||||
|
|
||||||
|
log_message "INFO" "Creating auto-upgrades configuration"
|
||||||
|
|
||||||
|
cat > "$auto_upgrades" << EOF
|
||||||
|
// Auto-upgrade configuration
|
||||||
|
// Generated by security hardening script
|
||||||
|
|
||||||
|
APT::Periodic::Update-Package-Lists "1";
|
||||||
|
APT::Periodic::Download-Upgradeable-Packages "1";
|
||||||
|
APT::Periodic::AutocleanInterval "7";
|
||||||
|
APT::Periodic::Unattended-Upgrade "1";
|
||||||
|
EOF
|
||||||
|
|
||||||
|
log_message "SUCCESS" "auto-upgrades configuration created at $auto_upgrades"
|
||||||
|
|
||||||
|
# Configure apt-listchanges
|
||||||
|
local listchanges_conf="/etc/apt/listchanges.conf"
|
||||||
|
|
||||||
|
log_message "INFO" "Creating apt-listchanges configuration"
|
||||||
|
backup_file "$listchanges_conf"
|
||||||
|
|
||||||
|
cat > "$listchanges_conf" << EOF
|
||||||
|
[apt]
|
||||||
|
frontend=pager
|
||||||
|
email_address=root
|
||||||
|
confirm=0
|
||||||
|
save_seen=/var/lib/apt/listchanges.db
|
||||||
|
which=both
|
||||||
|
EOF
|
||||||
|
|
||||||
|
log_message "SUCCESS" "apt-listchanges configuration created at $listchanges_conf"
|
||||||
|
|
||||||
|
# Enable and start unattended-upgrades service
|
||||||
|
log_message "INFO" "Enabling unattended-upgrades service"
|
||||||
|
systemctl enable unattended-upgrades
|
||||||
|
systemctl restart unattended-upgrades
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
log_message "SUCCESS" "unattended-upgrades service enabled and restarted successfully"
|
||||||
|
else
|
||||||
|
log_message "ERROR" "Failed to enable or restart unattended-upgrades service"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main execution for automatic updates
|
||||||
|
configure_auto_updates
|
||||||
|
|
||||||
|
log_message "SUCCESS" "Automatic updates configuration completed"
|
245
test/modules/custom_prompt.sh
Normal file
245
test/modules/custom_prompt.sh
Normal file
@ -0,0 +1,245 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# =============================================================================
|
||||||
|
# Custom prompt configuration module
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# Set script directory
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
# Source common functions and variables
|
||||||
|
source "./common.sh"
|
||||||
|
|
||||||
|
# Function to configure custom banner
|
||||||
|
configure_custom_banner() {
|
||||||
|
log_message "INFO" "Configuring custom banner"
|
||||||
|
|
||||||
|
# Create custom banner file
|
||||||
|
local banner_file="/etc/banner"
|
||||||
|
|
||||||
|
log_message "INFO" "Creating custom banner file"
|
||||||
|
|
||||||
|
cat > "$banner_file" << 'EOF'
|
||||||
|
|
||||||
|
_______ _ ____ __ __ __ _
|
||||||
|
|__ __(_) / __ \ / _| | \/ (_)
|
||||||
|
| | _ _ __ ___ ___| | | | |_ ___| \ / |_ _ __ ___
|
||||||
|
| | | | '_ \/ __|___| | | | _|___| |\/| | | '_ \ / _ \
|
||||||
|
| | | | |_) \__ \ | |__| | | | | | | | | | | __/
|
||||||
|
|_| |_| .__/|___/ \____/|_| |_| |_|_|_| |_|\___|
|
||||||
|
| |
|
||||||
|
|_|
|
||||||
|
|
||||||
|
AVERTISSEMENT : L'accès à ce système est réservé aux utilisateurs
|
||||||
|
dûment autorisés.
|
||||||
|
|
||||||
|
Toute tentative d'accès, d'accès à ce système sans autorisation ou
|
||||||
|
de maintien frauduleux dans ce système fera l'objet de poursuites
|
||||||
|
conformément à la politique de Tips-Of-Mine.
|
||||||
|
|
||||||
|
Tout utilisateur autorisé est informé et reconnaît que ses actions
|
||||||
|
peuvent être enregistrées, conservées et auditées conformément aux
|
||||||
|
chartes/politiques internes de aux chartes/politiques internes de
|
||||||
|
Tips-Of-Mine.
|
||||||
|
EOF
|
||||||
|
|
||||||
|
chmod +x "$banner_file"
|
||||||
|
|
||||||
|
local file="/etc/ssh/sshd_config"
|
||||||
|
local line=`grep -n "#Banner none" $file | cut -d ":" -f 1`
|
||||||
|
|
||||||
|
#echo $line
|
||||||
|
|
||||||
|
# Vérification de la présence de la ligne AuthorizedKeysFile
|
||||||
|
if [ -z "$line" ]; then
|
||||||
|
echo "#Banner none" | tee -a $file
|
||||||
|
else
|
||||||
|
sed -i ''$line'c\Banner /etc/banner' $file > /dev/null || handle_error "Échec de "
|
||||||
|
fi
|
||||||
|
|
||||||
|
#
|
||||||
|
line=`grep -n "#Banner none" $file | cut -d ":" -f 1` || handle_error "Échec de "
|
||||||
|
|
||||||
|
log_message "SUCCESS" "Custom banner file created at $banner_file"
|
||||||
|
|
||||||
|
# Source the prompt file to apply immediately
|
||||||
|
source "$banner_file"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to configure custom profile
|
||||||
|
configure_custom_profile() {
|
||||||
|
log_message "INFO" "Configuring custom profile"
|
||||||
|
|
||||||
|
# Create custom profile file
|
||||||
|
local profile_file="/etc/profile.d/custom-profile.sh"
|
||||||
|
|
||||||
|
log_message "INFO" "Creating custom profile file"
|
||||||
|
|
||||||
|
cat > "$profile_file" << 'EOF'
|
||||||
|
#!/bin/bash
|
||||||
|
# Custom secure server profile
|
||||||
|
# Generated by security hardening script
|
||||||
|
|
||||||
|
# Check if the terminal supports colors
|
||||||
|
if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
|
||||||
|
# Color definitions
|
||||||
|
BLUE="\[\033[01;34m\]"
|
||||||
|
GREEN="\[\033[01;32m\]"
|
||||||
|
RED="\[\033[01;31m\]"
|
||||||
|
YELLOW="\[\033[01;33m\]"
|
||||||
|
PURPLE="\[\033[01;35m\]"
|
||||||
|
CYAN="\[\033[01;36m\]"
|
||||||
|
WHITE="\[\033[01;37m\]"
|
||||||
|
RESET="\[\033[00m\]"
|
||||||
|
BOLD="\[\033[01m\]"
|
||||||
|
|
||||||
|
# Get server IP
|
||||||
|
SERVER_IP=$(hostname -I | awk '{print $1}')
|
||||||
|
|
||||||
|
# Define symbols based on privilege
|
||||||
|
if [ "$(id -u)" -eq 0 ]; then
|
||||||
|
# Root user - red prompt
|
||||||
|
USER_COLOR=$RED
|
||||||
|
PROMPT_SYMBOL="#"
|
||||||
|
else
|
||||||
|
# Regular user - green prompt
|
||||||
|
USER_COLOR=$GREEN
|
||||||
|
PROMPT_SYMBOL="$"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set the prompt
|
||||||
|
PS1="${BOLD}[${USER_COLOR}\u${RESET}${BOLD}@${CYAN}\h${RESET}${BOLD} ${YELLOW}\w${RESET}${BOLD}]${RESET}\\n${USER_COLOR}${PROMPT_SYMBOL}${RESET} "
|
||||||
|
|
||||||
|
# Show additional security information for root users
|
||||||
|
if [ "$(id -u)" -eq 0 ]; then
|
||||||
|
# Display system information
|
||||||
|
echo -e "\n${RED}ATTENTION: ROOT LOGIN${RESET}"
|
||||||
|
echo -e "${YELLOW}System Info:${RESET}"
|
||||||
|
echo -e " ${CYAN}Hostname:${RESET} $(hostname)"
|
||||||
|
echo -e " ${CYAN}IP Address:${RESET} ${SERVER_IP}"
|
||||||
|
echo -e " ${CYAN}Kernel:${RESET} $(uname -r)"
|
||||||
|
echo -e " ${CYAN}Uptime:${RESET} $(uptime -p | sed 's/up //')"
|
||||||
|
echo -e " ${CYAN}Load:${RESET} $(cat /proc/loadavg | awk '{print $1 ", " $2 ", " $3}')"
|
||||||
|
|
||||||
|
# Show recent failed login attempts
|
||||||
|
FAILED_LOGINS=$(grep "Failed password" /var/log/auth.log | tail -5)
|
||||||
|
if [ ! -z "$FAILED_LOGINS" ]; then
|
||||||
|
echo -e "\n${YELLOW}Recent Failed Login Attempts:${RESET}"
|
||||||
|
echo -e "${RED}$(grep "Failed password" /var/log/auth.log | tail -5)${RESET}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "\n${RED}THIS IS A SECURED SERVER - ALL ACTIONS ARE LOGGED${RESET}\n"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# Simple prompt for terminals without color support
|
||||||
|
PS1="[\u@\h \W]\\$ "
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set some useful aliases
|
||||||
|
alias ll='ls -la'
|
||||||
|
alias l='ls -l'
|
||||||
|
alias rm='rm -i'
|
||||||
|
alias cp='cp -i'
|
||||||
|
alias mv='mv -i'
|
||||||
|
alias grep='grep --color=auto'
|
||||||
|
EOF
|
||||||
|
|
||||||
|
chmod +x "$profile_file"
|
||||||
|
|
||||||
|
log_message "SUCCESS" "Custom profile file created at $profile_file"
|
||||||
|
|
||||||
|
# Source the profile file to apply immediately
|
||||||
|
source "$profile_file"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to configure custom prompt
|
||||||
|
configure_custom_prompt() {
|
||||||
|
log_message "INFO" "Configuring custom prompt"
|
||||||
|
|
||||||
|
# Create custom prompt file
|
||||||
|
local prompt_file="/etc/update-motd.d/00-basic"
|
||||||
|
|
||||||
|
log_message "INFO" "Creating custom prompt file"
|
||||||
|
|
||||||
|
cat > "$prompt_file" << 'EOF'
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# get load averages
|
||||||
|
IFS=" " read LOAD1 LOAD5 LOAD15 <<<$(awk '{ print $1,$2,$3 }' /proc/loadavg)
|
||||||
|
# get free memory
|
||||||
|
IFS=" " read USED AVAIL TOTAL <<<$(free -htm | awk '/Mem/ { print $3,$7,$2 }')
|
||||||
|
# get processes
|
||||||
|
PROCESS=$(ps -eo user=|sort|uniq -c | awk '{ print $2 " " $1 }')
|
||||||
|
PROCESS_ALL=$(echo "$PROCESS"| awk {'print $2'} | awk '{ SUM += $1} END { print SUM }')
|
||||||
|
PROCESS_ROOT=$(echo "$PROCESS" | awk '/root/ { print $2}')
|
||||||
|
PROCESS_USER=$(echo "$PROCESS" | awk '!/root/ { SUM += $2} END { print SUM }')
|
||||||
|
# get processors
|
||||||
|
PROCESSOR_NAME=$(awk -F": " '/model name/ { print $2 }' /proc/cpuinfo | head -1)
|
||||||
|
PROCESSOR_COUNT=$(grep -ioPc 'processor\t:' /proc/cpuinfo)
|
||||||
|
|
||||||
|
# colors
|
||||||
|
W="\e[0;39m"
|
||||||
|
G="\e[1;32m"
|
||||||
|
R="\e[1;31m"
|
||||||
|
dim="\e[2m"
|
||||||
|
undim="\e[0m"
|
||||||
|
|
||||||
|
echo -e "${W}System info:
|
||||||
|
$W Hostname$dim····$undim: $W${HOSTNAME}
|
||||||
|
$W Distro$dim······$undim: $W$(grep "PRETTY_NAME" /etc/*release | cut -d "=" -f 2- | sed 's/"//g')
|
||||||
|
$W Kernel$dim······$undim: $W$(uname -sr)
|
||||||
|
$W Uptime$dim······$undim: $W$(uptime -p)
|
||||||
|
$W Load$dim········$undim: $G$LOAD1$W (1m), $G$LOAD5$W (5m), $G$LOAD15$W (15m)
|
||||||
|
$W Processes$dim···$undim: $G$PROCESS_ROOT$W (root), $G$PROCESS_USER$W (user), $G$PROCESS_ALL$W (total)
|
||||||
|
$W CPU$dim·········$undim: $W$PROCESSOR_NAME ($G$PROCESSOR_COUNT$W vCPU)
|
||||||
|
$W Memory$dim······$undim: $G$USED$W used, $G$AVAIL$W avail, $G$TOTAL$W total"
|
||||||
|
|
||||||
|
# config
|
||||||
|
max_usage=90
|
||||||
|
bar_width=50
|
||||||
|
|
||||||
|
# disk usage: ignore zfs, squashfs & tmpfs
|
||||||
|
printf "\nDisk usage:\n"
|
||||||
|
|
||||||
|
while read line; do
|
||||||
|
# get disk usage
|
||||||
|
usage=$(echo "$line" | awk '{print $2}' | sed 's/%//')
|
||||||
|
used_width=$((($usage*$bar_width)/100))
|
||||||
|
# color is green if usage < max_usage, else red
|
||||||
|
if [ "${usage}" -ge "${max_usage}" ]; then
|
||||||
|
color=$R
|
||||||
|
else
|
||||||
|
color=$G
|
||||||
|
fi
|
||||||
|
# print green/red bar until used_width
|
||||||
|
bar="[${color}"
|
||||||
|
for ((i=0; i<$used_width; i++)); do
|
||||||
|
bar+="="
|
||||||
|
done
|
||||||
|
# print dimmmed bar until end
|
||||||
|
bar+="${W}${dim}"
|
||||||
|
for ((i=$used_width; i<$bar_width; i++)); do
|
||||||
|
bar+="·"
|
||||||
|
done
|
||||||
|
bar+="${undim}]"
|
||||||
|
# print usage line & bar
|
||||||
|
echo "${line}" | awk '{ printf("%-31s%+3s used out of %+4s\n", $1, $2, $3); }' | sed -e 's/^/ /'
|
||||||
|
echo -e "${bar}" | sed -e 's/^/ /'
|
||||||
|
done < <(df -H -x zfs -x squashfs -x tmpfs -x devtmpfs -x overlay -x nfs -x nfs4 -x cifs --output=target,pcent,size | tail -n+2)
|
||||||
|
|
||||||
|
printf "\n"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
chmod +x "$prompt_file"
|
||||||
|
|
||||||
|
log_message "SUCCESS" "Custom prompt file created at $prompt_file"
|
||||||
|
|
||||||
|
# Source the prompt file to apply immediately
|
||||||
|
source "$prompt_file"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main execution for custom prompt
|
||||||
|
configure_custom_banner
|
||||||
|
configure_custom_profile
|
||||||
|
configure_custom_prompt
|
||||||
|
|
||||||
|
log_message "SUCCESS" "Custom prompt configuration completed"
|
76
test/modules/dns_config.sh
Normal file
76
test/modules/dns_config.sh
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# =============================================================================
|
||||||
|
# DNS configuration module
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# Set script directory
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
# Source common functions and variables
|
||||||
|
source "./common.sh"
|
||||||
|
|
||||||
|
# Function to configure DNS settings
|
||||||
|
configure_dns() {
|
||||||
|
log_message "INFO" "Configuring DNS settings"
|
||||||
|
|
||||||
|
# Backup current resolv.conf
|
||||||
|
backup_file "/etc/resolv.conf"
|
||||||
|
|
||||||
|
# Create systemd-resolved configuration
|
||||||
|
local resolved_conf="/etc/systemd/resolved.conf"
|
||||||
|
|
||||||
|
log_message "INFO" "Creating systemd-resolved configuration"
|
||||||
|
backup_file "$resolved_conf"
|
||||||
|
|
||||||
|
cat > "$resolved_conf" << EOF
|
||||||
|
[Resolve]
|
||||||
|
# Google and Cloudflare DNS servers
|
||||||
|
DNS=8.8.8.8 8.8.4.4 1.1.1.1 1.0.0.1
|
||||||
|
# Use DNS over TLS if possible
|
||||||
|
DNSOverTLS=opportunistic
|
||||||
|
# Default search domains
|
||||||
|
Domains=
|
||||||
|
# Fallback DNS
|
||||||
|
FallbackDNS=9.9.9.9 149.112.112.112
|
||||||
|
# Cache DNS responses
|
||||||
|
Cache=yes
|
||||||
|
# Try IPv4 first, then IPv6
|
||||||
|
DNSStubListener=yes
|
||||||
|
ReadEtcHosts=yes
|
||||||
|
EOF
|
||||||
|
|
||||||
|
log_message "SUCCESS" "systemd-resolved configuration created at $resolved_conf"
|
||||||
|
|
||||||
|
# Restart systemd-resolved service
|
||||||
|
if systemctl is-active systemd-resolved >/dev/null 2>&1; then
|
||||||
|
log_message "INFO" "Restarting systemd-resolved service"
|
||||||
|
systemctl restart systemd-resolved
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
log_message "SUCCESS" "systemd-resolved service restarted successfully"
|
||||||
|
else
|
||||||
|
log_message "ERROR" "Failed to restart systemd-resolved service"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# If systemd-resolved is not active, create a static resolv.conf
|
||||||
|
log_message "INFO" "systemd-resolved not active, creating static resolv.conf"
|
||||||
|
|
||||||
|
cat > "/etc/resolv.conf" << EOF
|
||||||
|
# DNS configuration
|
||||||
|
# Generated by security hardening script
|
||||||
|
|
||||||
|
nameserver 8.8.8.8
|
||||||
|
nameserver 1.1.1.1
|
||||||
|
nameserver 8.8.4.4
|
||||||
|
nameserver 1.0.0.1
|
||||||
|
options edns0 timeout:2 rotate
|
||||||
|
EOF
|
||||||
|
|
||||||
|
log_message "SUCCESS" "Static resolv.conf created"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main execution for DNS configuration
|
||||||
|
configure_dns
|
||||||
|
|
||||||
|
log_message "SUCCESS" "DNS configuration completed"
|
96
test/modules/fail2ban.sh
Normal file
96
test/modules/fail2ban.sh
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# =============================================================================
|
||||||
|
# Fail2ban configuration module
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# Set script directory
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
# Source common functions and variables
|
||||||
|
source "./common.sh"
|
||||||
|
|
||||||
|
# Function to install and configure fail2ban
|
||||||
|
configure_fail2ban() {
|
||||||
|
log_message "INFO" "Installing fail2ban"
|
||||||
|
|
||||||
|
# Install fail2ban if not already installed
|
||||||
|
if ! is_package_installed "fail2ban"; then
|
||||||
|
apt-get install -y fail2ban
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
log_message "ERROR" "Failed to install fail2ban"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log_message "INFO" "fail2ban is already installed"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create fail2ban local configuration
|
||||||
|
local fail2ban_local="/etc/fail2ban/jail.local"
|
||||||
|
|
||||||
|
log_message "INFO" "Creating fail2ban configuration"
|
||||||
|
backup_file "$fail2ban_local"
|
||||||
|
|
||||||
|
cat > "$fail2ban_local" << EOF
|
||||||
|
[DEFAULT]
|
||||||
|
# Ban hosts for 1 hour
|
||||||
|
bantime = 3600
|
||||||
|
# Check for new failed login attempts every 10 minutes
|
||||||
|
findtime = 600
|
||||||
|
# Ban after 5 failures
|
||||||
|
maxretry = 5
|
||||||
|
# Use both iptables and nftables (if available)
|
||||||
|
banaction = iptables-multiport
|
||||||
|
banaction_allports = iptables-allports
|
||||||
|
|
||||||
|
# Email notifications (uncomment and configure to enable)
|
||||||
|
# mta = mail
|
||||||
|
# sender = fail2ban@example.com
|
||||||
|
# destemail = admin@example.com
|
||||||
|
# action = %(action_mwl)s
|
||||||
|
|
||||||
|
# SSH jail configuration (custom port)
|
||||||
|
[sshd]
|
||||||
|
enabled = true
|
||||||
|
port = 2222
|
||||||
|
filter = sshd
|
||||||
|
logpath = /var/log/auth.log
|
||||||
|
maxretry = 3
|
||||||
|
bantime = 86400
|
||||||
|
|
||||||
|
# HTTP jail
|
||||||
|
[apache-auth]
|
||||||
|
enabled = true
|
||||||
|
port = http,https
|
||||||
|
filter = apache-auth
|
||||||
|
logpath = /var/log/apache2/error.log
|
||||||
|
maxretry = 3
|
||||||
|
|
||||||
|
# NGINX jail
|
||||||
|
[nginx-http-auth]
|
||||||
|
enabled = true
|
||||||
|
port = http,https
|
||||||
|
filter = nginx-http-auth
|
||||||
|
logpath = /var/log/nginx/error.log
|
||||||
|
maxretry = 3
|
||||||
|
EOF
|
||||||
|
|
||||||
|
log_message "SUCCESS" "fail2ban configuration created at $fail2ban_local"
|
||||||
|
|
||||||
|
# Restart fail2ban service
|
||||||
|
log_message "INFO" "Restarting fail2ban service"
|
||||||
|
systemctl enable fail2ban
|
||||||
|
systemctl restart fail2ban
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
log_message "SUCCESS" "fail2ban service restarted successfully"
|
||||||
|
else
|
||||||
|
log_message "ERROR" "Failed to restart fail2ban service"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main execution for fail2ban
|
||||||
|
configure_fail2ban
|
||||||
|
|
||||||
|
log_message "SUCCESS" "fail2ban configuration completed"
|
72
test/modules/firewall.sh
Normal file
72
test/modules/firewall.sh
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# =============================================================================
|
||||||
|
# Firewall configuration module
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# Set script directory
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
# Source common functions and variables
|
||||||
|
source "./common.sh"
|
||||||
|
|
||||||
|
# Function to configure UFW
|
||||||
|
configure_ufw() {
|
||||||
|
log_message "INFO" "Configuring UFW firewall"
|
||||||
|
|
||||||
|
# Check if UFW is installed
|
||||||
|
if ! command_exists ufw; then
|
||||||
|
log_message "INFO" "Installing UFW"
|
||||||
|
apt-get install -y ufw
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
log_message "ERROR" "Failed to install UFW"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Reset UFW to default settings
|
||||||
|
log_message "INFO" "Resetting UFW to default settings"
|
||||||
|
ufw --force reset
|
||||||
|
|
||||||
|
# Set default policies
|
||||||
|
log_message "INFO" "Setting default UFW policies"
|
||||||
|
ufw default deny incoming
|
||||||
|
ufw default allow outgoing
|
||||||
|
|
||||||
|
# Allow SSH on custom port
|
||||||
|
log_message "INFO" "Allowing SSH on port 2222"
|
||||||
|
ufw allow 2222/tcp
|
||||||
|
|
||||||
|
# Allow HTTP/HTTPS for web services if needed
|
||||||
|
log_message "INFO" "Allowing HTTP/HTTPS ports"
|
||||||
|
ufw allow 80/tcp
|
||||||
|
ufw allow 443/tcp
|
||||||
|
|
||||||
|
# Allow SNMP for monitoring
|
||||||
|
log_message "INFO" "Allowing SNMP port for monitoring"
|
||||||
|
ufw allow 161/udp
|
||||||
|
|
||||||
|
# Allow NRPE for monitoring
|
||||||
|
log_message "INFO" "Allowing NRPE port for monitoring"
|
||||||
|
ufw allow 5666/tcp
|
||||||
|
|
||||||
|
# Enable UFW
|
||||||
|
log_message "INFO" "Enabling UFW"
|
||||||
|
echo "y" | ufw enable
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
log_message "SUCCESS" "UFW enabled successfully"
|
||||||
|
else
|
||||||
|
log_message "ERROR" "Failed to enable UFW"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Show UFW status
|
||||||
|
log_message "INFO" "UFW status:"
|
||||||
|
ufw status verbose
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main execution for firewall
|
||||||
|
configure_ufw
|
||||||
|
|
||||||
|
log_message "SUCCESS" "Firewall configuration completed"
|
155
test/modules/glpi_agent.sh
Normal file
155
test/modules/glpi_agent.sh
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# =============================================================================
|
||||||
|
# GLPI agent installation module
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# Set script directory
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
# Source common functions and variables
|
||||||
|
source "./common.sh"
|
||||||
|
|
||||||
|
# Function to install GLPI agent
|
||||||
|
install_glpi_agent() {
|
||||||
|
log_message "INFO" "Installing GLPI agent"
|
||||||
|
|
||||||
|
# Check if GLPI agent is already installed
|
||||||
|
if command_exists glpi-agent; then
|
||||||
|
log_message "INFO" "GLPI agent is already installed"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
log_message "INFO" "Installing dependencies for GLPI agent"
|
||||||
|
apt-get install -y dmidecode hwdata ucf hdparm perl libuniversal-require-perl \
|
||||||
|
libxml-treepp-perl libyaml-perl libnet-cups-perl libnet-ip-perl libwww-perl \
|
||||||
|
libparse-edid-perl libproc-daemon-perl libfile-which-perl libhttp-daemon-perl \
|
||||||
|
libio-socket-ssl-perl libnet-snmp-perl libcrypt-des-perl libnet-nbname-perl \
|
||||||
|
libdigest-hmac-perl libfusioninventory-agent-task-network-perl
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
log_message "ERROR" "Failed to install dependencies for GLPI agent"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Determine the latest GLPI agent version and download URL for Debian/Ubuntu
|
||||||
|
log_message "INFO" "Determining latest GLPI agent version"
|
||||||
|
|
||||||
|
# Determine system architecture
|
||||||
|
ARCH=$(dpkg --print-architecture)
|
||||||
|
|
||||||
|
# Prepare GLPI agent installation
|
||||||
|
TEMP_DIR=$(mktemp -d)
|
||||||
|
cd "$TEMP_DIR" || return 1
|
||||||
|
|
||||||
|
# Download the latest GLPI agent package
|
||||||
|
if [ "$ARCH" = "amd64" ]; then
|
||||||
|
DOWNLOAD_URL="https://github.com/glpi-project/glpi-agent/releases/download/1.4/glpi-agent_1.4-1_all.deb"
|
||||||
|
else
|
||||||
|
DOWNLOAD_URL="https://github.com/glpi-project/glpi-agent/releases/download/1.4/glpi-agent_1.4-1_all.deb"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_message "INFO" "Downloading GLPI agent from $DOWNLOAD_URL"
|
||||||
|
wget "$DOWNLOAD_URL" -O glpi-agent.deb
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
log_message "ERROR" "Failed to download GLPI agent"
|
||||||
|
rm -rf "$TEMP_DIR"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Install the GLPI agent package
|
||||||
|
log_message "INFO" "Installing GLPI agent package"
|
||||||
|
dpkg -i glpi-agent.deb
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
log_message "ERROR" "Failed to install GLPI agent package"
|
||||||
|
apt-get install -f -y # Try to fix broken dependencies
|
||||||
|
dpkg -i glpi-agent.deb
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
log_message "ERROR" "Failed to install GLPI agent package after fixing dependencies"
|
||||||
|
rm -rf "$TEMP_DIR"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Cleanup
|
||||||
|
cd - > /dev/null
|
||||||
|
rm -rf "$TEMP_DIR"
|
||||||
|
|
||||||
|
# Configure GLPI agent
|
||||||
|
log_message "INFO" "Configuring GLPI agent"
|
||||||
|
|
||||||
|
local glpi_conf="/etc/glpi-agent/agent.cfg"
|
||||||
|
|
||||||
|
# Backup existing configuration if it exists
|
||||||
|
if [ -f "$glpi_conf" ]; then
|
||||||
|
backup_file "$glpi_conf"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create configuration file
|
||||||
|
cat > "$glpi_conf" << EOF
|
||||||
|
# GLPI Agent Configuration
|
||||||
|
# Generated by security hardening script
|
||||||
|
|
||||||
|
# Server URL - Replace with your actual GLPI server URL
|
||||||
|
server = http://glpi-server/glpi/api/inventory
|
||||||
|
# Disable SSL certificate validation for testing (set to 1 for production)
|
||||||
|
no-ssl-check = 0
|
||||||
|
# Run as daemon (0 = no, 1 = yes)
|
||||||
|
daemon = 1
|
||||||
|
# Logger configuration
|
||||||
|
logger = File
|
||||||
|
logfile = /var/log/glpi-agent/glpi-agent.log
|
||||||
|
# Scan local network
|
||||||
|
scan-homedirs = 0
|
||||||
|
scan-profiles = 0
|
||||||
|
# Inventory frequency (in hours)
|
||||||
|
delaytime = 24
|
||||||
|
# Tag for the agent
|
||||||
|
tag = SecuredServer
|
||||||
|
EOF
|
||||||
|
|
||||||
|
log_message "SUCCESS" "GLPI agent configuration created at $glpi_conf"
|
||||||
|
|
||||||
|
# Create GLPI agent systemd service if not already created by package
|
||||||
|
if [ ! -f "/etc/systemd/system/glpi-agent.service" ]; then
|
||||||
|
log_message "INFO" "Creating GLPI agent service"
|
||||||
|
|
||||||
|
cat > "/etc/systemd/system/glpi-agent.service" << EOF
|
||||||
|
[Unit]
|
||||||
|
Description=GLPI Agent
|
||||||
|
Documentation=https://glpi-agent.readthedocs.io/
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
ExecStart=/usr/bin/glpi-agent --daemon
|
||||||
|
Restart=always
|
||||||
|
RestartSec=60
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
|
||||||
|
log_message "SUCCESS" "GLPI agent service created"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Enable and start GLPI agent service
|
||||||
|
log_message "INFO" "Enabling and starting GLPI agent service"
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl enable glpi-agent
|
||||||
|
systemctl restart glpi-agent
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
log_message "SUCCESS" "GLPI agent service enabled and started"
|
||||||
|
else
|
||||||
|
log_message "ERROR" "Failed to enable or start GLPI agent service"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main execution for GLPI agent
|
||||||
|
install_glpi_agent
|
||||||
|
|
||||||
|
log_message "SUCCESS" "GLPI agent installation completed"
|
297
test/modules/monitoring.sh
Normal file
297
test/modules/monitoring.sh
Normal file
@ -0,0 +1,297 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# =============================================================================
|
||||||
|
# Monitoring configuration module (SNMP and NRPE)
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# Set script directory
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
# Source common functions and variables
|
||||||
|
source "./common.sh"
|
||||||
|
|
||||||
|
# Function to configure SNMP
|
||||||
|
configure_snmp() {
|
||||||
|
log_message "INFO" "Configuring SNMP monitoring"
|
||||||
|
|
||||||
|
# Install SNMP if not already installed
|
||||||
|
if ! is_package_installed "snmpd"; then
|
||||||
|
log_message "INFO" "Installing SNMP"
|
||||||
|
apt-get install -y snmpd snmp
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
log_message "ERROR" "Failed to install SNMP"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log_message "INFO" "SNMP is already installed"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Configure SNMP
|
||||||
|
local snmpd_conf="/etc/snmp/snmpd.conf"
|
||||||
|
|
||||||
|
log_message "INFO" "Creating SNMP configuration"
|
||||||
|
backup_file "$snmpd_conf"
|
||||||
|
|
||||||
|
cat > "$snmpd_conf" << EOF
|
||||||
|
# SNMP Configuration
|
||||||
|
# Generated by security hardening script
|
||||||
|
|
||||||
|
# Listen on localhost and specific network interface
|
||||||
|
agentAddress udp:127.0.0.1:161,udp:161
|
||||||
|
|
||||||
|
# Information about this host
|
||||||
|
sysLocation "Server Room"
|
||||||
|
sysContact admin@example.com
|
||||||
|
sysName $(hostname)
|
||||||
|
sysDescr "Linux $(uname -r) on $(uname -m)"
|
||||||
|
|
||||||
|
# Authentication (replace with your own values)
|
||||||
|
# Format: user_name security_name auth_protocol auth_passphrase priv_protocol priv_passphrase
|
||||||
|
createUser authOnlyUser MD5 "auth_pass_phrase"
|
||||||
|
createUser authPrivUser SHA "auth_pass_phrase" DES "priv_pass_phrase"
|
||||||
|
|
||||||
|
# Grant access to SNMPv3 users
|
||||||
|
rouser authOnlyUser auth
|
||||||
|
rouser authPrivUser priv
|
||||||
|
|
||||||
|
# Views
|
||||||
|
view systemonly included .1.3.6.1.2.1.1
|
||||||
|
view systemonly included .1.3.6.1.2.1.25.1
|
||||||
|
|
||||||
|
# Grant only system information to SNMPv3 users
|
||||||
|
access grpAuthOnlyUser "" usm auth nopriv exact systemonly none none
|
||||||
|
access grpAuthPrivUser "" usm auth priv exact systemonly none none
|
||||||
|
|
||||||
|
# Additional monitoring
|
||||||
|
# Load averages
|
||||||
|
extend load /bin/cat /proc/loadavg
|
||||||
|
# Disk space
|
||||||
|
extend dfspace /bin/df -P
|
||||||
|
|
||||||
|
# Disable older SNMP versions (only allow SNMPv3)
|
||||||
|
disableSnmpv1d yes
|
||||||
|
disableSnmpv2cd yes
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
authtrapenable 1
|
||||||
|
EOF
|
||||||
|
|
||||||
|
log_message "SUCCESS" "SNMP configuration created at $snmpd_conf"
|
||||||
|
|
||||||
|
# Create SNMP client configuration example
|
||||||
|
local snmp_client_conf="/root/snmp-client-example.txt"
|
||||||
|
|
||||||
|
log_message "INFO" "Creating SNMP client configuration example"
|
||||||
|
|
||||||
|
cat > "$snmp_client_conf" << EOF
|
||||||
|
# SNMP Client Configuration Example
|
||||||
|
# Generated by security hardening script
|
||||||
|
|
||||||
|
# Add the following to your SNMP client configuration to connect to this server
|
||||||
|
|
||||||
|
# SNMPv3 with authentication
|
||||||
|
# Replace SERVER_IP with the IP address of this server
|
||||||
|
snmpwalk -v 3 -u authOnlyUser -a MD5 -A "auth_pass_phrase" SERVER_IP
|
||||||
|
|
||||||
|
# SNMPv3 with authentication and privacy
|
||||||
|
# Replace SERVER_IP with the IP address of this server
|
||||||
|
snmpwalk -v 3 -u authPrivUser -a SHA -A "auth_pass_phrase" -x DES -X "priv_pass_phrase" SERVER_IP
|
||||||
|
EOF
|
||||||
|
|
||||||
|
log_message "SUCCESS" "SNMP client configuration example created at $snmp_client_conf"
|
||||||
|
|
||||||
|
# Restart SNMP service
|
||||||
|
log_message "INFO" "Restarting SNMP service"
|
||||||
|
systemctl enable snmpd
|
||||||
|
systemctl restart snmpd
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
log_message "SUCCESS" "SNMP service restarted successfully"
|
||||||
|
else
|
||||||
|
log_message "ERROR" "Failed to restart SNMP service"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to configure NRPE
|
||||||
|
configure_nrpe() {
|
||||||
|
log_message "INFO" "Configuring NRPE monitoring"
|
||||||
|
|
||||||
|
# Install NRPE if not already installed
|
||||||
|
if ! is_package_installed "nagios-nrpe-server"; then
|
||||||
|
log_message "INFO" "Installing NRPE and monitoring plugins"
|
||||||
|
apt-get install -y nagios-nrpe-server nagios-plugins
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
log_message "ERROR" "Failed to install NRPE"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log_message "INFO" "NRPE is already installed"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Configure NRPE
|
||||||
|
local nrpe_conf="/etc/nagios/nrpe.conf"
|
||||||
|
|
||||||
|
log_message "INFO" "Creating NRPE configuration"
|
||||||
|
backup_file "$nrpe_conf"
|
||||||
|
|
||||||
|
cat > "$nrpe_conf" << EOF
|
||||||
|
# NRPE Configuration
|
||||||
|
# Generated by security hardening script
|
||||||
|
|
||||||
|
# Log facility to use
|
||||||
|
log_facility=daemon
|
||||||
|
|
||||||
|
# Log level
|
||||||
|
debug=0
|
||||||
|
|
||||||
|
# Run as this user
|
||||||
|
nrpe_user=nagios
|
||||||
|
nrpe_group=nagios
|
||||||
|
|
||||||
|
# NRPE port
|
||||||
|
server_port=5666
|
||||||
|
|
||||||
|
# NRPE server address (listen on all interfaces)
|
||||||
|
server_address=0.0.0.0
|
||||||
|
|
||||||
|
# Allow connections from these monitoring servers (replace with your Nagios server IP)
|
||||||
|
allowed_hosts=127.0.0.1,NAGIOS_SERVER_IP
|
||||||
|
|
||||||
|
# Connection restrictions
|
||||||
|
dont_blame_nrpe=0
|
||||||
|
allow_bash_command_substitution=0
|
||||||
|
|
||||||
|
# Command timeout
|
||||||
|
command_timeout=60
|
||||||
|
connection_timeout=300
|
||||||
|
|
||||||
|
# SSL/TLS options
|
||||||
|
ssl_version=TLSv1.2+
|
||||||
|
use_ssl=1
|
||||||
|
|
||||||
|
# Command definitions
|
||||||
|
|
||||||
|
# Basic system checks
|
||||||
|
command[check_users]=/usr/lib/nagios/plugins/check_users -w 5 -c 10
|
||||||
|
command[check_load]=/usr/lib/nagios/plugins/check_load -w 15,10,5 -c 30,25,20
|
||||||
|
command[check_disk]=/usr/lib/nagios/plugins/check_disk -w 20% -c 10% -p /
|
||||||
|
command[check_zombie_procs]=/usr/lib/nagios/plugins/check_procs -w 5 -c 10 -s Z
|
||||||
|
command[check_total_procs]=/usr/lib/nagios/plugins/check_procs -w 150 -c 200
|
||||||
|
command[check_mem]=/usr/lib/nagios/plugins/check_mem -w 80 -c 90
|
||||||
|
|
||||||
|
# Network checks
|
||||||
|
command[check_ssh]=/usr/lib/nagios/plugins/check_ssh -p 2222 localhost
|
||||||
|
command[check_http]=/usr/lib/nagios/plugins/check_http localhost
|
||||||
|
command[check_ping]=/usr/lib/nagios/plugins/check_ping -H 8.8.8.8 -w 100.0,20% -c 500.0,60%
|
||||||
|
|
||||||
|
# Service checks
|
||||||
|
command[check_ntp]=/usr/lib/nagios/plugins/check_ntp_time -H pool.ntp.org -w 0.5 -c 1
|
||||||
|
EOF
|
||||||
|
|
||||||
|
log_message "SUCCESS" "NRPE configuration created at $nrpe_conf"
|
||||||
|
|
||||||
|
# Install memory check plugin if it doesn't exist
|
||||||
|
if [ ! -f "/usr/lib/nagios/plugins/check_mem" ]; then
|
||||||
|
log_message "INFO" "Installing memory check plugin for NRPE"
|
||||||
|
|
||||||
|
cat > "/usr/lib/nagios/plugins/check_mem" << 'EOF'
|
||||||
|
#!/bin/bash
|
||||||
|
# Check memory usage plugin for Nagios
|
||||||
|
|
||||||
|
# Defaults
|
||||||
|
WARNING=80
|
||||||
|
CRITICAL=90
|
||||||
|
|
||||||
|
# Process arguments
|
||||||
|
while getopts "w:c:" opt; do
|
||||||
|
case $opt in
|
||||||
|
w) WARNING=$OPTARG ;;
|
||||||
|
c) CRITICAL=$OPTARG ;;
|
||||||
|
*) echo "Usage: $0 -w warning_percent -c critical_percent"; exit 3 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Get memory information
|
||||||
|
MEM_TOTAL=$(free -m | grep "Mem:" | awk '{print $2}')
|
||||||
|
MEM_FREE=$(free -m | grep "Mem:" | awk '{print $4+$6+$7}')
|
||||||
|
MEM_USED=$((MEM_TOTAL - MEM_FREE))
|
||||||
|
MEM_PERCENT=$((MEM_USED * 100 / MEM_TOTAL))
|
||||||
|
|
||||||
|
# Perform check
|
||||||
|
if [ $MEM_PERCENT -ge $CRITICAL ]; then
|
||||||
|
echo "CRITICAL - Memory usage: $MEM_PERCENT% ($MEM_USED MB of $MEM_TOTAL MB) | memory=$MEM_PERCENT%;$WARNING;$CRITICAL;0;100"
|
||||||
|
exit 2
|
||||||
|
elif [ $MEM_PERCENT -ge $WARNING ]; then
|
||||||
|
echo "WARNING - Memory usage: $MEM_PERCENT% ($MEM_USED MB of $MEM_TOTAL MB) | memory=$MEM_PERCENT%;$WARNING;$CRITICAL;0;100"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo "OK - Memory usage: $MEM_PERCENT% ($MEM_USED MB of $MEM_TOTAL MB) | memory=$MEM_PERCENT%;$WARNING;$CRITICAL;0;100"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
EOF
|
||||||
|
|
||||||
|
chmod +x "/usr/lib/nagios/plugins/check_mem"
|
||||||
|
log_message "SUCCESS" "Memory check plugin installed for NRPE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create NRPE setup documentation
|
||||||
|
local nrpe_doc="/root/nrpe-setup-documentation.txt"
|
||||||
|
|
||||||
|
log_message "INFO" "Creating NRPE setup documentation"
|
||||||
|
|
||||||
|
cat > "$nrpe_doc" << EOF
|
||||||
|
# NRPE Setup Documentation
|
||||||
|
# Generated by security hardening script
|
||||||
|
|
||||||
|
To complete the NRPE setup:
|
||||||
|
|
||||||
|
1. Edit the NRPE configuration file: $nrpe_conf
|
||||||
|
- Replace "NAGIOS_SERVER_IP" with the IP address of your Nagios server
|
||||||
|
- Add any additional custom commands you need
|
||||||
|
|
||||||
|
2. Restart the NRPE service:
|
||||||
|
systemctl restart nagios-nrpe-server
|
||||||
|
|
||||||
|
3. On your Nagios server, add this host with commands like:
|
||||||
|
check_nrpe -H SERVER_IP -c check_load
|
||||||
|
check_nrpe -H SERVER_IP -c check_disk
|
||||||
|
check_nrpe -H SERVER_IP -c check_mem
|
||||||
|
|
||||||
|
4. Remember to open port 5666 in the firewall if you need to connect from a remote Nagios server:
|
||||||
|
ufw allow 5666/tcp
|
||||||
|
|
||||||
|
5. Available commands:
|
||||||
|
- check_users: Checks number of logged-in users
|
||||||
|
- check_load: Checks system load
|
||||||
|
- check_disk: Checks disk usage
|
||||||
|
- check_zombie_procs: Checks for zombie processes
|
||||||
|
- check_total_procs: Checks total number of processes
|
||||||
|
- check_mem: Checks memory usage
|
||||||
|
- check_ssh: Checks SSH service
|
||||||
|
- check_http: Checks HTTP service
|
||||||
|
- check_ping: Checks network connectivity
|
||||||
|
- check_ntp: Checks NTP synchronization
|
||||||
|
EOF
|
||||||
|
|
||||||
|
log_message "SUCCESS" "NRPE setup documentation created at $nrpe_doc"
|
||||||
|
|
||||||
|
# Restart NRPE service
|
||||||
|
log_message "INFO" "Restarting NRPE service"
|
||||||
|
systemctl enable nagios-nrpe-server
|
||||||
|
systemctl restart nagios-nrpe-server
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
log_message "SUCCESS" "NRPE service restarted successfully"
|
||||||
|
else
|
||||||
|
log_message "ERROR" "Failed to restart NRPE service"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main execution for monitoring
|
||||||
|
configure_snmp
|
||||||
|
configure_nrpe
|
||||||
|
|
||||||
|
log_message "SUCCESS" "Monitoring configuration completed"
|
103
test/modules/ntp.sh
Normal file
103
test/modules/ntp.sh
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# =============================================================================
|
||||||
|
# NTP configuration module
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# Set script directory
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
# Source common functions and variables
|
||||||
|
source "./common.sh"
|
||||||
|
|
||||||
|
# Function to configure NTP
|
||||||
|
configure_ntp() {
|
||||||
|
log_message "INFO" "Configuring NTP"
|
||||||
|
|
||||||
|
# Install chrony if not already installed
|
||||||
|
if ! is_package_installed "chrony"; then
|
||||||
|
log_message "INFO" "Installing chrony NTP service"
|
||||||
|
apt-get install -y chrony
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
log_message "ERROR" "Failed to install chrony"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log_message "INFO" "chrony is already installed"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Configure chrony
|
||||||
|
local chrony_conf="/etc/chrony/chrony.conf"
|
||||||
|
|
||||||
|
log_message "INFO" "Creating chrony configuration"
|
||||||
|
backup_file "$chrony_conf"
|
||||||
|
|
||||||
|
cat > "$chrony_conf" << EOF
|
||||||
|
# Chrony NTP configuration
|
||||||
|
# Generated by security hardening script
|
||||||
|
|
||||||
|
# Use the NTP pool for time synchronization
|
||||||
|
pool 0.pool.ntp.org iburst
|
||||||
|
pool 1.pool.ntp.org iburst
|
||||||
|
pool 2.pool.ntp.org iburst
|
||||||
|
pool 3.pool.ntp.org iburst
|
||||||
|
|
||||||
|
# Record the rate at which the system clock gains/losses time
|
||||||
|
driftfile /var/lib/chrony/drift
|
||||||
|
|
||||||
|
# Allow the system clock to be stepped in the first three updates
|
||||||
|
makestep 1.0 3
|
||||||
|
|
||||||
|
# Enable kernel synchronization of the real-time clock (RTC)
|
||||||
|
rtcsync
|
||||||
|
|
||||||
|
# Serve time even if not synchronized to a time source
|
||||||
|
local stratum 10
|
||||||
|
|
||||||
|
# Specify file containing NTP authentication keys
|
||||||
|
keyfile /etc/chrony/chrony.keys
|
||||||
|
|
||||||
|
# Specify directory for log files
|
||||||
|
logdir /var/log/chrony
|
||||||
|
|
||||||
|
# Select which information is logged
|
||||||
|
log tracking measurements statistics
|
||||||
|
|
||||||
|
# Security settings
|
||||||
|
# Disable remote control and monitoring
|
||||||
|
cmdport 0
|
||||||
|
|
||||||
|
# Only allow localhost to synchronize with this server
|
||||||
|
allow 127.0.0.1
|
||||||
|
deny all
|
||||||
|
EOF
|
||||||
|
|
||||||
|
log_message "SUCCESS" "chrony configuration created at $chrony_conf"
|
||||||
|
|
||||||
|
# Restart chrony service
|
||||||
|
log_message "INFO" "Restarting chrony service"
|
||||||
|
systemctl enable chrony
|
||||||
|
systemctl restart chrony
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
log_message "SUCCESS" "chrony service restarted successfully"
|
||||||
|
else
|
||||||
|
log_message "ERROR" "Failed to restart chrony service"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set hardware clock to UTC
|
||||||
|
log_message "INFO" "Setting hardware clock to UTC"
|
||||||
|
timedatectl set-local-rtc 0
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
log_message "SUCCESS" "Hardware clock set to UTC"
|
||||||
|
else
|
||||||
|
log_message "ERROR" "Failed to set hardware clock to UTC"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main execution for NTP configuration
|
||||||
|
configure_ntp
|
||||||
|
|
||||||
|
log_message "SUCCESS" "NTP configuration completed"
|
151
test/modules/package_management.sh
Normal file
151
test/modules/package_management.sh
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# =============================================================================
|
||||||
|
# Package management module
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# Set script directory
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
# Source common functions and variables
|
||||||
|
source "./common.sh"
|
||||||
|
|
||||||
|
# Function to configure APT with proxy settings if needed
|
||||||
|
configure_apt_proxy() {
|
||||||
|
local proxy_file="/etc/apt/apt.conf.d/90proxy"
|
||||||
|
local proxy_doc="/root/apt-proxy-documentation.txt"
|
||||||
|
|
||||||
|
log_message "INFO" "Creating APT proxy documentation at $proxy_doc"
|
||||||
|
|
||||||
|
cat > "$proxy_doc" << EOF
|
||||||
|
# APT Proxy Configuration
|
||||||
|
# To configure APT to use a proxy, edit the file /etc/apt/apt.conf.d/90proxy
|
||||||
|
# and add one of the following configurations:
|
||||||
|
|
||||||
|
# HTTP proxy
|
||||||
|
Acquire::http::Proxy "http://username:password@proxy.example.com:8080/";
|
||||||
|
|
||||||
|
# HTTPS proxy
|
||||||
|
Acquire::https::Proxy "http://username:password@proxy.example.com:8080/";
|
||||||
|
|
||||||
|
# For APT to use the system's proxy settings
|
||||||
|
Acquire::http::Proxy "http://${http_proxy}";
|
||||||
|
Acquire::https::Proxy "http://${https_proxy}";
|
||||||
|
|
||||||
|
# To disable proxy for specific hosts
|
||||||
|
Acquire::http::Proxy::hostname.example.com "DIRECT";
|
||||||
|
EOF
|
||||||
|
|
||||||
|
log_message "SUCCESS" "APT proxy documentation created. Edit $proxy_file to configure proxies if needed"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to update package lists and upgrade installed packages
|
||||||
|
update_upgrade_packages() {
|
||||||
|
log_message "INFO" "Updating package lists"
|
||||||
|
apt-get update
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
log_message "SUCCESS" "Package lists updated successfully"
|
||||||
|
else
|
||||||
|
log_message "ERROR" "Failed to update package lists"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_message "INFO" "Upgrading installed packages"
|
||||||
|
apt-get full-upgrade -y
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
log_message "SUCCESS" "Packages upgraded successfully"
|
||||||
|
else
|
||||||
|
log_message "ERROR" "Failed to upgrade packages"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to install essential security packages
|
||||||
|
install_essential_packages() {
|
||||||
|
local packages=(
|
||||||
|
"apt-transport-https"
|
||||||
|
"ca-certificates"
|
||||||
|
"gnupg"
|
||||||
|
"software-properties-common"
|
||||||
|
"curl"
|
||||||
|
"wget"
|
||||||
|
"ufw"
|
||||||
|
"unattended-upgrades"
|
||||||
|
"apt-listchanges"
|
||||||
|
)
|
||||||
|
|
||||||
|
log_message "INFO" "Installing essential security packages"
|
||||||
|
|
||||||
|
for package in "${packages[@]}"; do
|
||||||
|
if ! is_package_installed "$package"; then
|
||||||
|
log_message "INFO" "Installing $package"
|
||||||
|
apt-get install -y "$package"
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
log_message "SUCCESS" "Installed $package successfully"
|
||||||
|
else
|
||||||
|
log_message "ERROR" "Failed to install $package"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log_message "INFO" "$package is already installed"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create a new package installation module
|
||||||
|
cat > "$SCRIPT_DIR/install_packages.sh" << 'EOF'
|
||||||
|
#!/bin/bash
|
||||||
|
# =============================================================================
|
||||||
|
# New package installation module
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# Set script directory
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
# Source common functions and variables
|
||||||
|
source "./common.sh"
|
||||||
|
|
||||||
|
# Function to install new packages safely
|
||||||
|
install_new_packages() {
|
||||||
|
if [ $# -eq 0 ]; then
|
||||||
|
log_message "ERROR" "No packages specified for installation"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_message "INFO" "Installing new packages: $*"
|
||||||
|
|
||||||
|
# Update package lists first
|
||||||
|
apt-get update
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
log_message "ERROR" "Failed to update package lists"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Install the specified packages
|
||||||
|
apt-get install -y "$@"
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
log_message "SUCCESS" "Installed packages successfully: $*"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
log_message "ERROR" "Failed to install packages: $*"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Usage example:
|
||||||
|
# source "$SCRIPT_DIR/install_packages.sh"
|
||||||
|
# install_new_packages package1 package2 package3
|
||||||
|
EOF
|
||||||
|
|
||||||
|
chmod +x "$SCRIPT_DIR/install_packages.sh"
|
||||||
|
log_message "INFO" "Created new package installation module at $SCRIPT_DIR/install_packages.sh"
|
||||||
|
|
||||||
|
# Main execution for package management
|
||||||
|
configure_apt_proxy
|
||||||
|
update_upgrade_packages
|
||||||
|
install_essential_packages
|
||||||
|
|
||||||
|
log_message "SUCCESS" "Package management configuration completed"
|
168
test/modules/ssh_hardening.sh
Normal file
168
test/modules/ssh_hardening.sh
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# =============================================================================
|
||||||
|
# SSH hardening module
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# Set script directory
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
# Source common functions and variables
|
||||||
|
source "./common.sh"
|
||||||
|
|
||||||
|
# Function to create SSH keys for root user
|
||||||
|
create_root_ssh_keys() {
|
||||||
|
local ssh_dir="/root/.ssh"
|
||||||
|
local authorized_keys="$ssh_dir/authorized_keys"
|
||||||
|
local ssh_key_doc="/root/root-ssh-keys-documentation.txt"
|
||||||
|
|
||||||
|
# Create .ssh directory if it doesn't exist
|
||||||
|
mkdir -p "$ssh_dir"
|
||||||
|
chmod 700 "$ssh_dir"
|
||||||
|
|
||||||
|
# Create or backup authorized_keys file
|
||||||
|
if [ -f "$authorized_keys" ]; then
|
||||||
|
backup_file "$authorized_keys"
|
||||||
|
else
|
||||||
|
touch "$authorized_keys"
|
||||||
|
fi
|
||||||
|
|
||||||
|
chmod 600 "$authorized_keys"
|
||||||
|
|
||||||
|
# Create documentation
|
||||||
|
log_message "INFO" "Creating SSH key documentation for root user"
|
||||||
|
|
||||||
|
cat > "$ssh_key_doc" << EOF
|
||||||
|
# Root SSH Keys Documentation
|
||||||
|
#
|
||||||
|
# To add SSH public keys for root user, add them to the authorized_keys file:
|
||||||
|
# $authorized_keys
|
||||||
|
#
|
||||||
|
# Format:
|
||||||
|
# ssh-rsa AAAAB3NzaC1yc2EA... comment
|
||||||
|
#
|
||||||
|
# For security:
|
||||||
|
# - Key-based authentication is more secure than password-based authentication
|
||||||
|
# - Use strong, unique keys for each user or service
|
||||||
|
# - Regularly rotate SSH keys
|
||||||
|
# - Remove keys that are no longer needed
|
||||||
|
#
|
||||||
|
# Remember to maintain proper permissions:
|
||||||
|
# chmod 700 $ssh_dir
|
||||||
|
# chmod 600 $authorized_keys
|
||||||
|
EOF
|
||||||
|
|
||||||
|
log_message "SUCCESS" "SSH key documentation for root user created at $ssh_key_doc"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to create SSH keys for non-root users
|
||||||
|
create_non_root_ssh_keys() {
|
||||||
|
local ssh_key_doc="/etc/skel/.ssh-documentation.txt"
|
||||||
|
|
||||||
|
# Create /etc/skel/.ssh directory
|
||||||
|
mkdir -p "/etc/skel/.ssh"
|
||||||
|
chmod 700 "/etc/skel/.ssh"
|
||||||
|
touch "/etc/skel/.ssh/authorized_keys"
|
||||||
|
chmod 600 "/etc/skel/.ssh/authorized_keys"
|
||||||
|
|
||||||
|
# Create documentation
|
||||||
|
log_message "INFO" "Creating SSH key documentation for non-root users"
|
||||||
|
|
||||||
|
cat > "$ssh_key_doc" << EOF
|
||||||
|
# User SSH Keys Documentation
|
||||||
|
#
|
||||||
|
# To add SSH public keys for this user, add them to the authorized_keys file:
|
||||||
|
# ~/.ssh/authorized_keys
|
||||||
|
#
|
||||||
|
# Format:
|
||||||
|
# ssh-rsa AAAAB3NzaC1yc2EA... comment
|
||||||
|
#
|
||||||
|
# For security:
|
||||||
|
# - Key-based authentication is more secure than password-based authentication
|
||||||
|
# - Use strong, unique keys for each user or service
|
||||||
|
# - Regularly rotate SSH keys
|
||||||
|
# - Remove keys that are no longer needed
|
||||||
|
#
|
||||||
|
# Remember to maintain proper permissions:
|
||||||
|
# chmod 700 ~/.ssh
|
||||||
|
# chmod 600 ~/.ssh/authorized_keys
|
||||||
|
EOF
|
||||||
|
|
||||||
|
log_message "SUCCESS" "SSH key documentation for non-root users created at $ssh_key_doc"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to harden SSH configuration
|
||||||
|
harden_ssh_config() {
|
||||||
|
local ssh_config="/etc/ssh/sshd_config"
|
||||||
|
local ssh_config_backup="$BACKUP_DIR/etc/ssh/sshd_config"
|
||||||
|
|
||||||
|
# Backup current SSH configuration
|
||||||
|
backup_file "$ssh_config"
|
||||||
|
|
||||||
|
log_message "INFO" "Hardening SSH configuration"
|
||||||
|
|
||||||
|
# Create a new SSH configuration with hardened settings
|
||||||
|
cat > "$ssh_config" << EOF
|
||||||
|
# SSH Server Configuration
|
||||||
|
# Hardened configuration from security script
|
||||||
|
|
||||||
|
# Basic SSH server settings
|
||||||
|
Port 2222
|
||||||
|
AddressFamily inet
|
||||||
|
ListenAddress 0.0.0.0
|
||||||
|
|
||||||
|
# Authentication settings
|
||||||
|
#AuthorizedKeysFile /root/.ssh/authorized_keys/%u
|
||||||
|
PermitRootLogin prohibit-password
|
||||||
|
PubkeyAuthentication yes
|
||||||
|
PasswordAuthentication no
|
||||||
|
PermitEmptyPasswords no
|
||||||
|
ChallengeResponseAuthentication no
|
||||||
|
UsePAM yes
|
||||||
|
|
||||||
|
# Security settings
|
||||||
|
X11Forwarding no
|
||||||
|
PrintMotd no
|
||||||
|
AcceptEnv LANG LC_*
|
||||||
|
Subsystem sftp /usr/lib/openssh/sftp-server
|
||||||
|
|
||||||
|
# Hardening options
|
||||||
|
LoginGraceTime 30
|
||||||
|
MaxAuthTries 3
|
||||||
|
MaxSessions 5
|
||||||
|
ClientAliveInterval 300
|
||||||
|
ClientAliveCountMax 3
|
||||||
|
|
||||||
|
# Disable weak crypto
|
||||||
|
KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256
|
||||||
|
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
|
||||||
|
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
SyslogFacility AUTH
|
||||||
|
LogLevel VERBOSE
|
||||||
|
EOF
|
||||||
|
|
||||||
|
log_message "INFO" "Configured SSH to use port 2222 and disabled root password login"
|
||||||
|
log_message "SUCCESS" "SSH configuration hardened"
|
||||||
|
|
||||||
|
# Restart SSH service to apply changes
|
||||||
|
log_message "INFO" "Restarting SSH service"
|
||||||
|
systemctl restart sshd
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
log_message "SUCCESS" "SSH service restarted successfully"
|
||||||
|
else
|
||||||
|
log_message "ERROR" "Failed to restart SSH service"
|
||||||
|
# Revert to backup
|
||||||
|
cp "$ssh_config_backup" "$ssh_config"
|
||||||
|
systemctl restart sshd
|
||||||
|
log_message "WARNING" "Reverted to original SSH configuration"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main execution for SSH hardening
|
||||||
|
create_root_ssh_keys
|
||||||
|
create_non_root_ssh_keys
|
||||||
|
harden_ssh_config
|
||||||
|
|
||||||
|
log_message "SUCCESS" "SSH hardening completed"
|
108
test/modules/wazuh_agent.sh
Normal file
108
test/modules/wazuh_agent.sh
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# =============================================================================
|
||||||
|
# Wazuh agent installation module
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# Set script directory
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
# Source common functions and variables
|
||||||
|
source "./common.sh"
|
||||||
|
|
||||||
|
# Function to install Wazuh agent
|
||||||
|
install_wazuh_agent() {
|
||||||
|
log_message "INFO" "Installing Wazuh agent"
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
log_message "INFO" "Installing dependencies for Wazuh agent"
|
||||||
|
apt-get install -y curl apt-transport-https lsb-release gnupg2
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
log_message "ERROR" "Failed to install dependencies for Wazuh agent"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Import GPG key
|
||||||
|
log_message "INFO" "Importing Wazuh GPG key"
|
||||||
|
curl -s https://packages.wazuh.com/key/GPG-KEY-WAZUH | gpg --no-default-keyring --keyring gnupg-ring:/usr/share/keyrings/wazuh.gpg --import
|
||||||
|
chmod 644 /usr/share/keyrings/wazuh.gpg
|
||||||
|
|
||||||
|
# Add Wazuh repository
|
||||||
|
log_message "INFO" "Adding Wazuh repository"
|
||||||
|
echo "deb [signed-by=/usr/share/keyrings/wazuh.gpg] https://packages.wazuh.com/4.x/apt/ stable main" | tee -a /etc/apt/sources.list.d/wazuh.list
|
||||||
|
|
||||||
|
# Update package lists
|
||||||
|
apt-get update
|
||||||
|
|
||||||
|
# Install Wazuh agent
|
||||||
|
log_message "INFO" "Installing Wazuh agent package"
|
||||||
|
apt-get install -y wazuh-agent
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
log_message "ERROR" "Failed to install Wazuh agent"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Configure Wazuh agent
|
||||||
|
log_message "INFO" "Configuring Wazuh agent"
|
||||||
|
|
||||||
|
local wazuh_conf="/var/ossec/etc/ossec.conf"
|
||||||
|
|
||||||
|
# Backup existing configuration
|
||||||
|
if [ -f "$wazuh_conf" ]; then
|
||||||
|
backup_file "$wazuh_conf"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Modify the configuration to point to your Wazuh server
|
||||||
|
# Replace with your actual Wazuh server IP address
|
||||||
|
local WAZUH_MANAGER="YOUR_WAZUH_MANAGER_IP"
|
||||||
|
|
||||||
|
# Configure Wazuh agent to connect to the manager
|
||||||
|
/var/ossec/bin/agent-auth -m "$WAZUH_MANAGER"
|
||||||
|
|
||||||
|
# Update the ossec.conf file with the manager IP
|
||||||
|
sed -i "s/<address>.*<\/address>/<address>$WAZUH_MANAGER<\/address>/" "$wazuh_conf"
|
||||||
|
|
||||||
|
log_message "INFO" "Wazuh agent configured to connect to manager: $WAZUH_MANAGER"
|
||||||
|
|
||||||
|
# Create a README file to explain how to update the manager IP
|
||||||
|
cat > "/root/wazuh-agent-setup.txt" << EOF
|
||||||
|
# Wazuh Agent Configuration
|
||||||
|
# Generated by security hardening script
|
||||||
|
|
||||||
|
To update the Wazuh manager IP address, edit the following file:
|
||||||
|
$wazuh_conf
|
||||||
|
|
||||||
|
And change the <address> tag to point to your Wazuh manager:
|
||||||
|
<address>YOUR_WAZUH_MANAGER_IP</address>
|
||||||
|
|
||||||
|
Then, register the agent with your Wazuh manager:
|
||||||
|
/var/ossec/bin/agent-auth -m YOUR_WAZUH_MANAGER_IP
|
||||||
|
|
||||||
|
Finally, restart the Wazuh agent:
|
||||||
|
systemctl restart wazuh-agent
|
||||||
|
|
||||||
|
For more information, see the Wazuh documentation:
|
||||||
|
https://documentation.wazuh.com/current/installation-guide/installing-wazuh-agent/index.html
|
||||||
|
EOF
|
||||||
|
|
||||||
|
log_message "SUCCESS" "Wazuh agent setup documentation created at /root/wazuh-agent-setup.txt"
|
||||||
|
|
||||||
|
# Enable and start Wazuh agent
|
||||||
|
log_message "INFO" "Enabling and starting Wazuh agent"
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl enable wazuh-agent
|
||||||
|
systemctl restart wazuh-agent
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
log_message "SUCCESS" "Wazuh agent service enabled and started"
|
||||||
|
else
|
||||||
|
log_message "ERROR" "Failed to enable or start Wazuh agent service"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main execution for Wazuh agent
|
||||||
|
install_wazuh_agent
|
||||||
|
|
||||||
|
log_message "SUCCESS" "Wazuh agent installation completed"
|
Loading…
x
Reference in New Issue
Block a user