|
#!/bin/bash |
|
|
|
# ============================================================================== |
|
# Ultimate macOS Server Optimization Script |
|
# Adheres to CLI Output Style Guide (v1.0) |
|
# ============================================================================== |
|
|
|
# ───────────────────────────────────────────────────────────────────────────── |
|
# CLI Output Utilities (Style Guide Implementation) |
|
# ───────────────────────────────────────────────────────────────────────────── |
|
|
|
_use_color() { |
|
[[ -z "${NO_COLOR:-}" ]] && [[ "${FORCE_COLOR:-}" == "1" || -t 1 ]] && [[ "${TERM:-}" != "dumb" ]] |
|
} |
|
|
|
if _use_color; then |
|
_RED='\033[0;31m' |
|
_GREEN='\033[0;32m' |
|
_YELLOW='\033[0;33m' |
|
_BLUE='\033[0;34m' |
|
_PURPLE='\033[0;35m' |
|
_CYAN='\033[0;36m' |
|
_WHITE='\033[0;37m' |
|
_GRAY='\033[0;90m' |
|
_NC='\033[0m' |
|
|
|
_CHECK="${_GREEN}[✓]${_NC}" |
|
_CROSS="${_RED}[✗]${_NC}" |
|
_WARN="${_YELLOW}[!]${_NC}" |
|
_INFO="${_CYAN}[i]${_NC}" |
|
else |
|
_RED='' _GREEN='' _YELLOW='' _BLUE='' _PURPLE='' _CYAN='' _WHITE='' _GRAY='' _NC='' |
|
_CHECK='[+]' _CROSS='[x]' _WARN='[!]' _INFO='[i]' |
|
fi |
|
|
|
# Counters for final summary |
|
_PASS=0 |
|
_FAIL=0 |
|
_SKIP=0 |
|
|
|
log_success() { echo -e "$_CHECK $1"; ((_PASS++)); } |
|
log_error() { echo -e "$_CROSS $1" >&2; ((_FAIL++)); } |
|
log_warn() { echo -e "$_WARN $1"; ((_SKIP++)); } |
|
log_info() { echo -e "$_INFO $1"; } |
|
|
|
print_divider() { |
|
local color="${1:-$_PURPLE}" label="${2:-}" |
|
local width="${COLUMNS:-80}" |
|
|
|
if [[ -n "$label" ]]; then |
|
local padding=$((width - ${#label} - 6)) |
|
local line; printf -v line '%*s' "$padding" ''; line="${line// /━}" |
|
printf '%b━━━━[%s]%s%b\n' "$color" "$label" "$line" "$_NC" |
|
else |
|
local line; printf -v line '%*s' "$width" ''; line="${line// /━}" |
|
printf '%b%s%b\n' "$color" "$line" "$_NC" |
|
fi |
|
} |
|
|
|
# ───────────────────────────────────────────────────────────────────────────── |
|
# Pre-flight Checks |
|
# ───────────────────────────────────────────────────────────────────────────── |
|
|
|
if [[ $EUID -ne 0 ]]; then |
|
log_error "Permission denied. This script must be run as root." |
|
echo -e " Run with elevated privileges:" |
|
echo -e " $ sudo $0" |
|
exit 1 |
|
fi |
|
|
|
# ───────────────────────────────────────────────────────────────────────────── |
|
# Main Execution |
|
# ───────────────────────────────────────────────────────────────────────────── |
|
|
|
TOTAL_STEPS=13 |
|
STEP=0 |
|
|
|
print_divider "$_PURPLE" "macOS Server Optimization" |
|
echo "" |
|
|
|
# 1. SERVER PERFORMANCE MODE |
|
# ----------------------------------------------------------------------------- |
|
((STEP++)) |
|
log_info "Step ${STEP}/${TOTAL_STEPS}: Checking Server Performance Mode..." |
|
|
|
current_boot_args=$(nvram boot-args 2>/dev/null | cut -f 2-) |
|
|
|
if [[ "$current_boot_args" != *"serverperfmode=1"* ]]; then |
|
if nvram boot-args="serverperfmode=1 $current_boot_args"; then |
|
log_success "Enabled Server Performance Mode (reboot required)" |
|
else |
|
log_error "Failed to set Server Performance Mode" |
|
echo -e " Check NVRAM access or SIP status:" |
|
echo -e " $ csrutil status" |
|
fi |
|
else |
|
log_success "Server Performance Mode is already active" |
|
fi |
|
echo "" |
|
|
|
# 2. POWER MANAGEMENT |
|
# ----------------------------------------------------------------------------- |
|
((STEP++)) |
|
print_divider "$_BLUE" "Step ${STEP}/${TOTAL_STEPS}: Power Management" |
|
|
|
log_info "Configuring 'Always On' power settings..." |
|
|
|
pmset -a sleep 0 && log_success "System sleep disabled" |
|
pmset -a displaysleep 0 && log_success "Display sleep disabled" |
|
pmset -a disksleep 0 && log_success "Disk sleep disabled" |
|
pmset -a womp 1 && log_success "Wake on Ethernet enabled" |
|
pmset -a autorestart 1 && log_success "Auto-restart on power loss enabled" |
|
pmset -a tcpkeepalive 1 && log_success "TCP KeepAlive enabled" |
|
|
|
# Disable standby/hibernation for always-on server |
|
pmset -a standby 0 && log_success "Standby mode disabled" |
|
pmset -a autopoweroff 0 && log_success "Auto power-off disabled" |
|
pmset -a hibernatemode 0 && log_success "Hibernate mode disabled (pure sleep)" |
|
pmset -a powernap 0 && log_success "Power Nap disabled" |
|
pmset -a ttyskeepawake 1 && log_success "TTY sessions prevent sleep" |
|
|
|
# High Power Mode (supported Macs only, fails gracefully) |
|
if pmset -a powermode 2 2>/dev/null; then |
|
log_success "High Power Mode enabled (fans run at higher speeds)" |
|
else |
|
log_warn "High Power Mode not available on this Mac (skipped)" |
|
fi |
|
|
|
# Disable proximity wake (Bluetooth wakes from nearby devices) |
|
if pmset -a proximitywake 0 2>/dev/null; then |
|
log_success "Proximity wake disabled" |
|
else |
|
log_warn "Proximity wake setting not available (skipped)" |
|
fi |
|
echo "" |
|
|
|
# 3. DISABLE SPOTLIGHT & TIME MACHINE |
|
# ----------------------------------------------------------------------------- |
|
((STEP++)) |
|
print_divider "$_BLUE" "Step ${STEP}/${TOTAL_STEPS}: Services & Background Tasks" |
|
|
|
log_info "Disabling resource-heavy background services..." |
|
|
|
if mdutil -i off -a > /dev/null 2>&1; then |
|
log_success "Spotlight indexing disabled on all volumes" |
|
else |
|
log_warn "Failed to fully disable Spotlight (check SIP status)" |
|
fi |
|
|
|
if tmutil disable > /dev/null 2>&1; then |
|
log_success "Time Machine auto-backups disabled" |
|
else |
|
log_warn "Time Machine is already disabled or not configured" |
|
fi |
|
echo "" |
|
|
|
# 4. ADVANCED NETWORK & KERNEL TUNING |
|
# ----------------------------------------------------------------------------- |
|
((STEP++)) |
|
print_divider "$_BLUE" "Step ${STEP}/${TOTAL_STEPS}: Network & Kernel Tuning" |
|
|
|
PLIST_PATH="/Library/LaunchDaemons/com.server.sysctl.plist" |
|
log_info "Installing persistent sysctl configuration..." |
|
|
|
cat <<EOF > "$PLIST_PATH" |
|
<?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.server.sysctl</string> |
|
<key>ProgramArguments</key> |
|
<array> |
|
<string>/usr/sbin/sysctl</string> |
|
<string>-w</string> |
|
<!-- File descriptor and process limits --> |
|
<string>kern.maxfiles=65536</string> |
|
<string>kern.maxfilesperproc=32768</string> |
|
<!-- Socket buffer limits --> |
|
<string>kern.ipc.maxsockbuf=16777216</string> |
|
<string>kern.ipc.somaxconn=8192</string> |
|
<!-- TCP send/receive buffer sizes (1MB each) --> |
|
<string>net.inet.tcp.sendspace=1048576</string> |
|
<string>net.inet.tcp.recvspace=1048576</string> |
|
<!-- TCP window scaling for high-bandwidth networks --> |
|
<string>net.inet.tcp.win_scale_factor=8</string> |
|
<!-- Disable delayed ACK for lower latency --> |
|
<string>net.inet.tcp.delayed_ack=0</string> |
|
<!-- Maximum segment size (accounts for TCP timestamps) --> |
|
<string>net.inet.tcp.mssdflt=1448</string> |
|
<!-- Ephemeral port range --> |
|
<string>net.inet.ip.portrange.first=1024</string> |
|
<string>net.inet.ip.portrange.last=65535</string> |
|
<!-- TCP autotuning buffer maximums (32MB) for high-speed networks --> |
|
<string>net.inet.tcp.autorcvbufmax=33554432</string> |
|
<string>net.inet.tcp.autosndbufmax=33554432</string> |
|
<!-- Enable RFC1323 TCP High Performance (window scaling + timestamps) --> |
|
<string>net.inet.tcp.rfc1323=1</string> |
|
<!-- Stealth mode - silently drop probes on closed ports --> |
|
<string>net.inet.tcp.blackhole=2</string> |
|
<string>net.inet.udp.blackhole=1</string> |
|
<!-- Slow start flight size - faster ramp-up on new connections --> |
|
<string>net.inet.tcp.slowstart_flightsize=20</string> |
|
<!-- Maximum Segment Lifetime - reduce TIME_WAIT duration (ms) --> |
|
<string>net.inet.tcp.msl=15000</string> |
|
<!-- IPv6 MSS default --> |
|
<string>net.inet.tcp.v6mssdflt=1412</string> |
|
<!-- ICMP rate limit --> |
|
<string>net.inet.icmp.icmplim=50</string> |
|
</array> |
|
<key>RunAtLoad</key> |
|
<true/> |
|
</dict> |
|
</plist> |
|
EOF |
|
|
|
if [[ -f "$PLIST_PATH" ]]; then |
|
chown root:wheel "$PLIST_PATH" |
|
chmod 644 "$PLIST_PATH" |
|
log_success "Created LaunchDaemon at ${_BLUE}${PLIST_PATH}${_NC}" |
|
|
|
launchctl unload "$PLIST_PATH" 2>/dev/null |
|
if launchctl load -w "$PLIST_PATH"; then |
|
log_success "Loaded kernel tuning configuration" |
|
else |
|
log_error "Failed to load LaunchDaemon at ${_BLUE}${PLIST_PATH}${_NC}" |
|
echo -e " Verify the plist syntax and permissions:" |
|
echo -e " $ plutil -lint ${PLIST_PATH}" |
|
echo -e " $ ls -la ${PLIST_PATH}" |
|
fi |
|
else |
|
log_error "Failed to create plist file at ${_BLUE}${PLIST_PATH}${_NC}" |
|
echo -e " Check that the directory exists and is writable:" |
|
echo -e " $ ls -la /Library/LaunchDaemons/" |
|
fi |
|
echo "" |
|
|
|
# 5. FILE DESCRIPTOR & PROCESS LIMITS |
|
# ----------------------------------------------------------------------------- |
|
((STEP++)) |
|
print_divider "$_BLUE" "Step ${STEP}/${TOTAL_STEPS}: File Descriptor & Process Limits" |
|
|
|
log_info "Configuring persistent file descriptor limits..." |
|
|
|
LIMITS_PLIST="/Library/LaunchDaemons/com.server.limits.plist" |
|
cat <<EOF > "$LIMITS_PLIST" |
|
<?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.server.limits</string> |
|
<key>ProgramArguments</key> |
|
<array> |
|
<string>launchctl</string> |
|
<string>limit</string> |
|
<string>maxfiles</string> |
|
<string>65536</string> |
|
<string>524288</string> |
|
</array> |
|
<key>RunAtLoad</key> |
|
<true/> |
|
<key>ServiceIPC</key> |
|
<false/> |
|
</dict> |
|
</plist> |
|
EOF |
|
|
|
chown root:wheel "$LIMITS_PLIST" |
|
chmod 644 "$LIMITS_PLIST" |
|
|
|
launchctl unload "$LIMITS_PLIST" 2>/dev/null |
|
if launchctl load -w "$LIMITS_PLIST"; then |
|
log_success "File descriptor limits: soft=65536, hard=524288" |
|
else |
|
log_error "Failed to load file descriptor limits" |
|
echo -e " Verify the plist:" |
|
echo -e " $ plutil -lint ${LIMITS_PLIST}" |
|
fi |
|
|
|
# Apply immediately for current session |
|
if launchctl limit maxfiles 65536 524288 2>/dev/null; then |
|
log_success "Applied file descriptor limits to current session" |
|
else |
|
log_warn "Could not apply file descriptor limits to current session" |
|
fi |
|
|
|
MAXPROC_PLIST="/Library/LaunchDaemons/com.server.maxproc.plist" |
|
cat <<EOF > "$MAXPROC_PLIST" |
|
<?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.server.maxproc</string> |
|
<key>ProgramArguments</key> |
|
<array> |
|
<string>launchctl</string> |
|
<string>limit</string> |
|
<string>maxproc</string> |
|
<string>2048</string> |
|
<string>4096</string> |
|
</array> |
|
<key>RunAtLoad</key> |
|
<true/> |
|
<key>ServiceIPC</key> |
|
<false/> |
|
</dict> |
|
</plist> |
|
EOF |
|
|
|
chown root:wheel "$MAXPROC_PLIST" |
|
chmod 644 "$MAXPROC_PLIST" |
|
|
|
launchctl unload "$MAXPROC_PLIST" 2>/dev/null |
|
if launchctl load -w "$MAXPROC_PLIST"; then |
|
log_success "Process limits: soft=2048, hard=4096" |
|
else |
|
log_error "Failed to load process limits" |
|
echo -e " Verify the plist:" |
|
echo -e " $ plutil -lint ${MAXPROC_PLIST}" |
|
fi |
|
|
|
if launchctl limit maxproc 2048 4096 2>/dev/null; then |
|
log_success "Applied process limits to current session" |
|
else |
|
log_warn "Could not apply process limits to current session" |
|
fi |
|
echo "" |
|
|
|
# 6. DISABLE UNNECESSARY DAEMONS & AGENTS |
|
# ----------------------------------------------------------------------------- |
|
((STEP++)) |
|
print_divider "$_BLUE" "Step ${STEP}/${TOTAL_STEPS}: Disable Unnecessary Daemons & Agents" |
|
|
|
log_info "Disabling non-essential system services for server use..." |
|
|
|
# System-level daemons to disable |
|
SYSTEM_DAEMONS=( |
|
com.apple.analyticsd # Apple analytics/telemetry |
|
com.apple.osanalytics.osanalyticshelper # OS analytics helper |
|
com.apple.SubmitDiagInfo # Diagnostic submission |
|
com.apple.symptomsd-diag # Diagnostics |
|
com.apple.rtcreportingd # RTC reporting |
|
com.apple.systemstats.daily # System statistics |
|
com.apple.systemstats.analysis # System stats analysis |
|
com.apple.systemstats.microstackshot_periodic # Microstackshot sampling |
|
com.apple.wifianalyticsd # WiFi analytics |
|
com.apple.GameController.gamecontrollerd # Game controller |
|
com.apple.netbiosd # NetBIOS (SMB browsing) |
|
com.apple.memoryanalyticsd # Memory analytics |
|
) |
|
|
|
for daemon in "${SYSTEM_DAEMONS[@]}"; do |
|
if launchctl bootout system/"${daemon}" 2>/dev/null && \ |
|
launchctl disable system/"${daemon}" 2>/dev/null; then |
|
log_success "Disabled system/${daemon}" |
|
else |
|
log_warn "Could not disable ${daemon} (may require SIP off or already disabled)" |
|
fi |
|
done |
|
|
|
# User-level agents to disable (if running as sudo with a real user) |
|
if [ -n "$SUDO_USER" ]; then |
|
USER_UID=$(id -u "$SUDO_USER") |
|
|
|
USER_AGENTS=( |
|
com.apple.ReportCrash # Crash reporter agent |
|
com.apple.gamed # Game Center |
|
com.apple.knowledge-agent # Knowledge/Siri learning |
|
com.apple.parsecd # Parsec (Siri/search) |
|
com.apple.parsec-fbf # Parsec feedback |
|
com.apple.suggestd # Suggestions daemon |
|
com.apple.tipsd # Tips notifications |
|
com.apple.ap.adprivacyd # Ad privacy |
|
com.apple.ap.adservicesd # Ad services |
|
com.apple.ap.promotedcontentd # Promoted content |
|
com.apple.BiomeAgent # Biome/usage tracking |
|
com.apple.biomesyncd # Biome sync |
|
com.apple.UsageTrackingAgent # Usage tracking |
|
com.apple.routined # Location routines |
|
com.apple.triald # A/B trial experiments |
|
com.apple.intelligenceplatformd # Apple Intelligence |
|
com.apple.mediaanalysisd # Media analysis (Photos) |
|
com.apple.photoanalysisd # Photo analysis (face detect) |
|
com.apple.newsd # Apple News |
|
com.apple.SafariBookmarksSyncAgent # Safari bookmark sync |
|
com.apple.SafariCloudHistoryPushAgent # Safari cloud history |
|
com.apple.amsaccountsd # App Store account |
|
com.apple.amsengagementd # App Store engagement |
|
com.apple.transparencyd # Transparency daemon |
|
) |
|
|
|
for agent in "${USER_AGENTS[@]}"; do |
|
if launchctl bootout gui/"${USER_UID}"/"${agent}" 2>/dev/null && \ |
|
launchctl disable gui/"${USER_UID}"/"${agent}" 2>/dev/null; then |
|
log_success "Disabled gui/${USER_UID}/${agent}" |
|
else |
|
log_warn "Could not disable ${agent} (may require SIP off or already disabled)" |
|
fi |
|
done |
|
fi |
|
echo "" |
|
|
|
# 7. UI & ANIMATION KILLER |
|
# ----------------------------------------------------------------------------- |
|
((STEP++)) |
|
print_divider "$_BLUE" "Step ${STEP}/${TOTAL_STEPS}: UI & Animation Stripping" |
|
|
|
if [ -n "$SUDO_USER" ]; then |
|
log_info "Applying settings for user: ${_BLUE}${SUDO_USER}${_NC}" |
|
|
|
# Window animations |
|
sudo -u "$SUDO_USER" defaults write NSGlobalDomain NSAutomaticWindowAnimationsEnabled -bool false |
|
sudo -u "$SUDO_USER" defaults write NSGlobalDomain NSWindowResizeTime -float 0.001 |
|
sudo -u "$SUDO_USER" defaults write -g QLPanelAnimationDuration -float 0 |
|
|
|
# Finder animations |
|
sudo -u "$SUDO_USER" defaults write com.apple.finder DisableAllAnimations -bool true |
|
|
|
# Dock animations |
|
sudo -u "$SUDO_USER" defaults write com.apple.dock launchanim -bool false |
|
sudo -u "$SUDO_USER" defaults write com.apple.dock autohide-time-modifier -float 0 |
|
sudo -u "$SUDO_USER" defaults write com.apple.dock autohide-delay -float 0 |
|
sudo -u "$SUDO_USER" defaults write com.apple.dock expose-animation-duration -float 0 |
|
sudo -u "$SUDO_USER" defaults write com.apple.dock mineffect -string "scale" |
|
|
|
# Reduce motion and transparency system-wide |
|
sudo -u "$SUDO_USER" defaults write com.apple.Accessibility DifferentiateWithoutColor -int 1 |
|
sudo -u "$SUDO_USER" defaults write com.apple.Accessibility ReduceMotionEnabled -int 1 |
|
sudo -u "$SUDO_USER" defaults write com.apple.universalaccess reduceMotion -int 1 |
|
sudo -u "$SUDO_USER" defaults write com.apple.universalaccess reduceTransparency -int 1 |
|
|
|
# Disable window tiling margins (Sequoia+) |
|
sudo -u "$SUDO_USER" defaults write com.apple.WindowManager EnableTiledWindowMargins -bool false 2>/dev/null |
|
|
|
log_success "Disabled all window, Finder, Dock, and motion animations" |
|
|
|
killall Finder 2>/dev/null && log_success "Restarted Finder" |
|
killall Dock 2>/dev/null && log_success "Restarted Dock" |
|
else |
|
log_warn "Running in non-interactive root shell — skipping user UI tweaks" |
|
fi |
|
echo "" |
|
|
|
# 8. SYSTEM NOISE REDUCTION |
|
# ----------------------------------------------------------------------------- |
|
((STEP++)) |
|
print_divider "$_BLUE" "Step ${STEP}/${TOTAL_STEPS}: System Noise Reduction" |
|
|
|
defaults write com.apple.CrashReporter DialogType -string "none" |
|
log_success "Disabled Crash Reporter dialogs" |
|
|
|
softwareupdate --schedule on > /dev/null 2>&1 |
|
log_success "Enabled critical security updates schedule" |
|
|
|
# Mute startup chime |
|
if nvram StartupMute=%01 2>/dev/null; then |
|
log_success "Muted startup chime" |
|
else |
|
log_warn "Could not mute startup chime (NVRAM not writable)" |
|
fi |
|
|
|
# Disable .DS_Store on network and USB drives |
|
if [ -n "$SUDO_USER" ]; then |
|
sudo -u "$SUDO_USER" defaults write com.apple.desktopservices DSDontWriteNetworkStores -bool true |
|
sudo -u "$SUDO_USER" defaults write com.apple.desktopservices DSDontWriteUSBStores -bool true |
|
log_success "Disabled .DS_Store creation on network/USB volumes" |
|
|
|
# Disable session state saving (faster reboot) |
|
sudo -u "$SUDO_USER" defaults write com.apple.loginwindow TALLogoutSavesState -bool false |
|
log_success "Disabled session state restoration on reboot" |
|
fi |
|
|
|
# Disable screen lock (for headless server use) |
|
# Uncomment the following if this is a headless server: |
|
# defaults write com.apple.loginwindow DisableScreenLock -bool true |
|
# log_success "Disabled screen lock (headless mode)" |
|
echo "" |
|
|
|
# 9. PRIVACY & TELEMETRY REDUCTION |
|
# ----------------------------------------------------------------------------- |
|
((STEP++)) |
|
print_divider "$_BLUE" "Step ${STEP}/${TOTAL_STEPS}: Privacy & Telemetry Reduction" |
|
|
|
log_info "Disabling analytics and telemetry..." |
|
|
|
if [ -n "$SUDO_USER" ]; then |
|
# Disable Siri |
|
sudo -u "$SUDO_USER" defaults write com.apple.assistant.support "Assistant Enabled" -bool false |
|
sudo -u "$SUDO_USER" defaults write com.apple.Siri StatusMenuVisible -bool false |
|
sudo -u "$SUDO_USER" defaults write com.apple.Siri UserHasDeclinedEnable -bool true |
|
log_success "Disabled Siri" |
|
|
|
# Disable Spotlight web suggestions |
|
sudo -u "$SUDO_USER" defaults write com.apple.lookup.shared LookupSuggestionsDisabled -bool true |
|
log_success "Disabled Spotlight web suggestions" |
|
|
|
# Disable personalized ads |
|
sudo -u "$SUDO_USER" defaults write com.apple.AdLib allowApplePersonalizedAdvertising -bool false |
|
log_success "Disabled Apple personalized advertising" |
|
|
|
# Disable all text auto-corrections (server = no typing) |
|
sudo -u "$SUDO_USER" defaults write NSGlobalDomain NSAutomaticCapitalizationEnabled -bool false |
|
sudo -u "$SUDO_USER" defaults write NSGlobalDomain NSAutomaticDashSubstitutionEnabled -bool false |
|
sudo -u "$SUDO_USER" defaults write NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool false |
|
sudo -u "$SUDO_USER" defaults write NSGlobalDomain NSAutomaticPeriodSubstitutionEnabled -bool false |
|
sudo -u "$SUDO_USER" defaults write NSGlobalDomain NSAutomaticSpellingCorrectionEnabled -bool false |
|
sudo -u "$SUDO_USER" defaults write NSGlobalDomain NSAutomaticTextCompletionEnabled -bool false |
|
log_success "Disabled all automatic text corrections" |
|
|
|
# Prevent Photos from auto-launching on device connect |
|
sudo -u "$SUDO_USER" defaults -currentHost write com.apple.ImageCapture disableHotPlug -bool true |
|
log_success "Disabled Photos auto-launch on device connect" |
|
|
|
# Prevent apps from going to sleep (keep background processes active) |
|
sudo -u "$SUDO_USER" defaults write NSGlobalDomain NSAppSleepDisabled -bool true |
|
log_success "Disabled App Nap (apps stay active in background)" |
|
fi |
|
|
|
# System-level analytics opt-out |
|
defaults write "/Library/Application Support/CrashReporter/DiagnosticMessagesHistory.plist" AutoSubmit -bool false 2>/dev/null |
|
defaults write "/Library/Application Support/CrashReporter/DiagnosticMessagesHistory.plist" ThirdPartyDataSubmit -bool false 2>/dev/null |
|
log_success "Opted out of diagnostic data submission" |
|
echo "" |
|
|
|
# 10. SOFTWARE UPDATE CONTROL |
|
# ----------------------------------------------------------------------------- |
|
((STEP++)) |
|
print_divider "$_BLUE" "Step ${STEP}/${TOTAL_STEPS}: Software Update Control" |
|
|
|
log_info "Configuring update behavior for server stability..." |
|
|
|
# Disable automatic download of updates (manual control for servers) |
|
defaults write /Library/Preferences/com.apple.SoftwareUpdate AutomaticDownload -bool false |
|
log_success "Disabled automatic update downloads" |
|
|
|
# Disable auto-install of macOS updates (prevent surprise reboots) |
|
defaults write /Library/Preferences/com.apple.SoftwareUpdate AutomaticallyInstallMacOSUpdates -bool false |
|
log_success "Disabled automatic macOS update installation" |
|
|
|
# Keep critical security updates enabled |
|
defaults write /Library/Preferences/com.apple.SoftwareUpdate CriticalUpdateInstall -int 1 |
|
log_success "Critical security updates remain enabled" |
|
|
|
# Disable App Store auto-updates |
|
defaults write /Library/Preferences/com.apple.commerce AutoUpdate -bool false |
|
log_success "Disabled App Store auto-updates" |
|
echo "" |
|
|
|
# 11. LOGIN WINDOW & BOOT OPTIMIZATION |
|
# ----------------------------------------------------------------------------- |
|
((STEP++)) |
|
print_divider "$_BLUE" "Step ${STEP}/${TOTAL_STEPS}: Login & Boot Optimization" |
|
|
|
log_info "Configuring login and boot settings..." |
|
|
|
# Show host info at login window (useful for server identification) |
|
defaults write /Library/Preferences/com.apple.loginwindow AdminHostInfo HostName |
|
log_success "Login window shows hostname on clock click" |
|
|
|
# Disable login window input menu |
|
defaults write /Library/Preferences/com.apple.loginwindow showInputMenu -bool false |
|
log_success "Disabled login window input menu" |
|
|
|
# Expand save/print panels by default |
|
if [ -n "$SUDO_USER" ]; then |
|
sudo -u "$SUDO_USER" defaults write NSGlobalDomain NSNavPanelExpandedStateForSaveMode -bool true |
|
sudo -u "$SUDO_USER" defaults write NSGlobalDomain NSNavPanelExpandedStateForSaveMode2 -bool true |
|
sudo -u "$SUDO_USER" defaults write NSGlobalDomain PMPrintingExpandedStateForPrint -bool true |
|
sudo -u "$SUDO_USER" defaults write NSGlobalDomain PMPrintingExpandedStateForPrint2 -bool true |
|
log_success "Expanded save/print panels by default" |
|
|
|
# Save to disk, not iCloud, by default |
|
sudo -u "$SUDO_USER" defaults write NSGlobalDomain NSDocumentSaveNewDocumentsToCloud -bool false |
|
log_success "Default save location set to disk (not iCloud)" |
|
fi |
|
|
|
# Set desktop wallpaper to blank (reduce GPU compositing) |
|
defaults write /Library/Preferences/com.apple.loginwindow DesktopPicture "" 2>/dev/null |
|
log_success "Cleared login window desktop picture" |
|
echo "" |
|
|
|
# 12. DISABLE BLUETOOTH & AIRDROP (HEADLESS SERVER) |
|
# ----------------------------------------------------------------------------- |
|
((STEP++)) |
|
print_divider "$_BLUE" "Step ${STEP}/${TOTAL_STEPS}: Wireless Services (Headless Server)" |
|
|
|
log_info "Disabling wireless services for headless operation..." |
|
log_warn "Skip this section if you need Bluetooth or AirDrop" |
|
|
|
# Disable Bluetooth (if not needed) |
|
if command -v blueutil &>/dev/null; then |
|
blueutil --power 0 |
|
log_success "Bluetooth powered off via blueutil" |
|
else |
|
if launchctl disable system/com.apple.bluetoothd 2>/dev/null; then |
|
log_success "Bluetooth daemon disabled" |
|
else |
|
log_warn "Could not disable Bluetooth daemon (SIP or missing blueutil)" |
|
echo -e " Install blueutil for reliable control:" |
|
echo -e " $ brew install blueutil" |
|
fi |
|
fi |
|
|
|
# Disable AirDrop |
|
if [ -n "$SUDO_USER" ]; then |
|
sudo -u "$SUDO_USER" defaults write com.apple.NetworkBrowser DisableAirDrop -bool true 2>/dev/null |
|
log_success "AirDrop disabled" |
|
fi |
|
|
|
# Disable Location Services (server doesn't need GPS) |
|
if launchctl disable system/com.apple.locationd 2>/dev/null; then |
|
log_success "Location services daemon disabled" |
|
else |
|
log_warn "Could not disable locationd (may require SIP off)" |
|
echo -e " Check SIP status:" |
|
echo -e " $ csrutil status" |
|
fi |
|
|
|
# Disable Find My Mac messenger (server-specific) |
|
if launchctl disable system/com.apple.findmymacmessenger 2>/dev/null; then |
|
log_success "Find My Mac messenger disabled" |
|
else |
|
log_warn "Could not disable Find My Mac messenger" |
|
fi |
|
echo "" |
|
|
|
# 13. PRINTING / CUPS (IF NOT NEEDED) |
|
# ----------------------------------------------------------------------------- |
|
((STEP++)) |
|
print_divider "$_BLUE" "Step ${STEP}/${TOTAL_STEPS}: Printing Services" |
|
|
|
log_info "Disabling printing services (not needed on most servers)..." |
|
|
|
if launchctl disable system/org.cups.cupsd 2>/dev/null; then |
|
log_success "CUPS print daemon disabled" |
|
else |
|
log_warn "Could not disable CUPS (may require SIP off)" |
|
echo -e " Check SIP status:" |
|
echo -e " $ csrutil status" |
|
fi |
|
|
|
if launchctl disable system/org.cups.cups-lpd 2>/dev/null; then |
|
log_success "CUPS LPD daemon disabled" |
|
else |
|
log_warn "Could not disable CUPS LPD daemon" |
|
fi |
|
echo "" |
|
|
|
# ───────────────────────────────────────────────────────────────────────────── |
|
# SYSTEM INFORMATION |
|
# ───────────────────────────────────────────────────────────────────────────── |
|
|
|
print_divider "$_CYAN" "System Information" |
|
echo "" |
|
log_info "Current kernel limits after tuning:" |
|
echo "" |
|
printf " ${_GRAY}%-34s %s${_NC}\n" "kern.maxfiles:" "$(sysctl -n kern.maxfiles 2>/dev/null)" |
|
printf " ${_GRAY}%-34s %s${_NC}\n" "kern.maxfilesperproc:" "$(sysctl -n kern.maxfilesperproc 2>/dev/null)" |
|
printf " ${_GRAY}%-34s %s${_NC}\n" "kern.maxproc:" "$(sysctl -n kern.maxproc 2>/dev/null)" |
|
printf " ${_GRAY}%-34s %s${_NC}\n" "kern.maxprocperuid:" "$(sysctl -n kern.maxprocperuid 2>/dev/null)" |
|
printf " ${_GRAY}%-34s %s${_NC}\n" "kern.ipc.somaxconn:" "$(sysctl -n kern.ipc.somaxconn 2>/dev/null)" |
|
printf " ${_GRAY}%-34s %s${_NC}\n" "kern.ipc.maxsockbuf:" "$(sysctl -n kern.ipc.maxsockbuf 2>/dev/null)" |
|
echo "" |
|
printf " ${_GRAY}%-34s %s${_NC}\n" "net.inet.tcp.sendspace:" "$(sysctl -n net.inet.tcp.sendspace 2>/dev/null)" |
|
printf " ${_GRAY}%-34s %s${_NC}\n" "net.inet.tcp.recvspace:" "$(sysctl -n net.inet.tcp.recvspace 2>/dev/null)" |
|
printf " ${_GRAY}%-34s %s${_NC}\n" "net.inet.tcp.win_scale_factor:" "$(sysctl -n net.inet.tcp.win_scale_factor 2>/dev/null)" |
|
printf " ${_GRAY}%-34s %s${_NC}\n" "net.inet.tcp.autorcvbufmax:" "$(sysctl -n net.inet.tcp.autorcvbufmax 2>/dev/null)" |
|
printf " ${_GRAY}%-34s %s${_NC}\n" "net.inet.tcp.autosndbufmax:" "$(sysctl -n net.inet.tcp.autosndbufmax 2>/dev/null)" |
|
echo "" |
|
|
|
current_maxfiles=$(launchctl limit maxfiles 2>/dev/null) |
|
log_info "launchctl maxfiles: ${current_maxfiles}" |
|
|
|
# Show server perf mode status |
|
if command -v serverinfo &>/dev/null; then |
|
serverinfo --perfmode 2>/dev/null && log_info "Server info available" |
|
fi |
|
echo "" |
|
print_divider "$_CYAN" |
|
|
|
# ───────────────────────────────────────────────────────────────────────────── |
|
# COMPLETION SUMMARY |
|
# ───────────────────────────────────────────────────────────────────────────── |
|
|
|
echo "" |
|
print_divider "$_GREEN" "Optimization Complete" |
|
echo "" |
|
log_info "Result: ${_GREEN}${_PASS} passed${_NC}, ${_YELLOW}${_SKIP} skipped${_NC}, ${_RED}${_FAIL} failed${_NC}" |
|
echo "" |
|
|
|
if ((_FAIL > 0)); then |
|
log_warn "Some operations failed. Review errors above for remediation steps." |
|
echo "" |
|
fi |
|
|
|
echo -e "${_YELLOW}[!] A system reboot is STRONGLY recommended to apply all kernel changes.${_NC}" |
|
echo "" |
|
echo -e " ${_GRAY}Optimizations applied:${_NC}" |
|
echo -e " ${_GRAY} • Standby/hibernate/Power Nap disabled for always-on operation${_NC}" |
|
echo -e " ${_GRAY} • High Power Mode enabled (where supported)${_NC}" |
|
echo -e " ${_GRAY} • File descriptor limits raised to 65536/524288 (soft/hard)${_NC}" |
|
echo -e " ${_GRAY} • Process limits raised to 2048/4096 (soft/hard)${_NC}" |
|
echo -e " ${_GRAY} • TCP autotuning buffers raised to 32MB for high-speed networks${_NC}" |
|
echo -e " ${_GRAY} • RFC1323 high-performance TCP explicitly enabled${_NC}" |
|
echo -e " ${_GRAY} • TCP/UDP blackhole mode (stealth on closed ports)${_NC}" |
|
echo -e " ${_GRAY} • TIME_WAIT reduction via MSL tuning${_NC}" |
|
echo -e " ${_GRAY} • ~25 unnecessary daemons/agents disabled (analytics, telemetry, games)${_NC}" |
|
echo -e " ${_GRAY} • Reduce Motion & Transparency enabled system-wide${_NC}" |
|
echo -e " ${_GRAY} • Siri, ads, and all text auto-corrections disabled${_NC}" |
|
echo -e " ${_GRAY} • App Nap disabled (background processes stay active)${_NC}" |
|
echo -e " ${_GRAY} • Software updates set to manual (no surprise reboots)${_NC}" |
|
echo -e " ${_GRAY} • Bluetooth, AirDrop, Location Services, CUPS disabled${_NC}" |
|
echo -e " ${_GRAY} • .DS_Store disabled on network/USB volumes${_NC}" |
|
echo -e " ${_GRAY} • Session state restoration disabled for faster reboots${_NC}" |
|
echo -e " ${_GRAY} • Startup chime muted${_NC}" |
|
echo "" |
|
print_divider "$_GREEN" |
|
echo "" |