Skip to content

Instantly share code, notes, and snippets.

@corporatepiyush
Last active August 24, 2024 06:48
Show Gist options
  • Save corporatepiyush/061123b340babf28d51e568b44bf9ab3 to your computer and use it in GitHub Desktop.
Save corporatepiyush/061123b340babf28d51e568b44bf9ab3 to your computer and use it in GitHub Desktop.
MacOS and Linux Optimisation and hardening
#!/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."
#!/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
#!/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
#!/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'."
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
# 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
#!/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."
#!/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