If timezonedb download or extraction fails, log a warning and continue
with installation instead of exiting. This prevents installation from
failing when the cyberpanel.sh proxy URL returns 403 or other errors.
Checks added:
- Verify timezonedb.tgz downloaded successfully
- Verify tar extraction succeeded
- Verify cd to timezonedb directory succeeded
- Clean up temp directory and return gracefully on any failure
RHEL 9 binaries use '-rhel' suffix instead of '-rhel9':
- openlitespeed-phpconfig-x86_64-rhel (not rhel9)
- cyberpanel_ols_x86_64_rhel.so (not rhel9.so)
Updated URLs in install and upgrade modules to use correct filenames.
Ubuntu systems were incorrectly being detected as rhel9. Added explicit
Ubuntu/Debian check at the beginning of detectBinarySuffix() before
checking for RHEL-based distributions.
This ensures Ubuntu and Debian systems are properly identified and use
the correct binaries from the ubuntu/ directory instead of rhel9/.
Update OS detection and binary distribution to support separate binaries
for AlmaLinux/RHEL 8 and 9. The new structure uses:
- rhel8/ directory for AlmaLinux/RHEL 8.x binaries
- rhel9/ directory for AlmaLinux/RHEL 9.x binaries
- ubuntu/ directory for Ubuntu/Debian binaries
Changes:
- Enhanced detectBinarySuffix() to distinguish between RHEL 8 and 9
- Updated binary URLs to use new directory structure
- Updated ModSecurity checksums for all OS variants
- Applied changes to install, upgrade, and ModSecurity modules
This ensures proper ABI compatibility by providing OS-specific builds
with correct glibc and library dependencies for each platform.
Replace counter-based logic with initialization flags to properly handle
toggle state changes. The previous implementation used counters that would
block the first user click from triggering install/uninstall actions.
Handle the scenario where users install ModSecurity after CyberPanel is already
installed with custom OpenLiteSpeed binaries.
Problem:
- When users click "Install ModSecurity" in CyberPanel UI, the system used
package manager (yum/apt) to install stock ModSecurity
- Stock ModSecurity is NOT ABI-compatible with custom OLS binaries
- This causes immediate server crashes (segfaults) when installed
Solution:
- Detect if custom OLS binary is already installed before installing ModSecurity
- If custom OLS detected, download compatible ModSecurity from cyberpanel.net
- If stock OLS detected, use package manager as usual
Implementation:
- isCustomOLSBinaryInstalled(): Detects custom OLS by scanning binary for markers
- detectBinarySuffix(): Determines Ubuntu vs RHEL binaries needed
- installCompatibleModSecurity(): Downloads, verifies, and installs compatible ModSecurity
- Modified installModSec(): Main entry point - routes to compatible installer if needed
User flow:
1. User with custom OLS clicks "Install ModSecurity" in UI
2. System detects custom OLS binary is installed
3. System writes "Detected custom OpenLiteSpeed binary" to install log
4. System downloads OS-specific compatible ModSecurity from cyberpanel.net
5. System verifies SHA256 checksum
6. System backs up any existing ModSecurity
7. System installs compatible version with OLS restart
8. User sees "ModSecurity Installed (ABI-compatible version).[200]"
Safety features:
- Checksum verification before installation
- Automatic backup of existing ModSecurity
- Graceful OLS restart with timeout handling
- Detailed logging to /home/cyberpanel/modSecInstallLog
This prevents server crashes when users install ModSecurity after custom OLS
binaries are already deployed.
Implement automatic detection and update of ModSecurity when upgrading to custom OpenLiteSpeed binaries.
Problem:
- Stock ModSecurity modules are NOT ABI-compatible with custom OLS binaries
- Using stock ModSecurity with custom OLS causes server crashes (segfaults)
- Custom OLS has different memory layout and function signatures
- ModSecurity must be rebuilt against custom OLS headers
Solution:
- Detect if custom OLS binary is installed (check for PHPConfig markers)
- Detect if ModSecurity is currently installed
- Automatically download and install ABI-compatible ModSecurity
- Verify checksums before installation
- Backup existing ModSecurity before replacing
Implementation:
- isCustomOLSBinaryInstalled(): Detects custom OLS by scanning binary for markers
- installCompatibleModSecurity(): Downloads OS-specific compatible ModSecurity
- handleModSecurityCompatibility(): Orchestrates the compatibility check and update
- Integrated into upgrade process after custom binary installation
Binary URLs:
- RHEL/AlmaLinux: https://cyberpanel.net/mod_security-compatible-rhel.so
- Ubuntu/Debian: https://cyberpanel.net/mod_security-compatible-ubuntu.so
Checksums:
- RHEL SHA256: db580afc431fda40d46bdae2249ac74690d9175ff6d8b1843f2837d86f8d602f
- Ubuntu SHA256: 115971fcd44b74bc7c7b097b9cec33ddcfb0fb07bb9b562ec9f4f0691c388a6b
Safety features:
- Checksum verification before installation
- Automatic backup of existing ModSecurity
- Graceful OLS restart with timeout handling
- Non-fatal errors allow upgrade to continue
This prevents server crashes for existing CyberPanel users who have ModSecurity
installed when they upgrade to custom OpenLiteSpeed binaries.
- Change N8N_HOST to 0.0.0.0 (internal bind address, not domain)
- Simplify VHost extraHeaders to ONLY set Origin header
- Remove duplicate X-Forwarded-* headers (OLS adds these automatically)
- Remove N8N_ALLOWED_ORIGINS and N8N_ALLOW_CONNECTIONS_FROM (not needed)
The key issue was duplicate X-Forwarded-Host headers. OpenLiteSpeed proxy
contexts automatically add X-Forwarded-* headers, so explicitly setting
them creates duplicates that cause n8n validation to fail.
Only the Origin header needs explicit configuration in extraHeaders.
This works with the patched OLS binary (MD5: b9c65aa2563778975d0d2361494e9d31)
that forwards Origin headers from the client.
- Changed from pinned version 1.86.1 to latest
- Requires OpenLiteSpeed binaries with Origin header forwarding support
- Compatible with n8n 1.87.0+ which has strict Origin validation
Note: This requires the OpenLiteSpeed binary that includes the Origin
header forwarding patch in the proxy module. The patch is available
in the CyberPanel OpenLiteSpeed distribution.
- Pin n8n to version 1.86.1 to avoid Origin header validation issues
- Change N8N_HOST from 0.0.0.0 to domain for better compatibility
- Add N8N_PROXY_HOPS=1 to fix X-Forwarded-For errors
- Add N8N_ALLOWED_ORIGINS and N8N_ALLOW_CONNECTIONS_FROM for future compatibility
- Fix SetupN8NVhost to remove malformed Origin header setting
n8n versions 1.87.0+ introduced strict Origin header validation that is
incompatible with OpenLiteSpeed proxy (which doesn't forward Origin headers).
Version 1.86.1 works correctly with OLS and SSE push backend.
Implement safety checks to verify custom OpenLiteSpeed binaries work before committing to them:
Verification checks:
- Check library dependencies with ldd to detect missing libraries
- Test binary execution with -v flag to ensure it can run
- Detect issues like wrong binary type (ubuntu vs rhel) for the OS
Rollback mechanism:
- Automatically restore original binary from backup if verification fails
- Remove incompatible custom module
- Continue installation with standard OLS if custom binary fails
This prevents installation failures and system downtime when:
- Wrong binary type is downloaded due to OS detection issues
- Library dependencies are missing
- Binary cannot execute on the target system
Changes:
- Added verifyCustomBinary() method to check dependencies and execution
- Added rollbackCustomBinary() method to restore from backup
- Updated installCustomOLSBinaries() to verify and rollback on failure
- Applied to both install/installCyberPanel.py and plogical/upgrade.py
Benefits:
- Zero downtime: System falls back to working binary automatically
- Better error reporting: Shows which libraries are missing
- Safer upgrades: Users won't be left with broken installations
Add OS detection logic to download correct OpenLiteSpeed binaries based on system type:
- Ubuntu/Debian systems: Download binaries with libcrypt.so.1 (GLIBC 2.35)
- RHEL/AlmaLinux/Rocky 8+/9+: Download binaries with libcrypt.so.2 (GLIBC 2.34)
This fixes the "libcrypt.so.2: cannot open shared object file" error that occurred
when Ubuntu systems tried to use RHEL-compiled binaries.
Changes:
- Added detectBinarySuffix() method to both installCyberPanel.py and upgrade.py
- Updated binary URLs to use https://cyberpanel.net with OS-specific suffix
- Module URL: cyberpanel_ols_x86_64_{ubuntu|rhel}.so
- Binary URL: openlitespeed-phpconfig-x86_64-{ubuntu|rhel}
Binary compatibility matrix:
- Ubuntu 20.04/22.04/24.04, Debian 10+, CentOS 7 → ubuntu binaries
- AlmaLinux 8+/9+, Rocky 8+/9+, RHEL 8+/9+, OpenEuler → rhel binaries
- Add green gradient banner with modern design and animations
- Display text: Full .htaccess support • PHP configuration now works • Zero rule rewrites needed
- Link to https://cyberpanel.net/cyberpanel-htaccess-module
- Include ripple effect on button hover and rotation on close
- Add smart dismissal logic with localStorage persistence
- Show banner once per day with staggered delay for better UX
- Support mobile responsive design with flexible layout
- Position banner properly when multiple notifications are shown
Reduce minimum file size from 1MB to 10KB to allow the module file
(~35KB) to pass validation. The 1MB threshold was too strict and only
appropriate for the main OLS binary. Now displays size in KB or MB
appropriately.
Change download verification to check file existence and size instead of
relying on return code. The wget command succeeds but install_utils.call()
may not return 0. Now verifies downloaded file exists and is at least 1MB.
Integrate custom OLS binaries during installation to enable Apache-style
php_value/php_flag directives in .htaccess files. The installer now:
- Downloads custom OLS binary and module from cyberpanel.net
- Creates backup of existing binaries before replacement
- Installs custom binaries with enhanced .htaccess support
- Configures CyberPanel module in OpenLiteSpeed config
- Gracefully falls back to standard OLS if download fails
- Only installs on x86_64 architecture
Features enabled by custom binaries:
- Apache-style .htaccess support
- php_value and php_flag directives
- Enhanced header control
- Better Apache compatibility
Problem: Bulk fix operations were hitting rate limits (100 backups per scan).
Solution:
- Implemented 10x higher rate limits for API key authenticated requests
- These are trusted requests from the platform for legitimate bulk operations
- Regular file token auth keeps original limits for security
Rate Limit Changes:
- backup-file: 100 → 1000 for API key auth
- get-file: 500 → 5000 for API key auth
- replace-file: 100 → 1000 for API key auth
- rename-file: 50 → 500 for API key auth
- delete-file: 50 → 500 for API key auth
This allows bulk fix operations to process up to 1000 files without hitting rate limits,
while maintaining security for regular scan operations.
Problem: Bulk fix operations were hitting rate limits (100 backups per scan).
Solution:
- Implemented 10x higher rate limits for API key authenticated requests
- These are trusted requests from the platform for legitimate bulk operations
- Regular file token auth keeps original limits for security
Rate Limit Changes:
- backup-file: 100 → 1000 for API key auth
- get-file: 500 → 5000 for API key auth
- replace-file: 100 → 1000 for API key auth
- rename-file: 50 → 500 for API key auth
- delete-file: 50 → 500 for API key auth
This allows bulk fix operations to process up to 1000 files without hitting rate limits,
while maintaining security for regular scan operations.
Problem: VPS API keys were generated dynamically but never saved to the database,
causing file fix operations to fail with "Invalid token" error.
Root Cause:
- When CyberPanel runs on VPS, it calls platform's /api/vps/generate-api-key/
- The returned API key was used for scan submission but not persisted
- Later file fix operations couldn't validate this API key
Solution:
- Save VPS API key to ai_scanner_settings table whenever obtained
- Modified 4 locations where VPS API key is retrieved:
1. startScan() - Save when initiating a scan
2. getPlatformMonitorUrl() - Save when checking scan status
3. addPaymentMethod() - Save when configuring payment (2 locations)
Implementation:
- Use get_or_create() to ensure scanner settings exist
- Update existing settings if API key is empty or different
- Set is_payment_configured=True for VPS accounts (implicit payment)
- Continue operation even if saving fails (non-blocking)
Result:
- VPS API keys are automatically persisted on first use
- File fixes work without manual database intervention
- All AI Scanner features work seamlessly on VPS instances
Problem: "Failed to backup file before replacement" error when using API key authentication.
Root Cause:
- The externalApp field (which contains the system user for file operations) was sometimes None
- When using API key authentication, the code couldn't determine which user to run commands as
Solution:
- Added fallback logic to ensure we always have a valid user for file operations:
1. First try wp_site.owner.externalApp
2. If not set, try Websites.objects.get(domain).externalApp
3. If still not set, fall back to admin username
- Added detailed error messages and logging throughout backup operations
- Enhanced error reporting to include user context and operation details
- Added validation for backup directory creation with proper error handling
Changes:
- Modified validate_access_token() OPTION 2 and OPTION 3 to ensure external_app is always set
- Enhanced backup and replace operations with better error messages
- Added detailed logging for debugging file operation failures
- Include user context in error messages for easier troubleshooting
This ensures file operations work correctly even when externalApp field is not properly configured.
Problem: File fixes were failing with "Invalid token" even though the platform was sending the correct API key.
Solution:
- Updated validate_access_token() to accept CyberPanel's own API keys for file operations
- Added three validation options:
1. FileAccessToken (temporary tokens for active scans)
2. API key validation with less restrictive admin check
3. Simple validation for platform callbacks (any valid API key + valid scan)
- Added extract_auth_token() helper to support both Bearer and X-API-Key headers
- Created debug endpoints for testing authentication (/api/ai-scanner/test-auth)
- Added test script for validation testing (supports remote servers via env vars)
This fix allows the platform to use CyberPanel's API key to fix files for any scan,
solving the "File access token has expired" issue for older scans.
Usage for remote testing:
CYBERPANEL_SERVER=http://your-server:8001 \
CYBERPANEL_API_KEY=cp_your_key \
CYBERPANEL_SCAN_ID=your-scan-id \
./test_api_key_fix.sh
- Added extract_auth_token() function to handle both Bearer and X-API-Key authentication
- Updated all file operation endpoints to support X-API-Key headers:
- list_files()
- get_file_content()
- scanner_backup_file()
- scanner_get_file()
- scanner_replace_file()
- scanner_rename_file()
- scanner_delete_file()
- Maintains backward compatibility with existing Bearer token authentication
- Added test script to verify both authentication methods work correctly
- Enables permanent API key authentication for file fixes (no more expired token issues)
This change allows the platform to fix files using the permanent CyberPanel API key
instead of temporary file access tokens that expire after ~1 hour.
- Write temp files to /tmp (accessible by all users)
- Website user can read from /tmp for cat command
- No permission issues with cross-directory operations
- Simplifies file operations (no intermediate copy needed)
- Clean up temp file with os.remove() as root
- Fixes: Files becoming empty due to permission issues
- Shell redirection requires shell=True parameter in executioner
- Without shell=True, the > is treated as literal argument
- Fixes: File contents not being replaced
- Change from cp to 'cat temp > target' for replacing file contents
- cat redirection is more reliable for overwriting existing files
- Ensures file contents are actually replaced
- Fixes: Files not being replaced even though cp returns success
- Write to /home/cyberpanel temp first (no user permission issues)
- Copy from /home/cyberpanel to user directory using executioner
- Use cp instead of mv for final file replacement (more reliable)
- Clean up temp files after successful operations
- Fixes: File corruption due to failed mv command via lscpd
- Write content to /home/cyberpanel/scanner_temp_{scan_id}_{timestamp}.tmp first
- Use Python open() instead of shell here-document to avoid:
- lscpd connection reset for large files (>2KB)
- EOF_MARKER conflicts in file content
- Shell command size limits
- Copy temp file to user directory using executioner with user context
- Clean up CyberPanel temp file after copy
- Fixes: [Errno 104] Connection reset by peer when writing large files
- Add bypass check for 'content' field INSIDE isAPIEndpoint block
- Prevents blocking of legitimate JavaScript/PHP code in replace-file API
- Bypass list includes: content, fileContent, configData, rewriteRules, modSecRules
- Security check still applies to other fields in API requests
- Fixes: Replace-file API being blocked by security middleware
- executioner() returns 1 for success, 0 for failure (inverted)
- Fix mkdir check: if mkdir_result != 1 (was != 0)
- Fix cp check: if cp_result[0] != 1 (was != 0)
- Fix double slash in backup path by stripping trailing slash from wp_path
- Add logging to show mkdir_result value for debugging
- Add external_app field to AuthWrapper class
- Get externalApp from website object during authentication
- For FileAccessToken: Use Websites.externalApp
- For API Key: Use WPSites.owner.externalApp
- Update all 5 file operation endpoints to use file_token.external_app
- scanner_backup_file
- scanner_get_file
- scanner_replace_file
- scanner_rename_file
- scanner_delete_file
- Ensures externalApp matches wp_path since they come from same source
- Fixes backup API failing due to incorrect user context
Separate acme.sh certificate issuance and installation steps to ensure
domain configurations are properly stored. Previously, combining --issue
with --cert-file/--key-file/--fullchain-file in a single command caused
acme.sh to skip storing domain configs, breaking automatic renewals and
requiring manual certificate recreation for domain aliases.
Fixes#1583 - Ubuntu 24 permission issues causing 404 errors
Changes:
- Move main public_html permission setting to END of fixPermissions function
- Ensures public_html maintains user:nogroup ownership (not user:user)
- Prevents child domain processing from interfering with main directory permissions
- Changed all async popenExecutioner calls to sync executioner calls
- Reordered operations: permissions first, then ownership
This fixes the issue where clicking "Fix Permissions" in file manager
would incorrectly change public_html group from nogroup to the user's group,
causing 404 errors on Ubuntu 24.
Fixes#1583
The fixPermissions function in file manager was causing sites to become
inaccessible after running "Fix Permissions" on Ubuntu 24. The root causes:
1. Async execution (popenExecutioner) caused race conditions where commands
executed in unpredictable order
2. The public_html directory group was incorrectly changed from 'nogroup'
to the user's group, breaking web server access
Changes:
- Changed all async popenExecutioner calls to sync executioner calls
- Reordered commands to set permissions before ownership
- Ensured public_html directory maintains correct group ownership (nogroup)
- Added comments to clarify the purpose of each step
This ensures the file manager's "Fix Permissions" feature works correctly
on Ubuntu 24 while maintaining proper security.
- Ensure /home/cyberpanel directory exists with proper permissions before download
- Set directory permissions to 755 to allow application write access
- Refactor SCP/SFTP fallback logic to work regardless of debug mode
- Add better status messages during download process