#!/bin/bash

# Usage
# Clone the he_migration_cwh_fms_plesk repo from code.wartung.xyz to /tmp/
# run /tmp/he_migration_cwh_fms_plesk/update_server_plesk_migration_cwh.sh 

# Ensure the log directory exists
mkdir -p /tmp/migration_logs/

# Get the filename of current script and strip .sh from the end
SCRIPT_FILE_NAME=$(basename "$0" .sh)

# Create the log and error filenames. Output can then be redirected using 
# >> "$LOG_FILE_NAME" 2>> "$ERR_FILE_NAME"
LOG_FILE_NAME="/tmp/migration_logs/$SCRIPT_FILE_NAME.log"
ERR_FILE_NAME="/tmp/migration_logs/$SCRIPT_FILE_NAME.err"

# Print info about logging
echo "STDOUT redirected to $LOG_FILE_NAME"
echo "STDERR redirected to $ERR_FILE_NAME"

# update installed components
echo "Install OS Updates"
export DEBIAN_FRONTEND=noninteractive
apt update >> "$LOG_FILE_NAME" 2>> "$ERR_FILE_NAME" && apt upgrade -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" >> "$LOG_FILE_NAME" 2>> "$ERR_FILE_NAME"

# update plesk
echo "Install Plesk Updates"
plesk installer --select-release-latest --upgrade-installed-components >> "$LOG_FILE_NAME" 2>> "$ERR_FILE_NAME"
sleep 30

# Install php_handler
echo "Install PHP Handler"
available_php=()
available_php=$(plesk installer --select-release-current --show-components 2>&1 | grep 'php' | grep '\[install\]')
sleep 30

# Display the list of available PHP handlers before asking the user
echo "Available PHP handlers:"
  for ITEM in "${available_php[@]}"; do
          echo "$ITEM"
  done

  # Ask the user about outdated PHP handlers
  read -r -p "Install outdated PHP handlers (y/N)? " install_outdated

  # Default to 'n' if the user just presses Enter
  install_outdated="${install_outdated:-n}"

  # Filter outdated handlers if the user chooses 'n' or presses Enter
  if [[ "$install_outdated" == "n" || "$install_outdated" == "N" ]]; then
          available_php=($(echo "$available_php" | grep -v "outdated" | awk '{print $1}')) # Filter component name and exclude outdated handlers
          echo "Only Up2Date PHP handlers will be installed"
          for ITEM in "${available_php[@]}"; do
                  echo "Installing $ITEM - This might take a while"
                  plesk installer --select-release-current --install-component $ITEM >> "$LOG_FILE_NAME" 2>> "$ERR_FILE_NAME"
                  sleep 30
          done
  elif [[ "$install_outdated" == "y" || "$install_outdated" == "Y" ]]; then
          available_php=($(echo "$available_php" | awk '{print $1}')) # Filter component name
          echo "All, even outdated PHP handlers will be installed"
          for ITEM in "${available_php[@]}"; do
                  echo "Installing $ITEM - This might take a while"
                  plesk installer --select-release-current --install-component $ITEM >> "$LOG_FILE_NAME" 2>> "$ERR_FILE_NAME"
                  sleep 30
          done
  else
          echo "Invalid input. Defaulting to no outdated PHP handlers."
  fi

# Remove unwanted extensions
echo "Remove unwanted Plesk extensions"
for EXTENSION in revisium-antivirus xovi advisor social-login domain-connect ; do /usr/local/psa/bin/extension --uninstall ${EXTENSION} >> "$LOG_FILE_NAME" 2>> "$ERR_FILE_NAME"; done
 
# disable Plesk Server Backup
echo "Disable Plesk Backups"
plesk db "UPDATE BackupsScheduled SET active = 'false' where obj_type = 'server'"
 
# Install typical extensions
echo "Install typical extensions"
for EXTENSION in dnssec traffic-monitor symantec sectigo ; do /usr/local/psa/bin/extension --install ${EXTENSION} >> "$LOG_FILE_NAME" 2>> "$ERR_FILE_NAME"; done
 
# Install typical components
echo "Install typical components - This might take a while"
for COMPONENT in site-import horde fail2ban pmm sitebuilder git spamassassin modsecurity psa-firewall wp-toolkit sslit letsencrypt composer ; do plesk installer --select-release-current --install-component ${COMPONENT} >> "$LOG_FILE_NAME" 2>> "$ERR_FILE_NAME"; done
 
# Enable typical apache modules
echo "Enable typical apache modules - This might take a while"
for MODULE in auth_digest authz_groupfile cache cgi dav dav_fs dav_lock expires ; do plesk bin optimization_settings -e ${MODULE} >> "$LOG_FILE_NAME" 2>> "$ERR_FILE_NAME"; done
 
# Remove social-media-links
echo "Remove social-media-links in Plesk"

if ! grep -q '[facebook]' /usr/local/psa/admin/conf/panel.ini; then
	cat >> /usr/local/psa/admin/conf/panel.ini <<-EOF
		[facebook]
		; Hide Like link
		showLikeLink = off
	EOF
fi
 
if ! grep -q '[rating]' /usr/local/psa/admin/conf/panel.ini; then
	cat >> /usr/local/psa/admin/conf/panel.ini <<-EOF
		[rating]
		; Hide feedback dialog with question to rate product
		enabled = off
	EOF
fi

if ! grep -q '[extensions]' /usr/local/psa/admin/conf/panel.ini; then
	cat >> /usr/local/psa/admin/conf/panel.ini <<-EOF
		[extensions]
		blacklist = "kernelcare-plesk"
		autoBackup = off
	EOF
fi

if ! grep -q '[twitter]' /usr/local/psa/admin/conf/panel.ini; then
	cat >> /usr/local/psa/admin/conf/panel.ini <<-EOF
		[twitter]
		showFollowLink = off
	EOF
fi

if ! grep -q '[promos]' /usr/local/psa/admin/conf/panel.ini; then
	cat >> /usr/local/psa/admin/conf/panel.ini <<-EOF
		[promos]
		enabled = off
		extensions.featured = off
		extensions.installed = off
		extensions.catalog = off
	EOF
fi

if ! grep -q '[userActivityTracking]' /usr/local/psa/admin/conf/panel.ini; then
	cat >> /usr/local/psa/admin/conf/panel.ini <<-EOF
		[userActivityTracking]
		enabled = off
	EOF
fi

if ! grep -q '[rating]' /usr/local/psa/admin/conf/panel.ini; then
	cat >> /usr/local/psa/admin/conf/panel.ini <<-EOF
		[rating]
		; Hide feedback dialog with question to rate product
		enabled = off
	EOF
fi
 
# Limit DNS recursions to localhost
echo "Limit DNS recursions to localhost"
plesk bin server_dns -u -recursion localhost >> "$LOG_FILE_NAME" 2>> "$ERR_FILE_NAME"
 
# Modify DNS Template
echo "Modify DNS Template"
HOST=$(hostname -f)
 
/usr/local/psa/bin/server_dns --set "NS,,pdns02.domaincontrol.com;NS,,$HOST;A,,<ip>;AAAA,,<ipv6>;A,webmail,<ip>;AAAA,webmail,<ipv6>;MX,,mail.<domain>.,10;A,mail,<ip>;AAAA,mail,<ipv6>;CNAME,www,<domain>.;CNAME,ftp,<domain>.;TXT,,v=spf1 +a +mx include:secureserver.net -all;A,ipv4,<ip>;AAAA,ipv6,<ipv6>;" >> "$LOG_FILE_NAME" 2>> "$ERR_FILE_NAME"
 
# Allow zonetransfer
echo "ACL Configuration for pDNS"
/usr/local/psa/bin/server_dns -u -add-acl "80.237.128.0/24,208.109.132.0/24,50.63.22.0/24" >> "$LOG_FILE_NAME" 2>> "$ERR_FILE_NAME"
 
# Configure Notify
echo "Configure Notify for pDNS"
# Ubuntu/Debian
if command -v apt-get &>/dev/null; then
	if ! grep -q 'notify yes;' /var/named/run-root/etc/named-user-options.conf; then
		cat >> /var/named/run-root/etc/named-user-options.conf <<-EOF
			notify yes;
			also-notify { 97.74.112.1; 97.74.112.2; };
		EOF
	fi
# Modern CenotOS, AlmaLinux etc 
elif command -v dnf &>/dev/null; then
	if ! grep -q 'notify yes;' /var/named/chroot/etc/named-user-options.conf; then
		cat >> /var/named/chroot/etc/named-user-options.conf <<-EOF
			notify yes;
			also-notify { 97.74.112.1; 97.74.112.2; };
		EOF
	fi
else
  echo "Unable to configure notify"
fi
 
