344 lines
9.0 KiB
Bash
344 lines
9.0 KiB
Bash
#!/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
|
|
service 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" |