/opt/imunify360/venv/share/imunify360/scripts
NameSizeModeActions
migrate_csf/-0755rm
__pycache__/-0755rm
check-detached.py11410755editdlrm
create_default_config12630755editdlrm
delay_on_cron_call.py11490755editdlrm
imunify-check-pkg-integrity76500755editdlrm
imunify-core-release4150700editdlrm
imunify-disable-cpu-accounting.sh10240744editdlrm
imunify-doctor.sh269560744editdlrm
imunify-force-update.sh83450744editdlrm
imunify_core_release.py222740644editdlrm
purge-clamav5390755editdlrm
send-notifications154724770editdlrm
setup_cagefs.py45830700editdlrm
track-fpfn-submissions.sh38960755editdlrm
update_components_versions.py42090755editdlrm
Edit: /opt/imunify360/venv/share/imunify360/scripts/imunify-check-pkg-integrity (7650B)
#!/bin/bash PKG_INTEGRITY_VERSION="1.0.3" # imunify-check-pkg-integrity: verify imunify* package file integrity # via rpm -V / dpkg -V. Outputs results to stdout. # # Deployed to (both RPM and DEB, spec overrides _prefix): # /opt/imunify360/venv/share/imunify360/scripts/imunify-check-pkg-integrity # Package: imunify-core # # This script is also sourced by imunify-force-update.sh for shared functions # (filter_integrity_output, check_dpkg_verify_supported, etc.). # set -euo pipefail is only applied when run directly, not when sourced. DEBIAN_VERSION_FILE="${DEBIAN_VERSION_FILE:-/etc/debian_version}" # Files always reported as modified on a healthy system. # On RPM most of these are %config and already filtered by filter_verify_noise; # on Debian they are NOT marked as conffiles, so we whitelist explicitly. # Uses substring matching (grep -v -F). INTEGRITY_WHITELIST_FILES=( "imunify360.config.defaults.example" # imunify-ui-*-cpanel: triggerin runs sed to patch IMUNIFY_PACKAGE in config.js "imunify/assets/js/config.js" # imunify-ui-antivirus-directadmin: %posttrans/%triggerin and the deb postinst # sed these in place (IMUNIFY_PACKAGE, ImunifyAV->Imunify360, php shebang). # The cPanel entry above cannot cover them: matching is case-sensitive and # this tree is 'Imunify/images/assets/...', not 'imunify/assets/...'. "directadmin/plugins/Imunify/plugin.conf" "directadmin/plugins/Imunify/hooks/" "directadmin/plugins/Imunify/images/assets/js/config.js" "directadmin/plugins/Imunify/admin/index.html" "directadmin/plugins/Imunify/admin/request.raw" "directadmin/plugins/Imunify/user/index.html" "directadmin/plugins/Imunify/user/request.raw" # imunify360-php-i360: postinst copies .ini/.so per PHP version from templates "/i360.ini" "/i360.so" # i360-php-opts: module.ini modified during config (conffile on RPM, not on DEB) "i360-php-opts/module.ini" # imunify360-ossec-server: postinst sed-patches analysisd.stats_maxdiff "internal_options.conf" # imunify360-webshield-bundle: service updates these at runtime (conffile on RPM, not on DEB) "imunify360-webshield/common-proxies.conf" "imunify360-webshield/country_ips.conf" "imunify360-webshield/whitelisted-domains.conf" # imunify360-webshield-bundle: postinst awk-merges wscheck.conf on DEB. # DEF-41475 registers it as a conffile going forward; this whitelist line # keeps hosts on older bundles quiet until the new .deb rolls out. "imunify360-webshield/wscheck.conf" ) detect_pkg_manager() { if [ -f "$DEBIAN_VERSION_FILE" ]; then echo "dpkg" elif command -v rpm >/dev/null 2>&1; then echo "rpm" else echo "unknown" fi } check_dpkg_verify_supported() { # Inspect help text instead of `dpkg -V ` exit code: the latter goes # non-zero when the probe package has any modified files, falsely marking # -V as unsupported. Pure bash to avoid SIGPIPE under set -o pipefail. local help help=$(dpkg --help 2>&1) || return 1 [[ $help == *--verify* || $help == *" -V"* ]] } # Filter rpm -V / dpkg -V output to keep only lines indicating real corruption. # # Both tools use a 9-char flag string + optional type flag + path. # rpm: SM5DLUGTP [c|d|g|l|r| ] /path dpkg: ??5?????? [c| ] /path # rpm also emits: missing /path # # Excluded: # - config files (type 'c') and ghost files (type 'g') # - .pyc files (Python bytecode cache, regenerated at import) # - metadata-only changes (no S or 5 flag - just mode/group/time drift) # Kept: # - 'missing' lines for non-pyc files # - lines with S (size, pos 1) or 5 (digest, pos 3) change filter_verify_noise() { grep -v -E '^.{9} +[cg] ' \ | grep -v '\.pyc$' \ | grep -E '^(S|..5|[?][?]5|missing)' \ || true } filter_whitelisted_files() { local input input=$(cat) if [[ ${#INTEGRITY_WHITELIST_FILES[@]} -eq 0 ]]; then echo "$input" return fi local pattern="" for entry in "${INTEGRITY_WHITELIST_FILES[@]}"; do if [[ -n "$pattern" ]]; then pattern+=$'\n' fi pattern+="$entry" done echo "$input" | grep -v -F "$pattern" || true } # imunify360-php-i360 declares a directory tree per supported PHP version, so a # host running only a few of them reports ~200 absent directories -- enough to # keep the package permanently BROKEN and force-update reinstalling it forever. # # Scoped to 'missing' only, so a content change under these roots still reports. # The trade-off: an absent file we do own under these roots also goes quiet. # Only i360.ini/i360.so live there, and both are already whitelisted above. filter_phantom_php_dirs() { grep -v -E '^missing +(/opt/cpanel|/opt/plesk|/usr/share/cagefs/\.cpanel\.multiphp)(/|$)' \ || true } # The single place that defines what counts as real corruption. Shared with # imunify-force-update.sh, which sources this script. filter_integrity_output() { filter_verify_noise | filter_whitelisted_files | filter_phantom_php_dirs } list_packages_rpm() { rpm -qa 'imunify*' 2>/dev/null | sort } list_packages_dpkg() { dpkg-query -W -f '${Status} ${Package}\n' 'imunify*' 2>/dev/null \ | sed -n 's/.* installed \(.*\)/\1/p' \ | sort } verify_package_rpm() { local pkg="$1" local raw_output="" raw_output=$(rpm -V "$pkg" 2>&1) || raw_output="${raw_output}" local filtered="" filtered=$(echo "$raw_output" | filter_integrity_output) if [[ -n "$filtered" ]]; then echo "$filtered" return 1 fi return 0 } verify_package_dpkg() { local pkg="$1" local raw_output="" raw_output=$(dpkg -V "$pkg" 2>&1) || raw_output="${raw_output}" local filtered="" filtered=$(echo "$raw_output" | filter_integrity_output) if [[ -n "$filtered" ]]; then echo "$filtered" return 1 fi return 0 } check_packages() { local pkg_manager pkg_manager=$(detect_pkg_manager) local verify_supported="yes" local overall_status="ok" local broken_output="" local packages="" case "$pkg_manager" in rpm) packages=$(list_packages_rpm) ;; dpkg) packages=$(list_packages_dpkg) if ! check_dpkg_verify_supported; then verify_supported="no" fi ;; *) verify_supported="no" ;; esac if [[ "$verify_supported" == "yes" ]] && [[ -n "$packages" ]]; then while IFS= read -r pkg; do [[ -z "$pkg" ]] && continue local output="" local rc=0 case "$pkg_manager" in rpm) output=$(verify_package_rpm "$pkg") || rc=$? ;; dpkg) output=$(verify_package_dpkg "$pkg") || rc=$? ;; esac if [[ $rc -ne 0 ]]; then overall_status="broken" broken_output+=$'\n'"BROKEN: ${pkg}"$'\n'"${output}"$'\n' fi done <<< "$packages" fi echo "PKG_MANAGER: ${pkg_manager}" echo "VERIFY_SUPPORTED: ${verify_supported}" echo "STATUS: ${overall_status}" if [[ -n "$broken_output" ]]; then echo "$broken_output" fi } main_entrypoint() { local output output=$(check_packages) echo "$output" if echo "$output" | grep -q "^STATUS: broken"; then return 1 fi return 0 } if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then set -euo pipefail main_entrypoint fi