1051 lines
No EOL
36 KiB
Bash
1051 lines
No EOL
36 KiB
Bash
#!/usr/bin/env bash
|
|
|
|
# shellcheck disable=1117
|
|
# shellcheck disable=2162
|
|
|
|
# Enforce script only be run on Proxmox hosts
|
|
if [ ! -f "/etc/pve/.version" ] ; then
|
|
echo "ERROR: This script only supports Proxmox"
|
|
exit 1
|
|
fi
|
|
|
|
if [ -f "/etc/system-optimization" ] ; then
|
|
echo "ERROR: Script can only be run once"
|
|
exit 1
|
|
fi
|
|
|
|
function ask-user() {
|
|
|
|
# Check for AMD processors (EPYC or Ryzen)
|
|
echo -e "Check for AMD processors (EPYC or Ryzen)"
|
|
if [ "$(grep -i -m 1 "model name" /proc/cpuinfo | grep -i "EPYC")" != "" ]; then
|
|
echo "AMD EPYC detected"
|
|
if [ -z "$PMX_AMDFIXES" ]; then
|
|
read -p "Do you want to enable AMD fixes? (yes/no): " PMX_AMDFIXES
|
|
fi
|
|
elif [ "$(grep -i -m 1 "model name" /proc/cpuinfo | grep -i "Ryzen")" != "" ]; then
|
|
echo "AMD Ryzen detected"
|
|
if [ -z "$PMX_AMDFIXES" ]; then
|
|
read -p "Do you want to enable AMD fixes? (yes/no): " PMX_AMDFIXES
|
|
fi
|
|
else
|
|
sleep 1
|
|
echo -e "Non-AMD processor detected... Assuming Intel processor."
|
|
fi
|
|
|
|
# Force APT to use IPv4
|
|
if [ -z "$PMX_APTIPV4" ]; then
|
|
while true; do
|
|
read -p "Do you want to force APT to use IPv4? (yes/no): " PMX_APTIPV4
|
|
case "$PMX_APTIPV4" in
|
|
yes|no) break ;;
|
|
*) echo "Please answer 'yes' or 'no'." ;;
|
|
esac
|
|
done
|
|
fi
|
|
|
|
# Update Proxmox and install various system utils
|
|
if [ -z "$PMX_APTUPGRADE" ]; then
|
|
while true; do
|
|
read -p "Do you want to update Proxmox and install various system utilities? (yes/no): " PMX_APTUPGRADE
|
|
case "$PMX_APTUPGRADE" in
|
|
yes|no) break ;;
|
|
*) echo "Please answer 'yes' or 'no'." ;;
|
|
esac
|
|
done
|
|
fi
|
|
|
|
# Customize bashrc
|
|
if [ -z "$PMX_BASHRC" ]; then
|
|
while true; do
|
|
read -p "Do you want to customize bashrc? (yes/no): " PMX_BASHRC
|
|
case "$PMX_BASHRC" in
|
|
yes|no) break ;;
|
|
*) echo "Please answer 'yes' or 'no'." ;;
|
|
esac
|
|
done
|
|
fi
|
|
|
|
# Add the latest Ceph provided by Proxmox
|
|
if [ -z "$PMX_CEPH" ]; then
|
|
while true; do
|
|
read -p "Do you want to add the latest Ceph provided by Proxmox? (yes/no): " PMX_CEPH
|
|
case "$PMX_CEPH" in
|
|
yes|no) break ;;
|
|
*) echo "Please answer 'yes' or 'no'." ;;
|
|
esac
|
|
done
|
|
fi
|
|
|
|
# Disable portmapper / rpcbind for security
|
|
if [ -z "$PMX_DISABLERPC" ]; then
|
|
while true; do
|
|
read -p "Do you want to disable portmapper/rpcbind for security? (yes/no): " PMX_DISABLERPC
|
|
case "$PMX_DISABLERPC" in
|
|
yes|no) break ;;
|
|
*) echo "Please answer 'yes' or 'no'." ;;
|
|
esac
|
|
done
|
|
fi
|
|
|
|
# Ensure Entropy Pools are Populated
|
|
if [ -z "$PMX_ENTROPY" ]; then
|
|
while true; do
|
|
read -p "Do you want to ensure entropy pools are populated? (yes/no): " PMX_ENTROPY
|
|
case "$PMX_ENTROPY" in
|
|
yes|no) break ;;
|
|
*) echo "Please answer 'yes' or 'no'." ;;
|
|
esac
|
|
done
|
|
fi
|
|
|
|
# Protect the web interface with fail2ban
|
|
if [ -z "$PMX_FAIL2BAN" ]; then
|
|
while true; do
|
|
read -p "Do you want to protect the web interface with fail2ban? (yes/no): " PMX_FAIL2BAN
|
|
case "$PMX_FAIL2BAN" in
|
|
yes|no) break ;;
|
|
*) echo "Please answer 'yes' or 'no'." ;;
|
|
esac
|
|
done
|
|
fi
|
|
|
|
# Install ifupdown2 for a virtual internal network
|
|
if [ -z "$PMX_IFUPDOWN2" ]; then
|
|
while true; do
|
|
read -p "Do you want to install ifupdown2 for a virtual internal network? (yes/no): " PMX_IFUPDOWN2
|
|
case "$PMX_IFUPDOWN2" in
|
|
yes|no) break ;;
|
|
*) echo "Please answer 'yes' or 'no'." ;;
|
|
esac
|
|
done
|
|
fi
|
|
|
|
# Limit the size and optimize journald
|
|
if [ -z "$PMX_JOURNALD" ]; then
|
|
while true; do
|
|
read -p "Do you want to limit the size and optimize journald? (yes/no): " PMX_JOURNALD
|
|
case "$PMX_JOURNALD" in
|
|
yes|no) break ;;
|
|
*) echo "Please answer 'yes' or 'no'." ;;
|
|
esac
|
|
done
|
|
fi
|
|
|
|
# Install kernel source headers
|
|
if [ -z "$PMX_KERNELHEADERS" ]; then
|
|
while true; do
|
|
read -p "Do you want to install kernel source headers? (yes/no): " PMX_KERNELHEADERS
|
|
case "$PMX_KERNELHEADERS" in
|
|
yes|no) break ;;
|
|
*) echo "Please answer 'yes' or 'no'." ;;
|
|
esac
|
|
done
|
|
fi
|
|
|
|
# Ensure ksmtuned is enabled and optimize according to RAM size
|
|
if [ -z "$PMX_KSMTUNED" ]; then
|
|
while true; do
|
|
read -p "Do you want to ensure ksmtuned is enabled and optimize according to RAM size? (yes/no): " PMX_KSMTUNED
|
|
case "$PMX_KSMTUNED" in
|
|
yes|no) break ;;
|
|
*) echo "Please answer 'yes' or 'no'." ;;
|
|
esac
|
|
done
|
|
fi
|
|
|
|
# Set language to en_US.UTF-8
|
|
if [ -z "$PMX_LANG" ]; then
|
|
while true; do
|
|
read -p "Do you want to set the language to en_US.UTF-8? (yes/no): " PMX_LANG
|
|
case "$PMX_LANG" in
|
|
yes|no) break ;;
|
|
*) echo "Please answer 'yes' or 'no'." ;;
|
|
esac
|
|
done
|
|
fi
|
|
|
|
# Enable restart on kernel panic, kernel oops, and hardlockup
|
|
if [ -z "$PMX_KERNELPANIC" ]; then
|
|
while true; do
|
|
read -p "Do you want to enable restart on kernel panic, kernel oops, and hardlockup? (yes/no): " PMX_KERNELPANIC
|
|
case "$PMX_KERNELPANIC" in
|
|
yes|no) break ;;
|
|
*) echo "Please answer 'yes' or 'no'." ;;
|
|
esac
|
|
done
|
|
fi
|
|
|
|
# Increase max user watches, FD limit, FD ulimit, and max key limit
|
|
if [ -z "$PMX_LIMITS" ]; then
|
|
while true; do
|
|
read -p "Do you want to increase max user watches, FD limit, FD ulimit, and max key limit? (yes/no): " PMX_LIMITS
|
|
case "$PMX_LIMITS" in
|
|
yes|no) break ;;
|
|
*) echo "Please answer 'yes' or 'no'." ;;
|
|
esac
|
|
done
|
|
fi
|
|
|
|
# Optimize logrotate
|
|
if [ -z "$PMX_LOGROTATE" ]; then
|
|
while true; do
|
|
read -p "Do you want to optimize logrotate? (yes/no): " PMX_LOGROTATE
|
|
case "$PMX_LOGROTATE" in
|
|
yes|no) break ;;
|
|
*) echo "Please answer 'yes' or 'no'." ;;
|
|
esac
|
|
done
|
|
fi
|
|
|
|
# 2FA for SSH and TUI
|
|
if [ -z "$PMX_2FA" ]; then
|
|
while true; do
|
|
read -p "Do you want 2FA for SSH and TUI? (yes/no): " PMX_2FA
|
|
case "$PMX_2FA" in
|
|
yes|no) break ;;
|
|
*) echo "Please answer 'yes' or 'no'." ;;
|
|
esac
|
|
done
|
|
fi
|
|
|
|
# Summary Section
|
|
echo -e "\nSummary of your answers:"
|
|
echo "PMX_AMDFIXES: ${PMX_AMDFIXES:-not set}"
|
|
echo "PMX_APTIPV4: ${PMX_APTIPV4:-not set}"
|
|
echo "PMX_APTUPGRADE: ${PMX_APTUPGRADE:-not set}"
|
|
echo "PMX_BASHRC: ${PMX_BASHRC:-not set}"
|
|
echo "PMX_CEPH: ${PMX_CEPH:-not set}"
|
|
echo "PMX_DISABLERPC: ${PMX_DISABLERPC:-not set}"
|
|
echo "PMX_ENTROPY: ${PMX_ENTROPY:-not set}"
|
|
echo "PMX_FAIL2BAN: ${PMX_FAIL2BAN:-not set}"
|
|
echo "PMX_IFUPDOWN2: ${PMX_IFUPDOWN2:-not set}"
|
|
echo "PMX_JOURNALD: ${PMX_JOURNALD:-not set}"
|
|
echo "PMX_KERNELHEADERS: ${PMX_KERNELHEADERS:-not set}"
|
|
echo "PMX_KSMTUNED: ${PMX_KSMTUNED:-not set}"
|
|
echo "PMX_LANG: ${PMX_LANG:-not set}"
|
|
echo "PMX_KERNELPANIC: ${PMX_KERNELPANIC:-not set}"
|
|
echo "PMX_LIMITS: ${PMX_LIMITS:-not set}"
|
|
echo "PMX_LOGROTATE: ${PMX_LOGROTATE:-not set}"
|
|
echo "PMX_2FA: ${PMX_2FA:-not set}"
|
|
|
|
}
|
|
|
|
## Main Process
|
|
|
|
function main() {
|
|
echo "Lets start with your chosen optimizations .... "
|
|
|
|
# Check if PMX_2FA is not set or is empty
|
|
if [ "${PMX_2FA,,}" == "yes" ] ; then
|
|
echo "2FA for SSH & TUI are not set, proceeding with 2FA setup."
|
|
# Update system packages
|
|
apt update && sudo apt upgrade -y
|
|
# Install necessary packages
|
|
apt install -y libpam-google-authenticator ssh
|
|
# Install Google Authenticator PAM module
|
|
apt install -y libpam-google-authenticator
|
|
# Configure SSH for 2FA
|
|
# Backup the original sshd_config file
|
|
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
|
|
# Modify sshd_config to enable ChallengeResponseAuthentication
|
|
sed -i 's/^#ChallengeResponseAuthentication no/ChallengeResponseAuthentication yes/' /etc/ssh/sshd_config
|
|
# Restart the SSH service to apply changes
|
|
systemctl restart sshd
|
|
# Set up Google Authenticator for the user
|
|
echo "Setting up Google Authenticator for user $(whoami)..."
|
|
# Run the Google Authenticator setup
|
|
google-authenticator
|
|
# Enable PAM Google Authenticator for TUI login
|
|
echo "Configuring TUI login with Google Authenticator..."
|
|
# Backup PAM's common-auth configuration file
|
|
cp /etc/pam.d/common-auth /etc/pam.d/common-auth.bak
|
|
# Add Google Authenticator PAM module to common-auth
|
|
echo "auth required pam_google_authenticator.so" | sudo tee -a /etc/pam.d/common-auth
|
|
# Apply changes to PAM configuration
|
|
systemctl restart systemd-logind
|
|
# Output success message
|
|
echo "2FA setup complete! Please verify by logging in via SSH or TUI."
|
|
# Inform user of next steps
|
|
echo "1. Use the Google Authenticator app to scan the QR code during the setup."
|
|
echo "2. After completing the setup, try logging in via SSH or a TTY session."
|
|
else
|
|
echo "PMX_2FA is set, skipping 2FA setup."
|
|
fi
|
|
|
|
# Set the local
|
|
if [ "$PMX_LANG" == "" ] ; then
|
|
PMX_LANG="en_US.UTF-8"
|
|
fi
|
|
echo -r "Set the locales"
|
|
export LANG="$PMX_LANG"
|
|
export LC_ALL="C"
|
|
|
|
# Get variables
|
|
echo -e "Get current OS information"
|
|
OS_CODENAME="$(grep "VERSION_CODENAME=" /etc/os-release | cut -d"=" -f 2 | xargs )"
|
|
echo -e "Get current RAM configuration"
|
|
RAM_SIZE_GB=$(( $(vmstat -s | grep -i "total memory" | xargs | cut -d" " -f 1) / 1024 / 1000))
|
|
|
|
if [ "${PMX_LANG}" == "en_US.UTF-8" ] && [ "${PMX_NOAPTLANG,,}" == "yes" ] ; then
|
|
# save bandwidth and skip downloading additional languages
|
|
echo -e "Disable translations:"
|
|
echo -e "Save bandwidth and skip downloading additional languages."
|
|
echo -e "Acquire::Languages \"none\";\\n" > /etc/apt/apt.conf.d/99-pmx-disable-translations
|
|
fi
|
|
|
|
if [ "${PMX_APTIPV4,,}" == "yes" ] ; then
|
|
# force APT to use IPv4
|
|
echo -e "Force APT to use IPv4."
|
|
echo -e "Acquire::ForceIPv4 \"true\";\\n" > /etc/apt/apt.conf.d/99-pmx-force-ipv4
|
|
fi
|
|
|
|
if [ "${PMX_NOENTREPO,,}" == "yes" ] ; then
|
|
# Disable enterprise proxmox repo
|
|
if [ -f /etc/apt/sources.list.d/pve-enterprise.list ]; then
|
|
echo -e "Disable Enterprise Proxmox Repo."
|
|
sed -i "s/^deb/#deb/g" /etc/apt/sources.list.d/pve-enterprise.list
|
|
fi
|
|
# Enable free public proxmox repo
|
|
if [ ! -f /etc/apt/sources.list.d/proxmox.list ] && [ ! -f /etc/apt/sources.list.d/pve-public-repo.list ] && [ ! -f /etc/apt/sources.list.d/pve-install-repo.list ] ; then
|
|
echo -e "Enable non-subscription Proxmox Repo."
|
|
echo -e "deb http://download.proxmox.com/debian/pve ${OS_CODENAME} pve-no-subscription\\n" > /etc/apt/sources.list.d/pve-public-repo.list
|
|
fi
|
|
if [ "${PMX_TESTREPO,,}" == "yes" ] ; then
|
|
# Enable Testing Proxmox Repo
|
|
echo -e "Enable Testing Proxmox Repo."
|
|
echo -e "deb http://download.proxmox.com/debian/pve ${OS_CODENAME} pvetest\\n" > /etc/apt/sources.list.d/pve-testing-repo.list
|
|
fi
|
|
fi
|
|
|
|
# Rebuild and add non-free to /etc/apt/sources.list
|
|
echo -e "Rebuild and add non-free to /etc/apt/sources.list"
|
|
cat <<EOF > /etc/apt/sources.list
|
|
deb https://ftp.debian.org/debian ${OS_CODENAME} main contrib
|
|
deb https://ftp.debian.org/debian ${OS_CODENAME}-updates main contrib
|
|
# non-free
|
|
deb https://httpredir.debian.org/debian/ ${OS_CODENAME} main contrib non-free
|
|
# security updates
|
|
deb https://security.debian.org/debian-security ${OS_CODENAME}/updates main contrib
|
|
EOF
|
|
|
|
# Refresh the package lists
|
|
echo -e "Refresh the package lists..."
|
|
apt-get update > /dev/null 2>&1
|
|
|
|
# Remove conflicting utilities
|
|
echo -e "Refresh the package lists"
|
|
/usr/bin/env DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::='--force-confdef' purge ntp openntpd systemd-timesyncd
|
|
|
|
# Fixes for common apt repo errors
|
|
echo -e "Refresh the package lists"
|
|
/usr/bin/env DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::='--force-confdef' install apt-transport-https debian-archive-keyring ca-certificates curl
|
|
|
|
if [ "${PMX_APTUPGRADE,,}" == "yes" ] ; then
|
|
# Update Proxmox and install a few imporant devops/sysadmin utils
|
|
echo -e "Update Proxmox and install a few imporant devops/sysadmin utils"
|
|
/usr/bin/env DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::='--force-confdef' dist-upgrade
|
|
pveam update
|
|
fi
|
|
|
|
# Install packages which are sometimes missing on Proxmox installs.
|
|
echo -e "Update Proxmox and install a few important devops/sysadmin utils"
|
|
/usr/bin/env DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::='--force-confdef' install zfsutils-linux proxmox-backup-restore-image chrony
|
|
|
|
if [ "${PMX_UTILS,,}" == "yes" ] ; then
|
|
# Install common system utilities
|
|
/usr/bin/env DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::='--force-confdef' install \
|
|
axel \
|
|
build-essential \
|
|
curl \
|
|
dialog \
|
|
dnsutils \
|
|
dos2unix \
|
|
git \
|
|
gnupg-agent \
|
|
grc \
|
|
htop \
|
|
iftop \
|
|
iotop \
|
|
iperf \
|
|
ipset \
|
|
iptraf \
|
|
mlocate \
|
|
msr-tools \
|
|
nano \
|
|
net-tools \
|
|
omping \
|
|
software-properties-common \
|
|
sshpass \
|
|
tmux \
|
|
unzip \
|
|
vim \
|
|
vim-nox \
|
|
wget \
|
|
whois \
|
|
zip \
|
|
ncdu \
|
|
duf
|
|
fi
|
|
|
|
if [ "${PMX_CEPH,,}" == "yes" ] ; then
|
|
# Add the latest CEPH packages provided by Proxmox
|
|
echo -e "Add the latest CEPH packages provided by Proxmox"
|
|
echo "deb http://download.proxmox.com/debian/ceph-pacific ${OS_CODENAME} main" > /etc/apt/sources.list.d/ceph-pacific.list
|
|
## Refresh the package lists
|
|
echo -e "Refresh the package lists..."
|
|
apt-get update > /dev/null 2>&1
|
|
## Install CEPH support
|
|
echo -e "Install CEPH support packages for Proxmox"
|
|
echo "Y" | pveceph install
|
|
fi
|
|
|
|
if [ "${PMX_LYNIS,,}" == "yes" ] ; then
|
|
# Lynis security scan tool by Cisofy
|
|
echo -e "Installing Lynis security scan tool"
|
|
wget -O - https://packages.cisofy.com/keys/cisofy-software-public.key | apt-key add -
|
|
## Add the latest lynis
|
|
echo "deb https://packages.cisofy.com/community/lynis/deb/ stable main" > /etc/apt/sources.list.d/cisofy-lynis.list
|
|
## Refresh the package lists
|
|
apt-get update > /dev/null 2>&1
|
|
/usr/bin/env DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::='--force-confdef' install lynis
|
|
fi
|
|
|
|
if [ "${PMX_OPENVSWITCH,,}" == "yes" ] && [ "${PMX_IFUPDOWN2}" == "no" ] ; then
|
|
## Install openvswitch for a virtual internal network
|
|
echo -e "Install openvswitch for a virtual internal network"
|
|
/usr/bin/env DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::='--force-confdef' install ifenslave ifupdown
|
|
/usr/bin/env DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::='--force-confdef' remove ifupdown2
|
|
/usr/bin/env DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::='--force-confdef' install openvswitch-switch
|
|
else
|
|
## Install ifupdown2 for a virtual internal network allows rebootless networking changes (not compatible with openvswitch-switch)
|
|
echo -e "Install ifupdown2 for a virtual internal network allows rebootless networking changes (not compatible with openvswitch-switch)"
|
|
/usr/bin/env DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::='--force-confdef' purge openvswitch-switch
|
|
/usr/bin/env DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::='--force-confdef' install ifupdown2
|
|
/usr/bin/env DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::='--force-confdef' remove ifenslave ifupdown
|
|
fi
|
|
|
|
if [ "${PMX_ZFSAUTOSNAPSHOT,,}" == "yes" ] ; then
|
|
## Install zfs-auto-snapshot
|
|
echo -e "Install zfs-auto-snapshot utility"
|
|
/usr/bin/env DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::='--force-confdef' install zfs-auto-snapshot
|
|
|
|
# Prompt user for snapshot retention settings
|
|
read -p "How many 5-minute snapshots would you like to keep? " SNAP_5MIN
|
|
read -p "How many hourly snapshots would you like to keep? " SNAP_HOURLY
|
|
read -p "How many daily snapshots would you like to keep? " SNAP_DAILY
|
|
read -p "How many weekly snapshots would you like to keep? " SNAP_WEEKLY
|
|
read -p "How many monthly snapshots would you like to keep? " SNAP_MONTHLY
|
|
|
|
# Make 5min snapshots, keep specified number
|
|
if [ -f "/etc/cron.d/zfs-auto-snapshot" ] ; then
|
|
sed -i "s|--keep=[0-9]*|--keep=$SNAP_5MIN|g" /etc/cron.d/zfs-auto-snapshot
|
|
sed -i "s|*/[0-9]*|*/5|g" /etc/cron.d/zfs-auto-snapshot
|
|
|
|
# Keep hourly snapshots, retain the specified number
|
|
if [ -f "/etc/cron.hourly/zfs-auto-snapshot" ] ; then
|
|
sed -i "s|--keep=[0-9]*|--keep=$SNAP_HOURLY|g" /etc/cron.hourly/zfs-auto-snapshot
|
|
fi
|
|
|
|
# Keep daily snapshots, retain the specified number
|
|
if [ -f "/etc/cron.daily/zfs-auto-snapshot" ] ; then
|
|
sed -i "s|--keep=[0-9]*|--keep=$SNAP_DAILY|g" /etc/cron.daily/zfs-auto-snapshot
|
|
fi
|
|
|
|
# Keep weekly snapshots, retain the specified number
|
|
if [ -f "/etc/cron.weekly/zfs-auto-snapshot" ] ; then
|
|
sed -i "s|--keep=[0-9]*|--keep=$SNAP_WEEKLY|g" /etc/cron.weekly/zfs-auto-snapshot
|
|
fi
|
|
|
|
# Keep monthly snapshots, retain the specified number
|
|
if [ -f "/etc/cron.monthly/zfs-auto-snapshot" ] ; then
|
|
sed -i "s|--keep=[0-9]*|--keep=$SNAP_MONTHLY|g" /etc/cron.monthly/zfs-auto-snapshot
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
if [ "${PMX_KSMTUNED,,}" == "yes" ] ; then
|
|
## Ensure ksmtuned (ksm-control-daemon) is enabled and optimise according to ram size
|
|
echo -e "Ensure ksmtuned (ksm-control-daemon) is enabled and optimise according to ram size"
|
|
|
|
# Install ksm-control-daemon
|
|
/usr/bin/env DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::='--force-confdef' install ksm-control-daemon
|
|
|
|
# Get the system's RAM size in GB
|
|
RAM_SIZE_GB=$(free -g | awk '/^Mem:/{print $2}')
|
|
|
|
# Ask user for KSM settings
|
|
echo "Detected RAM size: $RAM_SIZE_GB GB"
|
|
echo "Please specify the KSM settings for your system."
|
|
|
|
# Get KSM threshold and sleep values from user
|
|
read -p "Enter the KSM threshold coefficient (as a percentage, e.g., 50 for 50%): " KSM_THRES_COEF
|
|
read -p "Enter the KSM sleep time in milliseconds (e.g., 80): " KSM_SLEEP_MSEC
|
|
|
|
# Validate input (ensure valid numbers)
|
|
if [[ ! "$KSM_THRES_COEF" =~ ^[0-9]+$ ]] || [[ ! "$KSM_SLEEP_MSEC" =~ ^[0-9]+$ ]]; then
|
|
echo "Invalid input. Please enter valid numerical values."
|
|
exit 1
|
|
fi
|
|
|
|
# Apply the user's input to the configuration
|
|
sed -i -e "s/\# KSM_THRES_COEF=.*/KSM_THRES_COEF=${KSM_THRES_COEF}/g" /etc/ksmtuned.conf
|
|
sed -i -e "s/\# KSM_SLEEP_MSEC=.*/KSM_SLEEP_MSEC=${KSM_SLEEP_MSEC}/g" /etc/ksmtuned.conf
|
|
|
|
# Enable and start ksmtuned service
|
|
systemctl enable ksmtuned
|
|
systemctl start ksmtuned
|
|
echo "KSM settings applied. KSM threshold coefficient is set to ${KSM_THRES_COEF}% and KSM sleep time is set to ${KSM_SLEEP_MSEC}ms."
|
|
fi
|
|
|
|
if [ "${PMX_AMDFIXES,,}" == "yes" ] ; then
|
|
## Detect AMD EPYC and Ryzen CPU and Apply Fixes
|
|
if [ "$(grep -i -m 1 "model name" /proc/cpuinfo | grep -i "EPYC")" != "" ]; then
|
|
echo "AMD EPYC detected"
|
|
elif [ "$(grep -i -m 1 "model name" /proc/cpuinfo | grep -i "Ryzen")" != "" ]; then
|
|
echo "AMD Ryzen detected"
|
|
else
|
|
PMX_AMDFIXES="no"
|
|
fi
|
|
|
|
if [ "${PMX_AMDFIXES,,}" == "yes" ] ; then
|
|
#Apply fix to kernel : Fixes random crashing and instability
|
|
if ! grep "GRUB_CMDLINE_LINUX_DEFAULT" /etc/default/grub | grep -q "idle=nomwait" ; then
|
|
echo "Setting kernel idle=nomwait"
|
|
sed -i 's/GRUB_CMDLINE_LINUX_DEFAULT="/GRUB_CMDLINE_LINUX_DEFAULT="idle=nomwait /g' /etc/default/grub
|
|
update-grub
|
|
fi
|
|
## Add msrs ignore to fix Windows guest on EPIC/Ryzen host
|
|
echo "options kvm ignore_msrs=Y" >> /etc/modprobe.d/kvm.conf
|
|
echo "options kvm report_ignored_msrs=N" >> /etc/modprobe.d/kvm.conf
|
|
|
|
echo "Installing Proxmox Kernel 6.8"
|
|
/usr/bin/env DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::='--force-confdef' install pve-kernel-6.8
|
|
fi
|
|
fi
|
|
|
|
if [ "${PMX_KERNELHEADERS,,}" == "yes" ] ; then
|
|
## Install kernel source headers
|
|
/usr/bin/env DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::='--force-confdef' install pve-headers module-assistant
|
|
fi
|
|
|
|
# if [ "$PMX_KEXEC" == "yes" ] ; then
|
|
# ## Install kexec, allows for quick reboots into the latest updated kernel set as primary in the boot-loader.
|
|
# # use command 'reboot-quick'
|
|
# echo "kexec-tools kexec-tools/load_kexec boolean false" | debconf-set-selections
|
|
# /usr/bin/env DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::='--force-confdef' install kexec-tools
|
|
# cat <<'EOF' > /etc/systemd/system/kexec-pve.service
|
|
# [Unit]
|
|
# Description=Loading new kernel into memory
|
|
# Documentation=man:kexec(8)
|
|
# DefaultDependencies=no
|
|
# Before=reboot.target
|
|
# RequiresMountsFor=/boot
|
|
# #Before=shutdown.target umount.target final.target
|
|
|
|
# [Service]
|
|
# Type=oneshot
|
|
# RemainAfterExit=yes
|
|
# ExecStart=/sbin/kexec -d -l /boot/pve/vmlinuz --initrd=/boot/pve/initrd.img --reuse-cmdline
|
|
|
|
# [Install]
|
|
# WantedBy=default.target
|
|
# EOF
|
|
# systemctl enable kexec-pve.service
|
|
# echo "alias reboot-quick='systemctl kexec'" >> /root/.bash_profile
|
|
# fi
|
|
|
|
if [ "${PMX_DISABLERPC,,}" == "yes" ] ; then
|
|
## Disable portmapper / rpcbind (Increases Security)
|
|
echo -e "Disable portmapper / rpcbind (Increases Security."
|
|
systemctl disable rpcbind
|
|
systemctl stop rpcbind
|
|
fi
|
|
|
|
if [ "${PMX_TIMEZONE}" == "" ] ; then
|
|
## Set Timezone, empty = set automatically by IP
|
|
echo -e "Set Timezone, empty = set automatically by IP"
|
|
this_ip="$(dig +short myip.opendns.com @resolver1.opendns.com)"
|
|
timezone="$(curl "https://ipapi.co/${this_ip}/timezone")"
|
|
if [ "$timezone" != "" ] ; then
|
|
echo "Found $timezone for ${this_ip}"
|
|
timedatectl set-timezone "$timezone"
|
|
else
|
|
echo "WARNING: Timezone not found for ${this_ip}, set to UTC"
|
|
timedatectl set-timezone UTC
|
|
fi
|
|
else
|
|
## Set Timezone to PMX_TIMEZONE
|
|
timedatectl set-timezone "$PMX_TIMEZONE"
|
|
fi
|
|
|
|
if [ "${PMX_TIMESYNC,,}" == "yes" ] ; then
|
|
echo -e "Setup ntp time sync."
|
|
timedatectl set-ntp true
|
|
fi
|
|
|
|
if [ "${PMX_PIGZ,,}" == "yes" ] ; then
|
|
## Set pigz to replace gzip, 2x faster gzip compression
|
|
echo -e "Set pigz to replace gzip, 2x faster gzip compression."
|
|
sed -i "s/#pigz:.*/pigz: 1/" /etc/vzdump.conf
|
|
/usr/bin/env DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::='--force-confdef' install pigz
|
|
cat <<EOF > /bin/pigzwrapper
|
|
#!/bin/sh
|
|
# System Optimizations by h@x - For Proxmox
|
|
PATH=/bin:\$PATH
|
|
GZIP="-1"
|
|
exec /usr/bin/pigz "\$@"
|
|
EOF
|
|
mv -f /bin/gzip /bin/gzip.original
|
|
cp -f /bin/pigzwrapper /bin/gzip
|
|
chmod +x /bin/pigzwrapper
|
|
chmod +x /bin/gzip
|
|
fi
|
|
|
|
if [ "${PMX_FAIL2BAN,,}" == "yes" ] ; then
|
|
## Hardening Proxmox Web Interface with fail2ban
|
|
echo -e "Hardening Proxmox Web Interface with fail2ban."
|
|
/usr/bin/env DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::='--force-confdef' install fail2ban
|
|
cat <<EOF > /etc/fail2ban/filter.d/proxmox.conf
|
|
[Definition]
|
|
failregex = pvedaemon\[.*authentication failure; rhost=<HOST> user=.* msg=.*
|
|
ignoreregex =
|
|
EOF
|
|
|
|
cat <<EOF > /etc/fail2ban/jail.d/proxmox.conf
|
|
[proxmox]
|
|
enabled = true
|
|
port = https,http,8006,8007
|
|
filter = proxmox
|
|
logpath = /var/log/daemon.log
|
|
maxretry = 3
|
|
# 1 hour
|
|
bantime = 3600
|
|
findtime = 600
|
|
EOF
|
|
|
|
# cat <<EOF > /etc/fail2ban/jail.local
|
|
# [DEFAULT]
|
|
# banaction = iptables-ipset-proto4
|
|
# EOF
|
|
systemctl enable fail2ban
|
|
# ##testing
|
|
# #fail2ban-regex /var/log/daemon.log /etc/fail2ban/filter.d/proxmox.conf
|
|
fi
|
|
|
|
if [ "${PMX_NOSUBBANNER,,}" == "yes" ] ; then
|
|
## Remove subscription banner
|
|
echo -e "Remove Proxmox Subscription banner."
|
|
if [ -f "/usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js" ] ; then
|
|
# create a daily cron to make sure the banner does not re-appear
|
|
cat <<'EOF' > /etc/cron.daily/pmx-pve-nosub
|
|
#!/bin/sh
|
|
# System Optimizations by h@x - For Proxmox Remove subscription banner
|
|
sed -i "s/data.status !== 'Active'/false/g" /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js
|
|
sed -i "s/checked_command: function(orig_cmd) {/checked_command: function() {} || function(orig_cmd) {/g" /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js
|
|
EOF
|
|
|
|
fi
|
|
fi
|
|
|
|
chmod 755 /etc/cron.daily/pmx-pve-nosub
|
|
bash /etc/cron.daily/pmx-pve-nosub
|
|
# Remove nag @tinof
|
|
echo "DPkg::Post-Invoke { \"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\.js$'; if [ \$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data.status/{s/\!//;s/Active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\"; };" > /etc/apt/apt.conf.d/pmx-pve-no-nag && apt --reinstall install proxmox-widget-toolkit
|
|
|
|
if [ "${PMX_MOTD,,}" == "yes" ] ; then
|
|
## Pretty MOTD BANNER
|
|
echo -e "Adding pretty MOTD Banner."
|
|
if ! grep -q https "/etc/motd" ; then
|
|
cat << 'EOF' > /etc/motd.new
|
|
This system is optimised by: h@x - for Proxmox
|
|
EOF
|
|
|
|
cat /etc/motd >> /etc/motd.new
|
|
mv /etc/motd.new /etc/motd
|
|
fi
|
|
fi
|
|
|
|
if [ "${PMX_KERNELPANIC,,}" == "yes" ] ; then
|
|
# Enable restart on kernel panic
|
|
echo -e "Enable restart on kernel panic"
|
|
cat <<EOF > /etc/sysctl.d/99-pmx-kernelpanic.conf
|
|
# System Optimizations by h@x - For Proxmox
|
|
# Enable restart on kernel panic, kernel oops and hardlockup
|
|
kernel.core_pattern=/var/crash/core.%t.%p
|
|
# Reboot on kernel panic afetr 10s
|
|
kernel.panic=10
|
|
# Panic on kernel oops, kernel exploits generally create an oops
|
|
kernel.panic_on_oops=1
|
|
# Panic on a hardlockup
|
|
kernel.hardlockup_panic=1
|
|
EOF
|
|
fi
|
|
|
|
if [ "${PMX_LIMITS,,}" == "yes" ] ; then
|
|
## Increase max user watches
|
|
# BUG FIX : No space left on device
|
|
echo -e "Increase max user watches & Bug fix : No space left on device."
|
|
cat <<EOF > /etc/sysctl.d/99-pmx-maxwatches.conf
|
|
# System Optimizations by h@x - For Proxmox
|
|
# Increase max user watches
|
|
fs.inotify.max_user_watches=1048576
|
|
fs.inotify.max_user_instances=1048576
|
|
fs.inotify.max_queued_events=1048576
|
|
EOF
|
|
## Increase max FD limit / ulimit
|
|
echo -e "Increase max FD limit / ulimit."
|
|
cat <<EOF >> /etc/security/limits.d/99-pmx-limits.conf
|
|
# System Optimizations by h@x - For Proxmox
|
|
# Increase max FD limit / ulimit
|
|
* soft nproc 1048576
|
|
* hard nproc 1048576
|
|
* soft nofile 1048576
|
|
* hard nofile 1048576
|
|
root soft nproc unlimited
|
|
root hard nproc unlimited
|
|
root soft nofile unlimited
|
|
root hard nofile unlimited
|
|
EOF
|
|
## Increase kernel max Key limit
|
|
echo -e "Increase kernel max Key limit."
|
|
cat <<EOF > /etc/sysctl.d/99-pmx-maxkeys.conf
|
|
# System Optimizations by h@x - For Proxmox
|
|
# Increase kernel max Key limit
|
|
kernel.keys.root_maxkeys=1000000
|
|
kernel.keys.maxkeys=1000000
|
|
EOF
|
|
## Set systemd ulimits
|
|
echo -e "Increase kernel max Key limit."
|
|
echo "DefaultLimitNOFILE=256000" >> /etc/systemd/system.conf
|
|
echo "DefaultLimitNOFILE=256000" >> /etc/systemd/user.conf
|
|
|
|
echo 'session required pam_limits.so' >> /etc/pam.d/common-session
|
|
echo 'session required pam_limits.so' >> /etc/pam.d/runuser-l
|
|
|
|
## Set ulimit for the shell user
|
|
echo -e "Set ulimit for the shell user."
|
|
echo "ulimit -n 256000" >> /root/.profile
|
|
fi
|
|
|
|
if [ "${PMX_LOGROTATE,,}" == "yes" ] ; then
|
|
## Optimise logrotate
|
|
echo -e "Optimise logrotate."
|
|
cat <<EOF > /etc/logrotate.conf
|
|
# System Optimizations by h@x - For Proxmox
|
|
daily
|
|
su root adm
|
|
rotate 7
|
|
create
|
|
compress
|
|
size=10M
|
|
delaycompress
|
|
copytruncate
|
|
|
|
include /etc/logrotate.d
|
|
EOF
|
|
systemctl restart logrotate
|
|
fi
|
|
|
|
if [ "${PMX_JOURNALD,,}" == "yes" ] ; then
|
|
## Limit the size and optimise journald
|
|
echo -e "Optimise logrotate."
|
|
cat <<EOF > /etc/systemd/journald.conf
|
|
# System Optimizations by h@x - For Proxmox
|
|
[Journal]
|
|
# Store on disk
|
|
Storage=persistent
|
|
# Don't split Journald logs by user
|
|
SplitMode=none
|
|
# Disable rate limits
|
|
RateLimitInterval=0
|
|
RateLimitIntervalSec=0
|
|
RateLimitBurst=0
|
|
# Disable Journald forwarding to syslog
|
|
ForwardToSyslog=no
|
|
# Journald forwarding to wall /var/log/kern.log
|
|
ForwardToWall=yes
|
|
# Disable signing of the logs, save cpu resources.
|
|
Seal=no
|
|
Compress=yes
|
|
# Fix the log size
|
|
SystemMaxUse=64M
|
|
RuntimeMaxUse=60M
|
|
# Optimise the logging and speed up tasks
|
|
MaxLevelStore=warning
|
|
MaxLevelSyslog=warning
|
|
MaxLevelKMsg=warning
|
|
MaxLevelConsole=notice
|
|
MaxLevelWall=crit
|
|
EOF
|
|
systemctl restart systemd-journald.service
|
|
journalctl --vacuum-size=64M --vacuum-time=1d;
|
|
journalctl --rotate
|
|
fi
|
|
|
|
if [ "${PMX_ENTROPY,,}" == "yes" ] ; then
|
|
## Ensure Entropy Pools are Populated, prevents slowdowns whilst waiting for entropy
|
|
echo -e "Ensure Entropy Pools are Populated, prevents slowdowns whilst waiting for entropy."
|
|
/usr/bin/env DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::='--force-confdef' install haveged
|
|
## Net optimising
|
|
cat <<EOF > /etc/default/haveged
|
|
# System Optimizations by h@x - For Proxmox
|
|
# -w sets low entropy watermark (in bits)
|
|
DAEMON_ARGS="-w 1024"
|
|
EOF
|
|
systemctl daemon-reload
|
|
systemctl enable haveged
|
|
fi
|
|
|
|
if [ "${PMX_VZDUMP,,}" == "yes" ] ; then
|
|
## Increase vzdump backup speed
|
|
echo -e "Increasing vzdump backup speed."
|
|
sed -i "s/#bwlimit:.*/bwlimit: 0/" /etc/vzdump.conf
|
|
sed -i "s/#ionice:.*/ionice: 5/" /etc/vzdump.conf
|
|
fi
|
|
|
|
if [ "${PMX_MEMORYFIXES,,}" == "yes" ] ; then
|
|
## Optimise Memory
|
|
echo -e "Optimising Memory."
|
|
cat <<EOF > /etc/sysctl.d/99-pmx-memory.conf
|
|
# System Optimizations by h@x - For Proxmox
|
|
# Memory Optimising
|
|
## Bugfix: reserve 1024MB memory for system
|
|
vm.min_free_kbytes=1048576
|
|
vm.nr_hugepages=72
|
|
# (Redis/MongoDB)
|
|
vm.max_map_count=262144
|
|
vm.overcommit_memory = 1
|
|
EOF
|
|
fi
|
|
|
|
if [ "${PMX_TCPBBR,,}" == "yes" ] ; then
|
|
## Enable TCP BBR congestion control
|
|
echo -e "Enable TCP BBR congestion control."
|
|
cat <<EOF > /etc/sysctl.d/99-pmx-kernel-bbr.conf
|
|
# System Optimizations by h@x - For Proxmox
|
|
# TCP BBR congestion control
|
|
net.core.default_qdisc=fq
|
|
net.ipv4.tcp_congestion_control=bbr
|
|
EOF
|
|
fi
|
|
|
|
if [ "${PMX_TCPFASTOPEN,,}" == "yes" ] ; then
|
|
## Enable TCP fastopen
|
|
echo -e "Enable TCP fastopen."
|
|
cat <<EOF > /etc/sysctl.d/99-pmx-tcp-fastopen.conf
|
|
# System Optimizations by h@x - For Proxmox
|
|
# TCP fastopen
|
|
net.ipv4.tcp_fastopen=3
|
|
EOF
|
|
fi
|
|
|
|
if [ "${PMX_NET,,}" == "yes" ] ; then
|
|
## Enable Network optimizing
|
|
echo -e "Enable Network optimizing."
|
|
cat <<EOF > /etc/sysctl.d/99-pmx-net.conf
|
|
# System Optimizations by h@x - For Proxmox
|
|
net.core.netdev_max_backlog=8192
|
|
net.core.optmem_max=8192
|
|
net.core.rmem_max=16777216
|
|
net.core.somaxconn=8151
|
|
net.core.wmem_max=16777216
|
|
net.ipv4.conf.all.accept_redirects = 0
|
|
net.ipv4.conf.all.accept_source_route = 0
|
|
net.ipv4.conf.all.log_martians = 0
|
|
net.ipv4.conf.all.rp_filter = 1
|
|
net.ipv4.conf.all.secure_redirects = 0
|
|
net.ipv4.conf.all.send_redirects = 0
|
|
net.ipv4.conf.default.accept_redirects = 0
|
|
net.ipv4.conf.default.accept_source_route = 0
|
|
net.ipv4.conf.default.log_martians = 0
|
|
net.ipv4.conf.default.rp_filter = 1
|
|
net.ipv4.conf.default.secure_redirects = 0
|
|
net.ipv4.conf.default.send_redirects = 0
|
|
net.ipv4.icmp_echo_ignore_broadcasts = 1
|
|
net.ipv4.icmp_ignore_bogus_error_responses = 1
|
|
net.ipv4.ip_local_port_range=1024 65535
|
|
net.ipv4.tcp_base_mss = 1024
|
|
net.ipv4.tcp_challenge_ack_limit = 999999999
|
|
net.ipv4.tcp_fin_timeout=10
|
|
net.ipv4.tcp_keepalive_intvl=30
|
|
net.ipv4.tcp_keepalive_probes=3
|
|
net.ipv4.tcp_keepalive_time=240
|
|
net.ipv4.tcp_limit_output_bytes=65536
|
|
net.ipv4.tcp_max_syn_backlog=8192
|
|
net.ipv4.tcp_max_tw_buckets = 1440000
|
|
net.ipv4.tcp_mtu_probing = 1
|
|
net.ipv4.tcp_rfc1337=1
|
|
net.ipv4.tcp_rmem=8192 87380 16777216
|
|
net.ipv4.tcp_sack=1
|
|
net.ipv4.tcp_slow_start_after_idle=0
|
|
net.ipv4.tcp_syn_retries=3
|
|
net.ipv4.tcp_synack_retries = 2
|
|
net.ipv4.tcp_tw_recycle = 0
|
|
net.ipv4.tcp_tw_reuse = 0
|
|
net.ipv4.tcp_wmem=8192 65536 16777216
|
|
net.netfilter.nf_conntrack_generic_timeout = 60
|
|
net.netfilter.nf_conntrack_helper=0
|
|
net.netfilter.nf_conntrack_max = 524288
|
|
net.netfilter.nf_conntrack_tcp_timeout_established = 28800
|
|
net.unix.max_dgram_qlen = 4096
|
|
EOF
|
|
fi
|
|
|
|
if [ "${PMX_SWAPPINESS,,}" == "yes" ] ; then
|
|
## Bugfix: high swap usage with low memory usage
|
|
echo -e "Bugfix: high swap usage with low memory usage."
|
|
cat <<EOF > /etc/sysctl.d/99-pmx-swap.conf
|
|
# System Optimizations by h@x - For Proxmox
|
|
# Bugfix: high swap usage with low memory usage
|
|
vm.swappiness=10
|
|
EOF
|
|
fi
|
|
|
|
if [ "${PMX_MAXFS,,}" == "yes" ] ; then
|
|
## Increase Max FS open files
|
|
echo -e "Increase Max FS open files."
|
|
cat <<EOF > /etc/sysctl.d/99-pmx-fs.conf
|
|
# System Optimizations by h@x - For Proxmox
|
|
# Max FS Optimising
|
|
fs.nr_open=12000000
|
|
fs.file-max=9000000
|
|
fs.aio-max-nr=524288
|
|
EOF
|
|
fi
|
|
|
|
if [ "${PMX_BASHRC,,}" == "yes" ] ; then
|
|
## Customize bashrc
|
|
cat <<EOF >> /root/.bashrc
|
|
export HISTTIMEFORMAT="%d/%m/%y %T "
|
|
export PS1='\u@\h:\W \$ '
|
|
alias l='ls -CF'
|
|
alias la='ls -A'
|
|
alias ll='ls -alF'
|
|
alias ls='ls --color=auto'
|
|
source /etc/profile.d/bash_completion.sh
|
|
export PS1="\[\e[31m\][\[\e[m\]\[\e[38;5;172m\]\u\[\e[m\]@\[\e[38;5;153m\]\h\[\e[m\] \[\e[38;5;214m\]\W\[\e[m\]\[\e[31m\]]\[\e[m\]\\$ "
|
|
EOF
|
|
echo "source /root/.bashrc" >> /root/.bash_profile
|
|
fi
|
|
|
|
if [ "${PMX_ZFSARC,,}" == "yes" ] ; then
|
|
## Optimise ZFS arc size accoring to memory size
|
|
echo -e "Optimise ZFS arc size accoring to memory size."
|
|
if [ "$(command -v zfs)" != "" ] ; then
|
|
if [[ RAM_SIZE_GB -le 16 ]] ; then
|
|
MY_ZFS_ARC_MIN=536870911
|
|
MY_ZFS_ARC_MAX=536870912
|
|
elif [[ RAM_SIZE_GB -le 32 ]] ; then
|
|
# 1GB/1GB
|
|
MY_ZFS_ARC_MIN=1073741823
|
|
MY_ZFS_ARC_MAX=1073741824
|
|
else
|
|
MY_ZFS_ARC_MIN=$((RAM_SIZE_GB * 1073741824 / 16))
|
|
MY_ZFS_ARC_MAX=$((RAM_SIZE_GB * 1073741824 / 8))
|
|
fi
|
|
# Enforce the minimum, incase of a faulty vmstat
|
|
if [[ MY_ZFS_ARC_MIN -lt 536870911 ]] ; then
|
|
echo -e "Enforce the minimum, incase of a faulty vmstat".
|
|
MY_ZFS_ARC_MIN=536870911
|
|
fi
|
|
if [[ MY_ZFS_ARC_MAX -lt 536870912 ]] ; then
|
|
MY_ZFS_ARC_MAX=536870912
|
|
fi
|
|
cat <<EOF > /etc/modprobe.d/99-pmx-zfsarc.conf
|
|
# System Optimizations by h@x - For Proxmox ZFS tuning
|
|
|
|
# Use 1/8 RAM for MAX cache, 1/16 RAM for MIN cache, or 1GB
|
|
options zfs zfs_arc_min=$MY_ZFS_ARC_MIN
|
|
options zfs zfs_arc_max=$MY_ZFS_ARC_MAX
|
|
|
|
# use the prefetch method
|
|
options zfs l2arc_noprefetch=0
|
|
|
|
# max write speed to l2arc
|
|
# tradeoff between write/read and durability of ssd (?)
|
|
# default : 8 * 1024 * 1024
|
|
# setting here : 500 * 1024 * 1024
|
|
options zfs l2arc_write_max=524288000
|
|
options zfs zfs_txg_timeout=60
|
|
EOF
|
|
fi
|
|
fi
|
|
|
|
|
|
# Fix missing /etc/network/interfaces.d include
|
|
echo -e "Fix missing /etc/network/interfaces.d include."
|
|
if ! grep -q 'source /etc/network/interfaces.d/*' "/etc/network/interfaces" ; then
|
|
echo "Added missing include to /etc/network/interfaces"
|
|
echo "source /etc/network/interfaces.d/*" >> /etc/network/interfaces
|
|
fi
|
|
|
|
if [ "${PMX_VFIO_IOMMU,,}" == "yes" ] ; then
|
|
# Enable IOMMU
|
|
echo -e "Enable IOMMU."
|
|
cpu=$(cat /proc/cpuinfo)
|
|
if [[ $cpu == *"GenuineIntel"* ]]; then
|
|
echo "Detected Intel CPU"
|
|
sed -i 's/quiet/quiet intel_iommu=on iommu=pt/g' /etc/default/grub
|
|
elif [[ $cpu == *"AuthenticAMD"* ]]; then
|
|
echo "Detected AMD CPU"
|
|
sed -i 's/quiet/quiet amd_iommu=on iommu=pt/g' /etc/default/grub
|
|
else
|
|
echo "Unknown CPU! Cannot enable IOMMU!"
|
|
fi
|
|
|
|
cat <<EOF >> /etc/modules
|
|
# System Optimizations by h@x - For Proxmox
|
|
vfio
|
|
vfio_iommu_type1
|
|
vfio_pci
|
|
vfio_virqfd
|
|
|
|
EOF
|
|
echo -e "Add common gpu drivers on a blacklist."
|
|
cat <<EOF >> /etc/modprobe.d/blacklist.conf
|
|
# System Optimizations by h@x - For Proxmox
|
|
blacklist nouveau
|
|
blacklist lbm-nouveau
|
|
options nouveau modeset=0
|
|
blacklist amdgpu
|
|
blacklist radeon
|
|
blacklist nvidia
|
|
blacklist nvidiafb
|
|
|
|
EOF
|
|
fi
|
|
|
|
# propagate the settings
|
|
echo -e "Apply changes."
|
|
update-initramfs -u -k all
|
|
update-grub
|
|
pve-efiboot-tool refresh
|
|
|
|
# cleanup
|
|
## Remove no longer required packages and purge old cached updates
|
|
echo -e "Remove no longer required packages and purge old cached updates"
|
|
/usr/bin/env DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::='--force-confdef' autoremove
|
|
/usr/bin/env DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::='--force-confdef' autoclean
|
|
|
|
echo "# System optimization has been installed." > /etc/system-optimization
|
|
date >> /etc/system-optimization
|
|
}
|
|
|
|
function finish() {
|
|
## Script Finish
|
|
echo -e '\033[1;33m Finished....please restart the system \033[0m'
|
|
echo "Optimizations by h@x"
|
|
}
|
|
|
|
function check_root() {
|
|
if [ "$(id -u)" -ne 0 ]; then
|
|
echo "Error: This script must be run as root."
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
check-root
|
|
ask-user
|
|
#main
|
|
#finish |