#!/bin/bash ###################################################################################### #### Version 2.00 #### #### For questions or comments contact@mylinux.work #### #### Author : Phil Connor #### #### #### #### Notes : #### #### This script configures sysctl network and system tuning on Linux servers. #### #### It writes an idempotent drop-in file to /etc/sysctl.d/ so it can be run #### #### multiple times safely without duplicating settings. #### #### #### #### Use this script at your OWN risk. There is no guarantee whatsoever. #### #### #### #### Usage: #### #### networktuning.sh - Standard tuning (HDD) #### #### networktuning.sh ssd - SSD-optimized dirty page settings #### #### networktuning.sh nvme - NVMe-optimized dirty page settings #### #### networktuning.sh --bbr - Enable BBR congestion control #### #### networktuning.sh ssd --bbr - SSD + BBR #### #### networktuning.sh --router - Enable IP forwarding #### #### networktuning.sh --dry-run - Show config without applying #### #### networktuning.sh --rollback - Restore previous configuration #### ###################################################################################### set -euo pipefail ########################## #### System Variables #### ########################## HOST=$(hostname) CONF_FILE="/etc/sysctl.d/99-network-tuning.conf" BACKUP_DIR="/etc/sysctl.d/backups" STORAGE_TYPE="hdd" ENABLE_BBR=false ENABLE_ROUTER=false DRY_RUN=false ROLLBACK=false ######################### #### Color Variables #### ######################### RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' ###################### #### Root Check #### ###################### if [[ $EUID -ne 0 ]]; then echo -e "${RED}Error: This script must be run as root${NC}" exit 1 fi ############################## #### Parse CLI Arguments #### ############################## for arg in "$@"; do case "$arg" in ssd) STORAGE_TYPE="ssd" ;; nvme) STORAGE_TYPE="nvme" ;; --bbr) ENABLE_BBR=true ;; --router) ENABLE_ROUTER=true ;; --dry-run) DRY_RUN=true ;; --rollback) ROLLBACK=true ;; --help|-h) echo "Usage: $(basename "$0") [ssd|nvme] [--bbr] [--router] [--dry-run] [--rollback]" echo "" echo "Options:" echo " ssd Optimize dirty page settings for SSD storage" echo " nvme Optimize dirty page settings for NVMe storage" echo " --bbr Enable BBR congestion control (requires kernel 4.9+)" echo " --router Enable IP forwarding (IPv4 and IPv6)" echo " --dry-run Display the configuration without applying it" echo " --rollback Restore the previous configuration backup" echo " --help Show this help message" exit 0 ;; *) echo -e "${RED}Unknown option: $arg${NC}" echo "Use --help for usage information" exit 1 ;; esac done ################################## #### Detect OS and OS Version #### ################################## if [[ ! -f /etc/os-release ]]; then echo -e "${RED}Error: /etc/os-release not found. Unsupported system.${NC}" exit 1 fi OS_ID=$(. /etc/os-release && echo "${ID}") OS_VERSION=$(. /etc/os-release && echo "${VERSION_ID}" | cut -d. -f1) # shellcheck disable=SC2034 case "$OS_ID" in ubuntu|debian) PAKMGR="apt-get -y" ;; centos|rhel|oracle|rocky|almalinux|fedora) if [[ "$OS_VERSION" -le 7 ]]; then PAKMGR="yum -y" else PAKMGR="dnf -y" fi ;; *) echo -e "${YELLOW}Warning: Unrecognized OS '${OS_ID}'. Proceeding without package manager.${NC}" PAKMGR="" ;; esac ################################ #### Handle Rollback #### ################################ if [[ "$ROLLBACK" == true ]]; then LATEST_BACKUP=$(find "$BACKUP_DIR" -name "99-network-tuning.conf.*" -type f 2>/dev/null | sort -r | head -1) if [[ -z "$LATEST_BACKUP" ]]; then echo -e "${RED}Error: No backup found in $BACKUP_DIR${NC}" exit 1 fi echo -e "${GREEN}Restoring from: $LATEST_BACKUP${NC}" cp "$LATEST_BACKUP" "$CONF_FILE" sysctl --system > /dev/null 2>&1 echo -e "${GREEN}Rollback complete. Settings applied.${NC}" exit 0 fi ########################## #### Sysctl Variables #### ########################## MEM_BYTES=$(awk '/MemTotal:/ { printf "%0.f",$2 * 1024}' /proc/meminfo) MEM_KB=$(awk '/MemTotal:/ { printf "%0.f",$2}' /proc/meminfo) MAX_ORPHAN=$((MEM_BYTES / 10 / 65536)) FILE_MAX=$((MEM_BYTES / 4194304 * 256)) MAX_TW=$((FILE_MAX * 2)) MIN_FREE=$((MEM_KB / 100)) ###################################### #### Storage-based dirty settings #### ###################################### case "$STORAGE_TYPE" in hdd) VM_DIRTY_BG_RATIO=5 VM_DIRTY_RATIO=15 ;; ssd) VM_DIRTY_BG_RATIO=3 VM_DIRTY_RATIO=5 ;; nvme) VM_DIRTY_BG_RATIO=1 VM_DIRTY_RATIO=3 ;; esac #################################### #### BBR availability check #### #################################### if [[ "$ENABLE_BBR" == true ]]; then if ! modprobe tcp_bbr 2>/dev/null; then echo -e "${YELLOW}Warning: BBR kernel module not available. Skipping BBR configuration.${NC}" ENABLE_BBR=false fi fi ################################# #### Generate Configuration #### ################################# echo "#######################################" echo "#### Network Tuning for $HOST" echo "#### Storage: $STORAGE_TYPE | BBR: $ENABLE_BBR | Router: $ENABLE_ROUTER" echo "#######################################" CONFIG=$(cat << EOF ############################################################################### # Network Tuning Configuration # Generated: $(date '+%Y-%m-%d %H:%M:%S') # Host: $HOST # Storage: $STORAGE_TYPE | BBR: $ENABLE_BBR | Router: $ENABLE_ROUTER # Generator: networktuning.sh v2.00 ############################################################################### ############################ #### Performance Tuning #### ############################ # Enable SYN cookies for SYN flood protection net.ipv4.tcp_syncookies = 1 # Basic TCP tuning net.ipv4.tcp_keepalive_time = 600 net.ipv4.tcp_synack_retries = 3 net.ipv4.tcp_syn_retries = 3 # RFC1337 — handle TIME-WAIT assassination hazards net.ipv4.tcp_rfc1337 = 1 # Defines the local port range used by TCP and UDP net.ipv4.ip_local_port_range = 1024 65535 # Log Martian packets with impossible addresses net.ipv4.conf.all.log_martians = 1 net.ipv4.conf.default.log_martians = 1 # Enable window scaling (RFC1323) net.ipv4.tcp_window_scaling = 1 # Enable timestamps (RFC1323) net.ipv4.tcp_timestamps = 1 # Enable selective acknowledgments net.ipv4.tcp_sack = 1 # Allow TCP to send duplicate SACKs net.ipv4.tcp_dsack = 1 # Loose reverse path filtering (compatible with cloud/multihomed) net.ipv4.conf.default.rp_filter = 2 net.ipv4.conf.all.rp_filter = 2 # Max remembered connection requests in SYN backlog net.ipv4.tcp_max_syn_backlog = 20000 # Max orphaned TCP sockets (calculated from system memory) net.ipv4.tcp_max_orphans = $MAX_ORPHAN # Retries before killing an orphaned TCP connection net.ipv4.tcp_orphan_retries = 1 # Time to hold sockets in FIN-WAIT-2 state (seconds) net.ipv4.tcp_fin_timeout = 20 # Maximum TIME-WAIT sockets held simultaneously net.ipv4.tcp_max_tw_buckets = $MAX_TW # Don't cache ssthresh from previous connections net.ipv4.tcp_no_metrics_save = 1 # Enable receive buffer auto-tuning net.ipv4.tcp_moderate_rcvbuf = 1 # TCP buffer auto-tuning limits (min default max bytes) net.ipv4.tcp_rmem = 4096 87380 16777216 net.ipv4.tcp_wmem = 4096 65536 16777216 # Max socket buffer sizes net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 # Network device backlog queue length net.core.netdev_max_backlog = 2500 # Max pending connections in listen queue net.core.somaxconn = 65000 ############################ #### VM / Storage Tuning ### ############################ # Prefer keeping processes in memory over swapping (1 = minimal swap) vm.swappiness = 1 # Dirty page writeback ratios (tuned for $STORAGE_TYPE) # Monitor with: grep -A 1 dirty /proc/vmstat vm.dirty_background_ratio = $VM_DIRTY_BG_RATIO vm.dirty_ratio = $VM_DIRTY_RATIO # Required free memory (1% of physical RAM) vm.min_free_kbytes = $MIN_FREE # System open file limit (calculated from system memory) fs.file-max = $FILE_MAX ############################ #### Kernel Settings #### ############################ # Kernel log levels kernel.printk = 4 4 1 7 kernel.core_uses_pid = 1 kernel.sysrq = 0 # Disable core dumps for setuid programs fs.suid_dumpable = 0 ########################### #### Security Settings #### ########################### # Full ASLR (randomize stack, VDSO, mmap, heap) kernel.randomize_va_space = 2 # Don't accept 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 # Don't send ICMP redirects net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.default.send_redirects = 0 # Don't accept IP source route packets net.ipv4.conf.all.accept_source_route = 0 net.ipv4.conf.default.accept_source_route = 0 net.ipv6.conf.all.accept_source_route = 0 # Ignore ICMP broadcasts and bogus error responses net.ipv4.icmp_echo_ignore_broadcasts = 1 net.ipv4.icmp_ignore_bogus_error_responses = 1 # IPv6 router advertisement hardening net.ipv6.conf.default.accept_ra_rtr_pref = 0 net.ipv6.conf.all.accept_ra_rtr_pref = 0 net.ipv6.conf.default.accept_ra_pinfo = 0 net.ipv6.conf.all.accept_ra_pinfo = 0 net.ipv6.conf.default.accept_ra_defrtr = 0 net.ipv6.conf.all.accept_ra_defrtr = 0 EOF ) # Append BBR congestion control if enabled if [[ "$ENABLE_BBR" == true ]]; then CONFIG+=$(cat << 'EOF' ########################### #### BBR Congestion #### ########################### # Use fair queuing packet scheduler (required for BBR) net.core.default_qdisc = fq # Enable BBR congestion control algorithm net.ipv4.tcp_congestion_control = bbr EOF ) fi # Append router/forwarding settings if enabled if [[ "$ENABLE_ROUTER" == true ]]; then CONFIG+=$(cat << 'EOF' ########################### #### Router / Forward #### ########################### # Enable IP forwarding (IPv4 and IPv6) net.ipv4.ip_forward = 1 net.ipv6.conf.all.forwarding = 1 EOF ) fi ############################## #### Apply Configuration #### ############################## if [[ "$DRY_RUN" == true ]]; then echo "" echo -e "${YELLOW}--- Dry Run: Configuration Preview ---${NC}" echo "$CONFIG" echo -e "${YELLOW}--- End Preview ---${NC}" exit 0 fi # Create backup directory mkdir -p "$BACKUP_DIR" # Backup existing config if present if [[ -f "$CONF_FILE" ]]; then cp "$CONF_FILE" "${BACKUP_DIR}/99-network-tuning.conf.$(date +%Y%m%d-%H%M%S)" echo -e "${GREEN}Backed up existing config to $BACKUP_DIR${NC}" fi # Write configuration atomically TEMP_FILE=$(mktemp) echo "$CONFIG" > "$TEMP_FILE" # Validate before installing if sysctl -p "$TEMP_FILE" > /dev/null 2>&1; then mv "$TEMP_FILE" "$CONF_FILE" chmod 644 "$CONF_FILE" sysctl --system > /dev/null 2>&1 echo -e "${GREEN}Network tuning applied successfully to $CONF_FILE${NC}" else echo -e "${RED}Error: Configuration validation failed. No changes applied.${NC}" echo -e "${RED}Review errors above and check kernel compatibility.${NC}" rm -f "$TEMP_FILE" exit 1 fi echo -e "${GREEN}Done. Use 'sysctl --system' to verify or '$(basename "$0") --rollback' to revert.${NC}" exit 0