Everything posted by TheHolbi
-
Fixing False Positive CWP Security Audit Alerts on AlmaLinux 9.x
After recent CWP updates, some AlmaLinux 9.x servers may report false security alerts when running: sh /scripts/cwp_security_audit A typical false positive looks like this: ------------------------------------------------------ [INFO] Auditing cwpsrv (PID: 767572) [OK] cwpsrv looks clean. ------------------------------------------------------ [INFO] Auditing php-fpm-cwp (PID: 710) [SECURITY ALERT] Unknown/Untrusted file: /usr/lib64/gconv/gconv-modules.cache Error:Can't add notification![SECURITY ALERT] Unauthorized port: php-fpm Error:Can't add notification!------------------------------------------------------ [INFO] Auditing apache (PID: 768077) [OK] apache looks clean. ------------------------------------------------------ [DONE] Security audit finished. In this case the warning is misleading. On AlmaLinux 9.x, the file: /usr/lib64/gconv/gconv-modules.cache is a normal system file used by the GNU C Library character conversion system. The original CWP audit script does not include /usr/lib64/gconv/ in the allowed library paths, so it incorrectly reports this file as unknown or untrusted. There is also a second parsing issue in the port audit section. The original script extracts listening ports using a simple awk -F':' expression against generic lsof output. In some cases this can incorrectly parse process-related text and produce an alert such as: [SECURITY ALERT] Unauthorized port: php-fpm Obviously, php-fpm is not a port number. What needs to be fixedThere are two small changes that solve the false positives. First, add this path to ALLOWED_LIB_PATHS: "/usr/lib64/gconv/" Second, replace the port audit line with a more precise lsof command that only checks TCP listening sockets: local CURRENT_PORTS=$(lsof -Pan -p $PID -iTCP -sTCP:LISTEN 2>/dev/null | awk 'NR>1 {split($9,a,":"); print a[length(a)]}') This avoids parsing unrelated lsof lines and prevents values like php-fpm from being treated as ports. Patched version of /scripts/cwp_security_auditBelow is the corrected version. It keeps the original logic but fixes the AlmaLinux 9.x false positives. #!/bin/bash # --- CONFIGURATION --- ALLOWED_LIB_PATHS=( "/usr/lib64/lib" "/usr/lib64/ld-" "/usr/local/ioncube/" "/usr/lib/locale/" "/usr/local/cwp/" "/usr/local/apache/modules/" "/usr/local/lib/" "/usr/lib64/gconv/" ) ALLOWED_BINARIES=( "/usr/local/cwpsrv/bin/cwpsrv" "/usr/local/cwp/php71/sbin/php-fpm" "/usr/local/apache/bin/httpd" ) ALLOWED_PORTS=("2030" "2031" "2082" "2083" "2086" "2087" "2095" "2096" "9000" "2302" "2304" "8181" "8443" "80" "443") # --- INITIALIZATION --- if ! command -v lsof &> /dev/null; then yum install -y lsof fi # --- FUNCTIONS --- check_process() { local PROC_NAME=$1 local SEARCH_PATTERN=$2 local PID=$(ps aux | grep "$SEARCH_PATTERN" | grep -v grep | awk '{print $2}' | head -n 1) if [ -z "$PID" ]; then echo "[SKIP] Process '$PROC_NAME' not found." return fi echo "------------------------------------------------------" echo "[INFO] Auditing $PROC_NAME (PID: $PID)" local GLOBAL_ERROR=0 # 1. Detect GHOST Files (DELETED or missing via stat) local GHOST_DATA=$(lsof -p $PID -n | grep -E "DEL|\(stat:" | grep -v "/dev/zero") if [ ! -z "$GHOST_DATA" ]; then echo "[!!! CRITICAL ALERT !!!] Ghost files (deleted but running) found:" echo "$GHOST_DATA" /usr/local/cwp/php71/bin/php /usr/local/cwpsrv/htdocs/resources/admin/include/libs/notifications/cli.php --level="danger" --subject="CWP Security Audit - Ghost files (deleted but running)" --message="[!!! CRITICAL ALERT !!!] Ghost files (deleted but running) found, for more info run: sh /scripts/cwp_security_audit" GLOBAL_ERROR=1 fi # 2. Deep Memory Audit (Path + RPM Package Check) local CURRENT_MEM=$(lsof -p $PID -n | grep "mem" | awk '{for(i=9;i<=NF;i++) printf "%s ", $i; print ""}' | sed 's/(stat:.*//' | xargs) for FILE in $CURRENT_MEM; do [[ -z "$FILE" || "$FILE" == "REG" || "$FILE" == "mem" || "$FILE" == "/" ]] && continue local MATCH=0 for ALLOWED in "${ALLOWED_LIB_PATHS[@]}"; do if [[ "$FILE" == "$ALLOWED"* ]]; then MATCH=1; break; fi done for ALLOWED in "${ALLOWED_BINARIES[@]}"; do if [[ "$FILE" == "$ALLOWED" ]]; then MATCH=1; break; fi done if [ $MATCH -eq 0 ]; then echo "[SECURITY ALERT] Unknown/Untrusted file: $FILE" /usr/local/cwp/php71/bin/php /usr/local/cwpsrv/htdocs/resources/admin/include/libs/notifications/cli.php --level="danger" --subject="CWP Security Audit - Unknown/Untrusted file" --message="[SECURITY ALERT] Unknown/Untrusted file: $FILE" GLOBAL_ERROR=1 else if [[ "$FILE" == "/usr/lib64/"* ]]; then if ! rpm -qf "$FILE" &>/dev/null; then echo "[!!! DANGER !!!] File in system path but NOT owned by any package: $FILE" /usr/local/cwp/php71/bin/php /usr/local/cwpsrv/htdocs/resources/admin/include/libs/notifications/cli.php --level="danger" --subject="CWP Security Audit - File in system path" --message="[!!! DANGER !!!] File in system path but NOT owned by any package, for more info run: sh /scripts/cwp_security_audit" GLOBAL_ERROR=1 fi fi fi done # 3. Port Audit local CURRENT_PORTS=$(lsof -Pan -p $PID -iTCP -sTCP:LISTEN 2>/dev/null | awk 'NR>1 {split($9,a,":"); print a[length(a)]}') for PORT in $CURRENT_PORTS; do local PORT_MATCH=0 for ALLOWED in "${ALLOWED_PORTS[@]}"; do if [ "$PORT" == "$ALLOWED" ]; then PORT_MATCH=1; break; fi done if [ $PORT_MATCH -eq 0 ]; then echo "[SECURITY ALERT] Unauthorized port: $PORT" /usr/local/cwp/php71/bin/php /usr/local/cwpsrv/htdocs/resources/admin/include/libs/notifications/cli.php --level="danger" --subject="CWP Security Audit - Unauthorized port: $PORT" --message="[SECURITY ALERT] Unauthorized port, for more info run: sh /scripts/cwp_security_audit" GLOBAL_ERROR=1 fi done [ $GLOBAL_ERROR -eq 0 ] && echo "[OK] $PROC_NAME looks clean." } # --- EXECUTION --- check_process "cwpsrv" "cwpsrv: master process" check_process "php-fpm-cwp" "php-fpm: master process .*cwpsrv.conf" check_process "apache" "/usr/local/apache/bin/httpd" echo "------------------------------------------------------" echo "[DONE] Security audit finished." Problem: CWP updates may overwrite the fixCWP updates may overwrite /scripts/cwp_security_audit, so manually patching the file once is not always enough. One practical solution is to keep a local fixed copy and automatically restore it if CWP replaces the file during an update. The following installer creates: /root/cwp-overrides/cwp_security_audit.fixed /root/cwp-overrides/repair-cwp-security-audit.sh /etc/systemd/system/cwp-security-audit-override.service /etc/systemd/system/cwp-security-audit-override.path /etc/cron.d/cwp-security-audit-override The systemd.path unit watches /scripts/cwp_security_audit. If the file changes, the repair script compares it to the fixed version and restores the patched file if needed. A daily cron fallback is also added in case the file watch misses an event. Installer scriptSave this as: install-cwp-security-audit-override.sh Then run it as root: chmod +x install-cwp-security-audit-override.sh ./install-cwp-security-audit-override.sh #!/bin/bash set -euo pipefail # ============================================================ # CWP security audit override installer # Restores the locally fixed /scripts/cwp_security_audit # if CWP updates overwrite it. # ============================================================ if [ "$(id -u)" -ne 0 ]; then echo "ERROR: This installer must be run as root." exit 1 fi OVERRIDE_DIR="/root/cwp-overrides" BACKUP_DIR="${OVERRIDE_DIR}/backups" FIXED_FILE="${OVERRIDE_DIR}/cwp_security_audit.fixed" REPAIR_SCRIPT="${OVERRIDE_DIR}/repair-cwp-security-audit.sh" TARGET="/scripts/cwp_security_audit" SERVICE_FILE="/etc/systemd/system/cwp-security-audit-override.service" PATH_FILE="/etc/systemd/system/cwp-security-audit-override.path" CRON_FILE="/etc/cron.d/cwp-security-audit-override" LOG_FILE="/var/log/cwp-security-audit-override.log" echo "------------------------------------------------------" echo "[INFO] Installing CWP security audit override" echo "------------------------------------------------------" mkdir -p "$OVERRIDE_DIR" "$BACKUP_DIR" chmod 700 "$OVERRIDE_DIR" chmod 700 "$BACKUP_DIR" if ! command -v lsof >/dev/null 2>&1; then echo "[INFO] lsof not found. Installing..." if command -v dnf >/dev/null 2>&1; then dnf install -y lsof elif command -v yum >/dev/null 2>&1; then yum install -y lsof else echo "WARNING: Neither dnf nor yum found. Please install lsof manually." fi fi if [ -f "$TARGET" ]; then INITIAL_BACKUP="${BACKUP_DIR}/cwp_security_audit.initial.$(date '+%Y%m%d-%H%M%S').bak" cp -a "$TARGET" "$INITIAL_BACKUP" echo "[INFO] Current target backed up to: $INITIAL_BACKUP" else echo "[WARNING] Target file does not exist yet: $TARGET" fi cat > "$FIXED_FILE" <<'CWP_FIXED_SCRIPT' #!/bin/bash # --- CONFIGURATION --- ALLOWED_LIB_PATHS=( "/usr/lib64/lib" "/usr/lib64/ld-" "/usr/local/ioncube/" "/usr/lib/locale/" "/usr/local/cwp/" "/usr/local/apache/modules/" "/usr/local/lib/" "/usr/lib64/gconv/" ) ALLOWED_BINARIES=( "/usr/local/cwpsrv/bin/cwpsrv" "/usr/local/cwp/php71/sbin/php-fpm" "/usr/local/apache/bin/httpd" ) ALLOWED_PORTS=("2030" "2031" "2082" "2083" "2086" "2087" "2095" "2096" "9000" "2302" "2304" "8181" "8443" "80" "443") if ! command -v lsof &> /dev/null; then yum install -y lsof fi check_process() { local PROC_NAME=$1 local SEARCH_PATTERN=$2 local PID=$(ps aux | grep "$SEARCH_PATTERN" | grep -v grep | awk '{print $2}' | head -n 1) if [ -z "$PID" ]; then echo "[SKIP] Process '$PROC_NAME' not found." return fi echo "------------------------------------------------------" echo "[INFO] Auditing $PROC_NAME (PID: $PID)" local GLOBAL_ERROR=0 local GHOST_DATA=$(lsof -p $PID -n | grep -E "DEL|\(stat:" | grep -v "/dev/zero") if [ ! -z "$GHOST_DATA" ]; then echo "[!!! CRITICAL ALERT !!!] Ghost files (deleted but running) found:" echo "$GHOST_DATA" /usr/local/cwp/php71/bin/php /usr/local/cwpsrv/htdocs/resources/admin/include/libs/notifications/cli.php --level="danger" --subject="CWP Security Audit - Ghost files (deleted but running)" --message="[!!! CRITICAL ALERT !!!] Ghost files (deleted but running) found, for more info run: sh /scripts/cwp_security_audit" GLOBAL_ERROR=1 fi local CURRENT_MEM=$(lsof -p $PID -n | grep "mem" | awk '{for(i=9;i<=NF;i++) printf "%s ", $i; print ""}' | sed 's/(stat:.*//' | xargs) for FILE in $CURRENT_MEM; do [[ -z "$FILE" || "$FILE" == "REG" || "$FILE" == "mem" || "$FILE" == "/" ]] && continue local MATCH=0 for ALLOWED in "${ALLOWED_LIB_PATHS[@]}"; do if [[ "$FILE" == "$ALLOWED"* ]]; then MATCH=1; break; fi done for ALLOWED in "${ALLOWED_BINARIES[@]}"; do if [[ "$FILE" == "$ALLOWED" ]]; then MATCH=1; break; fi done if [ $MATCH -eq 0 ]; then echo "[SECURITY ALERT] Unknown/Untrusted file: $FILE" /usr/local/cwp/php71/bin/php /usr/local/cwpsrv/htdocs/resources/admin/include/libs/notifications/cli.php --level="danger" --subject="CWP Security Audit - Unknown/Untrusted file" --message="[SECURITY ALERT] Unknown/Untrusted file: $FILE" GLOBAL_ERROR=1 else if [[ "$FILE" == "/usr/lib64/"* ]]; then if ! rpm -qf "$FILE" &>/dev/null; then echo "[!!! DANGER !!!] File in system path but NOT owned by any package: $FILE" /usr/local/cwp/php71/bin/php /usr/local/cwpsrv/htdocs/resources/admin/include/libs/notifications/cli.php --level="danger" --subject="CWP Security Audit - File in system path" --message="[!!! DANGER !!!] File in system path but NOT owned by any package, for more info run: sh /scripts/cwp_security_audit" GLOBAL_ERROR=1 fi fi fi done local CURRENT_PORTS=$(lsof -Pan -p $PID -iTCP -sTCP:LISTEN 2>/dev/null | awk 'NR>1 {split($9,a,":"); print a[length(a)]}') for PORT in $CURRENT_PORTS; do local PORT_MATCH=0 for ALLOWED in "${ALLOWED_PORTS[@]}"; do if [ "$PORT" == "$ALLOWED" ]; then PORT_MATCH=1; break; fi done if [ $PORT_MATCH -eq 0 ]; then echo "[SECURITY ALERT] Unauthorized port: $PORT" /usr/local/cwp/php71/bin/php /usr/local/cwpsrv/htdocs/resources/admin/include/libs/notifications/cli.php --level="danger" --subject="CWP Security Audit - Unauthorized port: $PORT" --message="[SECURITY ALERT] Unauthorized port, for more info run: sh /scripts/cwp_security_audit" GLOBAL_ERROR=1 fi done [ $GLOBAL_ERROR -eq 0 ] && echo "[OK] $PROC_NAME looks clean." } check_process "cwpsrv" "cwpsrv: master process" check_process "php-fpm-cwp" "php-fpm: master process .*cwpsrv.conf" check_process "apache" "/usr/local/apache/bin/httpd" echo "------------------------------------------------------" echo "[DONE] Security audit finished." CWP_FIXED_SCRIPT chmod 600 "$FIXED_FILE" cat > "$REPAIR_SCRIPT" <<'REPAIR_SCRIPT' #!/bin/bash set -euo pipefail TARGET="/scripts/cwp_security_audit" FIXED="/root/cwp-overrides/cwp_security_audit.fixed" BACKUP_DIR="/root/cwp-overrides/backups" LOG="/var/log/cwp-security-audit-override.log" mkdir -p "$BACKUP_DIR" timestamp="$(date '+%Y-%m-%d %H:%M:%S')" notify_cwp() { local level="$1" local subject="$2" local message="$3" if [ -x /usr/local/cwp/php71/bin/php ] && [ -f /usr/local/cwpsrv/htdocs/resources/admin/include/libs/notifications/cli.php ]; then /usr/local/cwp/php71/bin/php \ /usr/local/cwpsrv/htdocs/resources/admin/include/libs/notifications/cli.php \ --level="$level" \ --subject="$subject" \ --message="$message" \ >/dev/null 2>&1 || true fi } if [ ! -f "$FIXED" ]; then echo "[$timestamp] ERROR: fixed file not found: $FIXED" >> "$LOG" notify_cwp "danger" \ "CWP override error" \ "Fixed CWP security audit file not found: $FIXED" exit 1 fi if [ ! -f "$TARGET" ]; then echo "[$timestamp] WARNING: target file missing, restoring: $TARGET" >> "$LOG" install -m 755 "$FIXED" "$TARGET" notify_cwp "warning" \ "CWP security audit restored" \ "Target file was missing and has been restored: $TARGET" exit 0 fi target_hash="$(sha256sum "$TARGET" | awk '{print $1}')" fixed_hash="$(sha256sum "$FIXED" | awk '{print $1}')" if [ "$target_hash" != "$fixed_hash" ]; then backup="$BACKUP_DIR/cwp_security_audit.$(date '+%Y%m%d-%H%M%S').bak" cp -a "$TARGET" "$backup" install -m 755 "$FIXED" "$TARGET" echo "[$timestamp] RESTORED: $TARGET was changed. Backup saved to: $backup" >> "$LOG" notify_cwp "warning" \ "CWP override restored cwp_security_audit" \ "CWP update changed /scripts/cwp_security_audit. The local fixed version was restored. Backup: $backup" else echo "[$timestamp] OK: no change detected." >> "$LOG" fi REPAIR_SCRIPT chmod 700 "$REPAIR_SCRIPT" cat > "$SERVICE_FILE" <<'SERVICE_UNIT' [Unit] Description=Restore local fixed CWP security audit script if overwritten [Service] Type=oneshot ExecStart=/root/cwp-overrides/repair-cwp-security-audit.sh SERVICE_UNIT chmod 644 "$SERVICE_FILE" cat > "$PATH_FILE" <<'PATH_UNIT' [Unit] Description=Watch CWP security audit script for changes [Path] PathChanged=/scripts/cwp_security_audit PathModified=/scripts/cwp_security_audit Unit=cwp-security-audit-override.service [Install] WantedBy=multi-user.target PATH_UNIT chmod 644 "$PATH_FILE" cat > "$CRON_FILE" <<'CRON_FALLBACK' # CWP security audit override fallback check # Runs daily in case systemd.path missed a file change. 17 3 * * * root /root/cwp-overrides/repair-cwp-security-audit.sh >/dev/null 2>&1 CRON_FALLBACK chmod 644 "$CRON_FILE" systemctl daemon-reload systemctl enable --now cwp-security-audit-override.path echo "[INFO] Running first repair/check..." "$REPAIR_SCRIPT" echo "------------------------------------------------------" echo "[OK] Installation finished." echo echo "Status:" systemctl --no-pager status cwp-security-audit-override.path || true echo echo "Last log entries:" tail -n 10 "$LOG_FILE" 2>/dev/null || true echo "------------------------------------------------------" VerificationAfter installation, run: systemctl status cwp-security-audit-override.path tail -n 30 /var/log/cwp-security-audit-override.log sha256sum /scripts/cwp_security_audit /root/cwp-overrides/cwp_security_audit.fixed The two sha256sum values should be identical. Then run the CWP audit again: sh /scripts/cwp_security_audit On a clean AlmaLinux 9.x server, the previous false alerts for: /usr/lib64/gconv/gconv-modules.cache and: Unauthorized port: php-fpm should be gone. NotesThis does not disable the CWP security audit. It only fixes two false-positive conditions: missing allowed path for /usr/lib64/gconv/, unsafe parsing of listening ports from generic lsof output. The script also keeps backups of any CWP-provided version that gets overwritten, so you can later compare what changed after an update: ls -lah /root/cwp-overrides/backups/ This approach is safer than using: chattr +i /scripts/cwp_security_audit because CWP updates are not blocked. The update can complete normally, and the local fixed version is restored afterwards.
-
How to Add Custom PHP-FPM 8.4 / 8.5 Support to CWP on AlmaLinux 9.x
Thanks. It is good suggestion.
-
Upgrade MariaDB 10.11 In CWP Centos 7 Centos 8 stream AlmaLinux 7/8 RockyLinux 7/8
@Starburst The mentioned issue may related to this topic:
-
Policyd (cbpolicyd) Failure After upgrading MariaDB on AlmaLinux 8 / 9 with CWP
This phenomenon typically occurs after a MariaDB upgrade.Typical log fragments in the maillog: warning: connect to 127.0.0.1:10031: Connection timed out warning: problem talking to server 127.0.0.1:10031 451 4.3.5 Recipient address rejected: Server configuration problem install_driver(mysql) failed: Can't locate DBD/mysql.pmThis indicates that cbpolicyd (Cluebringer) cannot load the required Perl database driver. Root CausePolicyd relies on a Perl DBI driver to connect to its MariaDB/MySQL backend. If the DBD::mysql module is removed or mismatched, Policyd child processes exit with status 2, and Postfix rejects all RCPT requests due to policy service timeout. AlmaLinux 8 vs AlmaLinux 9 BehaviorAlmaLinux 8 (EL8)Policyd requires: perl-DBD-MySQL The configuration remains in /etc/cbpolicyd/cbpolicyd.conf DSN=DBI:mysql:database=postfix_policyd;host=localhostInstalling perl-DBD-MySQL resolves the issue. AlmaLinux 9 (EL9)EL9 introduces a packaging change where installing perl-DBD-MySQL may attempt to pull MySQL 8 libraries that conflict with MariaDB. Instead, install: dnf install perl-DBD-MariaDBThen update the Policyd configuration: Edit: /etc/cbpolicyd/cbpolicyd.confReplace: DSN=DBI:mysql:database=postfix_policyd;host=localhostWith: DSN=DBI:MariaDB:database=postfix_policyd;host=localhostThis forces Policyd to load the DBD::MariaDB driver instead of DBD::mysql. After modification: systemctl restart cbpolicyd systemctl restart postfixKey TakeawayEL8 → install perl-DBD-MySQL EL9 → install perl-DBD-MariaDB and change the DSN driver in /etc/cbpolicyd/cbpolicyd.conf Failure to update the DSN on EL9 will cause continuous Policyd crashes and complete mail flow disruption. This distinction is critical for maintaining stable CWP mail servers after MariaDB upgrades or package maintenance.
-
Web panels in 2024
Still CWP Pro with EL9 based op.system. It's true that it needs some tweaking after installation, but it still offers far better services than other alternatives.
-
Install latest version of php 8.4 PHP switcher in CWP- Control web panel - EL8/9 AlmaLinux 8/9
@SubZero5 Something was missing to run the installation script, but I can't see what it is.
-
Install latest version of php 8.4 PHP switcher in CWP- Control web panel - EL8/9 AlmaLinux 8/9
There was some change: https://www.alphagnu.com/topic/618-imagemagick-install-script-for-almalinux-9x-and-cwp/
-
ImageMagick install script for AlmaLinux 9.x and CWP
There was some change in the availability of ImageMagick, so the PHP 8.4 and 8.5 installation script needed to be corrected. #!/bin/bash # Detect PHP FPM version PHPFPM="/opt/alt/php-fpm84" if [ ! -e "${PHPFPM}/usr/bin/php-config" ]; then PHPFPM="/opt/alt/php-fpm85" fi PHPBIN="${PHPFPM}/usr/bin/php" PHPCONFIG="${PHPFPM}/usr/bin/php-config" PHPINIDIR="${PHPFPM}/usr/php/php.d" if [ ! -x "${PHPCONFIG}" ]; then echo "Skipping Imagick: php-config not found (${PHPCONFIG})" exit 0 fi echo "Installing prerequisites..." dnf -y install ImageMagick ImageMagick-devel ImageMagick-perl pkgconfig cd /usr/local/src rm -rf imagick-* echo "Downloading imagick-3.8.1..." wget https://pecl.php.net/get/imagick -O imagick.tgz tar -xf imagick.tgz cd imagick-* echo "phpize..." ${PHPFPM}/usr/bin/phpize echo "Configuring..." ./configure --with-php-config=${PHPCONFIG} echo "Compiling..." make -j"$(nproc)" && make install EXTDIR="$(${PHPCONFIG} --extension-dir)" if [ -e "${EXTDIR}/imagick.so" ]; then echo "Creating imagick.ini" echo "extension=imagick.so" > "${PHPINIDIR}/imagick.ini" echo "Imagick installation OK." else echo "ERROR: imagick.so missing: ${EXTDIR}/imagick.so" fi The place of the script is: /usr/local/cwpsrv/htdocs/resources/conf/el9/php-fpm_selector/external_modules/8.4
-
Install latest version of php 8.4 PHP switcher in CWP- Control web panel - EL8/9 AlmaLinux 8/9
Not fully. I will review these as well, because they should be in my own systems, but sometimes it gets delayed.
-
Install latest version of php 8.4 PHP switcher in CWP- Control web panel - EL8/9 AlmaLinux 8/9
E.g: Pre run module for Imap (PHP-FPM 8.4, 8.5) and the compiler takes care of the rest. The Pre run modules place is: /usr/local/cwpsrv/htdocs/resources/conf/el9/php-fpm_selector/pre_run/8.4/imap7.sh #/bin/bash dnf install uw-imap-devel -yEnd External module for MailParse (PHP-FPM 8.4, 8.5) #!/bin/bash set -euo pipefail # --- Detect PHP-FPM version (8.4 or 8.5) --- if [ -x /opt/alt/php-fpm84/usr/bin/php-config ]; then PHPFPM="/opt/alt/php-fpm84" elif [ -x /opt/alt/php-fpm85/usr/bin/php-config ]; then PHPFPM="/opt/alt/php-fpm85" else echo "ERROR: No php-fpm84 or php-fpm85 found." exit 1 fi PHPBIN="${PHPFPM}/usr/bin/php" PHPCONFIG="${PHPFPM}/usr/bin/php-config" PHPINIDIR="${PHPFPM}/usr/php/php.d" echo "Detected PHP: ${PHPBIN}" # --- Install dependencies --- dnf -y install re2c file cd /usr/local/src rm -rf mailparse* mailparse.tgz # --- Stable version: mailparse 3.1.6 --- MAILPARSE_VERSION="3.1.6" MAILPARSE_URL="https://pecl.php.net/get/mailparse-${MAILPARSE_VERSION}.tgz" echo "Downloading mailparse ${MAILPARSE_VERSION}..." wget -q "${MAILPARSE_URL}" -O mailparse.tgz tar -xf mailparse.tgz cd "mailparse-${MAILPARSE_VERSION}" # --- Build --- echo "Running phpize..." "${PHPFPM}/usr/bin/phpize" echo "Configuring..." ./configure --with-php-config="${PHPCONFIG}" echo "Compiling..." make -j"$(nproc)" make install # --- Check extension installation --- EXTDIR="$(${PHPCONFIG} --extension-dir)" if [ -f "${EXTDIR}/mailparse.so" ]; then echo "Creating mailparse.ini" echo "extension=mailparse.so" > "${PHPINIDIR}/mailparse.ini" echo "mailparse installed successfully." else echo "ERROR: mailparse.so was not found in ${EXTDIR}" exit 1 fi I hope this helped. Look at the full article: https://www.alphagnu.com/topic/614-how-to-add-custom-php-fpm-84-85-support-to-cwp-on-almalinux-9x/
-
Install latest version of php 8.4 PHP switcher in CWP- Control web panel - EL8/9 AlmaLinux 8/9
Hi @Starburst I have corrected the installation of the PECl modules for the PHP-FPM version only. You can find the installers of these modules in the External modules and Pre Run models ZIP files at the link, which ran in the AlmaLinux 9.6, 9.7 environment. Here: https://www.alphagnu.com/topic/614-how-to-add-custom-php-fpm-84-85-support-to-cwp-on-almalinux-9x/
-
How to Add Custom PHP-FPM 8.4 / 8.5 Support to CWP on AlmaLinux 9.x
Just a note: With the above script and the pre run and external modules, I have already installed PHP-FPM 8.3.28 and PHP-FPM 8.4.15 versions on 6 different AlmaLinux 9.6 based VPSs, and they run flawlessly.
-
How to Add Custom PHP-FPM 8.4 / 8.5 Support to CWP on AlmaLinux 9.x
We need Pre Run modules, the ZIP also added.
-
Install latest version of php 8.4 PHP switcher in CWP- Control web panel - EL8/9 AlmaLinux 8/9
Hello @Sandeep B. Thank you for the tutorial. I ran into a few problems under AlmaLinux 9.6, which this installation script has already fixed. #!/bin/bash set -euo pipefail set -x # For el9 only : dnf config-manager --set-enabled crb # run these for el8 and el9 dnf -y groupinstall "Development Tools" dnf -y install glibc-devel elfutils-libelf-devel dnf -y install git make gcc gcc-c++ \ binutils glibc-devel autoconf libtool \ bison re2c automake libxml2-devel openssl-devel \ sqlite-devel bzip2-devel libcurl-devel libpng-devel \ libavif-devel libwebp-devel libjpeg-devel \ libXpm-devel freetype-devel gmp-devel \ libicu-devel openldap-devel oniguruma-devel \ libargon2-devel libtidy-devel libxslt-devel # Build PHP 8.4 switcher: rm -rf /usr/local/php-84 mkdir -p /usr/local/php-84 cd /usr/local/php-84 wget http://php.net/distributions/php-8.4.15.tar.gz tar zxvf php-8.4.15.tar.gz cd php-8.4.15 # For el9 mandatory: --with-openssl=/usr/lib64 ./configure --with-config-file-path=/usr/local/php \ --enable-cgi \ --with-config-file-scan-dir=/usr/local/php/php.d \ --with-zlib=/usr \ --enable-mbstring \ --with-zip \ --enable-bcmath \ --enable-pcntl \ --enable-ftp \ --enable-exif \ --enable-calendar \ --enable-sysvmsg \ --enable-sysvsem \ --enable-sysvshm \ --with-tidy \ --with-curl \ --with-iconv \ --with-gmp \ --enable-gd \ --with-avif \ --with-jpeg \ --with-freetype \ --enable-gd-jis-conv \ --with-webp \ --with-xpm \ --with-openssl=/usr/lib64 \ --with-pdo-mysql=mysqlnd \ --with-gettext=/usr \ --with-bz2=/usr \ --with-mysqli \ --enable-soap \ --enable-phar \ --with-xsl \ --enable-posix \ --enable-sockets \ --with-external-pcre \ --with-libdir=lib64 \ --with-mysql-sock=/var/lib/mysql/mysql.sock \ --enable-intl \ --with-password-argon2 \ --enable-litespeed \ --with-ldap=/usr \ --with-ldap-sasl=/usr \ --with-pear \ --with-sodium # These settings will break on el9 - AlmaLinux 9.6 # export CFLAGS="-O2 -fPIE -DPIC" # export CXXFLAGS="-O2 -fPIE -DPIC" # export LDFLAGS="-pie -Wl,--as-needed" export PKG_CONFIG_PATH=/usr/lib64/pkgconfig export CFLAGS="-O2" export CXXFLAGS="-O2" export LDFLAGS="-L/usr/lib64 -Wl,--as-needed" make -j$(nproc) make install # ---------- remove old .ini from PHP 5.x, 7.x ----- rm -f /usr/local/php/php.d/sodium.ini # ---------- PECL IMAGICK INSTALL ---------- echo "Installing Imagick dependencies…" dnf -y install ImageMagick ImageMagick-devel echo "Installing Imagick via PECL…" /usr/local/bin/pecl install imagick echo "Adding imagick.ini…" mkdir -p /usr/local/php/php.d echo "extension=imagick.so" > /usr/local/php/php.d/imagick.ini echo "PHP CLI build with Imagick completed successfully!" php -v php -m | grep imagick --with-openssl=/usr/lib64 --with-pear --with-sodium without the switches and with the recommended FLAG settings, PHP 8.4.15 did not compile properly. And it may also be necessary to remove the old sodium.ini if it was left in the directory from PHP 5.x, 7.x. rm -f /usr/local/php/php.d/sodium.iniBut with the above settings, all parts of PHP 8.4.15 are compiling properly in AlmaLinux 9.6. [root@vps ~]# php -i | grep -i sodium Configure Command => './configure' '--with-config-file-path=/usr/local/php' '--enable-cgi' '--with-config-file-scan-dir=/usr/local/php/php.d' '--with-zlib=/usr' '--enable-mbstring' '--with-zip' '--enable-bcmath' '--enable-pcntl' '--enable-ftp' '--enable-exif' '--enable-calendar' '--enable-sysvmsg' '--enable-sysvsem' '--enable-sysvshm' '--with-tidy' '--with-curl' '--with-iconv' '--with-gmp' '--enable-gd' '--with-avif' '--with-jpeg' '--with-freetype' '--enable-gd-jis-conv' '--with-webp' '--with-xpm' '--with-openssl=/usr/lib64' '--with-pdo-mysql=mysqlnd' '--with-gettext=/usr' '--with-bz2=/usr' '--with-mysqli' '--enable-soap' '--enable-phar' '--with-xsl' '--enable-posix' '--enable-sockets' '--with-external-pcre' '--with-libdir=lib64' '--with-mysql-sock=/var/lib/mysql/mysql.sock' '--enable-intl' '--with-password-argon2' '--enable-litespeed' '--with-ldap=/usr' '--with-ldap-sasl=/usr' '--with-pear' '--with-sodium' sodium sodium support => enabled libsodium headers version => 1.0.18 libsodium library version => 1.0.18 [root@vps ~]# php -i | grep -i openssl Configure Command => './configure' '--with-config-file-path=/usr/local/php' '--enable-cgi' '--with-config-file-scan-dir=/usr/local/php/php.d' '--with-zlib=/usr' '--enable-mbstring' '--with-zip' '--enable-bcmath' '--enable-pcntl' '--enable-ftp' '--enable-exif' '--enable-calendar' '--enable-sysvmsg' '--enable-sysvsem' '--enable-sysvshm' '--with-tidy' '--with-curl' '--with-iconv' '--with-gmp' '--enable-gd' '--with-avif' '--with-jpeg' '--with-freetype' '--enable-gd-jis-conv' '--with-webp' '--with-xpm' '--with-openssl=/usr/lib64' '--with-pdo-mysql=mysqlnd' '--with-gettext=/usr' '--with-bz2=/usr' '--with-mysqli' '--enable-soap' '--enable-phar' '--with-xsl' '--enable-posix' '--enable-sockets' '--with-external-pcre' '--with-libdir=lib64' '--with-mysql-sock=/var/lib/mysql/mysql.sock' '--enable-intl' '--with-password-argon2' '--enable-litespeed' '--with-ldap=/usr' '--with-ldap-sasl=/usr' '--with-pear' '--with-sodium' SSL Version => OpenSSL/3.5.1 libSSH Version => libssh/0.10.4/openssl/zlib openssl OpenSSL support => enabled OpenSSL Library Version => OpenSSL 3.5.1 1 Jul 2025 OpenSSL Header Version => OpenSSL 3.5.1 1 Jul 2025 Openssl default config => /etc/pki/tls/openssl.cnf openssl.cafile => no value => no value openssl.capath => no value => no value OpenSSL support => enabled
-
How to Add Custom PHP-FPM 8.4 / 8.5 Support to CWP on AlmaLinux 9.x
Added the final, three-tier, fully robust PHP source download module: ✔ 1. CWP CDN (if there → fast) ✔ 2. php.net CDN (official) ✔ 3. GitHub codeload (always works in tar.gz format) Since PHP 8.4.14 package was found by the download section of the script, but for PHP 8.4.15 it gave a false not found signal.
-
Manual update of PHP in CWP
@Starburst @Sandeep B. here is the working for me manual PHP update of CWP: https://www.alphagnu.com/topic/614-how-to-add-custom-php-84-85-support-to-cwp-on-almalinux-9x/
-
How to Add Custom PHP-FPM 8.4 / 8.5 Support to CWP on AlmaLinux 9.x
Full tutorial with GUI integration, fixed OpenSSL support, external modules, and a working custom PHP builder. This guide explains how to properly add PHP 8.4 and PHP 8.5 to Control Web Panel (CWP) on EL9-based systems. Unlike older CWP releases, CWP does not provide official PHP 8.4/8.5 packages yet — but with the steps below you can fully integrate them into and you can also fix the PHP 8.3 OpenSSL problem based on this: ✔ the CWP PHP Selector GUI ✔ Apache / Nginx vhosts ✔ external PECL modules ✔ system services ✔ CSF/Monit integration This article provides everything: file paths, scripts, corrections, and the build steps. ⚙️ Step 1 — Extend the CWP GUI to Support PHP 8.4 and 8.5CWP reads available PHP versions from: /usr/local/cwpsrv/htdocs/resources/conf/el9/php-fpm_selector/versions.iniAdd the new PHP versions like: [8.3] version[]=8.3.28 version[]=8.3.27 version[]=8.3.25 version[]=8.3.21 version[]=8.3.20 version[]=8.3.19 version[]=8.3.17 version[]=8.3.16 version[]=8.3.15 version[]=8.3.14 version[]=8.3.13 version[]=8.3.12 version[]=8.3.11 version[]=8.3.10 version[]=8.3.9 version[]=8.3.8 version[]=8.3.7 version[]=8.3.6 version[]=8.3.4 version[]=8.3.3 version[]=8.3.2 version[]=8.3.1 version[]=8.3.0 [8.4] version[]=8.4.15 version[]=8.4.14 version[]=8.4.13 version[]=8.4.12 version[]=8.4.11 version[]=8.4.10 version[]=8.4.9 version[]=8.4.8 version[]=8.4.7 version[]=8.4.6 version[]=8.4.4 version[]=8.4.3 version[]=8.4.2 version[]=8.4.1 version[]=8.4.0 [8.5] version[]=8.5.0 This makes the versions selectable in the GUI. If you don't want to make previous PHP 8.4 versions optional under 8.4.14, you can leave them out of the list. ⚙️ Step 2 — Create 8.4.ini and 8.5.ini GUI TemplatesLocation: /usr/local/cwpsrv/htdocs/resources/conf/el9/php-fpm_selector/Create these files based on the sample and content of 8.3.ini: 8.4.ini 8.5.ini Both must contain a corrected OpenSSL section: [openssl] default=1 option="--with-openssl=/usr" info-file=openssl.txt (Older CWP templates use deprecated OpenSSL paths that break EL9 builds. The corrected version above is mandatory. And similarly, the OpenSSL section in the 8.3.ini file must be corrected.) These files provide the GUI-driven configure flags that our builder script will later use. ⚙️ Step 3 — Create External and Pre Run Modules for PHP 8.4 and 8.5Create these directories and update the content of 8.3 folder with the linked ZIP file: /usr/local/cwpsrv/htdocs/resources/conf/el9/php-fpm_selector/external_modules/8.3 /usr/local/cwpsrv/htdocs/resources/conf/el9/php-fpm_selector/external_modules/8.4 /usr/local/cwpsrv/htdocs/resources/conf/el9/php-fpm_selector/external_modules/8.5Populate each directory with the updated scripts: apcu.sh imagick.sh memcache.sh memcached.sh mailparse.sh mongodb.sh redis.sh ssh2.sh uploadprogress.sh xdebug.sh yaz.sh sodium.sh sourceguardian.sh sqlsrv.sh ioncube.sh (With proper loader URL handling: stable for 8.4, beta for 8.5.) 👉 Here is the ZIP file with all corrected module scripts to this post for download: External_Modules Create these directories and update the content of 8.3 folder with the linked ZIP file: /usr/local/cwpsrv/htdocs/resources/conf/el9/php-fpm_selector/pre_run/8.3 /usr/local/cwpsrv/htdocs/resources/conf/el9/php-fpm_selector/pre_run/8.4 /usr/local/cwpsrv/htdocs/resources/conf/el9/php-fpm_selector/pre_run/8.5Pre Run Modules ⚙️ Step 4 — Install the Custom Builder ScriptPlace the builder script in: /root/build-php-fpm84-el9.sh This script: ✔ reads the GUI-generated configure template ✔ enforces OpenSSL 3.x for EL9 ✔ builds PHP cleanly under /opt/alt/php-fpm84/usr/ ✔ installs FPM service, ini files, sockets ✔ compiles all external modules ✔ integrates CSF and Monit ✔ logs every step You can rewrite this script to install PHP 8.3.28 or PHP 8.5.0 by changing just a few variables. Here is the corrected PHP compiler script located in /root/build-php-fpm84-el9.sh file: #!/bin/bash set -euo pipefail set -x # --- Basic variables --- PHPMAJOR="84" # php-fpm84 PHPVER="8.4.15" # PHP version FPMDIR="/opt/alt/php-fpm${PHPMAJOR}" CONFBASE="/usr/local/cwp/.conf/php-fpm_conf" arch=$(uname -m) if [[ "$arch" == "x86_64" ]]; then platform="x86-64" libdir="/usr/lib64" else platform="x86" libdir="/usr/lib" fi # --- Packages for Build (EL9) --- dnf -y install \ krb5-devel glibc-common gnutls-devel \ libargon2 libargon2-devel libbsd-devel \ perl libzip libzip-devel pcre2 pcre2-devel \ libavif libavif-devel \ uw-imap-devel \ openssl-devel # If there is any old CWP OpenSSL hack left, don't use it.: if [ -d /usr/local/opensslso ]; then echo "WARN: /usr/local/opensslso exists, but we DO NOT USE for compiling PHP (OpenSSL 1.1 hack)." fi # --- Force OpenSSL 3.x --- export PKG_CONFIG_PATH=/usr/lib64/pkgconfig export OPENSSL_CFLAGS="-I/usr/include" export OPENSSL_LIBS="-L/usr/lib64" export LDFLAGS="-lssl -lcrypto" # --- CWP pre-conf, if exists (e.g.: pcre2, & other libs) --- if [ -e "${CONFBASE}/php${PHPMAJOR}_pre.conf" ]; then bash "${CONFBASE}/php${PHPMAJOR}_pre.conf" fi # --- PHP SOURCE DOWNLOAD CHECK: CWP CDN → OFFICIAL php.net → GitHub fallback --- CWP_URL="http://static.cdn-cwp.com/files/php/php-${PHPVER}.tar.gz" PHPNET_URL="https://www.php.net/distributions/php-${PHPVER}.tar.gz" GITHUB_URL="https://codeload.github.com/php/php-src/tar.gz/refs/tags/php-${PHPVER}" # Function: check HTTP 200 + verify tar.gz content check_and_verify() { local url="$1" local testfile="/tmp/php-test-${PHPVER}.tar.gz" echo "Checking: $url" # First check HTTP status code if ! curl -I -L -s "$url" | grep -q "200"; then echo " → HTTP check failed" return 1 fi # Download temporary test file if ! wget -q "$url" -O "$testfile"; then echo " → Download failed" return 1 fi # Validate MIME type of tar.gz if file "$testfile" | grep -qiE "gzip compressed data|tar archive"; then rm -f "$testfile" echo " → Valid TAR.GZ" return 0 fi echo " → Invalid TAR.GZ (HTML or wrong file)" rm -f "$testfile" return 1 } # Check sources in order (CWP → php.net → GitHub) if check_and_verify "$CWP_URL"; then PHPSOURCE="$CWP_URL" elif check_and_verify "$PHPNET_URL"; then PHPSOURCE="$PHPNET_URL" elif check_and_verify "$GITHUB_URL"; then PHPSOURCE="$GITHUB_URL" else echo "ERROR: Could not download a valid PHP source for version ${PHPVER}" exit 1 fi echo "Using source: $PHPSOURCE" # --- Build directory --- rm -rf /usr/local/src/php-build mkdir -p /usr/local/src/php-build cd /usr/local/src/php-build wget -q "${PHPSOURCE}" -O "php-${PHPVER}.tar.gz" tar -xvf "php-${PHPVER}.tar.gz" cd "php-${PHPVER}" # --- Configure: CWP's own php84.conf, but already wired to OpenSSL 3.x from env --- if [ ! -x "${CONFBASE}/php${PHPMAJOR}.conf" ]; then chmod +x "${CONFBASE}/php${PHPMAJOR}.conf" 2>/dev/null || true fi # IMPORTANT: LDFLAGS + PKG_CONFIG_PATH already exported bash "${CONFBASE}/php${PHPMAJOR}.conf" # --- Compiling --- if command -v nproc >/dev/null 2>&1; then make -j"$(nproc)" else make fi make install # --- PHP.ini + FPM scaffolding --- mkdir -p "${FPMDIR}/usr/php/php.d" mkdir -p "${FPMDIR}/usr/var/sockets" mkdir -p "${FPMDIR}/usr/etc/php-fpm.d" mkdir -p "${FPMDIR}/usr/etc/php-fpm.d/users" rsync php.ini-production "${FPMDIR}/usr/php/php.ini" sed -i 's/^short_open_tag.*/short_open_tag = On/' "${FPMDIR}/usr/php/php.ini" sed -i 's/^;cgi.fix_pathinfo=.*/cgi.fix_pathinfo=1/' "${FPMDIR}/usr/php/php.ini" sed -i 's/.*mail.add_x_header.*/mail.add_x_header = On/' "${FPMDIR}/usr/php/php.ini" sed -i 's@.*mail.log.*@mail.log = /usr/local/apache/logs/phpmail.log@' "${FPMDIR}/usr/php/php.ini" echo "include=${FPMDIR}/usr/etc/php-fpm.d/users/*.conf" > "${FPMDIR}/usr/etc/php-fpm.d/users.conf" echo "include=${FPMDIR}/usr/etc/php-fpm.d/*.conf" > "${FPMDIR}/usr/etc/php-fpm.conf" cat > "${FPMDIR}/usr/etc/php-fpm.d/cwpsvc.conf" <<EOF [cwpsvc] listen = ${FPMDIR}/usr/var/sockets/cwpsvc.sock listen.owner = cwpsvc listen.group = cwpsvc listen.mode = 0640 user = cwpsvc group = cwpsvc pm = ondemand pm.max_children = 25 pm.process_idle_timeout = 15s request_terminate_timeout = 0 EOF # --- Systemd service --- cp sapi/fpm/php-fpm.service "/usr/lib/systemd/system/php-fpm${PHPMAJOR}.service" sed -i "s|\${exec_prefix}|${FPMDIR}/usr|g" "/usr/lib/systemd/system/php-fpm${PHPMAJOR}.service" sed -i "s|\${prefix}|${FPMDIR}/usr|g" "/usr/lib/systemd/system/php-fpm${PHPMAJOR}.service" systemctl daemon-reload systemctl enable "php-fpm${PHPMAJOR}" # --- Loading Apache FPM module if not already present --- if [ ! -e "/usr/local/apache/conf.d/php-fpm.conf" ]; then cat > /usr/local/apache/conf.d/php-fpm.conf <<EOF <IfModule !proxy_fcgi_module> LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so </IfModule> EOF fi # --- External modules (imagick, redis, imap, etc.) --- if [ -e "${CONFBASE}/php${PHPMAJOR}_external.conf" ]; then bash "${CONFBASE}/php${PHPMAJOR}_external.conf" || true fi # --- Monitor integration --- if [ -d "/etc/monit.d" ]; then if [ ! -e "/etc/monit.d/php-fpm${PHPMAJOR}" ]; then if [ -e "/usr/local/cwpsrv/htdocs/resources/conf/monit.d/php-fpm${PHPMAJOR}" ]; then cp "/usr/local/cwpsrv/htdocs/resources/conf/monit.d/php-fpm${PHPMAJOR}" /etc/monit.d/ 2>/dev/null || true monit reload || true fi fi fi systemctl restart "php-fpm${PHPMAJOR}" # --- CSF pignore --- if [ -e "/etc/csf/csf.pignore" ]; then # PHP-FPM + PHP binary if ! grep -q "${FPMDIR}/usr/sbin/php-fpm" /etc/csf/csf.pignore; then echo "exe:${FPMDIR}/usr/sbin/php-fpm" >> /etc/csf/csf.pignore fi if ! grep -q "${FPMDIR}/usr/bin/php" /etc/csf/csf.pignore; then echo "exe:${FPMDIR}/usr/bin/php" >> /etc/csf/csf.pignore fi # memcached daemon if command -v memcached >/dev/null 2>&1; then if ! grep -q "exe:/usr/bin/memcached" /etc/csf/csf.pignore; then echo "exe:/usr/bin/memcached" >> /etc/csf/csf.pignore fi fi # redis-server daemon if command -v redis-server >/dev/null 2>&1; then if ! grep -q "exe:/usr/bin/redis-server" /etc/csf/csf.pignore; then echo "exe:/usr/bin/redis-server" >> /etc/csf/csf.pignore fi fi # Restart CSF/LFD to apply changes csf -r fi rm -rf /usr/local/src/php-build rm -rf /usr/local/src/build-dir echo "PHP ${PHPVER} (php-fpm${PHPMAJOR}) build finished successfully." It is for sample, you can modify it by your needs. ⚙️ Step 5 — Trigger the GUI Build OnceFrom the CWP Admin Panel: PHP-FPM Selector → PHP 8.4 → Choose desired version of PHP → Build CWP will: generate the build configuration files stop early because no packages exist (expected!) but now the config files are ready The GUI selector (Image on the shared link) This step must be done once so the GUI produces: /usr/local/cwp/.conf/php-fpm_conf/php84.conf /usr/local/cwp/.conf/php-fpm_conf/php84_pre.conf /usr/local/cwp/.conf/php-fpm_conf/php84_external.conf Our builder script depends on them. ⚙️ Step 6 — Build PHP 8.4 With LoggingRun the custom builder script manually: bash /root/build-php-fpm84-el9.sh 2>&1 | tee /root/php84-build.log This: logs all output compiles PHP 8.4.14 installs extensions - e.g. IonCube loader if it was selected reloads FPM integrates CSF pignore entries exe:/usr/bin/redis-server exe:/usr/bin/memcached After the build: Test PHP:/opt/alt/php-fpm84/usr/bin/php -v /opt/alt/php-fpm84/usr/sbin/php-fpm -t Verify IonCube:grep -Ri ioncube /opt/alt/php-fpm84/usr/php/php.d/ Verify Imagick:/opt/alt/php-fpm84/usr/bin/php -r "print_r(Imagick::getVersion());"⚙️ Repeat the Process for PHP 8.5The steps are identical, except: PHP version is different ionCube loader uses the beta build ioncube_loaders_lin_x86-64_beta.tar.gz Here is the IonCube documentation. The PHP 8.4 is fully supported, PHP 8.5 is Beta in the moment. 🎉 ResultAfter completing these steps you will have: ✔ Fully working PHP 8.4 or 8.5 ✔ 100% GUI-compatible (PHP Selector, vhost handler, extension manager) ✔ Proper OpenSSL 3.x integration ✔ All external PECL modules working ✔ Systemd FPM services ✔ Clean, isolated alt-PHP folders under /opt/alt ✔ No conflict with AlmaLinux REMI PHP packages And most importantly: You can now run PHP 8.4 / 8.5 safely in production on CWP EL9. I also fixed the PHP - OpenSSL compilation issue in AlmaLinux 9.x with PHP 8.3.28 version of the script. PHP now uses OpenSSL 3.x. Checking the compiled PHP versions (e.g. 8.4.14 and 8.3.28): [root@vps ~]# /opt/alt/php-fpm84/usr/bin/php -v PHP 8.4.14 (cli) (built: Dec 1 2025 22:53:34) (NTS) Copyright (c) The PHP Group Zend Engine v4.4.14, Copyright (c) Zend Technologies with the ionCube PHP Loader v15.0.0, Copyright (c) 2002-2025, by ionCube Ltd. with Zend OPcache v8.4.14, Copyright (c), by Zend Technologies [root@vps ~]# /opt/alt/php-fpm83/usr/bin/php -v PHP 8.3.28 (cli) (built: Dec 1 2025 16:39:53) (NTS) Copyright (c) The PHP Group Zend Engine v4.3.28, Copyright (c) Zend Technologies with Zend OPcache v8.3.28, Copyright (c), by Zend Technologies [root@vps ~]# Checking OpenSSL: [root@vps ~]# /opt/alt/php-fpm84/usr/bin/php -i | grep -i "openssl" Configure Command => './configure' '--prefix=/opt/alt/php-fpm84/usr' '--with-config-file-path=/opt/alt/php-fpm84/usr/php' '--with-config-file-scan-dir=/opt/alt/php-fpm84/usr/php/php.d' '--with-zlib=/usr' '--enable-mbstring' '--with-zip' '--enable-bcmath' '--enable-pcntl' '--enable-ftp' '--enable-exif' '--enable-calendar' '--enable-sysvmsg' '--enable-sysvsem' '--enable-sysvshm' '--with-tidy' '--with-curl' '--with-iconv' '--with-gmp' '--with-pspell' '--enable-gd' '--with-jpeg' '--with-freetype' '--enable-gd-jis-conv' '--with-webp' '--with-avif' '--with-zlib-dir=/usr' '--with-xpm' '--with-openssl=/usr' '--with-pdo-mysql=mysqlnd' '--with-gettext=/usr' '--with-bz2=/usr' '--with-mysqli' '--enable-soap' '--enable-phar' '--with-xsl' '--with-kerberos' '--enable-posix' '--enable-sockets' '--with-external-pcre' '--with-libdir=lib64' '--with-mysql-sock=/var/lib/mysql/mysql.sock' '--enable-intl' '--with-imap' '--with-imap-ssl' '--enable-fpm' '--enable-opcache' '--with-password-argon2' 'PKG_CONFIG_PATH=/usr/lib64/pkgconfig' 'OPENSSL_CFLAGS=-I/usr/include' 'OPENSSL_LIBS=-L/usr/lib64' SSL Version => OpenSSL/3.5.1 libSSH Version => libssh/0.10.4/openssl/zlib openssl OpenSSL support => enabled OpenSSL Library Version => OpenSSL 3.5.1 1 Jul 2025 OpenSSL Header Version => OpenSSL 3.5.1 1 Jul 2025 Openssl default config => /etc/pki/tls/openssl.cnf openssl.cafile => no value => no value openssl.capath => no value => no value OpenSSL support => enabled [root@vps ~]# If you have any suggestions, please feel free to write to me.
-
Manual update of PHP in CWP
Unfortunately, for some time now, the CSF + LFD firewall has not been installed under AlmaLinux 9.x when installing CWP Pro, so I have installed the last 3 servers under AlmaLinux 8.10. So I don't have a VPS suitable for testing, but I have put together a solution for PHP 8.4 on one of the less busy production AlmaLinux 9.x VPS, which is quite CWP GUI friendly. And this could perhaps be supplemented or improved. I'll post it here in a separate post.
-
Manual update of PHP in CWP
Hello @Sandeep B. What can we expect? Would you have some time to show a PHP 8.4, 8.5 installation that works with the CWP GUI?
-
Upgrade MariaDB 10.11 In CWP Centos 7 Centos 8 stream AlmaLinux 7/8 RockyLinux 7/8
When upgrading from 10.1, 10.2, 10.3 to 10.11 to find the proper MariaDB repo you can use this service: curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | sudo bash -s -- --mariadb-server-version="mariadb-10.11" Description: Link: https://mariadb.com/kb/en/mariadb/mariadb-package-repository-setup-and-usage/
-
CSF replacements needs
CSF replacement tested in old Centos 7, AlmaLinux 8.10 and AlmaLinux 9.6The CSF project is continuing as Open Source project, the website is here: https://docs.configserver.dev/ Github: https://github.com/Aetherinox/csf-firewall And as it was suggested in article https://www.jaspreet.net/2025/09/06/3180/how-to-fix-csf-firewall-error-oops-unable-to-download-no-host-option-provided/ you have to update the content of /etc/csf/downloadserver Comment out (or delete) the old content of the file and set the new line of download server: download.configserver.dev Restart CSF and from the GUI of CWP update Firewall. The result will be appear in the screen, and the CFS/LFD will update to the current version: Status: csf: v15.01 (CentOS Web Panel) Or, you can use the solution suggested by @Starburst above.
-
Manual update of PHP in CWP
I did an experiment with Remi based multi PHP. Here is the install script: #!/usr/bin/env bash set -euo pipefail # --- 0. Repos dnf install -y epel-release dnf install -y https://rpms.remirepo.net/enterprise/remi-release-9.rpm # --- 1. Which PHP SCL version do you want to install VERSIONS=("php83" "php84") # If only 8.4 needs, let: ("php84") # Base PHP exts (for both PHP versions) BASE_PKGS=( php-fpm php-cli php-common php-opcache php-mysqlnd php-mbstring php-zip php-bcmath php-process php-exif php-calendar php-tidy php-curl php-iconv php-gmp php-pspell php-gd php-xml php-xsl php-soap php-intl php-imap php-sockets php-sodium php-gettext php-bz2 ) # PECL add-ons (Usually used with CWP Pro ) PECL_PKGS=( php-pecl-imagick-im7 php-pecl-memcache php-pecl-redis php-pecl-apcu php-pecl-mcrypt # you may remove it, if no need ) # System libs for GD (webp/avif/jpeg/freetype) and imagick running dnf install -y libavif libwebp libjpeg-turbo freetype ImageMagick aspell aspell-en # --- 2. Install the selected SCL PHP for V in "${VERSIONS[@]}"; do SAFE_PREFIX="${V/83/83}" # for example: V e.g. "php84" echo "===> Installing: ${V} (Remi SCL)" dnf --enablerepo=remi-safe install -y \ $(printf '%s ' "${BASE_PKGS[@]/#/$(echo $V)-}") \ $(printf '%s ' "${PECL_PKGS[@]/#/$(echo $V)-}") done # --- 3. Service start (itt most a 8.4-et engedélyezzük) systemctl daemon-reload systemctl enable php84-php-fpm systemctl restart php84-php-fpm systemctl enable php83-php-fpm systemctl restart php83-php-fpm echo "=== Ready: Remi SCL PHP 8.3, 8.4 installed."The place of php-fpm pool is: `nano /etc/opt/remi/php84/php-fpm.d/%username%.conf` where the %username% is the account name as usually in CWP Pro. php-fpm pool template with manual setup: [%username%] listen = /var/opt/remi/php84/run/php-fpm/%backend%.sock listen.owner = "%username%" listen.group = nobody listen.mode = 0660 user = "%username%" group = "%username%" pm = ondemand pm.max_children = 4 pm.max_requests = 4000 pm.process_idle_timeout = 15s rlimit_files = 131072 rlimit_core = unlimited catch_workers_output = yes env[HOSTNAME] = $HOSTNAME env[TMP] = %home%/%username%/tmp env[TMPDIR] = %home%/%username%/tmp env[TEMP] = %home%/%username%/tmp env[PATH] = /opt/remi/php84/root/usr/bin:/usr/local/bin:/usr/bin:/binIf you use PHP 8.3 change version and set path accordingly. Change in generated Vhost template manually: <FilesMatch \.php$> SetHandler "proxy:unix:/var/opt/remi/php84/run/php-fpm/%username%.sock|fcgi://localhost" </FilesMatch>The only drawback is that we cannot use the excellent GUI features of CWP Pro this way, but everything runs flawlessly, and this PHP (both 8.3 and 8.4) integrates the correct version of OpenSSL 3.x. @Starburst You can try it. @Sandeep B. How we can integrate it into GUI ?
-
Manual update of PHP in CWP
We could also use the PHP packages described in https://blog.remirepo.net/ . Remi's PHP versions are automatically updated, its have everything wee need for AlmaLinux 9.x, we just need to configure the PHP-FPM service and coordinate it with the CWP Apache and NGINX vhost templates. And this can be done even without the GUI. I use a similar setup on my development system under Ubuntu with the multi-php repo there.
-
CSF replacements needs
🔍 Issue Summary (CSF v15.00):csf and lfd are both properly installed and running: systemctl status csf → active (exited) systemctl status lfd → active (running) Manual commands such as csf -e, csf -r work as expected lfd.log confirms proper startup, log watching, and IP tracking However, the CSF firewall still shows as "Disabled" on the CWP Admin interface. ✅ What Works Correctly (on another server):On a similar environment (CWP Pro + AlmaLinux 9.x), the CSF firewall is correctly shown as active in the CWP interface when using csf v14.24 (CentOS Web Panel) All functionality and UI detection works fine with that version
-
CSF replacements needs
The CSF project is abandoned, and newly installed CWP Pro already has several issues during installation. Here is the topic: https://www.jaspreet.net/2025/09/06/3180/how-to-fix-csf-firewall-error-oops-unable-to-download-no-host-option-provided/ @Sandeep B. Do you have any idea how to replace CSF in CWP Pro servers?