Server IP : 184.154.167.98 / Your IP : 18.191.91.15 Web Server : Apache System : Linux pink.dnsnetservice.com 4.18.0-553.22.1.lve.1.el8.x86_64 #1 SMP Tue Oct 8 15:52:54 UTC 2024 x86_64 User : puertode ( 1767) PHP Version : 7.2.34 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /usr/share/imunify360-webshield/ |
Upload File : |
#!/bin/bash if [ "$IM360_DEBUG_SHELL" = "1" ]; then echo "IM360_ARGV: <$0 [$@]>" set -x else : fi # For backwards compatibility with CentOS 6 only. WEBSHIELD='imunify360-webshield' JOBFILE=/etc/cron.d/imunify360-webshield-check STATEFILE="/usr/share/imunify360-webshield/.webshieldctl.status" VIRTSERVER_CONF="/etc/imunify360-webshield/virtserver.conf" WEBSHIELD_ANTIBOT_CONF="/etc/imunify360-webshield/splashscreen-antibot.conf" MODE='undefined' SSL_UNIT='imunify360-webshield-ssl-cache' WAFD_UNIT='imunify360-wafd' MAIN_UNIT='undefined' OUR_MODULES_DIR=/usr/share/imunify360-webshield/modules NGINX_MODULE_CONF=/etc/nginx/modules-enabled/40-imunify360-access-checker.conf NGINX_CHECKER_CONF=/etc/nginx/conf.d/imunify360-access-checker.conf PREVIOUS_MODE_STATE_PATH=/usr/share/imunify360-webshield/.previous_mode STATE_PATH=/usr/share/imunify360-webshield/modularity_mode readonly COMMON_CONF=/etc/sysconfig/imunify360/imunify360-merged.config # Returns code 0 if webshield is enabled and code 1 otherwise. # On any errors we suppose that webshield is enabled, which is the default value. # Refer to: defence360:config_schema/firewall.py. # WARN: According to the YAML standard, all maps must contains unique keys only. # But Python implementation silently overwrites the values with the same keys. # This parser behaves exactly the same - it returns the last value as the result. is_enabled_in_config() { [ -s "$COMMON_CONF" ] || return 0 local value=$( awk -F: ' /^WEBSHIELD:$/ { section_found=1; next; }; section_found == 1 && /^[A-Z][A-Z0-9_-]*:$/ { section_over=1; next; }; section_found == 1 && section_over != 1 && /^[[:space:]]+enable:/ { gsub(/[[:space:]]/, "", $2); print $2; }' "$COMMON_CONF" ) [ "$value" = 'false' ] && return 1 || return 0 } is_cloudways() { hostname -f 2>/dev/null | grep -qE '^.+\.(cloudwaysapps|cloudwaysstagingapps)\.com$' && return 0 [ -x /usr/local/sbin/apm ] && /usr/local/sbin/apm info | grep -qi cloudways } detect_mode() { local mode='standalone' # TODO: At the moment, module-based nginx is available for CloudWays only. if is_cloudways; then mode='nginx' fi if [ -s "$STATE_PATH" ] && [ "$1" = 'skip-on-update' ]; then # Do not override config on packages update. mode=$(<"$STATE_PATH") echo "Module-based config left untouched with mode: '$mode'." else echo $mode >| $STATE_PATH echo "Module-based mode set to: '$mode'." fi } load_mode() { local mode='undefined' local unit='undefined' local value='' [ -s "$STATE_PATH" ] && value=$(<"$STATE_PATH") case "$value" in nginx) mode="$value" unit="$value" ;; apache) mode="$value" unit=$(get_unit) ;; *) mode='standalone' unit='imunify360-webshield' ;; esac export MODE="$mode" export MAIN_UNIT="$unit" } is_cpanel(){ if [ -x /usr/local/cpanel/cpanel ];then return 0 fi return 1 } is_redhat(){ if [ -e /etc/redhat-release ];then return 0 fi return 1 } has_apache(){ if which apachectl &>/dev/null; then return 0 fi return 1 } is_supported(){ if has_apache && is_cpanel && [ ! -d /usr/local/lsws ]; then [ "$1" = "out" ] && echo yes return 0 else [ "$1" = "out" ] && echo no return 1 fi } get_apache_root(){ echo $(apachectl -V | awk -F= '/HTTPD_ROOT/{gsub("\042", "", $2);print $2}') } put_apache_conf(){ if is_supported; then local root=$(get_apache_root) if is_redhat;then if [ -d $root/conf.d ];then cp /usr/share/imunify360-webshield/access_checker.conf $root/conf.d fi else # By default debian-based apache has modules configs in ROOT/mods-available folder # and enables the modules with placing a symlink to the config file into ROOT/mods-enabled. # Ubuntu-based cpanel keeps configs in ROOT/conf.d if [ -d $root/conf.d ];then cp /usr/share/imunify360-webshield/access_checker.conf $root/conf.d elif [ -d $root/mods-available ] && [ -d $root/mods-enabled ];then cp /usr/share/imunify360-webshield/access_checker.conf $root/mods-available ln -s $root/mods-available/access_checker.conf $root/mods-enabled # But we've seen different debian apache setups elif [ -d $root/mods-enabled ];then cp /usr/share/imunify360-webshield/access_checker.conf $root/mods-enabled fi fi fi } remove_apache_conf(){ local root=$(get_apache_root) if is_redhat;then rm -f $root/conf.d/access_checker.conf else if [ -d $root/conf.d ];then rm -f $root/conf.d/access_checker.conf else rm -f $root/mods-enabled/access_checker.conf fi fi } check_apache_config(){ apachectl configtest } get_unit(){ if is_redhat;then # Both ea-apache and httpd packages supply the same unit: httpd echo httpd else # Ubuntu-based cPanel runs httpd unit. However, it returns 0 even on missing unit file # So we check output '0/1 unit files listed' if [ $(systemctl list-unit-files httpd.service 2>&1 | awk '/unit files listed/{print $1}') = '1' ];then echo httpd else echo apache2 fi fi } # the webshield is running as a separate entity is_standalone() { [ "$MODE" = 'standalone' ] } # We supplied our module for a hoster's NGINX. No webshield is running is_nginx(){ [ "$MODE" = nginx ] } # We supplied our module for a hoster's Apache. # Webshield is running as well and serves non-HTTP/HTTPS ports is_apache(){ [ "$MODE" = apache ] } cleanup_configs() { case "$MODE" in nginx) rm -vf "$NGINX_MODULE_CONF" "$NGINX_CHECKER_CONF" ;; apache) remove_apache_conf ;; esac } prepare_nginx() { local version=$(nginx -v 2>&1 | grep -oP '(\d+[.]){2}\d+') local mod_path="$OUR_MODULES_DIR"/"ngx_http_access_checker_module_${version}.so" if ! [ -s "$mod_path" ]; then echo "ERROR: Unable to find nginx module for version '$version'." >&2 return 1 fi # WARN: Explicit check that the path is exist and it is a directory # cause simple 'echo' to a file will raise error with an ambiguous message # "No such file or directory" like you're trying to *READ* from the file. # "dirname" does not check type of its argument and just cut everything # following the last slash. local path='' for path in "$NGINX_MODULE_CONF" "$NGINX_CHECKER_CONF"; do if ! [ -d $(dirname "$path") ]; then echo "ERROR: Unable to find directory for config '$path'." >&2 return 1 fi done if ! nginx -t ; then echo "ERROR: Invalid nginx config before installing module." >&2 return 1 fi echo "load_module ${mod_path};" >| "$NGINX_MODULE_CONF" || return 1 echo 'access_checker unix:/var/run/imunify360/libiplists-daemon.sock;' >| "$NGINX_CHECKER_CONF" || return 1 if ! nginx -t ; then echo "ERROR: Invalid nginx config after installing module." >&2 return 1 fi } prepare_configs() { is_enabled_in_config || return 0 case "$MODE" in nginx) prepare_nginx ;; apache) put_apache_conf ;; esac } check_nginx() { [ -s "$NGINX_MODULE_CONF" ] || return 1 [ -s "$NGINX_CHECKER_CONF" ] || return 1 nginx -T 2> /dev/null | grep -qE '^access_checker\s+unix:/[^.]+[.]sock;$' || return 1 local pid='' pid=$(pgrep -f 'nginx:\s+master') || return 1 # pid=1 is acquired by init. [[ "$pid" =~ ^([2-9]|[1-9][0-9]+)$ ]] || return 1 grep -qP '/ngx_http_access_checker_module_(\d+[.]){2}\d+[.]so$' /proc/"$pid"/maps } check_configs() { case "$MODE" in nginx) check_nginx ;; apache) check_apache_config ;; esac } has_hosting_panel(){ local checks=( /usr/local/cpanel/cpanel /usr/sbin/plesk /usr/local/directadmin/custombuild/build ) for i in ${checks[@]};do [ -e $i ] && return 0 done return 1 } count_processes(){ local count=$(ps aux | grep -c '[i]m360:\|webshield-[s]sl-cache') echo $count } check_running(){ # for hosts with hosting panels we expect 5 processes to be running. # otherwise 4 ones (ssl-cache is not expected to be run on no-panel hosts) local num=$(count_processes) local expected if has_hosting_panel; then expected=3; else expected=2; fi [ $num -ge $expected ] && return 0 return 1 } check_stopped(){ local num=$(count_processes) [ $num -eq 0 ] && return 0 return 1 } enable_for_systemd(){ systemctl enable $WAFD_UNIT || return $? systemctl enable $SSL_UNIT || return $? # Webshield should be enabled and running in standalone mode to serve all ports # and in Apache mode to serve non-standard HTTP/HTTPS ports like cPanel ports. is_nginx || systemctl enable $WEBSHIELD } safe_reload() { # WARN: In some cases 'reload-or-restart' action is not applicable # and need to be done directly. if systemctl --quiet is-active $1 ; then systemctl reload $1 else systemctl restart $1 fi } start_for_systemd(){ systemctl start $WAFD_UNIT || return $? if ! systemctl start $SSL_UNIT; then # WARN: Ignore error cause ssl-cache will exit if there is no panel. has_hosting_panel && return 1 || : fi if is_nginx;then prepare_configs && systemctl reload $MAIN_UNIT && return 0 cleanup_configs return 1 elif is_apache;then # In apache mode we expect both apache and webshield are running: apache # for HTTP/HTTPS ports and webshield for the rest of them (like 2082/2083) # WARN: Sometimes Apache unit can not be reloaded and must to be restarted. prepare_configs && safe_reload $MAIN_UNIT && systemctl start $WEBSHIELD && return 0 cleanup_configs return 1 elif is_standalone;then systemctl start $MAIN_UNIT else echo "Configuration error: unknown mode: $MODE" return 1 fi } activate_for_systemd(){ local RV enable_for_systemd RV=$? [ $RV -ne 0 ] && return $RV start_for_systemd } disable_for_systemd(){ local failed=0 # we don't disable wafd because it's used # for ip-list functionality systemctl disable $SSL_UNIT || failed=1 if is_standalone; then systemctl disable $MAIN_UNIT || failed=1 else cleanup_configs || failed=1 systemctl reload $MAIN_UNIT || failed=1 if is_apache; then # Webshield is enabled in Apache mode to serve # non-standard HTTP/HTTPS ports like cPanel ports. systemctl disable $WEBSHIELD || failed=1 fi fi return $failed } stop_for_systemd(){ local failed=0 local wafd_force=$1 # we stop wafd only in 'restart' action, i.e stop with # subsequent start if [ "x$wafd_force" = xforce ];then systemctl stop $WAFD_UNIT || failed=1 fi systemctl stop $SSL_UNIT || failed=1 if is_nginx;then cleanup_configs || failed=1 systemctl reload $MAIN_UNIT || failed=1 elif is_apache;then # stopping in apache mode means that we unload access_checker # module from apache server and stop webshield cleanup_configs || failed=1 systemctl reload $MAIN_UNIT || failed=1 systemctl stop $WEBSHIELD || failed=1 elif is_standalone;then systemctl stop $MAIN_UNIT || failed=1 fi return $failed } deactivate_for_systemd(){ local RV stop_for_systemd RV=$? [ $RV -ne 0 ] && return $RV disable_for_systemd } do_terminate(){ stop_for_systemd force local RV0=$? disable_for_systemd local RV=$? # We run both command but return success only if both of them succeded if [ $RV -ne 0 ]; then return $RV fi return $RV0 } do_enable(){ enable_for_systemd local rv=$? if [ $rv == 0 ]; then echo "enabled" > $STATEFILE fi return $rv } do_disable(){ disable_for_systemd local rv=$? if [ $rv == 0 ]; then echo "disabled" > $STATEFILE fi return $rv } do_start(){ start_for_systemd local rv=$? if [ $rv == 0 ]; then echo "started" > $STATEFILE fi return $rv } do_stop(){ local force=$1 stop_for_systemd $force local rv=$? if [ $rv == 0 ]; then echo "stopped" > $STATEFILE fi return $rv } do_activate(){ activate_for_systemd local rv=$? if [ $rv == 0 ]; then echo "activated" > $STATEFILE fi return $rv } do_deactivate(){ deactivate_for_systemd local rv=$? if [ $rv == 0 ]; then echo "deactivated" > $STATEFILE fi return $rv } is_enabled(){ # We don't care if ssl-cache unit is enabled. Webshield will start it # by 'Wants' dependency before its own start. If it's not required for # given environment (no known hosting panel) it'll exit then. local failed=0 if systemctl -q is-enabled $WAFD_UNIT; then echo "Unit '$WAFD_UNIT' is enabled." else echo "ERROR: Unit '$WAFD_UNIT' is NOT enabled." >&2 failed=1 fi # $MAIN_UNIT is either imunify360-webshield (in standalone mode) or a host # webserver. It seems that there's no sense to check if host webserver is # enabled as we don't have control over it at any rate. if is_standalone; then if systemctl -q is-enabled $MAIN_UNIT; then echo "Unit '$MAIN_UNIT' is enabled." else echo "Unit '$MAIN_UNIT' is NOT enabled." >&2 failed=1 fi else # WARN: Webshield is always disabled for Cloudways, so its state must not be used as the result. is_cloudways && check_nginx || systemctl -q is-enabled $WEBSHIELD failed=$? fi return $failed } is_active(){ if is_standalone; then if check_running; then echo "$MAIN_UNIT is running" return 0 else echo "$MAIN_UNIT is not running" return 1 fi fi local name='undefined' local state='undefined' local units=($MAIN_UNIT $WAFD_UNIT $SSL_UNIT) local failed=0 for name in ${units[@]}; do state="$(systemctl is-active $name 2>&1)" if [ "$state" = "active" ]; then echo "Unit '$name' is active." else # WARN: ssl-cache must be processed in its very special way, see below. if ! [ "$name" = $SSL_UNIT ]; then echo "ERROR: Unit '$name' is NOT active, result='$state'." >&2 failed=1 continue fi if has_hosting_panel; then echo "ERROR: Unit '$SSL_UNIT' is NOT active, result '$state'." >&2 failed=1 else echo "WARNING: Unit '$SSL_UNIT' is NOT active, result '$state' (ignored)." >&2 fi fi done if [ $failed -eq 0 ]; then if ! check_configs; then echo "ERROR: Web server is not configured properly." >&2 failed=1 fi fi return $failed } do_restart(){ do_stop force do_start } do_enable_splashscreen(){ is_standalone || return 0 local ss_state=$(awk '$1 == "splashscreen_antibot" {gsub(";","",$2);print $2}' $WEBSHIELD_ANTIBOT_CONF) if [ "$ss_state" = on ];then echo "splashscreen is already enabled" return 0 fi sed -i -e "/splashscreen_antibot/ {s/off/on/}" $WEBSHIELD_ANTIBOT_CONF do_restart } do_disable_splashscreen(){ is_standalone || return 0 local ss_state=$(awk '$1 == "splashscreen_antibot" {gsub(";","",$2);print $2}' $WEBSHIELD_ANTIBOT_CONF) if [ "$ss_state" = off ];then echo "splashscreen is already disabled" return 0 fi sed -i -e "/splashscreen_antibot/ {s/on/off/}" $WEBSHIELD_ANTIBOT_CONF do_restart } do_enable_cpanelprotection(){ is_standalone || return 0 local cp_state=$(awk '$2 == "$cpanel_protection" {gsub(";","",$3);print $3}' $VIRTSERVER_CONF) if [ "$cp_state" = 1 ];then echo "cpanel_protection is already enabled" return 0 fi sed -i -e '/$cpanel_protection/ {s/0/1/}' $VIRTSERVER_CONF do_restart } do_disable_cpanelprotection(){ is_standalone || return 0 local cp_state=$(awk '$2 == "$cpanel_protection" {gsub(";","",$3);print $3}' $VIRTSERVER_CONF) if [ "$cp_state" = 0 ];then echo "cpanel_protection is already disabled" return 0 fi sed -i -e '/$cpanel_protection/ {s/1/0/}' $VIRTSERVER_CONF do_restart } do_reload(){ # WARN: Ignoring errors here is for the compatibility with sysvinit script # which contains bug - on action "reload" it always exits with code 0. # try-reload-or-restart is supported only from version 229, # which is not the case for Centos7. The difference between try-reload-or-restart # and reload-or-restart is that former does nothing unless the service is running. if systemctl --quiet is-active $SSL_UNIT;then systemctl reload-or-restart $SSL_UNIT || : fi if systemctl --quiet is-active $WAFD_UNIT;then systemctl reload-or-restart $WAFD_UNIT || : fi if systemctl --quiet is-active $MAIN_UNIT;then systemctl reload-or-restart $MAIN_UNIT || : fi } # Enable standalone mode set_standalone(){ if ! is_standalone;then echo "$MODE" >| "$PREVIOUS_MODE_STATE_PATH" echo standalone >| "$STATE_PATH" do_stop force load_mode do_start else echo "Required mode is already applied. Nothing to do" return 1 fi } # Returned to the previous state if we have state backup file # otherwise switch to apache mode if supported unset_standalone(){ if is_standalone; then if [ -s "$PREVIOUS_MODE_STATE_PATH" ]; then local prev_mode=$(<"$PREVIOUS_MODE_STATE_PATH") if [ -n "$prev_mode" ] && [ "$prev_mode" != standalone ]; then echo -n "$prev_mode" >| "$STATE_PATH" || return 1 fi rm -f "$PREVIOUS_MODE_STATE_PATH" elif is_supported; then echo apache >| $STATE_PATH fi do_stop force load_mode do_start else echo "Required mode is already applied. Nothing to do" return 1 fi } configure() { deactivate_for_systemd || true systemctl unmask imunify360-webshield || true detect_mode 'skip-on-update' load_mode is_cloudways && systemctl mask imunify360-webshield || true activate_for_systemd } print_help(){ echo "enable : enables webshield starting on boot (without actully starting it)" echo "is-enabled : shows if the webshield is enabled to start on boot" echo "is-active : shows if the webshield is running now" echo "disable : disables webshield starting on boot (without actully stopping it)" echo "start : starts webshield (without enabling its starting on boot)" echo "stop : stops webshield (without disabling its starting on boot)" echo "activate : enables webshield starting on boot and starts it right away" echo "deactivate : stops webshield right away and disables its starting on boot" echo "terminate : stops webshield and wafd right away and disables its starting on boot" echo "enable-splashscreen : enables splashscreen functionality for webshield" echo "disable-splashscreen : disables splashscreen functionality for webshield" echo "enable-cpanelprotection : enables cpanelprotection functionality for webshield" echo "disable-cpanelprotection : disables cpanelprotection functionality for webshield" echo "set-standalone : forcibly use standalone mode" echo "unset-standalone : switch from forcibly set standalone mode to the previous one (if exists)" echo "mode : shows the current module" echo "mode module : if possible switch from standalone to module-based mode" echo "mode proxy : if possible switch from module-based to standalone mode" echo "mode supported : prints if switching to module-based mode is supported for current system" echo "reload : reload settings without restart" } load_mode case "$1" in enable) do_enable ;; disable) do_disable ;; is-enabled) is_enabled ;; is-active) is_active ;; start) do_start ;; stop) do_stop ;; activate) do_activate ;; deactivate) do_deactivate ;; terminate) do_terminate ;; enable-splashscreen) do_enable_splashscreen ;; disable-splashscreen) do_disable_splashscreen ;; enable-cpanelprotection) do_enable_cpanelprotection ;; disable-cpanelprotection) do_disable_cpanelprotection ;; reload) do_reload ;; mode) if [ "$2" = module ]; then unset_standalone elif [ "$2" = proxy ]; then set_standalone elif [ "$2" = supported ]; then is_supported 'out' elif [ -z "$2" ]; then if [ "$MODE" = standalone ]; then echo proxy else echo "$MODE" fi else echo "Unknown mode: $2. Exit" exit fi ;; mode-proxy) set_standalone ;; mode-module) unset_standalone ;; mode-supported) is_supported 'out' ;; set-standalone) set_standalone ;; unset-standalone) unset_standalone ;; detect-mode) detect_mode ;; is-apache) is_apache ;; is-nginx) is_nginx ;; is-cloudways) is_cloudways ;; is-standalone) is_standalone ;; configure) configure ;; help) print_help ;; *) echo "Usage: $0 {enable|disable|start|stop|activate|deactivate|is-enabled|is-active|enable-splashscreen|disable-splashscreen|enable-cpanelprotection|disable-cpanelprotection|reload|set_standalone|unset_standalone|mode|mode proxy|mode module|mode supported|detect-mode|is-apache|is-nginx|is-cloudways|is-standalone|help}" exit 2 esac