Last active
August 24, 2024 06:48
-
-
Save corporatepiyush/061123b340babf28d51e568b44bf9ab3 to your computer and use it in GitHub Desktop.
MacOS and Linux Optimisation and hardening
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Array to store user choices | |
declare -A choices | |
# Log file | |
LOGFILE="/var/log/linux_hardening.log" | |
# Function to log messages | |
log() { | |
echo "$(date +'%Y-%m-%d %H:%M:%S') - $1" | sudo tee -a "$LOGFILE" | |
} | |
# Function to display menu and get user choices | |
show_menu() { | |
local options=( | |
"Enable kTLS (Kernel TLS)|Disable kTLS" | |
"Enable ASLR (Address Space Layout Randomization)|Disable ASLR" | |
"Secure shared memory|Revert shared memory settings" | |
"Disable core dumps|Enable core dumps" | |
"Enable additional kernel security features|Disable additional kernel security features" | |
"Install and configure UFW (Uncomplicated Firewall)|Remove UFW" | |
"Disable rpcbind service|Enable rpcbind service" | |
"Configure SSH security features|Revert SSH security features" | |
"Install and configure fail2ban|Remove fail2ban" | |
"Set login banner|Remove login banner" | |
"Install and enable auditd|Remove auditd" | |
"Enable process accounting|Disable process accounting" | |
"Install AIDE for file integrity monitoring|Remove AIDE" | |
"Set up unattended-upgrades|Disable unattended-upgrades" | |
"Restrict compiler access|Restore compiler access" | |
"Enable log rotation and deletion|Disable log rotation and deletion" | |
) | |
echo "Welcome to the Linux Hardening and Reverting Script" | |
echo "Please select the actions you want to perform:" | |
echo "-----------------------------------------------------" | |
for i in "${!options[@]}"; do | |
IFS='|' read -r enable disable <<< "${options[$i]}" | |
echo "$((i+1)). $enable" | |
echo "$((-(i+1))). $disable" | |
done | |
echo "-----------------------------------------------------" | |
echo "Enter the numbers of your choices, separated by spaces (e.g., 1 -3 5)," | |
echo "or type 'all' to select all hardening options, or 'q' to quit:" | |
read -p "> " input | |
if [[ $input == "q" ]]; then | |
exit 0 | |
elif [[ $input == "all" ]]; then | |
for i in {1..16}; do | |
choices[$i]=1 | |
done | |
else | |
for num in $input; do | |
if [[ $num =~ ^-?[0-9]+$ ]] && (( num >= -16 && num <= 16 )); then | |
choices[$num]=1 | |
fi | |
done | |
fi | |
} | |
# Function to set sysctl values with error handling | |
set_sysctl() { | |
local key=$1 | |
local value=$2 | |
if ! grep -q "^$key" /etc/sysctl.conf; then | |
if sudo sysctl -w "$key=$value"; then | |
echo "$key=$value" | sudo tee -a /etc/sysctl.conf > /dev/null | |
log "- $key set to $value" | |
else | |
log "- Failed to set $key to $value" | |
fi | |
else | |
sudo sed -i "s/^$key=.*/$key=$value/" /etc/sysctl.conf | |
sudo sysctl -p | |
log "- $key updated to $value" | |
fi | |
} | |
# Function to enable kTLS | |
enable_ktls() { | |
log "Enabling kTLS (Kernel TLS)..." | |
kernel_version=$(uname -r) | |
if [[ "$(echo $kernel_version | cut -d'.' -f1)" < "5" || "$(echo $kernel_version | cut -d'.' -f1)" > "6" ]]; then | |
log "- This feature is designed for Linux kernels 5.x and 6.x. Your kernel version may not support it." | |
else | |
if ! lsmod | grep -q "^tls"; then | |
if ! sudo modprobe tls; then | |
log "- Warning: Failed to load kTLS module. Your kernel may not support kTLS." | |
else | |
set_sysctl net.ipv4.tcp_tls_enable 1 | |
fi | |
else | |
log "- kTLS module is already loaded" | |
fi | |
fi | |
} | |
# Function to disable kTLS | |
disable_ktls() { | |
log "Disabling kTLS..." | |
set_sysctl net.ipv4.tcp_tls_enable 0 | |
sudo rmmod tls 2>/dev/null | |
log "- kTLS disabled" | |
} | |
# Function to enable ASLR | |
enable_aslr() { | |
log "Enabling ASLR (Address Space Layout Randomization)..." | |
set_sysctl kernel.randomize_va_space 2 | |
} | |
# Function to disable ASLR | |
disable_aslr() { | |
log "Disabling ASLR..." | |
set_sysctl kernel.randomize_va_space 0 | |
} | |
# Function to secure shared memory | |
secure_shared_memory() { | |
log "Securing shared memory..." | |
if ! grep -q "/run/shm" /etc/fstab; then | |
echo 'tmpfs /run/shm tmpfs defaults,noexec,nosuid 0 0' | sudo tee -a /etc/fstab | |
sudo mount -o remount,noexec,nosuid /run/shm | |
log "- Shared memory secured" | |
else | |
log "- Shared memory is already secured in /etc/fstab" | |
fi | |
} | |
# Function to revert shared memory settings | |
revert_shared_memory() { | |
log "Reverting shared memory settings..." | |
sudo sed -i '/\/run\/shm/d' /etc/fstab | |
sudo mount -o remount,exec,suid /run/shm | |
log "- Shared memory settings reverted" | |
} | |
# Function to disable core dumps | |
disable_core_dumps() { | |
log "Disabling core dumps..." | |
set_sysctl fs.suid_dumpable 0 | |
if ! grep -q "ulimit -c 0" /etc/security/limits.conf; then | |
echo "* hard core 0" | sudo tee -a /etc/security/limits.conf | |
log "- Core dumps disabled" | |
else | |
log "- Core dumps are already disabled" | |
fi | |
} | |
# Function to enable core dumps | |
enable_core_dumps() { | |
log "Enabling core dumps..." | |
set_sysctl fs.suid_dumpable 2 | |
sudo sed -i '/\* hard core 0/d' /etc/security/limits.conf | |
log "- Core dumps enabled" | |
} | |
# Function to enable additional kernel security features | |
enable_kernel_security() { | |
log "Enabling additional kernel security features..." | |
set_sysctl kernel.kptr_restrict 2 | |
set_sysctl kernel.yama.ptrace_scope 1 | |
} | |
# Function to disable additional kernel security features | |
disable_kernel_security() { | |
log "Disabling additional kernel security features..." | |
set_sysctl kernel.kptr_restrict 0 | |
set_sysctl kernel.yama.ptrace_scope 0 | |
} | |
# Function to install and configure UFW | |
install_ufw() { | |
log "Installing and configuring UFW (Uncomplicated Firewall)..." | |
if ! dpkg -s ufw >/dev/null 2>&1; then | |
sudo apt-get install -y ufw | |
sudo ufw default deny incoming | |
sudo ufw default allow outgoing | |
sudo ufw allow ssh | |
sudo ufw allow 443/tcp | |
sudo ufw --force enable | |
log "- UFW installed and configured" | |
else | |
log "- UFW is already installed" | |
fi | |
} | |
# Function to remove UFW | |
remove_ufw() { | |
log "Removing UFW..." | |
sudo ufw disable | |
sudo apt-get remove -y ufw | |
log "- UFW removed" | |
} | |
# Function to disable rpcbind service | |
disable_rpcbind() { | |
log "Disabling rpcbind service..." | |
sudo systemctl disable rpcbind | |
sudo systemctl stop rpcbind | |
log "- rpcbind service disabled" | |
} | |
# Function to enable rpcbind service | |
enable_rpcbind() { | |
log "Enabling rpcbind service..." | |
sudo systemctl enable rpcbind | |
sudo systemctl start rpcbind | |
log "- rpcbind service enabled" | |
} | |
# Function to configure SSH security features | |
configure_ssh_security() { | |
log "Configuring SSH security features..." | |
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak | |
sudo sed -i 's/^#*PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config | |
sudo sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config | |
sudo sed -i 's/^#*PermitEmptyPasswords.*/PermitEmptyPasswords no/' /etc/ssh/sshd_config | |
sudo sed -i 's/^#*ChallengeResponseAuthentication.*/ChallengeResponseAuthentication no/' /etc/ssh/sshd_config | |
if ! grep -q "^UsePAM" /etc/ssh/sshd_config; then | |
echo "UsePAM yes" | sudo tee -a /etc/ssh/sshd_config | |
fi | |
if ! grep -q "^AllowUsers" /etc/ssh/sshd_config; then | |
read -p "Enter the username to allow SSH access: " ssh_username | |
echo "AllowUsers $ssh_username" | sudo tee -a /etc/ssh/sshd_config | |
fi | |
sudo systemctl restart ssh | |
log "- SSH security features configured" | |
} | |
# Function to revert SSH security features | |
revert_ssh_security() { | |
log "Reverting SSH security features..." | |
if [ -f /etc/ssh/sshd_config.bak ]; then | |
sudo mv /etc/ssh/sshd_config.bak /etc/ssh/sshd_config | |
sudo systemctl restart ssh | |
log "- SSH configuration reverted to original state" | |
else | |
log "- No backup of sshd_config found. Unable to revert." | |
fi | |
} | |
# Function to install and configure fail2ban | |
install_fail2ban() { | |
log "Installing and configuring fail2ban..." | |
if ! dpkg -s fail2ban >/dev/null 2>&1; then | |
sudo apt-get install -y fail2ban | |
sudo systemctl enable fail2ban | |
sudo systemctl start fail2ban | |
log "- fail2ban installed and configured" | |
else | |
log "- fail2ban is already installed" | |
fi | |
} | |
# Function to remove fail2ban | |
remove_fail2ban() { | |
log "Removing fail2ban..." | |
sudo systemctl stop fail2ban | |
sudo systemctl disable fail2ban | |
sudo apt-get remove -y fail2ban | |
log "- fail2ban removed" | |
} | |
# Function to set login banner | |
set_login_banner() { | |
log "Setting login banner..." | |
echo "Authorized access only. All activity may be monitored and reported." | sudo tee /etc/issue /etc/issue.net | |
log "- Login banner set" | |
} | |
# Function to remove login banner | |
remove_login_banner() { | |
log "Removing login banner..." | |
sudo truncate -s 0 /etc/issue /etc/issue.net | |
log "- Login banner removed" | |
} | |
# Function to install and enable auditd | |
install_auditd() { | |
log "Installing and enabling auditd..." | |
if ! dpkg -s auditd >/dev/null 2>&1; then | |
sudo apt-get install -y auditd | |
sudo systemctl enable auditd | |
sudo systemctl start auditd | |
log "- auditd installed and enabled" | |
else | |
log "- auditd is already installed" | |
fi | |
} | |
# Function to remove auditd | |
remove_auditd() { | |
log "Removing auditd..." | |
sudo systemctl stop auditd | |
sudo systemctl disable auditd | |
sudo apt-get remove -y auditd | |
log "- auditd removed" | |
} | |
# Function to enable process accounting | |
enable_process_accounting() { | |
log "Enabling process accounting..." | |
if ! dpkg -s acct >/dev/null 2>&1; then | |
sudo apt-get install -y acct | |
sudo systemctl enable acct | |
sudo systemctl start acct | |
log "- Process accounting enabled" | |
else | |
log "- Process accounting is already installed" | |
fi | |
} | |
# Function to disable process accounting | |
disable_process_accounting() { | |
log "Disabling process accounting..." | |
sudo systemctl stop acct | |
sudo systemctl disable acct | |
sudo apt-get remove -y acct | |
log "- Process accounting disabled and removed" | |
} | |
# Function to install AIDE | |
install_aide() { | |
log "Installing AIDE for file integrity monitoring..." | |
if ! dpkg -s aide >/dev/null 2>&1; then | |
sudo apt-get install -y aide | |
sudo aideinit | |
sudo mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db | |
log "- AIDE installed and initialized" | |
else | |
log "- AIDE is already installed" | |
fi | |
} | |
# Function to remove AIDE | |
remove_aide() { | |
log "Removing AIDE..." | |
sudo apt-get remove -y aide | |
sudo rm -f /var/lib/aide/aide.db* | |
log "- AIDE removed" | |
} | |
# Function to set up unattended-upgrades | |
setup_unattended_upgrades() { | |
log "Setting up unattended-upgrades..." | |
if ! dpkg -s unattended-upgrades >/dev/null 2>&1; then | |
sudo apt-get install -y unattended-upgrades | |
echo 'APT::Periodic::Update-Package-Lists "1"; | |
APT::Periodic::Unattended-Upgrade "1";' | sudo tee /etc/apt/apt.conf.d/20auto-upgrades | |
log "- unattended-upgrades configured" | |
else | |
log "- unattended-upgrades is already installed" | |
fi | |
} | |
# Function to disable unattended-upgrades | |
disable_unattended_upgrades() { | |
log "Disabling unattended-upgrades..." | |
sudo apt-get remove -y unattended-upgrades | |
sudo rm -f /etc/apt/apt.conf.d/20auto-upgrades | |
log "- unattended-upgrades disabled and removed" | |
} | |
# Function to restrict compiler access | |
restrict_compiler_access() { | |
log "Restricting compiler access..." | |
sudo chmod o-x /usr/bin/gcc /usr/bin/g++ /usr/bin/cc /usr/bin/c++ 2>/dev/null | |
log "- Compiler access restricted" | |
} | |
# Function to restore compiler access | |
restore_compiler_access() { | |
log "Restoring compiler access..." | |
sudo chmod o+x /usr/bin/gcc /usr/bin/g++ /usr/bin/cc /usr/bin/c++ 2>/dev/null | |
log "- Compiler access restored" | |
} | |
# Function to enable log rotation and deletion | |
enable_log_rotation() { | |
log "Enabling log rotation and deletion..." | |
sudo apt-get install -y logrotate | |
sudo sed -i 's/^#*rotate .*/rotate 7/' /etc/logrotate.conf | |
sudo sed -i 's/^#*compress/compress/' /etc/logrotate.conf | |
sudo systemctl enable logrotate | |
sudo systemctl start logrotate | |
log "- Log rotation and deletion enabled" | |
} | |
# Function to disable log rotation and deletion | |
disable_log_rotation() { | |
log "Disabling log rotation and deletion..." | |
sudo systemctl stop logrotate | |
sudo systemctl disable logrotate | |
sudo apt-get remove -y logrotate | |
log "- Log rotation and deletion disabled" | |
} | |
# Main script execution | |
show_menu | |
log "Executing selected actions..." | |
log "----------------------------------------" | |
# Execute selected actions | |
for choice in "${!choices[@]}"; do | |
case $choice in | |
1) enable_ktls ;; | |
-1) disable_ktls ;; | |
2) enable_aslr ;; | |
-2) disable_aslr ;; | |
3) secure_shared_memory ;; | |
-3) revert_shared_memory ;; | |
4) disable_core_dumps ;; | |
-4) enable_core_dumps ;; | |
5) enable_kernel_security ;; | |
-5) disable_kernel_security ;; | |
6) install_ufw ;; | |
-6) remove_ufw ;; | |
7) disable_rpcbind ;; | |
-7) enable_rpcbind ;; | |
8) configure_ssh_security ;; | |
-8) revert_ssh_security ;; | |
9) install_fail2ban ;; | |
-9) remove_fail2ban ;; | |
10) set_login_banner ;; | |
-10) remove_login_banner ;; | |
11) install_auditd ;; | |
-11) remove_auditd ;; | |
12) enable_process_accounting ;; | |
-12) disable_process_accounting ;; | |
13) install_aide ;; | |
-13) remove_aide ;; | |
14) setup_unattended_upgrades ;; | |
-14) disable_unattended_upgrades ;; | |
15) restrict_compiler_access ;; | |
-15) restore_compiler_access ;; | |
16) enable_log_rotation ;; | |
-16) disable_log_rotation ;; | |
*) log "Invalid choice: $choice" ;; | |
esac | |
done | |
log "----------------------------------------" | |
log "Script execution completed." | |
log "Please review the changes and consider rebooting your system to ensure all modifications take effect." |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
echo "Processes using Transparent Huge Pages (THP):" | |
for pid in $(ls /proc | grep '^[0-9]*$'); do | |
smaps_file="/proc/$pid/smaps" | |
if [ -f "$smaps_file" ]; then | |
anon_huge_pages=$(grep AnonHugePages "$smaps_file" 2>/dev/null | awk '{sum += $2} END {print sum}') | |
if [ -n "$anon_huge_pages" ] && [ "$anon_huge_pages" -gt 0 ]; then | |
process_name=$(cat /proc/$pid/comm 2>/dev/null) | |
echo "PID: $pid - $process_name - AnonHugePages: ${anon_huge_pages} kB" | |
fi | |
fi | |
done |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Function to disable and remove swap files | |
remove_swap_files() { | |
echo "Disabling all active swap files..." | |
# Get list of active swap files | |
swap_files=$(swapon --summary | grep '^/' | awk '{print $1}') | |
# Disable and remove each swap file | |
for swap_file in $swap_files; do | |
echo "Disabling swap file: $swap_file" | |
sudo swapoff "$swap_file" | |
echo "Removing swap file: $swap_file" | |
sudo rm -f "$swap_file" | |
done | |
echo "Removing swap file entries from /etc/fstab..." | |
# Backup /etc/fstab before modifying | |
sudo cp /etc/fstab /etc/fstab.bak | |
# Remove lines containing 'swap' and '/swapfile' | |
sudo sed -i '/swap/d' /etc/fstab | |
echo "Removing any existing swap files..." | |
# Remove any file that exists and matches the path /swap* (case insensitive) | |
for file in /swap*; do | |
if [ -f "$file" ]; then | |
echo "Removing swap file: $file" | |
sudo rm -f "$file" | |
fi | |
done | |
# Use find to find files with names matching /swap* (case insensitive) | |
find / -type f -name '/swap*' -exec sudo rm -f {} \; | |
echo "Swap files and entries have been removed." | |
} | |
# Execute the function | |
remove_swap_files |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -e | |
# Function to log messages | |
log_message() { | |
echo "$1" | |
} | |
log_error() { | |
echo "ERROR: $1" >&2 | |
} | |
log_warning() { | |
echo "WARNING: $1" >&2 | |
} | |
# Function to check and install required tools | |
check_and_install_tools() { | |
local tools=("pgrep" "systemctl") | |
local missing_tools=() | |
for tool in "${tools[@]}"; do | |
if ! command -v "$tool" &> /dev/null; then | |
missing_tools+=("$tool") | |
fi | |
done | |
if [[ ${#missing_tools[@]} -gt 0 ]]; then | |
log_message "Some required tools are missing. Attempting to install them..." | |
if command -v apt-get &> /dev/null; then | |
# Debian-based systems | |
sudo apt-get update | |
sudo apt-get install -y procps systemd | |
elif command -v yum &> /dev/null; then | |
# Red Hat-based systems | |
sudo yum install -y procps-ng systemd | |
elif command -v pacman &> /dev/null; then | |
# Arch-based systems | |
sudo pacman -Sy procps-ng systemd | |
else | |
log_error "Unable to install missing tools. Please install the following manually: ${missing_tools[*]}" | |
exit 1 | |
fi | |
log_message "Required tools have been installed." | |
else | |
log_message "All required tools are already installed." | |
fi | |
} | |
# Function to validate process name | |
validate_process_name() { | |
local process_name=$1 | |
if [[ -z $process_name ]]; then | |
log_error "Process name suffix cannot be empty." | |
return 1 | |
fi | |
return 0 | |
} | |
# Function to validate CPU limit | |
validate_cpu_limit() { | |
local cpu_limit=$1 | |
local cpu_count=$(nproc) | |
if [[ ! $cpu_limit =~ ^([0-9]+(-[0-9]+)?)(,[0-9]+(-[0-9]+)?)*$ ]]; then | |
log_error "Invalid CPU limit format. Example of valid formats: 0-3, 0,1,2,3, or single CPU like 2" | |
return 1 | |
fi | |
IFS=',' read -ra CPU_RANGES <<< "$cpu_limit" | |
for range in "${CPU_RANGES[@]}"; do | |
if [[ $range =~ ^([0-9]+)-([0-9]+)$ ]]; then | |
start=${BASH_REMATCH[1]} | |
end=${BASH_REMATCH[2]} | |
if ((start >= cpu_count || end >= cpu_count || start > end)); then | |
log_error "Invalid CPU range: $range. Available CPUs are 0-$((cpu_count-1))" | |
return 1 | |
fi | |
elif [[ $range =~ ^[0-9]+$ ]]; then | |
if ((range >= cpu_count)); then | |
log_error "Invalid CPU number: $range. Available CPUs are 0-$((cpu_count-1))" | |
return 1 | |
fi | |
else | |
log_error "Invalid CPU specification: $range" | |
return 1 | |
fi | |
done | |
return 0 | |
} | |
# Function to validate RAM limit | |
validate_ram_limit() { | |
local ram_limit=$1 | |
local max_ram_limit=$2 | |
if ! [[ $ram_limit =~ ^[0-9]+$ ]]; then | |
log_error "RAM limit must be a positive integer." | |
return 1 | |
elif ((ram_limit <= 0)); then | |
log_error "RAM limit must be greater than 0." | |
return 1 | |
elif ((ram_limit > max_ram_limit)); then | |
log_error "RAM limit must not be greater than $max_ram_limit MB (75% of available RAM)." | |
return 1 | |
fi | |
return 0 | |
} | |
# Check if script is run as root | |
if [[ $EUID -ne 0 ]]; then | |
log_error "This script must be run as root" | |
exit 1 | |
fi | |
# Check and install required tools | |
check_and_install_tools | |
# Check if cgroups v2 is enabled | |
if ! grep -q cgroup2 /proc/filesystems; then | |
log_error "Cgroups v2 is not enabled on this system." | |
exit 1 | |
fi | |
# Get total available RAM in MB | |
total_ram=$(grep MemTotal /proc/meminfo | awk '{print $2}') | |
total_ram_mb=$((total_ram / 1024)) | |
max_allowed_ram_mb=$((total_ram_mb * 50 / 100)) | |
# Prompt for the process name, CPU limit, and RAM limit with validation | |
while true; do | |
read -p "Enter the process name suffix: " PROCESS_NAME | |
if validate_process_name "$PROCESS_NAME"; then | |
break | |
fi | |
done | |
while true; do | |
read -p "Enter the CPU limit (e.g., 0-3 for CPUs 0 to 3 or single CPU like 2): " CPU_LIMIT | |
if validate_cpu_limit "$CPU_LIMIT"; then | |
break | |
fi | |
done | |
while true; do | |
read -p "Enter the RAM limit in MB (up to $max_allowed_ram_mb MB): " RAM_LIMIT_MB | |
if validate_ram_limit "$RAM_LIMIT_MB" "$max_allowed_ram_mb"; then | |
break | |
fi | |
done | |
# Convert RAM limit to bytes | |
RAM_LIMIT_BYTES=$((RAM_LIMIT_MB * 1024 * 1024)) | |
# Create a cgroup for the specified process | |
CGROUP_DIR="/sys/fs/cgroup/${PROCESS_NAME}_limit" | |
if [[ ! -d "$CGROUP_DIR" ]]; then | |
mkdir -p "$CGROUP_DIR" || { log_error "Failed to create cgroup directory"; exit 1; } | |
log_message "Created cgroup directory: $CGROUP_DIR" | |
else | |
log_message "Cgroup directory already exists: $CGROUP_DIR" | |
fi | |
# Restrict CPU usage to specified CPUs | |
current_cpu_limit=$(cat "$CGROUP_DIR/cpuset.cpus") | |
if [[ "$current_cpu_limit" != "$CPU_LIMIT" ]]; then | |
echo "$CPU_LIMIT" > "$CGROUP_DIR/cpuset.cpus" || { log_error "Failed to set CPU limit"; exit 1; } | |
log_message "Set CPU limit to: $CPU_LIMIT" | |
else | |
log_message "CPU limit is already set to: $CPU_LIMIT" | |
fi | |
# Restrict memory usage to specified limit | |
current_ram_limit=$(cat "$CGROUP_DIR/memory.max") | |
if [[ "$current_ram_limit" != "$RAM_LIMIT_BYTES" ]]; then | |
echo "$RAM_LIMIT_BYTES" > "$CGROUP_DIR/memory.max" || { log_error "Failed to set RAM limit"; exit 1; } | |
log_message "Set RAM limit to: ${RAM_LIMIT_MB}MB" | |
else | |
log_message "RAM limit is already set to: ${RAM_LIMIT_MB}MB" | |
fi | |
# Enable controllers | |
current_subtree_control=$(cat "$CGROUP_DIR/cgroup.subtree_control") | |
if [[ "$current_subtree_control" != "+cpu +memory +cpuset" ]]; then | |
echo "+cpu +memory +cpuset" > "$CGROUP_DIR/cgroup.subtree_control" || { log_error "Failed to enable controllers"; exit 1; } | |
log_message "Enabled cgroup controllers: cpu, memory, cpuset" | |
else | |
log_message "Cgroup controllers are already enabled: cpu, memory, cpuset" | |
fi | |
# Apply the cgroup to all current processes with the specified name suffix | |
while IFS= read -r pid; do | |
echo "$pid" > "$CGROUP_DIR/cgroup.procs" || log_warning "Failed to add process $pid to cgroup" | |
done < <(pgrep -f "$PROCESS_NAME$") | |
# Create the monitor script if it doesn't already exist | |
MONITOR_SCRIPT_PATH="/usr/local/bin/monitor_${PROCESS_NAME}_cgroup.sh" | |
if [[ ! -f "$MONITOR_SCRIPT_PATH" ]]; then | |
cat << EOF > "$MONITOR_SCRIPT_PATH" | |
#!/bin/bash | |
while true; do | |
while IFS= read -r pid; do | |
echo "\$pid" > $CGROUP_DIR/cgroup.procs 2>/dev/null || true | |
done < <(pgrep -f "$PROCESS_NAME\$") | |
sleep 5 | |
done | |
EOF | |
chmod +x "$MONITOR_SCRIPT_PATH" || { log_error "Failed to set execute permission on monitor script"; exit 1; } | |
log_message "Created and set permissions for monitor script: $MONITOR_SCRIPT_PATH" | |
else | |
log_message "Monitor script already exists: $MONITOR_SCRIPT_PATH" | |
fi | |
# Create a systemd service if it doesn't already exist | |
SERVICE_NAME="restrict_${PROCESS_NAME}" | |
SERVICE_PATH="/etc/systemd/system/${SERVICE_NAME}.service" | |
if [[ ! -f "$SERVICE_PATH" ]]; then | |
cat << EOF > "$SERVICE_PATH" | |
[Unit] | |
Description=Restrict CPU and Memory for processes ending with $PROCESS_NAME | |
After=network.target | |
[Service] | |
Type=simple | |
ExecStart=$MONITOR_SCRIPT_PATH | |
Restart=always | |
[Install] | |
WantedBy=multi-user.target | |
EOF | |
log_message "Created systemd service file: $SERVICE_PATH" | |
else | |
log_message "Systemd service file already exists: $SERVICE_PATH" | |
fi | |
# Enable and start the systemd service | |
if ! systemctl is-enabled "$SERVICE_NAME.service" &> /dev/null; then | |
systemctl enable "$SERVICE_NAME.service" || { log_error "Failed to enable systemd service"; exit 1; } | |
log_message "Systemd service $SERVICE_NAME has been enabled" | |
else | |
log_message "Systemd service $SERVICE_NAME is already enabled" | |
fi | |
systemctl restart "$SERVICE_NAME.service" || { log_error "Failed to restart systemd service"; exit 1; } | |
log_message "Systemd service $SERVICE_NAME has been restarted" | |
echo "Cgroup configuration for processes ending with '$PROCESS_NAME' applied or updated." | |
echo "These processes are now restricted to CPUs $CPU_LIMIT and a maximum of ${RAM_LIMIT_MB}MB of memory." | |
echo "The configuration will persist across reboots and apply to current and future instances of processes ending with '$PROCESS_NAME'." |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
enable_thp_and_hugetlb_in_grub() { | |
local grub_file="/etc/default/grub" | |
local grub_backup="/etc/default/grub.bak" | |
local thp_param="transparent_hugepage=always" | |
# Backup current GRUB configuration | |
echo "Backing up current GRUB configuration..." | |
sudo cp "${grub_file}" "${grub_backup}" | |
echo "Backup created at ${grub_backup}" | |
# Calculate total memory and 20% of it in kB | |
local total_memory_kb=$(grep MemTotal /proc/meminfo | awk '{print $2}') | |
local max_hugepages_memory_kb=$((total_memory_kb * 20 / 100)) | |
# Set the maximum allowed HugeTLB memory to 8GB | |
local max_hugepages_allowed_kb=$((8 * 1024 * 1024)) | |
# Use the lower value between 20% of total memory and 8GB | |
if [ "$max_hugepages_memory_kb" -gt "$max_hugepages_allowed_kb" ]; then | |
max_hugepages_memory_kb=$max_hugepages_allowed_kb | |
fi | |
# Calculate the number of 2MB huge pages to reserve | |
local hugepages_size_kb=2048 | |
local hugepages_count=$((max_hugepages_memory_kb / hugepages_size_kb)) | |
echo "Total system memory: $((total_memory_kb / 1024)) MB" | |
echo "Memory to reserve for HugeTLB: $((max_hugepages_memory_kb / 1024)) MB" | |
echo "Reserving $hugepages_count HugeTLB pages of 2 MB each." | |
# Add transparent_hugepage and HugeTLB parameters to GRUB_CMDLINE_LINUX_DEFAULT | |
if grep -q "transparent_hugepage=" "${grub_file}"; then | |
echo "Modifying existing transparent_hugepage setting..." | |
sudo sed -i "s/transparent_hugepage=[a-z]*/${thp_param}/" "${grub_file}" | |
else | |
echo "Adding transparent_hugepage setting to GRUB_CMDLINE_LINUX_DEFAULT..." | |
sudo sed -i "s/GRUB_CMDLINE_LINUX_DEFAULT=\"/&${thp_param} /" "${grub_file}" | |
fi | |
# Add HugeTLB parameters | |
if grep -q "hugepagesz=" "${grub_file}"; then | |
echo "Modifying existing HugeTLB settings..." | |
sudo sed -i "s/hugepagesz=[0-9]*[KMG]*/hugepagesz=${hugepages_size_kb}K/" "${grub_file}" | |
sudo sed -i "s/hugepages=[0-9]*/hugepages=${hugepages_count}/" "${grub_file}" | |
else | |
echo "Adding HugeTLB settings to GRUB_CMDLINE_LINUX_DEFAULT..." | |
sudo sed -i "s/GRUB_CMDLINE_LINUX_DEFAULT=\"/&hugepagesz=${hugepages_size_kb}K hugepages=${hugepages_count} /" "${grub_file}" | |
fi | |
# Update GRUB | |
echo "Updating GRUB configuration..." | |
sudo update-grub | |
echo "Transparent Huge Pages and HugeTLB pages configured. Please reboot your system." | |
} | |
# Execute the function | |
enable_thp_and_hugetlb_in_grub |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# mv /etc/sysctl.conf /etc/sysctl_backup.conf | |
# sudo nano /etc/sysctl.conf | |
net.ipv4.ip_local_port_range = 10240 65535 | |
net.ipv4.tcp_rmem = 65536 1048576 8388608 | |
net.ipv4.tcp_wmem = 65536 1048576 8388608 | |
net.ipv4.tcp_mem= 1073741824 4294967296 8589934592 | |
net.core.rmem_max = 8388608 | |
net.core.wmem_max = 8388608 | |
net.core.rmem_default = 1048576 | |
net.core.wmem_default = 1048576 | |
fs.pipe-max-size = 8388608 | |
net.core.somaxconn = 32768 | |
net.core.netdev_budget = 600 | |
net.core.dev_weight = 128 | |
net.ipv4.tcp_timestamps = 0 | |
# 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 | |
# Disable ICMP redirect acceptance | |
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 | |
# Enable IP spoofing protection | |
net.ipv4.conf.all.rp_filter = 1 | |
net.ipv4.conf.default.rp_filter = 1 | |
# Log Martian Packets | |
net.ipv4.conf.all.log_martians = 1 | |
net.ipv4.conf.default.log_martians = 1 | |
# Disable IPv6 | |
net.ipv6.conf.all.disable_ipv6 = 1 | |
net.ipv6.conf.default.disable_ipv6 = 1 | |
# Disable acceptance of router advertisements | |
net.ipv6.conf.all.accept_ra = 0 | |
net.ipv6.conf.default.accept_ra = 0 | |
# sudo sysctl -p |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Script to create and manage multiple swap files | |
# Configuration Variables | |
SWAP_SIZE="1G" # Size of each swap file | |
SWAP_PREFIX="/swapfile" # Prefix for swap file names | |
SWAPPINESS=30 # Swappiness value, bigger the RAM lower the value of this param | |
MAX_SWAP_SIZE_GB=16 # Maximum swap size in GB | |
# Error handling function | |
handle_error() { | |
echo "Error: $1" | |
exit 1 | |
} | |
# Ensure necessary commands are available | |
command -v fallocate >/dev/null 2>&1 || handle_error "fallocate is required but not installed." | |
command -v mkswap >/dev/null 2>&1 || handle_error "mkswap is required but not installed." | |
command -v swapon >/dev/null 2>&1 || handle_error "swapon is required but not installed." | |
# Get total RAM size in GB | |
TOTAL_RAM_GB=$(free -g | awk '/^Mem:/{print $2}') | |
if [ -z "$TOTAL_RAM_GB" ] || [ "$TOTAL_RAM_GB" -eq 0 ]; then | |
echo "Unable to determine total RAM size. Defaulting to 16GB." | |
TOTAL_RAM_GB=16 | |
fi | |
# Calculate the maximum number of swap files based on the limit (16GB) | |
SWAP_COUNT=$((MAX_SWAP_SIZE_GB)) | |
# Check available disk space where swap files will be created | |
DISK_SPACE_AVAILABLE=$(df --output=avail -BG / | tail -1 | sed 's/G//') | |
TOTAL_SWAP_SIZE_REQUIRED=$((SWAP_COUNT * 1)) # Each swap file is 1GB, so SWAP_COUNT * 1 | |
if [ "$DISK_SPACE_AVAILABLE" -lt "$TOTAL_SWAP_SIZE_REQUIRED" ]; then | |
handle_error "Not enough disk space. Required: ${TOTAL_SWAP_SIZE_REQUIRED}GB, Available: ${DISK_SPACE_AVAILABLE}GB." | |
fi | |
# Create and enable multiple swap files | |
for i in $(seq 1 $SWAP_COUNT); do | |
SWAP_FILE="${SWAP_PREFIX}${i}" | |
if [ ! -f "$SWAP_FILE" ]; then | |
echo "Creating swap file: $SWAP_FILE" | |
if ! sudo fallocate -l $SWAP_SIZE $SWAP_FILE; then | |
handle_error "Failed to allocate swap file $SWAP_FILE." | |
fi | |
sudo chmod 600 $SWAP_FILE || handle_error "Failed to set permissions on $SWAP_FILE." | |
sudo mkswap $SWAP_FILE || handle_error "Failed to create swap area on $SWAP_FILE." | |
sleep 5 | |
sudo swapon $SWAP_FILE || handle_error "Failed to enable swap on $SWAP_FILE." | |
else | |
echo "Swap file $SWAP_FILE already exists" | |
fi | |
done | |
# Verify swap files | |
sudo swapon --show || handle_error "Failed to display active swap files." | |
free -h || handle_error "Failed to display memory usage." | |
# Make swap files persistent across reboots | |
echo "Updating /etc/fstab" | |
for i in $(seq 1 $SWAP_COUNT); do | |
SWAP_FILE="${SWAP_PREFIX}${i}" | |
if ! grep -q "$SWAP_FILE" /etc/fstab; then | |
echo "$SWAP_FILE none swap sw 0 0" | sudo tee -a /etc/fstab || handle_error "Failed to update /etc/fstab." | |
else | |
echo "Swap file $SWAP_FILE already in /etc/fstab" | |
fi | |
done | |
# Adjust swappiness if needed | |
current_swappiness=$(sysctl vm.swappiness | awk '{print $3}') | |
if [ "$current_swappiness" -ne "$SWAPPINESS" ]; then | |
echo "Setting vm.swappiness to $SWAPPINESS" | |
sudo sysctl vm.swappiness=$SWAPPINESS || handle_error "Failed to set vm.swappiness." | |
sudo sed -i "s/^vm.swappiness=.*/vm.swappiness=$SWAPPINESS/" /etc/sysctl.conf || echo "vm.swappiness=$SWAPPINESS" | sudo tee -a /etc/sysctl.conf | |
else | |
echo "vm.swappiness is already set to $SWAPPINESS" | |
fi | |
echo "Swap configuration complete." |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Define paths | |
SYSCTL_SCRIPT_PATH="$HOME/set_sysctl_params.sh" | |
PLIST_PATH="/Library/LaunchDaemons/com.user.setsysctlparams.plist" | |
# Create the shell script for setting sysctl parameters | |
echo "Creating sysctl script at $SYSCTL_SCRIPT_PATH" | |
cat << 'EOF' > "$SYSCTL_SCRIPT_PATH" | |
#!/bin/bash | |
sysctl kern.sysv.shmmax=134217728 | |
sysctl kern.sysv.shmmin=1 | |
sysctl kern.sysv.shmmni=1048576 | |
sysctl kern.sysv.shmseg=1024 | |
sysctl kern.sysv.shmall=1048576 | |
sysctl kern.ipc.somaxconn=32767 | |
sysctl kern.maxfiles=1048576 | |
sysctl kern.maxvnodes=1048576 | |
sysctl kern.maxfilesperproc=8192 | |
sysctl kern.ipc.maxsockbuf=134217728 | |
sysctl net.inet.tcp.delayed_ack=0 | |
sysctl net.inet.ip.forwarding=0 | |
sysctl net.inet.icmp.bmcastecho=0 | |
sysctl net.inet.tcp.blackhole=2 | |
sysctl net.inet.udp.blackhole=1 | |
sysctl net.inet.tcp.msl=3000 | |
sysctl net.inet.tcp.mssdflt=1460 | |
sysctl net.inet.tcp.win_scale_factor=2 | |
sysctl net.inet.tcp.sendspace=1048576 | |
sysctl net.inet.tcp.recvspace=1048576 | |
sysctl net.inet.tcp.autorcvbufmax=134217728 | |
sysctl net.inet.tcp.autosndbufmax=134217728 | |
sysctl net.inet.ip.portrange.first=32768 | |
sysctl net.inet.ip.portrange.last=65535 | |
EOF | |
# Make the shell script executable | |
echo "Making the sysctl script executable" | |
chmod +x "$SYSCTL_SCRIPT_PATH" | |
# Verify the script creation | |
if [ ! -f "$SYSCTL_SCRIPT_PATH" ]; then | |
echo "Failed to create the sysctl script" | |
exit 1 | |
fi | |
# Create the LaunchDaemon plist file | |
echo "Creating LaunchDaemon plist at $PLIST_PATH" | |
sudo tee "$PLIST_PATH" > /dev/null << EOF | |
<?xml version="1.0" encoding="UTF-8"?> | |
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |
<plist version="1.0"> | |
<dict> | |
<key>Label</key> | |
<string>com.user.setsysctlparams</string> | |
<key>ProgramArguments</key> | |
<array> | |
<string>/bin/bash</string> | |
<string>$SYSCTL_SCRIPT_PATH</string> | |
</array> | |
<key>RunAtLoad</key> | |
<true/> | |
<key>KeepAlive</key> | |
<true/> | |
</dict> | |
</plist> | |
EOF | |
# Set proper permissions for the plist file | |
echo "Setting permissions for the plist file" | |
sudo chmod 644 "$PLIST_PATH" | |
# Verify the plist creation | |
if [ ! -f "$PLIST_PATH" ]; then | |
echo "Failed to create the plist file" | |
exit 1 | |
fi | |
# Load the LaunchDaemon | |
echo "Loading the LaunchDaemon" | |
sudo launchctl unload "$PLIST_PATH" | |
sudo launchctl load "$PLIST_PATH" | |
# Check for errors | |
if [ $? -eq 0 ]; then | |
echo "Setup complete. The sysctl parameters will be set at startup." | |
else | |
echo "Failed to load the LaunchDaemon. Please check the plist file and permissions." | |
echo "Contents of the plist file:" | |
cat "$PLIST_PATH" | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment