diff --git a/python/init.sh b/python/init.sh deleted file mode 100644 index 02f053c..0000000 --- a/python/init.sh +++ /dev/null @@ -1,1524 +0,0 @@ -#!/bin/bash - - -# Short Description :Deploy imunify360/ImunifyAV -# Description :Installs imunify360/ImunifyAV repository -# Copyright :Cloud Linux Zug GmbH -# License :Cloud Linux Commercial License - -# Do not edit/move/reformat this line except for actual version bump -# it is used by old versions of deploy scripts to check for update -version="2.110" - -readonly package="imunify360-firewall" -readonly imunify360="imunify360-firewall" -readonly imunify_av="imunify-antivirus" - - -if [[ "$package" != "$imunify360" ]] && [[ "$package" != "$imunify_av" ]]; then - exit 1 -fi - - -if [[ "$package" = "$imunify360" ]]; then - PRODUCT="Imunify360" - UI_PACKAGE="imunify-ui-firewall" - COMMAND="imunify360-agent" - STAND_ALONE_URL="https://docs.imunify360.com/control_panel_integration/#introduction" - LOG_FILE="/var/log/i360deploy.log" - LOCK="/var/lock/i360deploy.lck" - # packages mentioned in the update command in the daily cron job + PD packages - readonly additional_packages_to_remove="ai-bolit\ - alt-php-hyperscan\ - imunify-common\ - imunify-notifier\ - imunify-core\ - imunify-ui\ - imunify360-venv\ - imunify-antivirus\ - cloudlinux-backup-utils\ - imunify-realtime-av\ - imunify360-ossec\ - imunify360-pam\ - imunify360-php-i360\ - imunify360-webshield-bundle\ - imunify360-unified-access-logger\ - alt-php-internal\ - app-version-detector" - readonly additional_packages_to_remove_cl="ai-bolit\ - alt-php-hyperscan\ - imunify-common\ - imunify-notifier\ - imunify-core\ - imunify-ui\ - imunify360-venv\ - imunify-antivirus\ - cloudlinux-backup-utils\ - imunify-realtime-av\ - imunify360-ossec\ - imunify360-pam\ - imunify360-php-i360\ - imunify360-webshield-bundle\ - imunify360-unified-access-logger" - readonly additional_packages_to_remove_centos="imunify-auditd-log-reader\ - minidaemon" - readonly additional_packages_to_remove_debian="" -fi - - -readonly YUM_DISABLED_PHP_REPOS_OPTION="--disablerepo=imunify360-alt-php,imunify360-ea-php-hardened" -OS_RELEASE_INFO=/etc/os-release -set -o pipefail -# fail if any error: will not -#set -e -# error for unbound variable: not for now -#set -eu - -# $1 = Message prompt -# Returns ans=0 for yes, ans=1 for no -yesno() { - local YES=0 - local NO=1 - local PENDING=2 - - if [ $dry_run -eq 1 ]; then - echo "Would be asked here if you wanted to" - echo "$1 (y/n - y is assumed)" - local ans=$YES - elif [ "$assumeyes" = "true" ]; then - local ans=$YES - else - local ans=$PENDING - fi - - while [ $ans -eq $PENDING ]; do - echo "Do you want to $1 (y/n) ?" ; read -r reply - case "$reply" in - Y*|y*) ans=$YES ;; - N*|n*) ans=$NO ;; - *) echo "Please answer y or n" ;; - esac - done - - return "$ans" -} - -prepend_timestamp() { - # Prepend current time to each line - # - # Usage: source-program | prepend_timestamp - # - # Note: it may fail if the input contains \0 bytes - while IFS= read -r line - do - printf '[%s] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$line" - done -} - -log() -{ - # Run given command and append its duplicated stdout/stderr to - # $LOG_FILE. - # - # Usage: log [...] - # - "$@" |& prepend_timestamp | tee -a "$LOG_FILE" - return "${PIPESTATUS[0]}" -} - -exit_with_error() -{ - log echo -e "$@" - rm -rf "$lock" - exit 1 -} - -print_debug_info() -{ - if [ "$DEBUG" == "true" ]; then - echo "$@" - fi -} - -set_panel_detection_path() -{ - readonly CPANEL_BIN="/usr/local/cpanel/cpanel" - readonly DA_BIN="/usr/local/directadmin/directadmin" - readonly PLESK_BIN="/usr/sbin/plesk" - readonly INTEGRATION_CONF_PATH="/etc/sysconfig/imunify360/integration.conf" -} - -detect_python () -{ - # python executable is not present in CentOS 8 - if hash python2 2>/dev/null; then - PYTHON=python2 - CONFIG_PARSER="ConfigParser" - elif hash python3 2>/dev/null; then - PYTHON=python3 - CONFIG_PARSER="configparser" - else - exit_with_error "Neither python2 nor python3 executables found" - fi -} - -detect_panel () -{ - # note: keep the panel test order in sync with agent's get_hosting_panel(), - # to avoid detecting conflicting panels in agent vs. the deploy script - - PANEL="" - if [ -f "$INTEGRATION_CONF_PATH" ] ; then - PANEL="generic" - elif [ -f "$PLESK_BIN" ]; then - PANEL="plesk" - elif [ -f "$CPANEL_BIN" ]; then - PANEL="cpanel" - elif [ -f "$DA_BIN" ]; then - PANEL="directadmin" - else - exit_with_error "$PRODUCT has not detected any compatible hosting panel as well as integration.conf file to run the installation without a panel. \ -Please, follow the instructions on $STAND_ALONE_URL" - fi - print_debug_info "$PANEL panel was detected." -} - -# Only for imunify360-firewall -set_low_resource_usage_mode_if_necessary() -{ - local _package=$1 - local _package_version=$2 - imunify360_low_mem_limit=2147483648 - imunify360_python38_datadir=$venv_path/share/imunify360 - # total usable memory in bytes - mem_total=$(/dev/null - then - ostype=debian - else - ostype=centos - fi - fi - echo $ostype -} - -is_ubuntu() -{ - populate_os_release_vars - [ "$ID" == "ubuntu" ] -} - -is_debian() -{ - populate_os_release_vars - [ "$ID" == "debian" ] -} - -UNSUPPORTED_OS_MSG="You are running an unsupported OS. $PRODUCT supports only x86_64 processors." - -check_debian_release() -{ - populate_os_release_vars - - if is_debian && ([ "$VERSION_ID" -lt 10 ] || [ "$VERSION_ID" -gt 12 ]) - then - exit_with_error "You are running unsupported version of debian based OS. $PRODUCT supports only Debian [10, 11, 12]" - fi - if is_ubuntu && [ "$VERSION_ID" != 16.04 ] && [ "$VERSION_ID" != 18.04 ] && [ "$VERSION_ID" != 20.04 ] && [ "$VERSION_ID" != 22.04 ] - then - exit_with_error "You are running unsupported version of debian based OS. $PRODUCT supports only Ubuntu 16.04, 18.04, 20.04 and 22.04" - fi - - if [ "$(uname -m)" != x86_64 ] - then - exit_with_error "$UNSUPPORTED_OS_MSG" - fi -} - -check_centos_release() -{ - rpm -q --whatprovides redhat-release > /dev/null 2>&1 - check_exit_code 0 "There is no package providing /etc/redhat-release, please install redhat-release or centos-release first" - - ARCH=$(uname -i) - - # handle 32bit xen with x86_64 host kernel - if (! rpm -q glibc.x86_64 > /dev/null 2>&1) || [ "$ARCH" != "x86_64" ] ; then - exit_with_error "$UNSUPPORTED_OS_MSG" - fi - - check_centos_compatible - check_virtuozzo_compatible -} - -check_virtuozzo_compatible() -{ - if [ -f /proc/vz/vestat ]; then - if version "$(uname -r)" -lt "$VZ_VERSION_BRIEF"; then - echo "You are inside VZ." - echo "Virtuozzo 7 with kernel $VZ_VERSION_LONG or later has support for ipset in Containers." - exit_with_error "Please upgrade your OpenVZ hypervisor kernel version to $VZ_VERSION_LONG or later." - fi - fi -} - -check_centos_compatible() -{ - local os_version="${1:-$(rpm --eval '%{rhel}')}" - # shellcheck disable=SC2015 - [ "${os_version}" -lt 10 ] 2>/dev/null && [ "${os_version}" -gt 5 ] || \ - exit_with_error "Only CentOS/CloudLinux 6, 7, 8 and 9 are supported at the moment, but got os_version='${os_version}'" -} - -check_exit_code() { if [ $? -ne "$1" ]; then exit_with_error "$2"; fi; } - -disable_3rd_party_ids() -{ - if [ -d "$venv_path" ]; then - echo "imunify360-venv detected" - imunify360_python38_datadir=$venv_path/share/imunify360 - fi - if [ -d "$imunify360_python38_datadir" ]; then - datadir="$imunify360_python38_datadir" - else - datadir="$imunify360_python35_datadir" - fi - - $datadir/scripts/disable_3rd_party_ids -} - -install_first_install_default_overrides() -{ - local first_install_package=$1 - local package_version=$2 - if [ -d "$venv_path" ]; then - echo "imunify360-venv detected" - imunify360_python38_datadir=$venv_path/share/imunify360 - fi - local first_install_config_deprecated="$imunify360_python38_datadir/10_on_first_install.config" - local first_install_config_core="$imunify360_python38_datadir/10_on_first_install_core.config" - local first_install_config_av="$imunify360_python38_datadir/10_on_first_install_av.config" - local first_install_config_ids="$imunify360_python38_datadir/10_on_first_install_ids.config" - if [ -f "$first_install_config_deprecated" ]; then - log echo "Installing $first_install_config_deprecated from $first_install_package $package_version" - cp -v "$first_install_config_deprecated" /etc/sysconfig/imunify360/imunify360.config.d/ && log echo "Done." - else - log echo "Installing $first_install_config_core from $first_install_package $package_version" - cp -v "$first_install_config_core" /etc/sysconfig/imunify360/imunify360.config.d/ && log echo "Done." - - log echo "Installing $first_install_config_av from $first_install_package $package_version" - cp -v "$first_install_config_av" /etc/sysconfig/imunify360/imunify360.config.d/ && log echo "Done." - - if [[ "$package" = "$imunify360" ]]; then - log echo "Installing $first_install_config_ids from $first_install_package $package_version" - cp -v "$first_install_config_ids" /etc/sysconfig/imunify360/imunify360.config.d/ && log echo "Done." - fi - fi -} - -remove_first_install_default_overrides() -{ - unlink /etc/sysconfig/imunify360/imunify360.config.d/10_on_first_install.config 2>/dev/null || true - unlink /etc/sysconfig/imunify360/imunify360.config.d/10_on_first_install_core.config 2>/dev/null || true - unlink /etc/sysconfig/imunify360/imunify360.config.d/10_on_first_install_av.config 2>/dev/null || true - unlink /etc/sysconfig/imunify360/imunify360.config.d/10_on_first_install_ids.config 2>/dev/null || true -} - -init_vars() -{ - wget="/usr/bin/wget" - wget_options="-q --retry-connrefused --waitretry=15 --read-timeout=20 --timeout=15 -t 15" - uninstall=false - conversion=false - beta=false - install_vendors=false - freemium=false - - # get full path to the current script - script="$1" - case "$script" in - ./*) script="$(pwd)/${script#*/}" ;; - /*) script="$script" ;; - *) script="$(pwd)/$script" ;; - esac - scriptname=$(basename "$script") - script_run_args="$2" - - # Update checker URL - checksite="https://repo.imunify360.cloudlinux.com/defense360/" - checksite_forcurl='https://defense360:nraW!F%40%24x4Xd6HHQ@repo.imunify360.cloudlinux.com/defense360/' - upgradeurl="$checksite$scriptname" - dry_run="0" - - assumeyes=false - modifying_call=false - yum_beta_option="" - yum_beta_repo_enable=0 - apt_force="" - - apt_allow_unauthenticated="" - if [[ "$package" = "$imunify360" ]]; then - # Virtuozzo 7 with kernel 3.10.0 or later has support for ipset in Container - VZ_VERSION_LONG=3.10.0-327.10.1.vz7.12.8 - # Inside VZ version is provided without release - VZ_VERSION_BRIEF=3.10.0 - readonly imunify360_python35_datadir=/opt/alt/python35/share/imunify360 - fi - imunify360_python38_datadir=/opt/alt/python38/share/imunify360 - venv_path=/opt/imunify360/venv -} - -version() -{ - local lhs=$1 - local op=$2 - local rhs=$3 - - case $op in - -lt) test "$(echo -e "$lhs\\n$rhs" | sort --version-sort | head -1)" = "$lhs" && \ - test "$lhs" != "$rhs" - return $? - ;; - *) echo "function version(): operator $op is not supported." - return 2 - ;; - esac -} - -check_package_version() -{ - version="$1" - if [ -z "$version" ]; then - echo "No available package detected" - return 1 - else - echo "$version" - fi -} - -get_available_debian_package_version() -{ - version=$(apt-cache policy "$1" 2>/dev/null | sed -n '3p' | awk '{split($0, candidate); print candidate[2]}') - check_package_version "$version" - return $? -} - -get_available_centos_package_version() -{ - version=$(yum $yum_beta_option $YUM_DISABLED_PHP_REPOS_OPTION list available "$1" 2>/dev/null | grep -E "$1.x86_64|$1.noarch" | awk '{split($0, candidate); print candidate[2]}' | sort --version-sort | tail -n 1) - check_package_version "$version" - return $? -} - -check_integration_conf() -{ -# -# Check whether $INTEGRATION_CONF_PATH is sufficiently valid to continue the installation, exit with an error message otherwise -# -# Globals: -# Uses (reads) $INTEGRATION_CONF_PATH; -# Populates (writes) $PYTHON, $CONFIG_PARSER and uses them to parse $INTEGRATION_CONF_PATH ini-file -# - detect_python - # sanity check: the integration.conf is a valid ini-like file - $PYTHON -c "from $CONFIG_PARSER import ConfigParser; conf = ConfigParser(); conf.read('$INTEGRATION_CONF_PATH')" 2>/dev/null - check_exit_code 0 "syntax error in $INTEGRATION_CONF_PATH \ -Read the manual $STAND_ALONE_URL on how to create a valid config file. -" - # sanity check: ui_path should be present in the config - local ui_path="$($PYTHON -c "from $CONFIG_PARSER import ConfigParser; conf = ConfigParser(); conf.read('$INTEGRATION_CONF_PATH'); print(conf.get('paths', 'ui_path'))" 2>/dev/null)" - check_exit_code 0 "$PRODUCT has detected $INTEGRATION_CONF_PATH file from the stand-alone version of $PRODUCT. \ -Stand-alone version requires \"ui_path\" parameter specified in the $INTEGRATION_CONF_PATH. \ -Read the manual $STAND_ALONE_URL on how to create a valid config file. -" - # ui_path must not be empty - if [ -z "$ui_path" ]; then - exit_with_error "Could not get ui_path from $INTEGRATION_CONF_PATH. UI will not be installed. \ -Please ensure that you have provided ui_path in $INTEGRATION_CONF_PATH \ -More details is at $STAND_ALONE_URL." - # even if ui_path doesn't refer to a directory (first install), - # its parent directory must exist - elif [ ! -d "$ui_path" ]; then - # first install - log mkdir -m 0700 "$ui_path" - check_exit_code 0 "An error occurred during creating $ui_path directory. \ -Possibly parent directory doesn't exist or path point to file" - # symlinks are not supported (current behavior) - elif [[ -L "$ui_path" ]]; then - exit_with_error "ui_path specified in $INTEGRATION_CONF_PATH file $ui_path points to an existing symlink. \ -Installation is aborted, to avoid overwriting it. \ -ui_path must point to an empty web directory. More details is at $STAND_ALONE_URL." - # ui_path dir must be empty or point to an existing imunify installation; - # use bin/execute.py as a heuristic for detecting the agent install - elif [[ -n "$(ls -A "$ui_path" 2>/dev/null)" ]] && [[ ! -e "$ui_path/bin/execute.py" ]]; then - exit_with_error "ui_path specified in $INTEGRATION_CONF_PATH file $ui_path points to a non-empty directory. \ -Installation is aborted, to avoid overwriting data in it. \ -ui_path must point to an empty web directory. More details is at $STAND_ALONE_URL." - fi - - # sanity check: panel_info should be present in the config - $PYTHON -c "from $CONFIG_PARSER import ConfigParser; conf = ConfigParser(); conf.read('$INTEGRATION_CONF_PATH'); print(conf.get('integration_scripts', 'panel_info'))" 2>/dev/null - if [ $? -ne "0" ]; then - yesno "WARNING: integration_scripts.panel_info field will be mandatory soon, please refer to [documentation](https://docs.imunify360.com/control_panel_integration/#specifying-panel-information) and fill it! Do you want to continue? [y/N]" - else - # sanity check: panel_info must be a valid json with name and version fields in data object - local panel_info=$($PYTHON -c "from $CONFIG_PARSER import ConfigParser; conf = ConfigParser(); conf.read('$INTEGRATION_CONF_PATH'); print(conf.get('integration_scripts', 'panel_info'))" 2>/dev/null) - $panel_info | $PYTHON -c 'import sys,json; d=json.load(sys.stdin); print("Panel info:", d["data"]["name"], d["data"]["version"]);' - check_exit_code 0 "panel_info script should be executable and return valid json with name and version fields in data object. Please refer to the [documentation](https://docs.imunify360.com/control_panel_integration/#specifying-panel-information)." - fi -} - -install_plugin() { - local plugin_package=$1 - local panel=$2 - - echo "Installing $PRODUCT $panel plugin..." - install_${ostype}_pkgs "$plugin_package-$panel" - check_exit_code 0 "Failed to install $PRODUCT $panel plugin." -} - -install_ui_part() { - local ui_package=$1 - local panel=$2 - - echo "Installing UI part of $PRODUCT $panel plugin..." - install_${ostype}_pkgs "$ui_package-$panel" - check_exit_code 0 "Failed to install UI part of $PRODUCT $panel plugin." -} - -check_and_install() { - local package_to_install=$1 - local package_version=$2 - local ui_package=$3 - local panel=$4 - - if version "$package_version" -lt "7.3"; then - install_plugin "$package_to_install" "$panel" - else - if [[ "$package_to_install" = "$imunify360" ]]; then - install_plugin $package_to_install $panel - fi - install_ui_part "$ui_package" "$panel" - fi -} - -check_hardened_php_status() -{ - local agent_bin='/usr/bin/imunify360-agent' - local python_bin='/opt/imunify360/venv/bin/python' - local status=$(\ - ${agent_bin} features status hardened-php --json |\ - ${python_bin} -c 'import json; print(json.loads(input()).get("items", {}).get("status"))'\ - ) - echo ${status} -} - -remove_hardened_php_feature() -{ - local agent_bin='/usr/bin/imunify360-agent' - local python_bin='/opt/imunify360/venv/bin/python' - local timeout=900 - - if [ ! -f ${agent_bin} ] || [ ! -f ${python_bin} ]; then - return - fi - - if [ "$(check_hardened_php_status)" != "installed" ]; then - return - fi - - echo "Warning: Hardened PHP packages will be removed"\ - "and replaced with the default ones if possible."\ - "Some sites may stop working" - - echo -n "Starting removal, this may take a couple of minutes" - local logfile="$(${agent_bin} features remove hardened-php)" - local start_ts=$(date +%s) - - while true; do - removal_status="$(check_hardened_php_status)" - [ "${removal_status}" = "not_installed" ] && echo OK && break - - local current_ts=$(date +%s) - if [ $((current_ts - start_ts)) -gt ${timeout} ]; then - echo TIMEOUT - exit_with_error "Error occured while trying to remove Hardened PHP packages."\ - "See log: ${logfile}" - fi - echo -n "." - sleep 5 - done -} - -install_vendors_in_cw_environment() -{ - # log output but hide it from stdout - log echo "Run vendor installation in background for Cloudways" - file_path="/var/imunify360/files/modsec/v2/description.json" - while [ ! -f "$file_path" ]; do - log echo "Waiting for $file_path to appear" - sleep 5 - done - log echo "Installing vendors" - log /usr/bin/imunify360-agent --console-log-level=WARNING install-vendors -} - - -run_with_retries() -{ - cmd=$1 - expected_error_text=$2 - ignore_res=$3 - - min_timeout=2 - max_timeout=30 - - nattempts=10 - - for ((i=1;i<=nattempts;i++)); do - output=$( { $cmd ; } 2>&1 ) - res=$? - if [ $res -eq 0 ] && [[ "$ignore_res" != "true" ]]; then - echo "$output" - break - else - if echo "$output" | grep -q "$expected_error_text"; then - echo "$output" - echo "Attempt #$i/$nattempts: to run $cmd." - timeout=$(($RANDOM%($max_timeout-$min_timeout+1)+$min_timeout)) - [ $i -ne $nattempts ] && echo "Retrying in $timeout seconds.." - sleep $timeout - else - echo "$output" - break - fi - fi - done - return $res -} - -reopen_log() -{ - echo "-- $(date -R): $script $script_run_args --" >> "$LOG_FILE" - chmod 0600 "$LOG_FILE" -} - -check_debian_pkg_presence() -{ - test "$(dpkg-query --show --showformat='${db:Status-Status}\n' "$1" 2>/dev/null)" = "installed" -} - -check_centos_pkg_presence() -{ - rpm --query "$1" >/dev/null -} - -remove_debian_imunify() -{ - local pkgs_to_remove="$package $additional_packages_to_remove $additional_packages_to_remove_debian" - # shellcheck disable=SC2086 - apt-get remove --autoremove --ignore-missing --dry-run $pkgs_to_remove - yesno "apt-get --AUTOREMOVE to remove $pkgs_to_remove plus \ - aforementioned packages [y] or just $pkgs_to_remove [n]" - local res=$? - if [ $res = 0 ]; then - local autoremove="--autoremove" - else - local autoremove="" - fi - # --ignore-missing doesn't work if apt doesn't know about package - # shellcheck disable=SC2086 - apt-get remove $autoremove -y --ignore-missing $(dpkg-query -W -f='${binary:Package}\n' $pkgs_to_remove 2>/dev/null) -} - -remove_centos_imunify() -{ - if rpm -q cloudlinux-release &>/dev/null; then - local pkgs_to_remove="$package $additional_packages_to_remove_cl $additional_packages_to_remove_centos" - else - local pkgs_to_remove="$package $additional_packages_to_remove $additional_packages_to_remove_centos" - fi - yum remove -y $yum_beta_option $YUM_DISABLED_PHP_REPOS_OPTION \ - $pkgs_to_remove --setopt=clean_requirements_on_remove=1 -} - -remove_freemium_flag() -{ - if [ ! -f "/var/imunify360/myimunify-freemium.flag" ]; then - return - fi - - rm -f "/var/imunify360/myimunify-freemium.flag" -} - -get_debian_pkgs_manager() { - pkgs_manager="apt-get" -} - -get_centos_pkgs_manager() { - pkgs_manager="yum" -} - -remove_debian_pkgs() -{ - run_with_retries "apt-get remove -y $*" "Could not get lock" -} - -remove_centos_pkgs() -{ - yum remove -y "$@" -} - -install_debian_pkgs() -{ - local pkgs=$* - run_with_retries "apt-get $apt_opts install -y $apt_allow_unauthenticated $apt_force $pkgs" "" -} - -install_centos_pkgs() -{ - local pkgs=$* - yum install -y $yum_beta_option $YUM_DISABLED_PHP_REPOS_OPTION $pkgs -} - -install_debian_ipset() -{ - install_debian_pkgs ipset -} - -install_centos_ipset() -{ - yum install -y ipset -} - -detect_first_install() -{ - if check_${ostype}_pkg_presence "$package" >/dev/null - then - first_install=false - else - first_install=true - fi -} - -is_systemctl_avail() -{ - command -v systemctl >/dev/null 2>&1 -} - - -# $1 = Full URL to download -# $2 = Optional basename to save to (if omitted, then = basename $1) -# Also allow download to fail without exit if $2 is set -download_file() { - if [ "$2" = "" ]; then - dlbase="$(basename "$1")" - else - dlbase="$2" - fi - - if [ $dry_run -eq 1 ]; then - echo "Would download this URL to $dlbase :" - echo "$1" ; echo - return - fi - - old_dlbase="$dlbase.old" - if [ -f "$dlbase" ]; then - rm -f "$old_dlbase" - mv -f "$dlbase" "$old_dlbase" - fi - - echo "Downloading $dlbase (please wait)" - $wget $wget_options -O "$dlbase" "$1" - - if [ ! -s "$dlbase" ]; then - if [ -f "$old_dlbase" ]; then - mv -f "$old_dlbase" "$dlbase" - fi - if [ "$2" = "" ]; then - echo "Failed to download $dlbase" - exit 1 - fi - fi -} - -# Make sure that we are running the latest version -# $* = Params passed to script -check_version() { - echo "Checking for an update to $scriptname" - script_from_repo="$scriptname.repo_version" - download_file "$upgradeurl" "$script_from_repo" - newversion=$(grep "^version=" "$script_from_repo" | sed 's/[^0-9.]*//g') - if [ -z "$newversion" ]; then - newversion=$version - fi - - if [ $dry_run -eq 1 ]; then - echo -e "Would check if this running script (version $version) is out of date. \n" \ - "If it's been superseded, the new version would be downloaded and you'd be asked \n" \ - "if you want to upgrade to it and run the new version. \n" - return - fi - - local latest_version - latest_version=$(echo -e "$version\\n$newversion" | sort --reverse --version-sort | head -1) - if [ "$latest_version" = "$version" ]; then - echo "$scriptname is already the latest version ($version) - continuing" - rm -f "$script_from_repo" - else - echo "New version ($newversion) of $scriptname detected" - if yesno "run $scriptname $newversion now" - then - echo "OK, executing $script_from_repo $*" - # replace the current script with a new one - mv -f "$script_from_repo" "$script" - chmod u+x "$script" - echo "Download of $scriptname $newversion successful" - rm "$LOCK" - echo "Run $script $script_run_args" - # use $script_run_args without quotes to avoid error - # `getopt: unrecognized option` if there are more than 1 arguments - # shellcheck disable=SC2086 - exec "$script" --skip-version-check $script_run_args - error "Failed to run $script $script_run_args" - else - echo -e "New version of script is available: $upgradeurl \n" \ - "It was downloaded to $script_from_repo \n" \ - "If you prefer to use current version, run it with \"--skip-version-check\" key. \n" - exit 1 - fi - fi -} - -save_debian_repo() -{ - log install_debian_pkgs gnupg - - $wget $wget_options -O- https://repo.imunify360.cloudlinux.com/defense360/RPM-GPG-KEY-CloudLinux \ - | gpg --dearmor > /etc/apt/trusted.gpg.d/RPM-GPG-KEY-CloudLinux.gpg - - echo "deb [arch=amd64] https://repo.imunify360.cloudlinux.com/imunify360/$ID/$VERSION_ID/ $VERSION_CODENAME main" \ - > /etc/apt/sources.list.d/imunify360.list - - if [ "$beta" = "true" ]; then - echo "deb [arch=amd64] https://repo.imunify360.cloudlinux.com/imunify360/$ID-testing/$VERSION_ID/ $VERSION_CODENAME main" \ - > /etc/apt/sources.list.d/imunify360-testing.list - fi - - if ! log run_with_retries "apt-get update" ""; then - test "$dev_install" = true - check_exit_code 0 "apt-get update error." - fi -} - -save_centos_repo() -{ - local RPM_KEY=$checksite/RPM-GPG-KEY-CloudLinux - local RPM_KEY_forcurl=$checksite_forcurl/RPM-GPG-KEY-CloudLinux - - cat >/etc/yum.repos.d/imunify360.repo <<-EOF -[imunify360] -name=EL-\$releasever - Imunify360 -baseurl=$checksite/el/\$releasever/updates/x86_64/ -enabled=1 -gpgcheck=1 -gpgkey=$RPM_KEY -EOF - - # add testing repo as disabled by default - cat >/etc/yum.repos.d/imunify360-testing.repo <<-EOF -[imunify360-testing] -name=EL-\$releasever - Imunify360 -baseurl=$checksite/el/\$releasever/updates-testing/x86_64/ -enabled=$yum_beta_repo_enable -gpgcheck=1 -gpgkey=$RPM_KEY -EOF - - log rpm --import "$RPM_KEY_forcurl" - check_exit_code 0 "RPM import error." - modifying_call=true -} - -remove_debian_repo() -{ - rm /etc/apt/sources.list.d/imunify360.list \ - /etc/apt/sources.list.d/imunify360-testing.list \ - /etc/apt/sources.list.d/imunify360-alt-php.list 2>/dev/null -} - -remove_centos_repo() -{ - rm /etc/yum.repos.d/imunify360.repo \ - /etc/yum.repos.d/imunify360-testing.repo \ - /etc/yum.repos.d/imunify360-ea-php-hardened \ - /etc/yum.repos.d/imunify360-alt-php 2>/dev/null -} - -remove_acronis_agent() -{ - [ ! -e /usr/bin/restore_infected ] && return - - if /usr/bin/restore_infected acronis extra is_installed 2> /dev/null; then - # If Acronis installation logs are present in restore_infected folder, - # then remove Acronis and the logs - if ls /var/restore_infected/acronis_installation*.log; then - /usr/bin/restore_infected acronis extra uninstall > /dev/null || : - rm -f /var/restore_infected/acronis_installation*.log - fi - fi -} - -terminate_detached_scans () -{ - for file in /var/imunify360/aibolit/run/*/pid; do - test -e "$file" && kill -9 "$(cat "$file")" - done - rm -rf /var/imunify360/aibolit/run/ - rm -rf /var/imunify360/aibolit/scans.pickle -} - -# Only for imunify360-firewall -check_users() { - CHECK_GROUPS="ossec" - CHECK_USERS="ossec ossecr ossecm ossece" - - SYS_GID_MAX=$(awk '/^SYS_GID_MAX/ {print $2}' /etc/login.defs) - SYS_UID_MAX=$(awk '/^SYS_UID_MAX/ {print $2}' /etc/login.defs) - - # detect SYS_GID_MAX, SYS_UID_MAX indirectly (Ubuntu 16.04) - GID_MIN=$(awk '/^GID_MIN/ {print $2}' /etc/login.defs) - UID_MIN=$(awk '/^UID_MIN/ {print $2}' /etc/login.defs) - if [ "$SYS_GID_MAX" = "" -a "$GID_MIN" != "" ]; then - SYS_GID_MAX=$((GID_MIN - 1)) - fi - if [ "$SYS_UID_MAX" = "" -a "$UID_MIN" != "" ]; then - SYS_UID_MAX=$((UID_MIN - 1)) - fi - - for grp in $CHECK_GROUPS; do - gid=$(getent group $grp 2> /dev/null | cut -d ':' -f 3) - if [ -z "$gid" ]; then - gid='-1' - fi - if [ "$SYS_GID_MAX" != "" ]; then - if [ "$gid" -gt "$SYS_GID_MAX" ]; then - exit_with_error "Non-system group $grp already exists" - fi - elif [ "$first_install" = "true" -a "$gid" != "-1" ]; then - exit_with_error "Group $grp already exists" - fi - done - for usr in $CHECK_USERS; do - uid=$(id -u "$usr" 2>/dev/null || echo -1) - if [ "$SYS_UID_MAX" != "" ]; then - if [ "$uid" -gt "$SYS_UID_MAX" ]; then - exit_with_error "Non-system user $usr already exists" - fi - elif [ "$first_install" = "true" -a "$uid" != "-1" ]; then - exit_with_error "User $usr already exists" - fi - done -} - - -# Only for imunify360-firewall -remove_hardened_php_repos() -{ - if [[ $ostype = centos ]]; then - ALT_PHP=imunify360-alt-php.repo - EA_PHP=imunify360-ea-php-hardened.repo - REPOS_DIR=/etc/yum.repos.d - - # fix permissions - for REPO in $ALT_PHP $EA_PHP; do - test -f $REPOS_DIR/$REPO || continue - chattr -i $REPOS_DIR/$REPO - chmod 644 $REPOS_DIR/$REPO - done - - # remove unconditionally - rm -f $REPOS_DIR/$ALT_PHP - rm -f $REPOS_DIR/$EA_PHP - fi -} - -print_help () -{ - cat << EOF >&2 -Usage: - - -h, --help Print this message - --version Print script's version and exit - -k, --key Deploy $PRODUCT with activation key - -c, --uninstall Uninstall $PRODUCT - --skip-version-check Do not check for script updates - --skip-registration Do not register, just install (the default) - --dev-install Turn off software defect reporting - --beta Install packages from 'testing' repo - --check Check if imunify360 Agent can be installed and exit - -y, --yes Assume "yes" as answer to all prompts and run non-interactively -EOF -} - -print_version() -{ - echo "$scriptname $version" -} - -check_centos_iptables_compatibility() { - # dummy function that does nothing - : -} - -check_debian_iptables_compatibility() { - if is_debian && [ "$VERSION_ID" == "10" ] - then - local apt_opts="-t buster-backports" - log install_debian_pkgs iptables - check_exit_code 0 "iptables >= 1.8.5 required on Debian 10. \n\ - Please, turn on buster-backports repository and run the script/installation again. \n\ - Buster-backports repository may be turned on by following command: \n\ - echo "deb http://ftp.debian.org/debian buster-backports main" > /etc/apt/sources.list.d/buster-backports.list \n\ - Then run: \n\ - apt-get update \n" - fi -} - -detect_cloudways_environment() { - hostname=$(hostname -f) - lowercase_hostname=$(echo "$hostname" | tr '[:upper:]' '[:lower:]') - - if echo "$lowercase_hostname" | grep -Eq "\.cloudwaysapps\.com|cloudwaysstagingapps\.com"; then - is_cloudways=true - log echo "Cloudways environment detected" - touch /etc/sysconfig/imunify360/.cloudways_environment - elif [ -f /usr/local/sbin/apm ]; then - if /usr/local/sbin/apm info | grep -q "Cloudways"; then - is_cloudways=true - log echo "Cloudways environment detected" - mkdir -p /var/imunify360 - touch /etc/sysconfig/imunify360/.cloudways_environment - else - is_cloudways=false - fi - else - is_cloudways=false - fi -} - -setup_imunify360_dir() { - if [ ! -d "/var/imunify360/" ]; then - mkdir -m 2755 -p /var/imunify360 - fi -} - - -disable_firewall() { - setup_imunify360_dir - touch /var/imunify360/firewall_disabled -} - -special_config_cloudways() -{ - log echo "Installing cloudways configuration" - imunify360_python38_datadir=$venv_path/share/imunify360 - local first_install_cloudways="$imunify360_python38_datadir/11_on_first_install_cloudways.config" - cp -v "$first_install_cloudways" /etc/sysconfig/imunify360/imunify360.config.d/ && log echo "Done." -} - -create_short_lived_file() { - # create a script, which create a file and remove it after 20 minutes - echo '#!/bin/bash - touch '"$1"' - sleep 1200 - rm '"$1"'' > "$1".sh - - chmod +x "$1".sh - nohup "$1".sh > /dev/null 2>&1 & -} - -remove_short_lived_file() { - if [ -e "$1" ]; then - rm "$1" - fi - - if [ -e "$1".sh ]; then - rm "$1".sh - fi -} - -cleanup() -{ - rm -f "$LOCK" -} - -rapid_scan_basedir_override() { - touch /var/imunify360/rapid_scan_basedir_override -} - -# Lets start - -# if environment has umask=0000 (if called from plesk extension), all created files have -rw-rw-rw- permission -umask 0022 - -init_vars "$0" "$*" -reopen_log - -if [ -f "$LOCK" ] ; then - if [ -d "/proc/$(cat "$LOCK")" ] ; then - exit_with_error "$scriptname is already running" - fi -fi - -echo $$ > "$LOCK" -check_exit_code 0 "Please run $scriptname as root" - -trap cleanup SIGTERM SIGINT SIGHUP EXIT - -options=$(getopt -o ychk: -l yes,uninstall,help,version,check,skip-version-check,skip-registration,beta,dev-install,force,apt-force,freemium,key: -- "$@") -res=$? - -if [ "$res" != 0 ]; then - print_help - exit 1 -fi - -eval set -- "$options" - -while true; do - case "$1" in - -h|--help) - print_help - exit 0 - ;; - --version) - print_version - exit 0 - ;; - -y|--yes) - assumeyes=true - shift - ;; - -c|--uninstall) - uninstall=true - shift - ;; - -k|--key) - conversion=true - activationkey="$2" - shift 2 - ;; - --skip-version-check) - skipversioncheck=true - shift - ;; - --skip-registration) - registration=false - shift - ;; - --beta) - beta=true - yum_beta_option="--enablerepo=imunify360-testing" - yum_beta_repo_enable=1 - shift - ;; - --freemium) - freemium=true - shift - ;; - --dev-install) - dev_install=true - apt_allow_unauthenticated=--allow-unauthenticated - shift - ;; - --force|--apt-force) # used for Plesk extension installation - export DEBIAN_FRONTEND=noninteractive - apt_force='-o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confnew' - shift - ;; - --check) - detect_ostype - check_${ostype}_release - EXIT_CODE=$? - exit $EXIT_CODE - ;; - --) - shift - break - ;; - -*) - echo "$0: error - unrecognized option $1" 1>&2 - print_help - exit 1 - ;; - *) exit_with_error "Internal error!" ;; - esac -done - -if [ "$skipversioncheck" = "true" ]; then - log echo "Skipping check version" -else - log check_version "$*" -fi - -detect_ostype -check_${ostype}_release -detect_first_install - -if [[ "$package" = "$imunify360" ]]; then - check_users - remove_hardened_php_repos - # install vendors only for imunify360 - install_vendors="true" - detect_cloudways_environment -fi - - -if [ "$conversion" = "true" ] && [ "$uninstall" = "true" ] ; then - exit_with_error "invalid combination"; -fi - -if [ "$conversion" = "false" ] && [ "$registration" != "false" ] ; then - # Register by IP is the default now - conversion=true - activationkey=false -fi - -if [ "$uninstall" = "true" ]; then - remove_acronis_agent - remove_hardened_php_feature - remove_freemium_flag - log remove_${ostype}_imunify - terminate_detached_scans - - remove_${ostype}_repo - log remove_first_install_default_overrides - log echo "Uninstall complete." - exit 0 -fi - -set_panel_detection_path -detect_panel - - - -if [[ "$package" = "$imunify360" ]]; then - if ! check_${ostype}_pkg_presence ipset - then - log install_${ostype}_ipset - check_exit_code 0 "Package ipset was not installed." - fi - - if ! ipset list -n -t >/dev/null - then - exit_with_error "Your OS virtualization technology $(systemd-detect-virt 2>/dev/null || virt-what >/dev/null || echo of unknown type) has limited support for ipset in containers. Please, contact Imunify360 Support Team." - fi - - check_${ostype}_iptables_compatibility - - # Do not remove AV explicitly after moving 6.10 version into stable repo - if check_${ostype}_pkg_presence imunify-antivirus \ - && ! (check_${ostype}_pkg_presence imunify360-firewall); - then - # remove imunify-antivirus package for old imunify360 (due to conflict) - # for new imunify360 versions AV is a dependency of imunify360 - package_version=$(get_available_${ostype}_package_version "$package") - check_exit_code 0 "Failed to get package version" - log echo "$package $package_version is available" - - if [[ "${PANEL}" = "cpanel" ]]; then - # a marker file for UI for tracking the upgrade process - # short-lived because of the need to avoid hanging on upgrade process - create_short_lived_file /var/imunify360/upgrade_process_started - fi - - if version "$package_version" -lt "6.10" ; then - get_${ostype}_pkgs_manager - log echo "You are about to uninstall ImunifyAV and install Imunify360 that includes Malware Scanner. To get ImunifyAV back run the following commands: - # $pkgs_manager remove 'imunify360-firewall*' - # wget https://repo.imunify360.cloudlinux.com/defence360/imav-deploy.sh -O imav-deploy.sh - # bash imav-deploy.sh" - - if yesno "Do you agree to proceed with uninstalling ImunifyAV?"; then - log remove_${ostype}_pkgs 'imunify-antivirus' - else - exit 1 - fi - fi - fi - -fi - - -if [[ "$package" = "$imunify360" ]]; then - log echo "Checking prerequisites..." - case "$PANEL" in - cpanel) - if [ -f '/etc/cpanel/ea4/is_ea4' ] ; then - # modsec3 conflicts with mod_security2. Do not try to install - # mod_security2 if modsec3 exists - if ! check_${ostype}_pkg_presence ea-modsec30 - then - log echo "Installing mod_security2" - if [[ "$ostype" = "debian" ]]; then - # '-' (hyphen) - modsec_package=ea-apache24-mod-security2 - else - # '_' (underscore) - modsec_package=ea-apache24-mod_security2 - fi - log "install_${ostype}_pkgs" "$modsec_package" - fi - fi - # "activate" Freemium license: just feature flag for now - if [[ "${freemium}" = "true" ]]; then - log echo "Creating Imunify Freemium feature flag" - setup_imunify360_dir - touch "/var/imunify360/myimunify-freemium.flag" - fi - - ;; - directadmin) - pushd /usr/local/directadmin/custombuild/ - da_webserver="$(grep ^webserver= options.conf | sed s/webserver=//)" - da_modsecurity="$(grep ^modsecurity= options.conf | sed s/modsecurity=//)" - if [ "$da_webserver" != apache -a "$da_webserver" != litespeed ] - then - log echo "Imunify modsecurity ruleset is not supported for $da_webserver webserver." - else - if [ "$da_modsecurity" != yes ]; then - log echo "Installing DirectAdmin modsecurity..." - # create options.conf backup file before edit - # with name e.g. options.conf.bak_2018-03-29.1522323911 - sed -i.bak_"$(date +%F.%s)" \ - -e "s/^modsecurity=.*/modsecurity=yes/" \ - -e "s/^modsecurity_ruleset=.*/modsecurity_ruleset=no/" options.conf - ./build modsecurity - else - log echo "Installing DirectAdmin modsecurity... already installed!" - fi - modifying_call=true - fi - popd - ;; - generic) - if [ "$is_cloudways" != "true" ]; then - check_integration_conf - fi - ;; - plesk) - if ! /usr/local/psa/bin/server_pref --show-web-app-firewall >/dev/null 2>&1 \ - || ! ls /usr/local/psa/admin/sbin/modsecurity_ctl >/dev/null 2>&1 - then - # There appears to be a bug in Plesk - when installation is triggered via UI, using Plesk extension, - # i360deploy process somehow receives a SIGTERM from `plesk installer` process. - # See comments in https://cloudlinux.atlassian.net/browse/DEF-7450 for details. - # TODO: re-check this bug after installation is re-worked in https://cloudlinux.atlassian.net/browse/DEF-9061 - if [ "$I360_FROM_PLESK_EXTENSION" != 1 ]; then - log echo "Installing mod_security" - log run_with_retries "plesk installer --select-release-current --install-component modsecurity" "BUSY: Update operation was locked by another update process" "true" - fi - fi - ;; - esac -fi - - -if [ "$first_install" = "true" ]; then - log echo "In a few moments the script will install latest $package" \ - "package (w/dependencies)... (Ctrl-C to cancel)" - sleep 4 - save_${ostype}_repo - - - if [ "$is_cloudways" = "true" ]; then - disable_firewall - fi - - - package_version=$(get_available_${ostype}_package_version "$package") - check_exit_code 0 "Failed to get package version" - - log install_${ostype}_pkgs $package - rc=$? - # try installing the config overrides regardless of the installation success - log install_first_install_default_overrides "$package" "$package_version" - - if [[ "$package" = "$imunify360" ]]; then - log set_low_resource_usage_mode_if_necessary "$package" "$package_version" - fi - - # fail - if [ $rc -ne 0 ]; then - exit_with_error "Package $package $package_version was not installed." - fi - - if [ "$is_cloudways" = "true" ]; then - - special_config_cloudways - - rapid_scan_basedir_override - fi - - modifying_call=true -fi - -log echo "Installing ui packages..." -case "$PANEL" in - cpanel) - log check_and_install "$package" "$package_version" "$UI_PACKAGE" "$PANEL" - check_exit_code 0 "Failed to install $PRODUCT $PANEL plugin." - modifying_call=true - ;; - directadmin) - log check_and_install "$package" "$package_version" "$UI_PACKAGE" "$PANEL" - check_exit_code 0 "Failed to install $PRODUCT $PANEL plugin." - modifying_call=true - ;; - generic) - log check_and_install "$package" "$package_version" "imunify-ui" "$PANEL" - check_exit_code 0 "Failed to install $PRODUCT $PANEL plugin." - modifying_call=true - ;; - plesk) - log check_and_install "$package" "$package_version" "$UI_PACKAGE" "$PANEL" - check_exit_code 0 "Failed to install $PRODUCT $PANEL plugin." - - # disable ImunifyAV(revisium-antivirus) if it was installed - if /usr/local/psa/bin/extension --list | grep -q revisium-antivirus ; then - log echo "Disable ImunifyAV" - /usr/local/psa/bin/extension --disable revisium-antivirus - fi - modifying_call=true - ;; - *) - log echo "UI plugin is not installed." - log echo "No supported hosted panel detected and $INTEGRATION_CONF_PATH file is missing." - install_vendors=false - ;; -esac - -if [ "$conversion" = "true" ] ; then - - - if [[ "$package" = "$imunify360" ]]; then - if [ "$is_cloudways" != "true" ]; then - log echo "Checking if has already been registered... " - log imunify360-agent --console-log-level ERROR rstatus - rstatus=$? - if [ "$rstatus" = 11 ] ; then - exit_with_error "Registration server general error." - fi - if [ "$rstatus" = 0 -a "$activationkey" != false ] ; then - log echo "Unregister the previous registration key... " - log imunify360-agent --console-log-level WARNING unregister - fi - if [ "$activationkey" != false ] ; then - log echo "Register by key... " - log imunify360-agent --console-log-level WARNING register "$activationkey" - elif [ "$rstatus" != 0 ] ; then - # "$rstatus" != 0 check because it is no sense to re-register - # by IP (in comparison with re-register by activation key) - log echo "Register by IP... " - log imunify360-agent --console-log-level WARNING register IPL - fi - if [[ $? != 0 ]]; then - log echo "Registration was not successful." - else - log echo "Successfully registered" - fi - - disable_3rd_party_ids - fi - - if is_systemctl_avail; then - log systemctl enable imunify360.service - log systemctl start imunify360 - else - log /sbin/chkconfig --add imunify360 - log /sbin/service imunify360 start - fi - fi - - - check_exit_code 0 "Failed to start $package service." - - agent_start_success=false - - if [ "$is_cloudways" != "true" ]; then - log echo "Waiting for $PRODUCT to start..." - - for i in {1..10}; do - if log $COMMAND version - then - log echo "$PRODUCT is started" - agent_start_success=true - break - else - sleep 60 - fi - done - - remove_short_lived_file /var/imunify360/upgrade_process_started - - if ! $agent_start_success; then - log echo "Something went wrong during $PRODUCT start up" - exit_with_error "See /var/log/imunify360/error.log for details" - fi - - if [[ "$package" = "$imunify360" ]]; then - # agent is started - #force-disable WebShield - if [ "$PANEL" = "generic" ] ; then - imunify360-agent config update '{"WEBSHIELD": {"enable": false}}' - fi - # turn on MyImunify - if [[ "${freemium}" = "true" && "$PANEL" = "cpanel" ]]; then - log echo "Turning on MyImunify" - imunify360-agent config update '{"MY_IMUNIFY": {"enable": true}}' - fi - fi - if [ "$install_vendors" = "true" ]; then - /usr/bin/imunify360-agent --console-log-level=WARNING install-vendors - fi - else - install_vendors_in_cw_environment >/dev/null & - disown - - fi -elif ! $COMMAND rstatus >/dev/null 2>&1 -then - log echo "You have to register this software with registration key:" - log echo " $script --key " -fi - -if $modifying_call; then - log echo "Success" - log echo "You can find complete log in $LOG_FILE" -fi -exit 0 \ No newline at end of file