# Configure IPs in Plesk as shared
echo "Configure IPs in Plesk as shared"
plesk bin ipmanage -u $(ip a | grep -w 'inet' | grep 'global' | cut -d" " -f6) -type shared >> "$LOG_FILE_NAME" 2>> "$ERR_FILE_NAME" && \
plesk bin ipmanage -u $(ip a | grep -w 'inet6' | grep 'global' | cut -d" " -f6) -type shared >> "$LOG_FILE_NAME" 2>> "$ERR_FILE_NAME"
 
# Postfix process limits
echo "Set Postfix process limit to 25"
echo "default_process_limit = 25" >> /etc/postfix/main.cf

# Increase Mail-Size to 50M. Default is 10M 
plesk bin mailserver --set-max-letter-size 50M
 
# Configure locales
echo "Configure locales"
localectl set-locale LANG=de_DE.UTF-8 >> "$LOG_FILE_NAME" 2>> "$ERR_FILE_NAME"
/usr/local/psa/bin/server_pref --set-default -locale de-DE >> "$LOG_FILE_NAME" 2>> "$ERR_FILE_NAME"
 
# Enable SMTP on Port 587
echo "Enable SMTP on Port 587"
/usr/local/psa/bin/mailserver --set-message-submission true >> "$LOG_FILE_NAME" 2>> "$ERR_FILE_NAME"

# Enable MySQL upgrade in Plesk GUI
echo "Enable MySQL upgrade in Plesk GUI"
if ! grep -q '[databaseManagement]' /usr/local/psa/admin/conf/panel.ini; then
	cat >> /usr/local/psa/admin/conf/panel.ini <<-EOF
		[databaseManagement]
		features.canBeUpgraded = 1
	EOF
fi

# Configure timezone Europe/Berlin
echo "Configure timezone Europe/Berlin"
timedatectl set-timezone Europe/Berlin >> "$LOG_FILE_NAME" 2>> "$ERR_FILE_NAME"
 
# Upgrade min_password_strength
echo "Upgrade min_password_strength for Plesk"
/usr/local/psa/bin/server_pref -u -min_password_strength medium >> "$LOG_FILE_NAME" 2>> "$ERR_FILE_NAME"
 
# Enable Reverse Proxy configuration (NGINX <=> apache2)
echo "Enable Reverse Proxy configuration (NGINX <=> apache2)"
/usr/local/psa/admin/sbin/nginxmng -e >> "$LOG_FILE_NAME" 2>> "$ERR_FILE_NAME"
 
# Enable HTTP/2
echo "Enable HTTP/2"
plesk bin http2_pref enable >> "$LOG_FILE_NAME" 2>> "$ERR_FILE_NAME"
 
# Enable PSA-Firewall
echo "Enable PSA-Firewall"
plesk bin modules/firewall/settings -e && \
sleep 5 && \
SSH_CLIENT="127.0.0.1 65535 22" plesk bin modules/firewall/settings --confirm

# Check for Nydus firewall rule
echo "Check for Nydus firewall rule and create if missing"
if ! iptables -L INPUT | grep -q "tcp dpt:2224"; then
  # Add and enable firewall rule for NYDUS, if grep returns empty result
  plesk bin modules/firewall/settings -s -name 'NYDUS' -direction input -action allow -ports '2224/tcp,2224/udp' && \
  sleep 5 && \
  plesk bin modules/firewall/settings -a && \
  sleep 5 && \
  SSH_CLIENT="127.0.0.1 65535 22" plesk bin modules/firewall/settings --confirm
fi

# Create folders for migration data in /tmp/
echo "Create folders for migration data in /tmp/"
mkdir -p /tmp/migration_csv >> "$LOG_FILE_NAME" 2>> "$ERR_FILE_NAME"
mkdir -p /tmp/migration_db >> "$LOG_FILE_NAME" 2>> "$ERR_FILE_NAME"
mkdir -p /tmp/migration_webspace >> "$LOG_FILE_NAME" 2>> "$ERR_FILE_NAME"
mkdir -p /tmp/migration_ssl >> "$LOG_FILE_NAME" 2>> "$ERR_FILE_NAME"

# Remove migration-key.pem
rm ~/.ssh/migration-key.pem &> /dev/null

# Disable ModSecurity
plesk bin server_pref --update-web-app-firewall -waf-rule-engine off &> /dev/null

# Disable Fail2ban
plesk bin ip_ban --disable &> /dev/null

echo "Job done"
