diff --git a/CyberCP/phpmyadminMiddleware.py b/CyberCP/phpmyadminMiddleware.py new file mode 100644 index 000000000..0b218f67c --- /dev/null +++ b/CyberCP/phpmyadminMiddleware.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +""" +phpMyAdmin Access Control Middleware + +This middleware checks if users are trying to access phpMyAdmin directly +without being logged into CyberPanel and redirects them to the login page. +""" + +from django.shortcuts import redirect +from django.http import HttpResponseRedirect +from django.urls import reverse + + +class PhpMyAdminAccessMiddleware: + """ + Middleware to control phpMyAdmin access and redirect unauthenticated users to login page. + """ + + def __init__(self, get_response): + self.get_response = get_response + + def __call__(self, request): + # Check if the request is for phpMyAdmin + if request.path.startswith('/phpmyadmin/'): + # Check if user is authenticated (has session) + if 'userID' not in request.session: + # Redirect to CyberPanel login page + login_url = '/base/' + return HttpResponseRedirect(login_url) + + response = self.get_response(request) + return response diff --git a/CyberCP/settings.py b/CyberCP/settings.py index 242636410..91d6b1353 100644 --- a/CyberCP/settings.py +++ b/CyberCP/settings.py @@ -87,7 +87,8 @@ MIDDLEWARE = [ 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', - 'CyberCP.secMiddleware.secMiddleware' + 'CyberCP.secMiddleware.secMiddleware', + 'CyberCP.phpmyadminMiddleware.PhpMyAdminAccessMiddleware' ] ROOT_URLCONF = 'CyberCP.urls' @@ -106,6 +107,7 @@ TEMPLATES = [ 'django.contrib.messages.context_processors.messages', 'baseTemplate.context_processors.version_context', 'baseTemplate.context_processors.cosmetic_context', + 'baseTemplate.context_processors.notification_preferences_context', ], }, }, diff --git a/README.md b/README.md index 9ff9ab30c..cbe86b132 100755 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ CyberPanel comes with comprehensive documentation and step-by-step guides: - 🐳 **[Docker Command Execution](guides/Docker_Command_Execution_Guide.md)** - Execute commands in Docker containers - 🤖 **[AI Scanner Setup](guides/AIScannerDocs.md)** - Configure AI-powered security scanning - 📧 **[Mautic Installation](guides/MAUTIC_INSTALLATION_GUIDE.md)** - Email marketing platform setup +- 🎨 **[Custom CSS Guide](guides/CUSTOM_CSS_GUIDE.md)** - Create custom themes for CyberPanel 2.5.5-dev --- @@ -39,9 +40,9 @@ CyberPanel supports a wide range of PHP versions across different operating syst ### ☑️ **Currently Supported PHP Versions** -- **PHP 8.5** - Latest stable version (EOL: Dec 2028) +- **PHP 8.5** - Latest stable version (EOL: Dec 2028) ⭐ **NEW!** - **PHP 8.4** - Stable version (EOL: Dec 2027) -- **PHP 8.3** - Stable version (EOL: Dec 2027) +- **PHP 8.3** - **Default version** - Stable version (EOL: Dec 2027) 🎯 - **PHP 8.2** - Stable version (EOL: Dec 2026) - **PHP 8.1** - Stable version (EOL: Dec 2025) - **PHP 8.0** - Legacy support (EOL: Nov 2023) @@ -79,6 +80,9 @@ CyberPanel runs on x86_64 architecture and supports the following operating syst - **Ubuntu 24.04.3** - Supported until April 2029 ⭐ **NEW!** - **Ubuntu 22.04** - Supported until April 2027 - **Ubuntu 20.04** - Supported until April 2025 +- **Debian 13** - Supported until 2029 ⭐ **NEW!** +- **Debian 12** - Supported until 2027 +- **Debian 11** - Supported until 2026 - **AlmaLinux 10** - Supported until May 2030 ⭐ **NEW!** - **AlmaLinux 9** - Supported until May 2032 - **AlmaLinux 8** - Supported until May 2029 @@ -93,7 +97,6 @@ CyberPanel runs on x86_64 architecture and supports the following operating syst Additional operating systems may be supported through third-party repositories or community efforts: -- **Debian** - May work with Ubuntu-compatible packages - **openEuler** - Community-supported with limited testing - **Other RHEL derivatives** - May work with AlmaLinux/RockyLinux packages @@ -109,7 +112,6 @@ Install CyberPanel easily with the following command: sh <(curl https://cyberpanel.net/install.sh || wget -O - https://cyberpanel.net/install.sh) ``` - --- ## 📊 Upgrading CyberPanel @@ -124,17 +126,20 @@ sh <(curl https://raw.githubusercontent.com/usmannasir/cyberpanel/stable/preUpgr ## 🆕 Recent Updates & Fixes -### **Bandwidth Reset Issue Fixed** (January 2025) +### **Bandwidth Reset Issue Fixed** (September 2025) + - **Issue**: Monthly bandwidth usage was not resetting, causing cumulative values to grow indefinitely - **Solution**: Implemented automatic monthly bandwidth reset for all websites and child domains - **Affected OS**: All supported operating systems (Ubuntu, AlmaLinux, RockyLinux, RHEL, CloudLinux, CentOS) - **Manual Reset**: Use `/usr/local/CyberCP/scripts/reset_bandwidth.sh` for immediate reset - **Documentation**: See [Bandwidth Reset Fix Guide](to-do/cyberpanel-bandwidth-reset-fix.md) -### **New Operating System Support Added** (January 2025) +### **New Operating System Support Added** (September 2025) + - **Ubuntu 24.04.3**: Full compatibility with latest Ubuntu LTS +- **Debian 13**: Full compatibility with latest Debian stable release - **AlmaLinux 10**: Full compatibility with latest AlmaLinux release -- **Long-term Support**: Both supported until 2029-2030 +- **Long-term Support**: All supported until 2029-2030 --- @@ -157,17 +162,19 @@ sh <(curl https://raw.githubusercontent.com/usmannasir/cyberpanel/stable/preUpgr - 🐳 [Docker Command Execution](guides/Docker_Command_Execution_Guide.md) - Execute commands in Docker containers - 🤖 [AI Scanner Setup](guides/AIScannerDocs.md) - Configure AI-powered security scanning - 📧 [Mautic Installation](guides/MAUTIC_INSTALLATION_GUIDE.md) - Email marketing platform setup +- 🎨 [Custom CSS Guide](guides/CUSTOM_CSS_GUIDE.md) - Create custom themes for CyberPanel 2.5.5+ - 📚 [All Guides Index](guides/INDEX.md) - Complete documentation hub ### 🔗 **Direct Guide Links** -| Feature | Guide | Description | -| ----------- | ---------------------------------------------------------- | ------------------------------ | -| 🐳 Docker | [Command Execution](guides/Docker_Command_Execution_Guide.md) | Execute commands in containers | -| 🤖 Security | [AI Scanner](guides/AIScannerDocs.md) | AI-powered security scanning | -| 📧 Email | [Mautic Setup](guides/MAUTIC_INSTALLATION_GUIDE.md) | Email marketing platform | -| 📊 Bandwidth | [Reset Fix Guide](to-do/cyberpanel-bandwidth-reset-fix.md) | Fix bandwidth reset issues | -| 📚 All | [Complete Index](guides/INDEX.md) | Browse all available guides | +| Feature | Guide | Description | +| ------------ | ---------------------------------------------------------- | ---------------------------------- | +| 🐳 Docker | [Command Execution](guides/Docker_Command_Execution_Guide.md) | Execute commands in containers | +| 🤖 Security | [AI Scanner](guides/AIScannerDocs.md) | AI-powered security scanning | +| 📧 Email | [Mautic Setup](guides/MAUTIC_INSTALLATION_GUIDE.md) | Email marketing platform | +| 🎨 Design | [Custom CSS Guide](guides/CUSTOM_CSS_GUIDE.md) | Create custom themes for 2.5.5-dev | +| 📊 Bandwidth | [Reset Fix Guide](to-do/cyberpanel-bandwidth-reset-fix.md) | Fix bandwidth reset issues | +| 📚 All | [Complete Index](guides/INDEX.md) | Browse all available guides | --- @@ -176,12 +183,13 @@ sh <(curl https://raw.githubusercontent.com/usmannasir/cyberpanel/stable/preUpgr ### **Common Issues & Solutions** #### **Bandwidth Not Resetting Monthly** + - **Issue**: Bandwidth usage shows cumulative values instead of monthly usage - **Solution**: Run the bandwidth reset script: `/usr/local/CyberCP/scripts/reset_bandwidth.sh` - **Prevention**: Ensure monthly cron job is running: `0 0 1 * * /usr/local/CyberCP/bin/python /usr/local/CyberCP/postfixSenderPolicy/client.py monthlyCleanup` - #### **General Support** + - Check logs: `/usr/local/lscp/logs/error.log` - Verify cron jobs: `crontab -l` - Test manual reset: Use provided scripts in `/usr/local/CyberCP/scripts/` diff --git a/baseTemplate/apps.py b/baseTemplate/apps.py index f5ce2e6d1..773d21648 100644 --- a/baseTemplate/apps.py +++ b/baseTemplate/apps.py @@ -6,3 +6,6 @@ from django.apps import AppConfig class BasetemplateConfig(AppConfig): name = 'baseTemplate' + + def ready(self): + import baseTemplate.signals \ No newline at end of file diff --git a/baseTemplate/context_processors.py b/baseTemplate/context_processors.py index 13d871c10..696f9d840 100644 --- a/baseTemplate/context_processors.py +++ b/baseTemplate/context_processors.py @@ -23,4 +23,30 @@ def cosmetic_context(request): cosmetic.save() return { 'cosmetic': cosmetic - } \ No newline at end of file + } + +def notification_preferences_context(request): + """Add user notification preferences to all templates""" + try: + if 'userID' in request.session: + from .models import UserNotificationPreferences + from loginSystem.models import Administrator + user = Administrator.objects.get(pk=request.session['userID']) + try: + preferences = UserNotificationPreferences.objects.get(user=user) + return { + 'backup_notification_dismissed': preferences.backup_notification_dismissed, + 'ai_scanner_notification_dismissed': preferences.ai_scanner_notification_dismissed + } + except UserNotificationPreferences.DoesNotExist: + return { + 'backup_notification_dismissed': False, + 'ai_scanner_notification_dismissed': False + } + except: + pass + + return { + 'backup_notification_dismissed': False, + 'ai_scanner_notification_dismissed': False + } \ No newline at end of file diff --git a/baseTemplate/migrations/0002_usernotificationpreferences.py b/baseTemplate/migrations/0002_usernotificationpreferences.py new file mode 100644 index 000000000..3db48ac84 --- /dev/null +++ b/baseTemplate/migrations/0002_usernotificationpreferences.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.29 on 2024-01-01 00:00 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('baseTemplate', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='UserNotificationPreferences', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('backup_notification_dismissed', models.BooleanField(default=False, help_text='Whether user has dismissed the backup notification')), + ('ai_scanner_notification_dismissed', models.BooleanField(default=False, help_text='Whether user has dismissed the AI scanner notification')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='notification_preferences', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'verbose_name': 'User Notification Preferences', + 'verbose_name_plural': 'User Notification Preferences', + }, + ), + ] diff --git a/baseTemplate/models.py b/baseTemplate/models.py index 3ced4ced5..b02b2ca38 100644 --- a/baseTemplate/models.py +++ b/baseTemplate/models.py @@ -2,6 +2,7 @@ from django.db import models +from django.contrib.auth.models import User # Create your models here. @@ -11,4 +12,19 @@ class version(models.Model): build = models.IntegerField() class CyberPanelCosmetic(models.Model): - MainDashboardCSS = models.TextField(default='') \ No newline at end of file + MainDashboardCSS = models.TextField(default='') + +class UserNotificationPreferences(models.Model): + """Model to store user notification dismissal preferences""" + user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='notification_preferences') + backup_notification_dismissed = models.BooleanField(default=False, help_text="Whether user has dismissed the backup notification") + ai_scanner_notification_dismissed = models.BooleanField(default=False, help_text="Whether user has dismissed the AI scanner notification") + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + + class Meta: + verbose_name = "User Notification Preferences" + verbose_name_plural = "User Notification Preferences" + + def __str__(self): + return f"Notification Preferences for {self.user.username}" \ No newline at end of file diff --git a/baseTemplate/signals.py b/baseTemplate/signals.py new file mode 100644 index 000000000..6c7b22340 --- /dev/null +++ b/baseTemplate/signals.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +from django.db.models.signals import post_save +from django.dispatch import receiver +from django.contrib.auth.models import User +from .models import UserNotificationPreferences + + +@receiver(post_save, sender=User) +def create_user_notification_preferences(sender, instance, created, **kwargs): + """Create default notification preferences when a new user is created""" + if created: + UserNotificationPreferences.objects.create( + user=instance, + backup_notification_dismissed=False, + ai_scanner_notification_dismissed=False + ) + + +@receiver(post_save, sender=User) +def save_user_notification_preferences(sender, instance, **kwargs): + """Save notification preferences when user is saved""" + if hasattr(instance, 'notification_preferences'): + instance.notification_preferences.save() diff --git a/baseTemplate/templates/baseTemplate/index.html b/baseTemplate/templates/baseTemplate/index.html index 3a6986ddd..742a8f49f 100644 --- a/baseTemplate/templates/baseTemplate/index.html +++ b/baseTemplate/templates/baseTemplate/index.html @@ -1841,10 +1841,10 @@ // Backup notification banner logic function checkBackupStatus() { - // Check if user has dismissed the notification in this session - if (sessionStorage.getItem('backupNotificationDismissed') === 'true') { - return; - } + // Check if user has dismissed the notification permanently (from server-side context) + {% if backup_notification_dismissed %} + return; // Notification already dismissed permanently + {% endif %} // Check if user has backup configured (you'll need to implement this API) // For now, we'll show it by default unless they have a backup plan @@ -1871,16 +1871,34 @@ const body = document.body; banner.classList.remove('show'); body.classList.remove('notification-shown'); - // Remember dismissal for this session - sessionStorage.setItem('backupNotificationDismissed', 'true'); + + // Dismiss permanently via API + fetch('/base/dismiss_backup_notification', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-CSRFToken': getCookie('csrftoken') + } + }) + .then(response => response.json()) + .then(data => { + if (data.status === 1) { + console.log('Backup notification dismissed permanently'); + } else { + console.error('Failed to dismiss backup notification:', data.error); + } + }) + .catch(error => { + console.error('Error dismissing backup notification:', error); + }); } // AI Scanner Notification Functions function checkAIScannerStatus() { - // Check if user has dismissed the notification in this session - if (sessionStorage.getItem('aiScannerNotificationDismissed') === 'true') { - return; - } + // Check if user has dismissed the notification permanently (from server-side context) + {% if ai_scanner_notification_dismissed %} + return; // Notification already dismissed permanently + {% endif %} // Check if we're not already on the AI Scanner page if (!window.location.href.includes('aiscanner')) { @@ -1900,8 +1918,26 @@ const body = document.body; banner.classList.remove('show'); body.classList.remove('ai-scanner-shown'); - // Remember dismissal for this session - sessionStorage.setItem('aiScannerNotificationDismissed', 'true'); + + // Dismiss permanently via API + fetch('/base/dismiss_ai_scanner_notification', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-CSRFToken': getCookie('csrftoken') + } + }) + .then(response => response.json()) + .then(data => { + if (data.status === 1) { + console.log('AI scanner notification dismissed permanently'); + } else { + console.error('Failed to dismiss AI scanner notification:', data.error); + } + }) + .catch(error => { + console.error('Error dismissing AI scanner notification:', error); + }); } // Check both notification statuses when page loads diff --git a/baseTemplate/urls.py b/baseTemplate/urls.py index 6ebdc293b..c6190ea66 100644 --- a/baseTemplate/urls.py +++ b/baseTemplate/urls.py @@ -24,4 +24,7 @@ urlpatterns = [ re_path(r'^getSSHUserActivity$', views.getSSHUserActivity, name='getSSHUserActivity'), re_path(r'^getTopProcesses$', views.getTopProcesses, name='getTopProcesses'), re_path(r'^analyzeSSHSecurity$', views.analyzeSSHSecurity, name='analyzeSSHSecurity'), + re_path(r'^dismiss_backup_notification$', views.dismiss_backup_notification, name='dismiss_backup_notification'), + re_path(r'^dismiss_ai_scanner_notification$', views.dismiss_ai_scanner_notification, name='dismiss_ai_scanner_notification'), + re_path(r'^get_notification_preferences$', views.get_notification_preferences, name='get_notification_preferences'), ] diff --git a/baseTemplate/views.py b/baseTemplate/views.py index 4e4bfef57..22adee65d 100644 --- a/baseTemplate/views.py +++ b/baseTemplate/views.py @@ -6,7 +6,7 @@ from django.http import HttpResponse from plogical.getSystemInformation import SystemInformation import json from loginSystem.views import loadLoginPage -from .models import version +from .models import version, UserNotificationPreferences import requests import subprocess import shlex @@ -1305,3 +1305,88 @@ def getTopProcesses(request): except Exception as e: return HttpResponse(json.dumps({'error': str(e)}), content_type='application/json', status=500) + +@csrf_exempt +@require_POST +def dismiss_backup_notification(request): + """API endpoint to permanently dismiss the backup notification for the current user""" + try: + user_id = request.session.get('userID') + if not user_id: + return HttpResponse(json.dumps({'status': 0, 'error': 'Not logged in'}), content_type='application/json', status=403) + + # Get or create user notification preferences + user = Administrator.objects.get(pk=user_id) + preferences, created = UserNotificationPreferences.objects.get_or_create( + user=user, + defaults={ + 'backup_notification_dismissed': False, + 'ai_scanner_notification_dismissed': False + } + ) + + # Mark backup notification as dismissed + preferences.backup_notification_dismissed = True + preferences.save() + + return HttpResponse(json.dumps({'status': 1, 'message': 'Backup notification dismissed permanently'}), content_type='application/json') + + except Exception as e: + return HttpResponse(json.dumps({'status': 0, 'error': str(e)}), content_type='application/json', status=500) + +@csrf_exempt +@require_POST +def dismiss_ai_scanner_notification(request): + """API endpoint to permanently dismiss the AI scanner notification for the current user""" + try: + user_id = request.session.get('userID') + if not user_id: + return HttpResponse(json.dumps({'status': 0, 'error': 'Not logged in'}), content_type='application/json', status=403) + + # Get or create user notification preferences + user = Administrator.objects.get(pk=user_id) + preferences, created = UserNotificationPreferences.objects.get_or_create( + user=user, + defaults={ + 'backup_notification_dismissed': False, + 'ai_scanner_notification_dismissed': False + } + ) + + # Mark AI scanner notification as dismissed + preferences.ai_scanner_notification_dismissed = True + preferences.save() + + return HttpResponse(json.dumps({'status': 1, 'message': 'AI scanner notification dismissed permanently'}), content_type='application/json') + + except Exception as e: + return HttpResponse(json.dumps({'status': 0, 'error': str(e)}), content_type='application/json', status=500) + +@csrf_exempt +@require_GET +def get_notification_preferences(request): + """API endpoint to get current user's notification preferences""" + try: + user_id = request.session.get('userID') + if not user_id: + return HttpResponse(json.dumps({'status': 0, 'error': 'Not logged in'}), content_type='application/json', status=403) + + # Get user notification preferences + user = Administrator.objects.get(pk=user_id) + try: + preferences = UserNotificationPreferences.objects.get(user=user) + return HttpResponse(json.dumps({ + 'status': 1, + 'backup_notification_dismissed': preferences.backup_notification_dismissed, + 'ai_scanner_notification_dismissed': preferences.ai_scanner_notification_dismissed + }), content_type='application/json') + except UserNotificationPreferences.DoesNotExist: + # Return default values if preferences don't exist yet + return HttpResponse(json.dumps({ + 'status': 1, + 'backup_notification_dismissed': False, + 'ai_scanner_notification_dismissed': False + }), content_type='application/json') + + except Exception as e: + return HttpResponse(json.dumps({'status': 0, 'error': str(e)}), content_type='application/json', status=500) diff --git a/cyberpanel.sh b/cyberpanel.sh index 17ce2e110..b3c988a92 100644 --- a/cyberpanel.sh +++ b/cyberpanel.sh @@ -549,12 +549,14 @@ elif grep -q -E "Rocky Linux" /etc/os-release ; then Server_OS="RockyLinux" elif grep -q -E "Ubuntu 18.04|Ubuntu 20.04|Ubuntu 20.10|Ubuntu 22.04|Ubuntu 24.04" /etc/os-release ; then Server_OS="Ubuntu" +elif grep -q -E "Debian GNU/Linux 11|Debian GNU/Linux 12|Debian GNU/Linux 13" /etc/os-release ; then + Server_OS="Debian" elif grep -q -E "openEuler 20.03|openEuler 22.03" /etc/os-release ; then Server_OS="openEuler" else echo -e "Unable to detect your system..." - echo -e "\nCyberPanel is supported on x86_64 based Ubuntu 18.04, Ubuntu 20.04, Ubuntu 20.10, Ubuntu 22.04, Ubuntu 24.04, Ubuntu 24.04.3, CentOS 7, CentOS 8, CentOS 9, RHEL 8, RHEL 9, AlmaLinux 8, AlmaLinux 9, AlmaLinux 10, RockyLinux 8, CloudLinux 7, CloudLinux 8, openEuler 20.03, openEuler 22.03...\n" - Debug_Log2 "CyberPanel is supported on x86_64 based Ubuntu 18.04, Ubuntu 20.04, Ubuntu 20.10, Ubuntu 22.04, Ubuntu 24.04, Ubuntu 24.04.3, CentOS 7, CentOS 8, CentOS 9, RHEL 8, RHEL 9, AlmaLinux 8, AlmaLinux 9, AlmaLinux 10, RockyLinux 8, CloudLinux 7, CloudLinux 8, openEuler 20.03, openEuler 22.03... [404]" + echo -e "\nCyberPanel is supported on x86_64 based Ubuntu 18.04, Ubuntu 20.04, Ubuntu 20.10, Ubuntu 22.04, Ubuntu 24.04, Ubuntu 24.04.3, Debian 11, Debian 12, Debian 13, CentOS 7, CentOS 8, CentOS 9, RHEL 8, RHEL 9, AlmaLinux 8, AlmaLinux 9, AlmaLinux 10, RockyLinux 8, CloudLinux 7, CloudLinux 8, openEuler 20.03, openEuler 22.03...\n" + Debug_Log2 "CyberPanel is supported on x86_64 based Ubuntu 18.04, Ubuntu 20.04, Ubuntu 20.10, Ubuntu 22.04, Ubuntu 24.04, Ubuntu 24.04.3, Debian 11, Debian 12, Debian 13, CentOS 7, CentOS 8, CentOS 9, RHEL 8, RHEL 9, AlmaLinux 8, AlmaLinux 9, AlmaLinux 10, RockyLinux 8, CloudLinux 7, CloudLinux 8, openEuler 20.03, openEuler 22.03... [404]" exit fi @@ -568,6 +570,9 @@ if [[ $Server_OS = "CloudLinux" ]] || [[ "$Server_OS" = "AlmaLinux" ]] || [[ "$S Server_OS="CentOS" #CloudLinux gives version id like 7.8, 7.9, so cut it to show first number only #treat CloudLinux, Rocky and Alma as CentOS +elif [[ "$Server_OS" = "Debian" ]] ; then + Server_OS="Ubuntu" + #Treat Debian as Ubuntu for package management (both use apt-get) fi if [[ "$Debug" = "On" ]] ; then @@ -2278,7 +2283,7 @@ echo "echo \$@ > /etc/cyberpanel/adminPass" >> /usr/bin/adminPass chmod 700 /usr/bin/adminPass rm -f /usr/bin/php -ln -s /usr/local/lsws/lsphp80/bin/php /usr/bin/php +ln -s /usr/local/lsws/lsphp83/bin/php /usr/bin/php if [[ "$Server_OS" = "CentOS" ]] ; then #all centos 7/8 post change goes here diff --git a/deploy_phpmyadmin_redirect.sh b/deploy_phpmyadmin_redirect.sh new file mode 100644 index 000000000..203971f78 --- /dev/null +++ b/deploy_phpmyadmin_redirect.sh @@ -0,0 +1,54 @@ +#!/bin/bash + +# CyberPanel phpMyAdmin Access Control Deployment Script +# This script implements redirect functionality for unauthenticated phpMyAdmin access + +echo "=== CyberPanel phpMyAdmin Access Control Deployment ===" + +# Check if running as root +if [ "$EUID" -ne 0 ]; then + echo "Please run this script as root" + exit 1 +fi + +# Backup original phpMyAdmin index.php if it exists +if [ -f "/usr/local/CyberCP/public/phpmyadmin/index.php" ]; then + echo "Backing up original phpMyAdmin index.php..." + cp /usr/local/CyberCP/public/phpmyadmin/index.php /usr/local/CyberCP/public/phpmyadmin/index.php.backup.$(date +%Y%m%d_%H%M%S) +fi + +# Deploy the redirect index.php +echo "Deploying phpMyAdmin access control..." +cp /usr/local/CyberCP/phpmyadmin_index_redirect.php /usr/local/CyberCP/public/phpmyadmin/index.php + +# Deploy .htaccess for additional protection +echo "Deploying .htaccess protection..." +cp /usr/local/CyberCP/phpmyadmin_htaccess /usr/local/CyberCP/public/phpmyadmin/.htaccess + +# Set proper permissions +echo "Setting permissions..." +chown lscpd:lscpd /usr/local/CyberCP/public/phpmyadmin/index.php +chmod 644 /usr/local/CyberCP/public/phpmyadmin/index.php +chown lscpd:lscpd /usr/local/CyberCP/public/phpmyadmin/.htaccess +chmod 644 /usr/local/CyberCP/public/phpmyadmin/.htaccess + +# Restart LiteSpeed to ensure changes take effect +echo "Restarting LiteSpeed..." +systemctl restart lscpd + +echo "=== Deployment Complete ===" +echo "" +echo "phpMyAdmin access control has been deployed successfully!" +echo "" +echo "What this does:" +echo "- Users trying to access phpMyAdmin directly without being logged into CyberPanel" +echo " will now be redirected to the CyberPanel login page (/base/)" +echo "- Authenticated users will continue to access phpMyAdmin normally" +echo "" +echo "To revert changes, restore the backup:" +echo "cp /usr/local/CyberCP/public/phpmyadmin/index.php.backup.* /usr/local/CyberCP/public/phpmyadmin/index.php" +echo "" +echo "Test the implementation by:" +echo "1. Opening an incognito/private browser window" +echo "2. Going to https://your-server:2087/phpmyadmin/" +echo "3. You should be redirected to the CyberPanel login page" diff --git a/dockerManager/container.py b/dockerManager/container.py index a4ccada72..1bd25f751 100644 --- a/dockerManager/container.py +++ b/dockerManager/container.py @@ -323,17 +323,26 @@ class ContainerManager(multi.Thread): if 'ExposedPorts' in inspectImage['Config']: for item in inspectImage['Config']['ExposedPorts']: - # Do not allow priviledged port numbers - if int(data[item]) < 1024 or int(data[item]) > 65535: - data_ret = {'createContainerStatus': 0, 'error_message': "Choose port between 1024 and 65535"} - json_data = json.dumps(data_ret) - return HttpResponse(json_data) - portConfig[item] = data[item] + # Check if port data exists and is valid + if item in data and data[item]: + try: + port_num = int(data[item]) + # Do not allow priviledged port numbers + if port_num < 1024 or port_num > 65535: + data_ret = {'createContainerStatus': 0, 'error_message': "Choose port between 1024 and 65535"} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + portConfig[item] = data[item] + except (ValueError, TypeError): + data_ret = {'createContainerStatus': 0, 'error_message': f"Invalid port number: {data[item]}"} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) volumes = {} - for index, volume in volList.items(): - volumes[volume['src']] = {'bind': volume['dest'], - 'mode': 'rw'} + if volList: + for index, volume in volList.items(): + if isinstance(volume, dict) and 'src' in volume and 'dest' in volume: + volumes[volume['src']] = {'bind': volume['dest'], 'mode': 'rw'} ## Create Configurations admin = Administrator.objects.get(userName=dockerOwner) @@ -351,10 +360,15 @@ class ContainerManager(multi.Thread): try: container = client.containers.create(**containerArgs) except Exception as err: - if "port is already allocated" in err: # We need to delete container if port is not available + # Check if it's a port allocation error by converting to string first + error_message = str(err) + if "port is already allocated" in error_message: # We need to delete container if port is not available print("Deleting container") - container.remove(force=True) - data_ret = {'createContainerStatus': 0, 'error_message': str(err)} + try: + container.remove(force=True) + except: + pass # Container might not exist yet + data_ret = {'createContainerStatus': 0, 'error_message': error_message} json_data = json.dumps(data_ret) return HttpResponse(json_data) @@ -376,7 +390,9 @@ class ContainerManager(multi.Thread): except Exception as msg: - data_ret = {'createContainerStatus': 0, 'error_message': str(msg)} + # Ensure error message is properly converted to string + error_message = str(msg) if msg else "Unknown error occurred" + data_ret = {'createContainerStatus': 0, 'error_message': error_message} json_data = json.dumps(data_ret) return HttpResponse(json_data) diff --git a/dockerManager/static/dockerManager/dockerManager.js b/dockerManager/static/dockerManager/dockerManager.js index 5a89b644d..5d411a70d 100644 --- a/dockerManager/static/dockerManager/dockerManager.js +++ b/dockerManager/static/dockerManager/dockerManager.js @@ -273,6 +273,54 @@ app.controller('runContainer', function ($scope, $http) { } }; + // Helper function to generate Docker Compose YAML + function generateDockerComposeYml(containerInfo) { + var yml = 'version: \'3.8\'\n\n'; + yml += 'services:\n'; + yml += ' ' + containerInfo.name + ':\n'; + yml += ' image: ' + containerInfo.image + '\n'; + yml += ' container_name: ' + containerInfo.name + '\n'; + + // Add ports + var ports = Object.keys(containerInfo.ports); + if (ports.length > 0) { + yml += ' ports:\n'; + for (var i = 0; i < ports.length; i++) { + var port = ports[i]; + if (containerInfo.ports[port]) { + yml += ' - "' + containerInfo.ports[port] + ':' + port + '"\n'; + } + } + } + + // Add volumes + var volumes = Object.keys(containerInfo.volumes); + if (volumes.length > 0) { + yml += ' volumes:\n'; + for (var i = 0; i < volumes.length; i++) { + var volume = volumes[i]; + if (containerInfo.volumes[volume]) { + yml += ' - ' + containerInfo.volumes[volume] + ':' + volume + '\n'; + } + } + } + + // Add environment variables + var envVars = Object.keys(containerInfo.environment); + if (envVars.length > 0) { + yml += ' environment:\n'; + for (var i = 0; i < envVars.length; i++) { + var envVar = envVars[i]; + yml += ' - ' + envVar + '=' + containerInfo.environment[envVar] + '\n'; + } + } + + // Add restart policy + yml += ' restart: unless-stopped\n'; + + return yml; + } + // Docker Compose Functions for runContainer $scope.generateDockerCompose = function() { // Get container information from form @@ -1434,101 +1482,6 @@ app.controller('viewContainer', function ($scope, $http, $interval, $timeout) { }); }; - // Helper function to generate Docker Compose YAML - function generateDockerComposeYml(containerInfo) { - var yml = 'version: \'3.8\'\n\n'; - yml += 'services:\n'; - yml += ' ' + containerInfo.name + ':\n'; - yml += ' image: ' + containerInfo.image + '\n'; - yml += ' container_name: ' + containerInfo.name + '\n'; - - // Add ports - var ports = Object.keys(containerInfo.ports); - if (ports.length > 0) { - yml += ' ports:\n'; - for (var i = 0; i < ports.length; i++) { - var port = ports[i]; - if (containerInfo.ports[port]) { - yml += ' - "' + containerInfo.ports[port] + ':' + port + '"\n'; - } - } - } - - // Add volumes - var volumes = Object.keys(containerInfo.volumes); - if (volumes.length > 0) { - yml += ' volumes:\n'; - for (var i = 0; i < volumes.length; i++) { - var volume = volumes[i]; - if (containerInfo.volumes[volume]) { - yml += ' - ' + containerInfo.volumes[volume] + ':' + volume + '\n'; - } - } - } - - // Add environment variables - var envVars = Object.keys(containerInfo.environment); - if (envVars.length > 0) { - yml += ' environment:\n'; - for (var i = 0; i < envVars.length; i++) { - var envVar = envVars[i]; - yml += ' - ' + envVar + '=' + containerInfo.environment[envVar] + '\n'; - } - } - - // Add restart policy - yml += ' restart: unless-stopped\n'; - - return yml; - } - - // Helper function to generate Docker Compose YAML (for runContainer) - function generateDockerComposeYml(containerInfo) { - var yml = 'version: \'3.8\'\n\n'; - yml += 'services:\n'; - yml += ' ' + containerInfo.name + ':\n'; - yml += ' image: ' + containerInfo.image + '\n'; - yml += ' container_name: ' + containerInfo.name + '\n'; - - // Add ports - var ports = Object.keys(containerInfo.ports); - if (ports.length > 0) { - yml += ' ports:\n'; - for (var i = 0; i < ports.length; i++) { - var port = ports[i]; - if (containerInfo.ports[port]) { - yml += ' - "' + containerInfo.ports[port] + ':' + port + '"\n'; - } - } - } - - // Add volumes - var volumes = Object.keys(containerInfo.volumes); - if (volumes.length > 0) { - yml += ' volumes:\n'; - for (var i = 0; i < volumes.length; i++) { - var volume = volumes[i]; - if (containerInfo.volumes[volume]) { - yml += ' - ' + containerInfo.volumes[volume] + ':' + volume + '\n'; - } - } - } - - // Add environment variables - var envVars = Object.keys(containerInfo.environment); - if (envVars.length > 0) { - yml += ' environment:\n'; - for (var i = 0; i < envVars.length; i++) { - var envVar = envVars[i]; - yml += ' - ' + envVar + '=' + containerInfo.environment[envVar] + '\n'; - } - } - - // Add restart policy - yml += ' restart: unless-stopped\n'; - - return yml; - } $scope.showTop = function () { $scope.topHead = []; diff --git a/faq.sh b/faq.sh index 3f44544e3..40f5dd8ec 100644 --- a/faq.sh +++ b/faq.sh @@ -28,7 +28,7 @@ ${BLUE}------------------------------------------------------------${NC} ${PURPLE}3.${NC} How to access LiteSpeed webadmin console ? -Please check this post: ${GREEN}https://forums.cyberpanel.net/discussion/87/tutorial-how-to-setup-and-login-to-openlitespeed-webadmin-console/p1${NC} +Please check this post: ${GREEN}https://community.cyberpanel.net/c/support/55${NC} ${BLUE}------------------------------------------------------------${NC} @@ -52,9 +52,9 @@ ${BLUE}------------------------------------------------------------${NC} ${PURPLE}6.${NC} How to raise upload limit for cyberpanel's phpMyAdmin and File Manager? -edit file ${RED}/usr/local/lsws/lsphp73/etc/php.ini${NC} for CentOS or openEuler +edit file ${RED}/usr/local/lsws/lsphp83/etc/php.ini${NC} for CentOS or openEuler -${RED}/usr/local/lsws/lsphp73/etc/php/7.3/litespeed/php.ini${NC} for Ubbuntu +${RED}/usr/local/lsws/lsphp83/etc/php/8.3/litespeed/php.ini${NC} for Ubuntu find 2 configurations: @@ -66,9 +66,9 @@ ${BLUE}------------------------------------------------------------${NC} ${PURPLE}7.${NC} How to add more IPs to my website(s) ? -For OpenLiteSpeed, please check this post: ${GREEN}https://forums.cyberpanel.net/discussion/126/tutorial-how-to-add-2nd-ip-for-websites/p1${NC} +For OpenLiteSpeed, please check this post: ${GREEN}https://community.cyberpanel.net/c/support/55${NC} -For LiteSpeed Enterprise, please check this post: ${GREEN}https://forums.cyberpanel.net/discussion/3745/tutorial-how-to-add-2nd-ip-for-litespeed-enterprise/p1${NC} +For LiteSpeed Enterprise, please check this post: ${GREEN}https://community.cyberpanel.net/c/support/55${NC} ${BLUE}------------------------------------------------------------${NC} @@ -80,7 +80,7 @@ ${BLUE}------------------------------------------------------------${NC} ${PURPLE}9.${NC} How to enable Auto-Index for my site ? -Please check this post ${GREEN}https://forums.cyberpanel.net/discussion/3850/tutorial-how-to-enable-auto-index-on-openlitespeed-and-litespeed-enterprise${NC} +Please check this post ${GREEN}https://community.cyberpanel.net/c/support/55${NC} ${BLUE}------------------------------------------------------------${NC} @@ -111,5 +111,5 @@ ${BLUE}------------------------------------------------------------${NC} ${PURPLE}13.${NC} How to enable PHP error log ? -Please check this post ${GREEN}https://forums.cyberpanel.net/discussion/3977/tutorial-how-to-enable-php-error-log/p1${NC} +Please check this post ${GREEN}https://community.cyberpanel.net/c/support/55${NC} " \ No newline at end of file diff --git a/firewall/firewallManager.py b/firewall/firewallManager.py index e9cf462de..5375343f8 100644 --- a/firewall/firewallManager.py +++ b/firewall/firewallManager.py @@ -60,6 +60,30 @@ class FirewallManager: rules = FirewallRules.objects.all() + # Ensure CyberPanel port 7080 rule exists in database for visibility + cyberpanel_rule_exists = False + for rule in rules: + if rule.port == '7080': + cyberpanel_rule_exists = True + break + + if not cyberpanel_rule_exists: + # Create database entry for port 7080 (already enabled in system firewall) + try: + cyberpanel_rule = FirewallRules( + name="CyberPanel Admin", + proto="tcp", + port="7080", + ipAddress="0.0.0.0/0" + ) + cyberpanel_rule.save() + logging.CyberCPLogFileWriter.writeToFile("Added CyberPanel port 7080 to firewall database for UI visibility") + except Exception as e: + logging.CyberCPLogFileWriter.writeToFile(f"Failed to add CyberPanel port 7080 to database: {str(e)}") + + # Refresh rules after potential creation + rules = FirewallRules.objects.all() + json_data = "[" checker = 0 @@ -96,7 +120,6 @@ class FirewallManager: else: return ACLManager.loadErrorJson('add_status', 0) - ruleName = data['ruleName'] ruleProtocol = data['ruleProtocol'] rulePort = data['rulePort'] @@ -126,7 +149,6 @@ class FirewallManager: else: return ACLManager.loadErrorJson('delete_status', 0) - ruleID = data['id'] ruleProtocol = data['proto'] rulePort = data['port'] diff --git a/guides/CUSTOM_CSS_GUIDE.md b/guides/CUSTOM_CSS_GUIDE.md new file mode 100644 index 000000000..cc5d6f969 --- /dev/null +++ b/guides/CUSTOM_CSS_GUIDE.md @@ -0,0 +1,829 @@ +# CyberPanel 2.5.5-dev Custom CSS Guide + +A comprehensive guide for creating custom CSS that fully works with the new design system of CyberPanel 2.5.5-dev. + +## Table of Contents + +1. [Overview](#overview) +2. [Design System Architecture](#design-system-architecture) +3. [CSS Variables Reference](#css-variables-reference) +4. [Component Structure](#component-structure) +5. [Customization Examples](#customization-examples) +6. [Best Practices](#best-practices) +7. [Troubleshooting](#troubleshooting) +8. [Advanced Techniques](#advanced-techniques) + +## Overview + +CyberPanel 2.5.5-dev features a modern, CSS-variable-based design system that supports both light and dark themes. The system is built with: + +- **CSS Custom Properties (Variables)** for consistent theming +- **Modern CSS Grid and Flexbox** layouts +- **Responsive design** principles +- **Dark mode support** with automatic theme switching +- **Component-based architecture** for easy customization + +## Design System Architecture + +### Core Structure + +The design system is built around CSS custom properties defined in `:root` and `[data-theme="dark"]` selectors: + +```css +:root { + /* Light Theme Variables */ + --bg-primary: #f0f0ff; + --bg-secondary: white; + --text-primary: #2f3640; + --accent-color: #5856d6; + /* ... more variables */ +} + +[data-theme="dark"] { + /* Dark Theme Variables */ + --bg-primary: #0f0f23; + --bg-secondary: #1a1a3e; + --text-primary: #e4e4e7; + --accent-color: #7c7ff3; + /* ... more variables */ +} +``` + +### Key Components + +1. **Header** (`#header`) - Top navigation bar +2. **Sidebar** (`#sidebar`) - Left navigation panel +3. **Main Content** (`#main-content`) - Page content area +4. **Cards** (`.content-card`) - Content containers +5. **Buttons** (`.btn`) - Interactive elements +6. **Forms** (`.form-*`) - Input elements + +## CSS Variables Reference + +### Color Variables + +#### Background Colors +```css +--bg-primary /* Main background color */ +--bg-secondary /* Card/container background */ +--bg-sidebar /* Sidebar background */ +--bg-sidebar-item /* Sidebar menu item background */ +--bg-hover /* Hover state background */ +``` + +#### Text Colors +```css +--text-primary /* Main text color */ +--text-secondary /* Secondary text color */ +--text-heading /* Heading text color */ +``` + +#### Accent Colors +```css +--accent-color /* Primary accent color */ +--accent-hover /* Accent hover state */ +--danger-color /* Error/danger color */ +--success-color /* Success color */ +``` + +#### Border & Shadow +```css +--border-color /* Default border color */ +--shadow-color /* Default shadow color */ +``` + +### Special Variables + +#### Gradients +```css +--warning-bg /* Warning banner gradient */ +--ai-banner-bg /* AI scanner banner gradient */ +``` + +#### Status Colors +```css +--success-bg /* Success background */ +--success-border /* Success border */ +--danger-bg /* Danger background */ +--danger-border /* Danger border */ +--warning-bg /* Warning background */ +--info-bg /* Info background */ +``` + +## Component Structure + +### Header Component + +```css +#header { + background: var(--bg-secondary); + height: 80px; + display: flex; + align-items: center; + padding: 0 30px; + box-shadow: 0 2px 12px var(--shadow-color); + position: fixed; + top: 0; + left: 260px; + right: 0; + z-index: 1000; +} +``` + +**Customization Example:** +```css +/* Change header height and add custom styling */ +#header { + height: 100px; + background: linear-gradient(135deg, var(--accent-color), var(--accent-hover)); + border-bottom: 3px solid var(--accent-color); +} + +#header .logo-text .brand { + font-size: 32px; + text-shadow: 0 2px 4px rgba(0,0,0,0.1); +} +``` + +### Sidebar Component + +```css +#sidebar { + width: 260px; + background: var(--bg-sidebar); + height: 100vh; + position: fixed; + left: 0; + top: 0; + overflow-y: auto; + z-index: 1001; +} +``` + +**Customization Example:** +```css +/* Make sidebar wider with custom styling */ +#sidebar { + width: 300px; + background: linear-gradient(180deg, var(--bg-sidebar), var(--bg-secondary)); + border-right: 2px solid var(--accent-color); +} + +#sidebar .menu-item { + margin: 4px 20px; + border-radius: 12px; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); +} + +#sidebar .menu-item:hover { + transform: translateX(5px); + box-shadow: 0 4px 12px var(--shadow-color); +} +``` + +### Content Cards + +```css +.content-card { + background: var(--bg-secondary); + border-radius: 12px; + padding: 30px; + box-shadow: 0 2px 8px var(--shadow-color); + border: 1px solid var(--border-color); + margin-bottom: 25px; +} +``` + +**Customization Example:** +```css +/* Add glassmorphism effect to cards */ +.content-card { + background: rgba(255, 255, 255, 0.1); + backdrop-filter: blur(10px); + border: 1px solid rgba(255, 255, 255, 0.2); + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1); +} + +[data-theme="dark"] .content-card { + background: rgba(26, 26, 62, 0.3); + border: 1px solid rgba(255, 255, 255, 0.1); +} +``` + +## Customization Examples + +### 1. Complete Theme Override + +```css +/* Custom Purple Theme */ +:root { + --bg-primary: #f8f4ff; + --bg-secondary: #ffffff; + --bg-sidebar: #f3f0ff; + --bg-hover: #e8e0ff; + --text-primary: #2d1b69; + --text-secondary: #6b46c1; + --accent-color: #8b5cf6; + --accent-hover: #7c3aed; + --border-color: #e0d7ff; + --shadow-color: rgba(139, 92, 246, 0.1); +} + +[data-theme="dark"] { + --bg-primary: #1a0b2e; + --bg-secondary: #2d1b69; + --bg-sidebar: #1e0a3e; + --bg-hover: #3d2a7a; + --text-primary: #f3f0ff; + --text-secondary: #c4b5fd; + --accent-color: #a78bfa; + --accent-hover: #8b5cf6; + --border-color: #4c1d95; + --shadow-color: rgba(139, 92, 246, 0.3); +} +``` + +### 2. Custom Button Styles + +```css +/* Custom button variants */ +.btn-custom { + background: linear-gradient(135deg, var(--accent-color), var(--accent-hover)); + border: none; + border-radius: 20px; + padding: 12px 24px; + color: white; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.5px; + box-shadow: 0 4px 15px rgba(139, 92, 246, 0.3); + transition: all 0.3s ease; +} + +.btn-custom:hover { + transform: translateY(-2px); + box-shadow: 0 6px 20px rgba(139, 92, 246, 0.4); +} + +.btn-custom:active { + transform: translateY(0); +} +``` + +### 3. Custom Sidebar Menu Items + +```css +/* Animated sidebar menu items */ +#sidebar .menu-item { + position: relative; + overflow: hidden; +} + +#sidebar .menu-item::before { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent); + transition: left 0.5s; +} + +#sidebar .menu-item:hover::before { + left: 100%; +} + +#sidebar .menu-item .icon-wrapper { + position: relative; + z-index: 1; +} +``` + +### 4. Custom Form Styling + +```css +/* Modern form inputs */ +.form-control { + border: 2px solid var(--border-color); + border-radius: 12px; + padding: 12px 16px; + font-size: 14px; + transition: all 0.3s ease; + background: var(--bg-secondary); +} + +.form-control:focus { + border-color: var(--accent-color); + box-shadow: 0 0 0 4px rgba(139, 92, 246, 0.1); + transform: translateY(-1px); +} + +.form-control::placeholder { + color: var(--text-secondary); + opacity: 0.7; +} +``` + +### 5. Custom Notifications + +```css +/* Custom notification banners */ +.notification-banner { + background: linear-gradient(135deg, var(--accent-color), var(--accent-hover)); + border-radius: 16px; + padding: 20px; + margin: 20px; + box-shadow: 0 8px 32px rgba(139, 92, 246, 0.3); + position: relative; + overflow: hidden; +} + +.notification-banner::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 4px; + background: linear-gradient(90deg, #ff6b6b, #4ecdc4, #45b7d1, #96ceb4); + animation: rainbow 3s linear infinite; +} + +@keyframes rainbow { + 0% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } + 100% { background-position: 0% 50%; } +} +``` + +## Best Practices + +### 1. Use CSS Variables + +Always use CSS variables instead of hardcoded values: + +```css +/* ✅ Good */ +.custom-element { + background: var(--bg-secondary); + color: var(--text-primary); + border: 1px solid var(--border-color); +} + +/* ❌ Bad */ +.custom-element { + background: white; + color: #2f3640; + border: 1px solid #e8e9ff; +} +``` + +### 2. Support Both Themes + +Always provide both light and dark theme support: + +```css +.custom-element { + background: var(--bg-secondary); + color: var(--text-primary); +} + +/* Dark theme specific adjustments */ +[data-theme="dark"] .custom-element { + /* Additional dark theme styling if needed */ +} +``` + +### 3. Use Semantic Class Names + +```css +/* ✅ Good */ +.primary-button { } +.content-container { } +.navigation-item { } + +/* ❌ Bad */ +.red-button { } +.big-box { } +.item1 { } +``` + +### 4. Maintain Responsive Design + +```css +.custom-element { + padding: 20px; + font-size: 16px; +} + +@media (max-width: 768px) { + .custom-element { + padding: 15px; + font-size: 14px; + } +} +``` + +### 5. Use Modern CSS Features + +```css +.custom-element { + /* Use CSS Grid for layouts */ + display: grid; + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + gap: 20px; + + /* Use Flexbox for alignment */ + align-items: center; + justify-content: space-between; + + /* Use CSS custom properties for calculations */ + --element-height: 60px; + height: var(--element-height); + + /* Use modern selectors */ + &:hover { } + &:focus-within { } +} +``` + +## Troubleshooting + +### Common Issues + +#### 1. Custom CSS Not Applying + +**Problem:** Custom CSS doesn't appear to be working. + +**Solution:** +- Check CSS specificity - use more specific selectors +- Ensure CSS is placed after the base styles +- Use `!important` sparingly and only when necessary + +```css +/* Increase specificity */ +#main-content .content-card .custom-element { + background: var(--bg-secondary); +} +``` + +#### 2. Dark Mode Not Working + +**Problem:** Custom styles don't adapt to dark mode. + +**Solution:** +- Always use CSS variables +- Test both light and dark themes +- Provide dark mode specific overrides when needed + +```css +.custom-element { + background: var(--bg-secondary); + color: var(--text-primary); +} + +[data-theme="dark"] .custom-element { + /* Dark mode specific adjustments */ + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); +} +``` + +#### 3. Responsive Issues + +**Problem:** Custom styles break on mobile devices. + +**Solution:** +- Use relative units (rem, em, %) +- Test on different screen sizes +- Use CSS Grid and Flexbox for responsive layouts + +```css +.custom-element { + width: 100%; + max-width: 1200px; + margin: 0 auto; + padding: 1rem; +} + +@media (max-width: 768px) { + .custom-element { + padding: 0.5rem; + } +} +``` + +## Advanced Techniques + +### 1. CSS Animations + +```css +/* Smooth page transitions */ +.page-transition { + animation: fadeIn 0.3s ease-in-out; +} + +@keyframes fadeIn { + from { opacity: 0; transform: translateY(20px); } + to { opacity: 1; transform: translateY(0); } +} + +/* Hover animations */ +.interactive-element { + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); +} + +.interactive-element:hover { + transform: translateY(-2px) scale(1.02); + box-shadow: 0 8px 25px var(--shadow-color); +} +``` + +### 2. CSS Grid Layouts + +```css +/* Advanced grid layouts */ +.dashboard-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: 20px; + padding: 20px; +} + +.dashboard-card { + grid-column: span 1; + background: var(--bg-secondary); + border-radius: 12px; + padding: 20px; + box-shadow: 0 2px 8px var(--shadow-color); +} + +.dashboard-card.featured { + grid-column: span 2; +} + +@media (max-width: 768px) { + .dashboard-card.featured { + grid-column: span 1; + } +} +``` + +### 3. CSS Custom Properties with JavaScript + +```css +/* Dynamic theming with CSS variables */ +:root { + --custom-accent: #5856d6; + --custom-accent-hover: #4644c0; +} + +.custom-theme { + --accent-color: var(--custom-accent); + --accent-hover: var(--custom-accent-hover); +} +``` + +### 4. Advanced Selectors + +```css +/* Complex selectors for specific styling */ +#sidebar .menu-item:not(.active):hover { + background: var(--bg-hover); + transform: translateX(5px); +} + +.content-card > *:first-child { + margin-top: 0; +} + +.content-card > *:last-child { + margin-bottom: 0; +} + +/* Attribute selectors */ +[data-status="success"] { + border-left: 4px solid var(--success-color); +} + +[data-status="error"] { + border-left: 4px solid var(--danger-color); +} +``` + +### 5. CSS Functions and Calculations + +```css +/* Using CSS functions */ +.responsive-text { + font-size: clamp(14px, 2.5vw, 18px); + line-height: calc(1.5em + 0.5vw); +} + +.dynamic-spacing { + padding: calc(1rem + 2vw); + margin: calc(0.5rem + 1vw); +} + +/* CSS custom properties with calculations */ +:root { + --base-size: 16px; + --scale-factor: 1.2; + --large-size: calc(var(--base-size) * var(--scale-factor)); +} +``` + +## Implementation Guide + +### Step 1: Access the Design Page + +1. Log into CyberPanel +2. Navigate to **Design** in the sidebar +3. Scroll down to the **Custom CSS** section + +### Step 2: Add Your Custom CSS + +1. Paste your custom CSS into the textarea +2. Click **Save Changes** +3. Refresh the page to see your changes + +### Step 3: Test Your Changes + +1. Test in both light and dark modes +2. Test on different screen sizes +3. Verify all interactive elements work correctly + +### Step 4: Iterate and Refine + +1. Make adjustments as needed +2. Test thoroughly before finalizing +3. Document your customizations + +## Example: Complete Custom Theme + +Here's a complete example of a custom theme that you can use as a starting point: + +```css +/* Custom CyberPanel Theme - Ocean Blue */ + +/* Light Theme */ +:root { + --bg-primary: #f0f9ff; + --bg-secondary: #ffffff; + --bg-sidebar: #e0f2fe; + --bg-sidebar-item: #ffffff; + --bg-hover: #bae6fd; + --text-primary: #0c4a6e; + --text-secondary: #0369a1; + --text-heading: #0c4a6e; + --border-color: #bae6fd; + --shadow-color: rgba(6, 105, 161, 0.1); + --accent-color: #0284c7; + --accent-hover: #0369a1; + --danger-color: #dc2626; + --success-color: #059669; + --warning-bg: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%); + --ai-banner-bg: linear-gradient(135deg, #0284c7 0%, #0369a1 50%, #0c4a6e 100%); +} + +/* Dark Theme */ +[data-theme="dark"] { + --bg-primary: #0c4a6e; + --bg-secondary: #075985; + --bg-sidebar: #0c4a6e; + --bg-sidebar-item: #075985; + --bg-hover: #0369a1; + --text-primary: #e0f2fe; + --text-secondary: #bae6fd; + --text-heading: #f0f9ff; + --border-color: #0369a1; + --shadow-color: rgba(0, 0, 0, 0.3); + --accent-color: #38bdf8; + --accent-hover: #0ea5e9; + --danger-color: #f87171; + --success-color: #34d399; + --warning-bg: linear-gradient(135deg, #78350f 0%, #92400e 100%); + --ai-banner-bg: linear-gradient(135deg, #0c4a6e 0%, #075985 50%, #0369a1 100%); +} + +/* Custom Header Styling */ +#header { + background: linear-gradient(135deg, var(--accent-color), var(--accent-hover)); + box-shadow: 0 4px 20px var(--shadow-color); +} + +#header .logo-text .brand { + color: white; + text-shadow: 0 2px 4px rgba(0,0,0,0.1); +} + +/* Custom Sidebar Styling */ +#sidebar { + background: linear-gradient(180deg, var(--bg-sidebar), var(--bg-secondary)); + border-right: 3px solid var(--accent-color); +} + +#sidebar .menu-item { + border-radius: 12px; + margin: 4px 20px; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); +} + +#sidebar .menu-item:hover { + transform: translateX(8px); + box-shadow: 0 4px 15px var(--shadow-color); +} + +#sidebar .menu-item.active { + background: linear-gradient(135deg, var(--accent-color), var(--accent-hover)); + box-shadow: 0 4px 15px rgba(2, 132, 199, 0.3); +} + +/* Custom Content Cards */ +.content-card { + background: var(--bg-secondary); + border-radius: 16px; + box-shadow: 0 4px 20px var(--shadow-color); + border: 1px solid var(--border-color); + position: relative; + overflow: hidden; +} + +.content-card::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 4px; + background: linear-gradient(90deg, var(--accent-color), var(--accent-hover)); +} + +/* Custom Buttons */ +.btn { + border-radius: 12px; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.5px; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); +} + +.btn-primary { + background: linear-gradient(135deg, var(--accent-color), var(--accent-hover)); + box-shadow: 0 4px 15px rgba(2, 132, 199, 0.3); +} + +.btn-primary:hover { + transform: translateY(-2px); + box-shadow: 0 6px 20px rgba(2, 132, 199, 0.4); +} + +/* Custom Form Elements */ +.form-control { + border: 2px solid var(--border-color); + border-radius: 12px; + transition: all 0.3s ease; +} + +.form-control:focus { + border-color: var(--accent-color); + box-shadow: 0 0 0 4px rgba(2, 132, 199, 0.1); + transform: translateY(-1px); +} + +/* Custom Animations */ +@keyframes slideIn { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.content-card { + animation: slideIn 0.5s ease-out; +} + +/* Responsive Design */ +@media (max-width: 768px) { + #sidebar { + width: 100%; + height: auto; + position: relative; + } + + #header { + left: 0; + } + + .content-card { + margin: 10px; + padding: 20px; + } +} +``` + +This guide provides everything you need to create beautiful, functional custom CSS for CyberPanel 2.5.5+. Remember to always test your changes thoroughly and use the CSS variables for consistency across themes. diff --git a/guides/DEBIAN_13_INSTALLATION_GUIDE.md b/guides/DEBIAN_13_INSTALLATION_GUIDE.md new file mode 100644 index 000000000..f714ac6ff --- /dev/null +++ b/guides/DEBIAN_13_INSTALLATION_GUIDE.md @@ -0,0 +1,327 @@ +# Debian 13 Installation Guide for CyberPanel + +## 🎯 Overview + +This guide provides step-by-step instructions for installing CyberPanel on Debian 13 (Bookworm). Debian 13 support has been added to CyberPanel with full compatibility for package management, service configuration, and web server setup. + +## 📋 Prerequisites + +### System Requirements +- **OS**: Debian 13 (Bookworm) x86_64 +- **RAM**: Minimum 1GB (2GB+ recommended) +- **Storage**: Minimum 10GB free space (20GB+ recommended) +- **CPU**: 2+ cores recommended +- **Network**: Internet connection required + +### Supported Debian Versions +- ✅ **Debian 13** (Bookworm) - Full Support +- ✅ **Debian 12** (Bookworm) - Full Support +- ✅ **Debian 11** (Bullseye) - Full Support + +## 🚀 Installation Steps + +### Step 1: Update System + +```bash +# Update package lists +sudo apt update + +# Upgrade system packages +sudo apt upgrade -y + +# Install essential packages +sudo apt install -y curl wget git +``` + +### Step 2: Download and Run CyberPanel Installer + +```bash +# Download the latest CyberPanel installer +wget https://cyberpanel.sh/install.sh + +# Make the installer executable +chmod +x install.sh + +# Run the installer +sudo ./install.sh +``` + +### Step 3: Follow Installation Prompts + +The installer will guide you through: + +1. **License Agreement**: Accept the terms +2. **Installation Type**: Choose between: + - OpenLiteSpeed (Free) + - LiteSpeed Enterprise (Requires license) +3. **MySQL Configuration**: + - Single MySQL instance (recommended) + - Double MySQL instance (for high availability) +4. **Additional Services**: + - Postfix/Dovecot (Email server) + - PowerDNS (DNS server) + - PureFTPD (FTP server) + +### Step 4: Verify Installation + +```bash +# Check CyberPanel service status +sudo systemctl status lscpd + +# Check web server status +sudo systemctl status apache2 + +# Check if CyberPanel is accessible +curl -I http://localhost:8090 +``` + +## 🔧 Post-Installation Configuration + +### Access CyberPanel + +1. Open your web browser +2. Navigate to: `http://your-server-ip:8090` +3. Default login credentials: + - **Username**: `admin` + - **Password**: `123456` (change immediately!) + +### Change Default Password + +```bash +# Login to CyberPanel CLI +sudo cyberpanel + +# Change admin password +cyberpanel --change-password admin +``` + +### Configure Firewall + +```bash +# Allow CyberPanel ports +sudo ufw allow 8090/tcp +sudo ufw allow 80/tcp +sudo ufw allow 443/tcp +sudo ufw allow 21/tcp +sudo ufw allow 25/tcp +sudo ufw allow 53/tcp +sudo ufw allow 587/tcp +sudo ufw allow 993/tcp +sudo ufw allow 995/tcp + +# Enable firewall +sudo ufw enable +``` + +## 🐛 Troubleshooting + +### Common Issues + +#### 1. OS Detection Failed +**Problem**: Installer doesn't recognize Debian 13 +**Solution**: Ensure you're running the latest installer version + +```bash +# Download latest installer +wget https://cyberpanel.sh/install.sh +chmod +x install.sh +sudo ./install.sh +``` + +#### 2. Package Installation Failed +**Problem**: apt-get errors during installation +**Solution**: Update repositories and retry + +```bash +# Update package lists +sudo apt update + +# Fix broken packages +sudo apt --fix-broken install + +# Retry installation +sudo ./install.sh +``` + +#### 3. Service Won't Start +**Problem**: CyberPanel service fails to start +**Solution**: Check logs and restart services + +```bash +# Check service status +sudo systemctl status lscpd + +# Check logs +sudo journalctl -u lscpd -f + +# Restart service +sudo systemctl restart lscpd +``` + +#### 4. Web Server Issues +**Problem**: Apache2 configuration problems +**Solution**: Reconfigure web server + +```bash +# Check Apache2 status +sudo systemctl status apache2 + +# Test configuration +sudo apache2ctl configtest + +# Restart Apache2 +sudo systemctl restart apache2 +``` + +### Log Files + +Important log locations: +- **CyberPanel**: `/usr/local/CyberCP/logs/` +- **Apache2**: `/var/log/apache2/` +- **System**: `/var/log/syslog` +- **Installation**: `/root/cyberpanel-install.log` + +## 🔒 Security Considerations + +### Initial Security Setup + +1. **Change Default Password** + ```bash + sudo cyberpanel --change-password admin + ``` + +2. **Update System** + ```bash + sudo apt update && sudo apt upgrade -y + ``` + +3. **Configure Firewall** + ```bash + sudo ufw enable + sudo ufw default deny incoming + sudo ufw default allow outgoing + ``` + +4. **Enable Fail2Ban** + ```bash + sudo apt install fail2ban -y + sudo systemctl enable fail2ban + sudo systemctl start fail2ban + ``` + +### SSL Certificate Setup + +1. **Access CyberPanel Web Interface** +2. **Navigate to**: SSL → Let's Encrypt +3. **Enter your domain name** +4. **Click "Issue" to get free SSL certificate** + +## 📊 Performance Optimization + +### System Optimization + +```bash +# Optimize Apache2 for Debian +sudo nano /etc/apache2/apache2.conf + +# Add these lines: +ServerTokens Prod +ServerSignature Off +KeepAlive On +MaxKeepAliveRequests 100 +KeepAliveTimeout 5 +``` + +### PHP Optimization + +1. **Access CyberPanel Web Interface** +2. **Navigate to**: PHP → PHP Settings +3. **Configure**: + - Memory limit: 256M + - Max execution time: 300 + - Upload max filesize: 64M + +## 🔄 Updates and Maintenance + +### Update CyberPanel + +```bash +# Update to latest version +sudo cyberpanel --update + +# Or use the upgrade script +sudo ./cyberpanel_upgrade.sh +``` + +### System Maintenance + +```bash +# Update system packages +sudo apt update && sudo apt upgrade -y + +# Clean package cache +sudo apt autoremove -y +sudo apt autoclean + +# Check disk usage +df -h + +# Check memory usage +free -h +``` + +## 📚 Additional Resources + +### Documentation +- [CyberPanel Official Docs](https://cyberpanel.net/docs/) +- [Debian 13 Release Notes](https://www.debian.org/releases/bookworm/releasenotes) +- [Apache2 Configuration Guide](https://httpd.apache.org/docs/2.4/) + +### Community Support +- [CyberPanel Community Forum](https://forums.cyberpanel.net/) +- [GitHub Issues](https://github.com/usmannasir/cyberpanel/issues) +- [Discord Server](https://discord.gg/cyberpanel) + +### Testing Compatibility + +Run the compatibility test script: + +```bash +# Download test script +wget https://raw.githubusercontent.com/cyberpanel/cyberpanel/main/test_debian13_support.sh + +# Make executable +chmod +x test_debian13_support.sh + +# Run test +sudo ./test_debian13_support.sh +``` + +## ✅ Verification Checklist + +After installation, verify these components: + +- [ ] CyberPanel web interface accessible +- [ ] Admin password changed +- [ ] SSL certificate installed +- [ ] Firewall configured +- [ ] Email server working (if installed) +- [ ] DNS server working (if installed) +- [ ] FTP server working (if installed) +- [ ] System updates applied +- [ ] Logs are clean +- [ ] Services are running + +## 🆘 Getting Help + +If you encounter issues: + +1. **Check the logs** (see Troubleshooting section) +2. **Run the compatibility test** +3. **Search the documentation** +4. **Ask in the community forum** +5. **Create a GitHub issue** with detailed information + +--- + +**Note**: This guide is specifically for Debian 13. For other operating systems, refer to the main CyberPanel documentation. diff --git a/guides/INDEX.md b/guides/INDEX.md index 6df7c3900..f42331e6a 100644 --- a/guides/INDEX.md +++ b/guides/INDEX.md @@ -14,6 +14,12 @@ Welcome to the CyberPanel documentation hub! This folder contains all guides, tu ### 📧 Email & Marketing - **[Mautic Installation Guide](MAUTIC_INSTALLATION_GUIDE.md)** - Step-by-step guide for installing and configuring Mautic email marketing platform +### 🐧 Operating System Support +- **[Debian 13 Installation Guide](DEBIAN_13_INSTALLATION_GUIDE.md)** - Complete installation and configuration guide for CyberPanel on Debian 13 (Bookworm) + +### 🎨 Customization & Design +- **[Custom CSS Guide](CUSTOM_CSS_GUIDE.md)** - Complete guide for creating custom CSS that works with CyberPanel 2.5.5-dev design system + ### 📖 General Documentation - **[README](../README.md)** - Main CyberPanel documentation with installation instructions and feature overview - **[Contributing Guide](CONTRIBUTING.md)** - Guidelines for contributing to the CyberPanel project @@ -21,16 +27,20 @@ Welcome to the CyberPanel documentation hub! This folder contains all guides, tu ## 🚀 Quick Start 1. **New to CyberPanel?** Start with the [README](../README.md) for installation and basic setup -2. **Need Docker help?** Check the [Docker Command Execution Guide](Docker_Command_Execution_Guide.md) -3. **Setting up email marketing?** Follow the [Mautic Installation Guide](MAUTIC_INSTALLATION_GUIDE.md) -4. **Want to contribute?** Read the [Contributing Guide](CONTRIBUTING.md) +2. **Installing on Debian 13?** Follow the [Debian 13 Installation Guide](DEBIAN_13_INSTALLATION_GUIDE.md) +3. **Need Docker help?** Check the [Docker Command Execution Guide](Docker_Command_Execution_Guide.md) +4. **Setting up email marketing?** Follow the [Mautic Installation Guide](MAUTIC_INSTALLATION_GUIDE.md) +5. **Want to customize the interface?** Check the [Custom CSS Guide](CUSTOM_CSS_GUIDE.md) +6. **Want to contribute?** Read the [Contributing Guide](CONTRIBUTING.md) ## 🔍 Finding What You Need - **Installation & Setup**: [README](../README.md) +- **Debian 13 Installation**: [Debian 13 Installation Guide](DEBIAN_13_INSTALLATION_GUIDE.md) - **Docker Features**: [Docker Command Execution Guide](Docker_Command_Execution_Guide.md) - **Security Features**: [AI Scanner Documentation](AIScannerDocs.md) - **Email Marketing**: [Mautic Installation Guide](MAUTIC_INSTALLATION_GUIDE.md) +- **Customization & Design**: [Custom CSS Guide](CUSTOM_CSS_GUIDE.md) - **Development**: [Contributing Guide](CONTRIBUTING.md) ## 📝 Guide Categories @@ -45,6 +55,11 @@ Welcome to the CyberPanel documentation hub! This folder contains all guides, tu - Third-party applications - Custom configurations +### 🎨 **Customization** +- Custom CSS theming +- Design system integration +- Interface personalization + ### 📖 **Documentation** - Installation guides - Configuration tutorials diff --git a/install/filesPermsUtilities.py.bak b/install/filesPermsUtilities.py.bak deleted file mode 100644 index 07261326b..000000000 --- a/install/filesPermsUtilities.py.bak +++ /dev/null @@ -1,190 +0,0 @@ -import os -import shutil -import pathlib -import stat - - -def mkdir_p(path, exist_ok=True): - """ - Creates the directory and paths leading up to it like unix mkdir -p . - Defaults to exist_ok so if it exists were not throwing fatal errors - https://docs.python.org/3.7/library/os.html#os.makedirs - """ - if not os.path.exists(path): - print('creating directory: ' + path) - os.makedirs(path, exist_ok) - - -def chmod_digit(file_path, perms): - """ - Helper function to chmod like you would in unix without having to preface 0o or converting to octal yourself. - Credits: https://stackoverflow.com/a/60052847/1621381 - """ - try: - os.chmod(file_path, int(str(perms), base=8)) - except: - print(f'Could not chmod : {file_path} to {perms}') - pass - - -def touch(filepath: str, exist_ok=True): - """ - Touches a file like unix `touch somefile` would. - """ - try: - pathlib.Path(filepath).touch(exist_ok) - except FileExistsError: - print('Could touch : ' + filepath) - pass - - -def symlink(src, dst): - """ - Symlink a path to another if the src exists. - """ - try: - if os.access(src, os.R_OK): - os.symlink(src, dst) - except: - print(f'Could not symlink Source: {src} > Destination: {dst}') - pass - - -def chown(path, user, group=-1): - """ - Chown file/path to user/group provided. Passing -1 to user or group will leave it unchanged. - Useful if just changing user or group vs both. - """ - try: - shutil.chown(path, user, group) - except PermissionError: - print(f'Could not change permissions for: {path} to {user}:{group}') - pass - - -def recursive_chown(path, owner, group=-1): - """ - Recursively chown a path and contents to owner. - https://docs.python.org/3/library/shutil.html - """ - for dirpath, dirnames, filenames in os.walk(path): - try: - shutil.chown(dirpath, owner, group) - except PermissionError: - print('Could not change permissions for: ' + dirpath + ' to: ' + owner) - pass - for filename in filenames: - try: - shutil.chown(os.path.join(dirpath, filename), owner, group) - except PermissionError: - print('Could not change permissions for: ' + os.path.join(dirpath, filename) + ' to: ' + owner) - pass - - -def recursive_permissions(path, dir_mode=755, file_mode=644, topdir=True): - """ - Recursively chmod a path and contents to mode. - Defaults to chmod top level directory but can be optionally - toggled off when you want to chmod only contents of like a user's homedir vs homedir itself - https://docs.python.org/3.6/library/os.html#os.walk - """ - - # Here we are converting the integers to string and then to octal. - # so this function doesn't need to be called with 0o prefixed for the file and dir mode - dir_mode = int(str(dir_mode), base=8) - file_mode = int(str(file_mode), base=8) - - if topdir: - # Set chmod on top level path - try: - os.chmod(path, dir_mode) - except: - print('Could not chmod :' + path + ' to ' + str(dir_mode)) - for root, dirs, files in os.walk(path): - for d in dirs: - try: - os.chmod(os.path.join(root, d), dir_mode) - except: - print('Could not chmod :' + os.path.join(root, d) + ' to ' + str(dir_mode)) - pass - for f in files: - try: - os.chmod(os.path.join(root, f), file_mode) - except: - print('Could not chmod :' + path + ' to ' + str(file_mode)) - pass - - -# Left intentionally here for reference. -# Set recursive chown for a path -# recursive_chown(my_path, 'root', 'root') -# for changing group recursively without affecting user -# recursive_chown('/usr/local/lscp/cyberpanel/rainloop/data', -1, 'lscpd') - -# explicitly set permissions for directories/folders to 0755 and files to 0644 -# recursive_permissions(my_path, 755, 644) - -# Fix permissions and use default values -# recursive_permissions(my_path) -# ========================================================= -# Below is a helper class for getting and working with permissions -# Original credits to : https://github.com/keysemble/perfm - -def perm_octal_digit(rwx): - digit = 0 - if rwx[0] == 'r': - digit += 4 - if rwx[1] == 'w': - digit += 2 - if rwx[2] == 'x': - digit += 1 - return digit - - -class FilePerm: - def __init__(self, filepath): - filemode = stat.filemode(os.stat(filepath).st_mode) - permissions = [filemode[-9:][i:i + 3] for i in range(0, len(filemode[-9:]), 3)] - self.filepath = filepath - self.access_dict = dict(zip(['user', 'group', 'other'], [list(perm) for perm in permissions])) - - def mode(self): - mode = 0 - for shift, digit in enumerate(self.octal()[::-1]): - mode += digit << (shift * 3) - return mode - - def digits(self): - """Get the octal chmod equivalent value 755 in single string""" - return "".join(map(str, self.octal())) - - def octal(self): - """Get the octal value in a list [7, 5, 5]""" - return [perm_octal_digit(p) for p in self.access_dict.values()] - - def access_bits(self, access): - if access in self.access_dict.keys(): - r, w, x = self.access_dict[access] - return [r == 'r', w == 'w', x == 'x'] - - def update_bitwise(self, settings): - def perm_list(read=False, write=False, execute=False): - pl = ['-', '-', '-'] - if read: - pl[0] = 'r' - if write: - pl[1] = 'w' - if execute: - pl[2] = 'x' - return pl - - self.access_dict = dict( - [(access, perm_list(read=r, write=w, execute=x)) for access, [r, w, x] in settings.items()]) - os.chmod(self.filepath, self.mode()) - -# project_directory = os.path.abspath(os.path.dirname(sys.argv[0])) -# home_directory = os.path.expanduser('~') -# print(f'Path: {home_directory} Mode: {FilePerm(home_directory).mode()} Octal: {FilePerm(home_directory).octal()} ' -# f'Digits: {FilePerm(home_directory).digits()}') -# Example: Output -# Path: /home/cooluser Mode: 493 Octal: [7, 5, 5] Digits: 755 diff --git a/install/install.py b/install/install.py index 31267817b..b5c290b1c 100644 --- a/install/install.py +++ b/install/install.py @@ -2969,7 +2969,7 @@ echo $oConfig->Save() ? 'Done' : 'Error'; writeToFile.write(content) writeToFile.close() - command = '/usr/local/lsws/lsphp72/bin/php /usr/local/CyberCP/public/snappymail.php' + command = '/usr/local/lsws/lsphp83/bin/php /usr/local/CyberCP/public/snappymail.php' subprocess.call(shlex.split(command)) command = "chown -R lscpd:lscpd /usr/local/lscp/cyberpanel/snappymail/data" diff --git a/install/install.py.bak b/install/install.py.bak deleted file mode 100644 index 48dea0ae4..000000000 --- a/install/install.py.bak +++ /dev/null @@ -1,2383 +0,0 @@ -import sys -import subprocess -import shutil -import installLog as logging -import argparse -import os -import shlex -from firewallUtilities import FirewallUtilities -import time -import string -import random -import socket -from os.path import * -from stat import * -import stat - -VERSION = '2.3' -BUILD = 1 - -char_set = {'small': 'abcdefghijklmnopqrstuvwxyz', 'nums': '0123456789', 'big': 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'} - - -def generate_pass(length=14): - chars = string.ascii_uppercase + string.ascii_lowercase + string.digits - size = length - return ''.join(random.choice(chars) for x in range(size)) - - -# There can not be peace without first a great suffering. - -# distros - -centos = 0 -ubuntu = 1 -cent8 = 2 - - -def get_distro(): - distro = -1 - distro_file = "" - if exists("/etc/lsb-release"): - distro_file = "/etc/lsb-release" - with open(distro_file) as f: - for line in f: - if line == "DISTRIB_ID=Ubuntu\n": - distro = ubuntu - - elif exists("/etc/os-release"): - distro_file = "/etc/os-release" - distro = centos - - data = open('/etc/redhat-release', 'r').read() - - if data.find('CentOS Linux release 8') > -1: - return cent8 - if data.find('AlmaLinux release 8') > -1: - return cent8 - if data.find('Rocky Linux release 8') > -1 or data.find('Rocky Linux 8') > -1 or data.find('rocky:8') > -1: - return cent8 - - else: - logging.InstallLog.writeToFile("Can't find linux release file - fatal error") - preFlightsChecks.stdOut("Can't find linux release file - fatal error") - os._exit(os.EX_UNAVAILABLE) - - if distro == -1: - logging.InstallLog.writeToFile("Can't find distro name in " + distro_file + " - fatal error") - preFlightsChecks.stdOut("Can't find distro name in " + distro_file + " - fatal error") - os._exit(os.EX_UNAVAILABLE) - - return distro - - -def get_Ubuntu_release(): - release = -1 - if exists("/etc/lsb-release"): - distro_file = "/etc/lsb-release" - with open(distro_file) as f: - for line in f: - if line[:16] == "DISTRIB_RELEASE=": - release = float(line[16:]) - - if release == -1: - preFlightsChecks.stdOut("Can't find distro release name in " + distro_file + " - fatal error", 1, 1, - os.EX_UNAVAILABLE) - - else: - logging.InstallLog.writeToFile("Can't find linux release file - fatal error") - preFlightsChecks.stdOut("Can't find linux release file - fatal error") - os._exit(os.EX_UNAVAILABLE) - - return release - - -class preFlightsChecks: - debug = 1 - cyberPanelMirror = "mirror.cyberpanel.net/pip" - cdn = 'cyberpanel.sh' - - def __init__(self, rootPath, ip, path, cwd, cyberPanelPath, distro, remotemysql=None, mysqlhost=None, mysqldb=None, - mysqluser=None, mysqlpassword=None, mysqlport=None): - self.ipAddr = ip - self.path = path - self.cwd = cwd - self.server_root_path = rootPath - self.cyberPanelPath = cyberPanelPath - self.distro = distro - self.remotemysql = remotemysql - self.mysqlhost = mysqlhost - self.mysqluser = mysqluser - self.mysqlpassword = mysqlpassword - self.mysqlport = mysqlport - self.mysqldb = mysqldb - - @staticmethod - def stdOut(message, log=0, do_exit=0, code=os.EX_OK): - print("\n\n") - print(("[" + time.strftime( - "%m.%d.%Y_%H-%M-%S") + "] #########################################################################\n")) - print(("[" + time.strftime("%m.%d.%Y_%H-%M-%S") + "] " + message + "\n")) - print(("[" + time.strftime( - "%m.%d.%Y_%H-%M-%S") + "] #########################################################################\n")) - - if log: - logging.InstallLog.writeToFile(message) - if do_exit: - logging.InstallLog.writeToFile(message) - sys.exit(code) - - def mountTemp(self): - try: - ## On OpenVZ there is an issue using .tempdisk for /tmp as it breaks network on container after reboot. - - if subprocess.check_output('systemd-detect-virt').decode("utf-8").find("openvz") > -1: - - varTmp = "/var/tmp /tmp none bind 0 0\n" - - fstab = "/etc/fstab" - writeToFile = open(fstab, "a") - writeToFile.writelines(varTmp) - writeToFile.close() - - else: - - command = "dd if=/dev/zero of=/usr/.tempdisk bs=100M count=15" - preFlightsChecks.call(command, self.distro, command, - command, - 1, 0, os.EX_OSERR) - - command = "mkfs.ext4 -F /usr/.tempdisk" - preFlightsChecks.call(command, self.distro, command, - command, - 1, 0, os.EX_OSERR) - - command = "mkdir -p /usr/.tmpbak/" - preFlightsChecks.call(command, self.distro, command, - command, - 1, 0, os.EX_OSERR) - - command = "cp -pr /tmp/* /usr/.tmpbak/" - subprocess.call(command, shell=True) - - command = "mount -o loop,rw,nodev,nosuid,noexec,nofail /usr/.tempdisk /tmp" - preFlightsChecks.call(command, self.distro, command, - command, - 1, 0, os.EX_OSERR) - - command = "chmod 1777 /tmp" - preFlightsChecks.call(command, self.distro, command, - command, - 1, 0, os.EX_OSERR) - - command = "cp -pr /usr/.tmpbak/* /tmp/" - subprocess.call(command, shell=True) - - command = "rm -rf /usr/.tmpbak" - preFlightsChecks.call(command, self.distro, command, - command, - 1, 0, os.EX_OSERR) - - command = "mount --bind /tmp /var/tmp" - preFlightsChecks.call(command, self.distro, command, - command, - 1, 0, os.EX_OSERR) - - tmp = "/usr/.tempdisk /tmp ext4 loop,rw,noexec,nosuid,nodev,nofail 0 0\n" - varTmp = "/tmp /var/tmp none bind 0 0\n" - - fstab = "/etc/fstab" - writeToFile = open(fstab, "a") - writeToFile.writelines(tmp) - writeToFile.writelines(varTmp) - writeToFile.close() - - except BaseException as msg: - preFlightsChecks.stdOut('[ERROR] ' + str(msg)) - return 0 - - @staticmethod - def pureFTPDServiceName(distro): - if distro == ubuntu: - return 'pure-ftpd-mysql' - return 'pure-ftpd' - - @staticmethod - def resFailed(distro, res): - if distro == ubuntu and res != 0: - return True - elif distro == centos and res != 0: - return True - return False - - @staticmethod - def call(command, distro, bracket, message, log=0, do_exit=0, code=os.EX_OK): - finalMessage = 'Running: %s' % (message) - preFlightsChecks.stdOut(finalMessage, log) - count = 0 - while True: - res = subprocess.call(shlex.split(command)) - - if preFlightsChecks.resFailed(distro, res): - count = count + 1 - finalMessage = 'Running %s failed. Running again, try number %s' % (message, str(count)) - preFlightsChecks.stdOut(finalMessage) - if count == 3: - fatal_message = '' - if do_exit: - fatal_message = '. Fatal error, see /var/log/installLogs.txt for full details' - - preFlightsChecks.stdOut("[ERROR] We are not able to run " + message + ' return code: ' + str(res) + - fatal_message + ".", 1, do_exit, code) - return False - else: - preFlightsChecks.stdOut('Successfully ran: %s.' % (message), log) - break - - return True - - def checkIfSeLinuxDisabled(self): - try: - command = "sestatus" - output = subprocess.check_output(shlex.split(command)).decode("utf-8") - - if output.find("disabled") > -1 or output.find("permissive") > -1: - logging.InstallLog.writeToFile("SELinux Check OK. [checkIfSeLinuxDisabled]") - preFlightsChecks.stdOut("SELinux Check OK.") - return 1 - else: - logging.InstallLog.writeToFile( - "SELinux is enabled, please disable SELinux and restart the installation!") - preFlightsChecks.stdOut("Installation failed, consult: /var/log/installLogs.txt") - os._exit(0) - - except BaseException as msg: - logging.InstallLog.writeToFile('[ERROR] ' + str(msg) + "[checkIfSeLinuxDisabled]") - logging.InstallLog.writeToFile('[ERROR] ' + "SELinux Check OK. [checkIfSeLinuxDisabled]") - preFlightsChecks.stdOut('[ERROR] ' + "SELinux Check OK.") - return 1 - - def checkPythonVersion(self): - if sys.version_info[0] == 3: - return 1 - else: - preFlightsChecks.stdOut("You are running Unsupported python version, please install python 3.x") - os._exit(0) - - def setup_account_cyberpanel(self): - try: - - if self.distro == centos or self.distro == cent8: - command = "yum install sudo -y" - preFlightsChecks.call(command, self.distro, command, - command, - 1, 0, os.EX_OSERR) - - ## - - if self.distro == ubuntu: - self.stdOut("Add Cyberpanel user") - command = 'adduser --disabled-login --gecos "" cyberpanel' - preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR) - - else: - command = "useradd -s /bin/false cyberpanel" - preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR) - - ############################### - - ### Docker User/group - - if self.distro == ubuntu: - command = 'adduser --disabled-login --gecos "" docker' - else: - command = "adduser docker" - - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = 'groupadd docker' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = 'usermod -aG docker docker' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = 'usermod -aG docker cyberpanel' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ### - - command = "mkdir -p /etc/letsencrypt/live/" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - except BaseException as msg: - logging.InstallLog.writeToFile("[ERROR] setup_account_cyberpanel. " + str(msg)) - - def installCyberPanelRepo(self): - self.stdOut("Install Cyberpanel repo") - - if self.distro == ubuntu: - try: - filename = "enable_lst_debain_repo.sh" - command = "wget http://rpms.litespeedtech.com/debian/" + filename - preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR) - - os.chmod(filename, S_IRWXU | S_IRWXG) - - command = "./" + filename - preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR) - except: - logging.InstallLog.writeToFile("[ERROR] Exception during CyberPanel install") - preFlightsChecks.stdOut("[ERROR] Exception during CyberPanel install") - os._exit(os.EX_SOFTWARE) - - elif self.distro == centos: - command = 'rpm -ivh http://rpms.litespeedtech.com/centos/litespeed-repo-1.2-1.el7.noarch.rpm' - preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR) - elif self.distro == cent8: - command = 'rpm -Uvh http://rpms.litespeedtech.com/centos/litespeed-repo-1.1-1.el8.noarch.rpm' - preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR) - - def fix_selinux_issue(self): - try: - cmd = [] - - cmd.append("setsebool") - cmd.append("-P") - cmd.append("httpd_can_network_connect") - cmd.append("1") - - res = subprocess.call(cmd) - - if preFlightsChecks.resFailed(self.distro, res): - logging.InstallLog.writeToFile("fix_selinux_issue problem") - else: - pass - except: - logging.InstallLog.writeToFile("[ERROR] fix_selinux_issue problem") - - def install_psmisc(self): - self.stdOut("Install psmisc") - - if self.distro == centos or self.distro == cent8: - command = "yum -y install psmisc" - else: - command = "apt-get -y install psmisc" - - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - def download_install_CyberPanel(self, mysqlPassword, mysql): - ## - - os.chdir(self.path) - - os.chdir('/usr/local') - - command = "git clone https://github.com/usmannasir/cyberpanel" - preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR) - - shutil.move('cyberpanel', 'CyberCP') - - ## - - ### update password: - - if self.remotemysql == 'OFF': - passFile = "/etc/cyberpanel/mysqlPassword" - - f = open(passFile) - data = f.read() - password = data.split('\n', 1)[0] - else: - password = self.mysqlpassword - - ### Put correct mysql passwords in settings file! - - # This allows root/sudo users to be able to work with MySQL/MariaDB without hunting down the password like - # all the other control panels allow - # reference: https://oracle-base.com/articles/mysql/mysql-password-less-logins-using-option-files - mysql_my_root_cnf = '/root/.my.cnf' - mysql_root_cnf_content = """ -[client] -user=root -password="%s" -""" % password - - with open(mysql_my_root_cnf, 'w') as f: - f.write(mysql_root_cnf_content) - os.chmod(mysql_my_root_cnf, 0o600) - command = 'chown root:root %s' % mysql_my_root_cnf - subprocess.call(shlex.split(command)) - - logging.InstallLog.writeToFile("Updating /root/.my.cnf!") - - logging.InstallLog.writeToFile("Updating settings.py!") - - path = self.cyberPanelPath + "/CyberCP/settings.py" - - data = open(path, "r").readlines() - - writeDataToFile = open(path, "w") - - counter = 0 - - for items in data: - if items.find('SECRET_KEY') > -1: - SK = "SECRET_KEY = '%s'\n" % (generate_pass(50)) - writeDataToFile.writelines(SK) - continue - - if mysql == 'Two': - if items.find("'PASSWORD':") > -1: - if counter == 0: - writeDataToFile.writelines(" 'PASSWORD': '" + mysqlPassword + "'," + "\n") - counter = counter + 1 - else: - writeDataToFile.writelines(" 'PASSWORD': '" + password + "'," + "\n") - - else: - writeDataToFile.writelines(items) - else: - if items.find("'PASSWORD':") > -1: - if counter == 0: - writeDataToFile.writelines(" 'PASSWORD': '" + mysqlPassword + "'," + "\n") - counter = counter + 1 - else: - writeDataToFile.writelines(" 'PASSWORD': '" + password + "'," + "\n") - elif items.find('127.0.0.1') > -1: - writeDataToFile.writelines(" 'HOST': 'localhost',\n") - elif items.find("'PORT':'3307'") > -1: - writeDataToFile.writelines(" 'PORT': '',\n") - else: - writeDataToFile.writelines(items) - - if self.distro == ubuntu: - os.fchmod(writeDataToFile.fileno(), stat.S_IRUSR | stat.S_IWUSR) - - writeDataToFile.close() - - if self.remotemysql == 'ON': - command = "sed -i 's|localhost|%s|g' %s" % (self.mysqlhost, path) - preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR) - - # command = "sed -i 's|'mysql'|'%s'|g' %s" % (self.mysqldb, path) - # preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR) - - command = "sed -i 's|root|%s|g' %s" % (self.mysqluser, path) - preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR) - - command = "sed -i \"s|'PORT': ''|'PORT':'%s'|g\" %s" % (self.mysqlport, path) - preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR) - - logging.InstallLog.writeToFile("settings.py updated!") - - # self.setupVirtualEnv(self.distro) - - ### Applying migrations - - os.chdir("/usr/local/CyberCP") - - command = "/usr/local/CyberPanel/bin/python manage.py makemigrations" - preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR) - - ## - - command = "/usr/local/CyberPanel/bin/python manage.py migrate" - preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR) - - if not os.path.exists("/usr/local/CyberCP/public"): - os.mkdir("/usr/local/CyberCP/public") - - ## Moving static content to lscpd location - command = 'mv static /usr/local/CyberCP/public/' - preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR) - - try: - path = "/usr/local/CyberCP/version.txt" - writeToFile = open(path, 'w') - writeToFile.writelines('%s\n' % (VERSION)) - writeToFile.writelines(str(BUILD)) - writeToFile.close() - except: - pass - - def fixCyberPanelPermissions(self): - - ###### fix Core CyberPanel permissions - - command = "usermod -G lscpd,lsadm,nobody lscpd" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = "usermod -G lscpd,lsadm,nogroup lscpd" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = "find /usr/local/CyberCP -type d -exec chmod 0755 {} \;" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = "find /usr/local/CyberCP -type f -exec chmod 0644 {} \;" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = "chmod -R 755 /usr/local/CyberCP/bin" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ## change owner - - command = "chown -R root:root /usr/local/CyberCP" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ########### Fix LSCPD - - command = "find /usr/local/lscp -type d -exec chmod 0755 {} \;" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = "find /usr/local/lscp -type f -exec chmod 0644 {} \;" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = "chmod -R 755 /usr/local/lscp/bin" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = "chmod -R 755 /usr/local/lscp/fcgi-bin" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = "chown -R lscpd:lscpd /usr/local/CyberCP/public/phpmyadmin/tmp" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ## change owner - - command = "chown -R root:root /usr/local/lscp" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = "chown -R lscpd:lscpd /usr/local/lscp/cyberpanel/rainloop/data" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = "chmod 700 /usr/local/CyberCP/cli/cyberPanel.py" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = "chmod 700 /usr/local/CyberCP/plogical/upgradeCritical.py" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = "chmod 755 /usr/local/CyberCP/postfixSenderPolicy/client.py" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = "chmod 640 /usr/local/CyberCP/CyberCP/settings.py" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = "chown root:cyberpanel /usr/local/CyberCP/CyberCP/settings.py" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - files = ['/etc/yum.repos.d/MariaDB.repo', '/etc/pdns/pdns.conf', '/etc/systemd/system/lscpd.service', - '/etc/pure-ftpd/pure-ftpd.conf', '/etc/pure-ftpd/pureftpd-pgsql.conf', - '/etc/pure-ftpd/pureftpd-mysql.conf', '/etc/pure-ftpd/pureftpd-ldap.conf', - '/etc/dovecot/dovecot.conf', '/usr/local/lsws/conf/httpd_config.xml', - '/usr/local/lsws/conf/modsec.conf', '/usr/local/lsws/conf/httpd.conf'] - - for items in files: - command = 'chmod 644 %s' % (items) - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - impFile = ['/etc/pure-ftpd/pure-ftpd.conf', '/etc/pure-ftpd/pureftpd-pgsql.conf', - '/etc/pure-ftpd/pureftpd-mysql.conf', '/etc/pure-ftpd/pureftpd-ldap.conf', - '/etc/dovecot/dovecot.conf', '/etc/pdns/pdns.conf', '/etc/pure-ftpd/db/mysql.conf', - '/etc/powerdns/pdns.conf'] - - for items in impFile: - command = 'chmod 600 %s' % (items) - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = 'chmod 640 /etc/postfix/*.cf' - subprocess.call(command, shell=True) - - command = 'chmod 644 /etc/postfix/main.cf' - subprocess.call(command, shell=True) - - command = 'chmod 640 /etc/dovecot/*.conf' - subprocess.call(command, shell=True) - - command = 'chmod 644 /etc/dovecot/dovecot.conf' - subprocess.call(command, shell=True) - - command = 'chmod 640 /etc/dovecot/dovecot-sql.conf.ext' - subprocess.call(command, shell=True) - - command = 'chmod 644 /etc/postfix/dynamicmaps.cf' - subprocess.call(command, shell=True) - - fileM = ['/usr/local/lsws/FileManager/', '/usr/local/CyberCP/install/FileManager', - '/usr/local/CyberCP/serverStatus/litespeed/FileManager', '/usr/local/lsws/Example/html/FileManager'] - - for items in fileM: - try: - shutil.rmtree(items) - except: - pass - - command = 'chmod 755 /etc/pure-ftpd/' - subprocess.call(command, shell=True) - - command = 'chmod +x /usr/local/CyberCP/plogical/renew.py' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = 'chmod +x /usr/local/CyberCP/CLManager/CLPackages.py' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - clScripts = ['/usr/local/CyberCP/CLScript/panel_info.py', '/usr/local/CyberCP/CLScript/CloudLinuxPackages.py', - '/usr/local/CyberCP/CLScript/CloudLinuxUsers.py', - '/usr/local/CyberCP/CLScript/CloudLinuxDomains.py', - '/usr/local/CyberCP/CLScript/CloudLinuxResellers.py', '/usr/local/CyberCP/CLScript/CloudLinuxAdmins.py', - '/usr/local/CyberCP/CLScript/CloudLinuxDB.py', '/usr/local/CyberCP/CLScript/UserInfo.py'] - - for items in clScripts: - command = 'chmod +x %s' % (items) - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = 'chmod 600 /usr/local/CyberCP/plogical/adminPass.py' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = 'chmod 600 /etc/cagefs/exclude/cyberpanelexclude' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = "find /usr/local/CyberCP/ -name '*.pyc' -delete" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - if self.distro == cent8 or self.distro == centos: - command = 'chown root:pdns /etc/pdns/pdns.conf' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = 'chmod 640 /etc/pdns/pdns.conf' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = 'chmod 640 /usr/local/lscp/cyberpanel/logs/access.log' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = 'mkdir -p/usr/local/lscp/cyberpanel/rainloop/data/_data_/_default_/configs/' - - rainloopinipath = '/usr/local/lscp/cyberpanel/rainloop/data/_data_/_default_/configs/application.ini' - - command = 'chmod 600 /usr/local/CyberCP/public/rainloop.php' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ### - - WriteToFile = open('/etc/fstab', 'a') - WriteToFile.write('proc /proc proc defaults,hidepid=2 0 0\n') - WriteToFile.close() - - command = 'mount -o remount,rw,hidepid=2 /proc' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ## symlink protection - - writeToFile = open('/usr/lib/sysctl.d/50-default.conf', 'a') - writeToFile.writelines('fs.protected_hardlinks = 1\n') - writeToFile.writelines('fs.protected_symlinks = 1\n') - writeToFile.close() - - command = 'sysctl --system' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = 'chmod 700 %s' % ('/home/cyberpanel') - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - destPrivKey = "/usr/local/lscp/conf/key.pem" - - command = 'chmod 600 %s' % (destPrivKey) - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ### - - def install_unzip(self): - self.stdOut("Install unzip") - try: - if self.distro == centos or self.distro == cent8: - command = 'yum -y install unzip' - else: - command = 'apt-get -y install unzip' - - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - except BaseException as msg: - logging.InstallLog.writeToFile('[ERROR] ' + str(msg) + " [install_unzip]") - - def install_zip(self): - self.stdOut("Install zip") - try: - if self.distro == centos or self.distro == cent8: - command = 'yum -y install zip' - else: - command = 'apt-get -y install zip' - - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - except BaseException as msg: - logging.InstallLog.writeToFile('[ERROR] ' + str(msg) + " [install_zip]") - - def download_install_phpmyadmin(self): - try: - - if not os.path.exists("/usr/local/CyberCP/public"): - os.mkdir("/usr/local/CyberCP/public") - - command = 'wget -O /usr/local/CyberCP/public/phpmyadmin.zip https://github.com/usmannasir/cyberpanel/raw/stable/phpmyadmin.zip' - - preFlightsChecks.call(command, self.distro, '[download_install_phpmyadmin]', - command, 1, 0, os.EX_OSERR) - - command = 'unzip /usr/local/CyberCP/public/phpmyadmin.zip -d /usr/local/CyberCP/public/' - preFlightsChecks.call(command, self.distro, '[download_install_phpmyadmin]', - command, 1, 0, os.EX_OSERR) - - command = 'mv /usr/local/CyberCP/public/phpMyAdmin-*-all-languages /usr/local/CyberCP/public/phpmyadmin' - subprocess.call(command, shell=True) - - command = 'rm -f /usr/local/CyberCP/public/phpmyadmin.zip' - preFlightsChecks.call(command, self.distro, '[download_install_phpmyadmin]', - command, 1, 0, os.EX_OSERR) - - ## Write secret phrase - - rString = ''.join([random.choice(string.ascii_letters + string.digits) for n in range(32)]) - - data = open('/usr/local/CyberCP/public/phpmyadmin/config.sample.inc.php', 'r').readlines() - - writeToFile = open('/usr/local/CyberCP/public/phpmyadmin/config.inc.php', 'w') - - writeE = 1 - - phpMyAdminContent = """ -$cfg['Servers'][$i]['AllowNoPassword'] = false; -$cfg['Servers'][$i]['auth_type'] = 'signon'; -$cfg['Servers'][$i]['SignonSession'] = 'SignonSession'; -$cfg['Servers'][$i]['SignonURL'] = 'phpmyadminsignin.php'; -$cfg['Servers'][$i]['LogoutURL'] = 'phpmyadminsignin.php?logout'; -""" - - for items in data: - if items.find('blowfish_secret') > -1: - writeToFile.writelines( - "$cfg['blowfish_secret'] = '" + rString + "'; /* YOU MUST FILL IN THIS FOR COOKIE AUTH! */\n") - elif items.find('/* Authentication type */') > -1: - writeToFile.writelines(items) - writeToFile.write(phpMyAdminContent) - writeE = 0 - elif items.find("$cfg['Servers'][$i]['AllowNoPassword']") > -1: - writeE = 1 - else: - if writeE: - writeToFile.writelines(items) - - writeToFile.writelines("$cfg['TempDir'] = '/usr/local/CyberCP/public/phpmyadmin/tmp';\n") - - writeToFile.close() - - os.mkdir('/usr/local/CyberCP/public/phpmyadmin/tmp') - - command = 'chown -R lscpd:lscpd /usr/local/CyberCP/public/phpmyadmin' - preFlightsChecks.call(command, self.distro, '[chown -R lscpd:lscpd /usr/local/CyberCP/public/phpmyadmin]', - 'chown -R lscpd:lscpd /usr/local/CyberCP/public/phpmyadmin', 1, 0, os.EX_OSERR) - - if self.remotemysql == 'ON': - command = "sed -i 's|'localhost'|'%s'|g' %s" % ( - self.mysqlhost, '/usr/local/CyberCP/public/phpmyadmin/config.inc.php') - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = 'cp /usr/local/CyberCP/plogical/phpmyadminsignin.php /usr/local/CyberCP/public/phpmyadmin/phpmyadminsignin.php' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - if self.remotemysql == 'ON': - command = "sed -i 's|localhost|%s|g' /usr/local/CyberCP/public/phpmyadmin/phpmyadminsignin.php" % ( - self.mysqlhost) - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - - except BaseException as msg: - logging.InstallLog.writeToFile('[ERROR] ' + str(msg) + " [download_install_phpmyadmin]") - return 0 - - ###################################################### Email setup - - def install_postfix_dovecot(self): - self.stdOut("Install dovecot - first remove postfix") - - try: - if self.distro == centos: - command = 'yum remove postfix -y' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - elif self.distro == ubuntu: - command = 'apt-get -y remove postfix' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - self.stdOut("Install dovecot - do the install") - - if self.distro == centos: - command = 'yum install --enablerepo=gf-plus -y postfix3 postfix3-ldap postfix3-mysql postfix3-pcre' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - elif self.distro == cent8: - - command = 'dnf --nogpg install -y https://mirror.ghettoforge.net/distributions/gf/gf-release-latest.gf.el8.noarch.rpm' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = 'dnf install --enablerepo=gf-plus postfix3 postfix3-mysql -y' - preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR) - - else: - command = 'apt-get -y install debconf-utils' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - file_name = self.cwd + '/pf.unattend.text' - pf = open(file_name, 'w') - pf.write('postfix postfix/mailname string ' + str(socket.getfqdn() + '\n')) - pf.write('postfix postfix/main_mailer_type string "Internet Site"\n') - pf.close() - command = 'debconf-set-selections ' + file_name - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = 'apt-get -y install postfix postfix-mysql' - # os.remove(file_name) - - preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR) - - ## - - if self.distro == centos: - command = 'yum --enablerepo=gf-plus -y install dovecot23 dovecot23-mysql' - elif self.distro == cent8: - command = 'dnf install --enablerepo=gf-plus dovecot23 dovecot23-mysql -y' - else: - command = 'apt-get -y install dovecot-mysql dovecot-imapd dovecot-pop3d' - - preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR) - - except BaseException as msg: - logging.InstallLog.writeToFile('[ERROR] ' + str(msg) + " [install_postfix_dovecot]") - return 0 - - return 1 - - def setup_email_Passwords(self, mysqlPassword, mysql): - try: - - logging.InstallLog.writeToFile("Setting up authentication for Postfix and Dovecot...") - - os.chdir(self.cwd) - - mysql_virtual_domains = "email-configs-one/mysql-virtual_domains.cf" - mysql_virtual_forwardings = "email-configs-one/mysql-virtual_forwardings.cf" - mysql_virtual_mailboxes = "email-configs-one/mysql-virtual_mailboxes.cf" - mysql_virtual_email2email = "email-configs-one/mysql-virtual_email2email.cf" - dovecotmysql = "email-configs-one/dovecot-sql.conf.ext" - - ### update password: - - data = open(dovecotmysql, "r").readlines() - - writeDataToFile = open(dovecotmysql, "w") - - if mysql == 'Two': - dataWritten = "connect = host=127.0.0.1 dbname=cyberpanel user=cyberpanel password=" + mysqlPassword + " port=3307\n" - else: - dataWritten = "connect = host=localhost dbname=cyberpanel user=cyberpanel password=" + mysqlPassword + " port=3306\n" - - for items in data: - if items.find("connect") > -1: - writeDataToFile.writelines(dataWritten) - else: - writeDataToFile.writelines(items) - - writeDataToFile.close() - - ### update password: - - data = open(mysql_virtual_domains, "r").readlines() - - writeDataToFile = open(mysql_virtual_domains, "w") - - dataWritten = "password = " + mysqlPassword + "\n" - - for items in data: - if items.find("password") > -1: - writeDataToFile.writelines(dataWritten) - else: - writeDataToFile.writelines(items) - - writeDataToFile.close() - - ### update password: - - data = open(mysql_virtual_forwardings, "r").readlines() - - writeDataToFile = open(mysql_virtual_forwardings, "w") - - dataWritten = "password = " + mysqlPassword + "\n" - - for items in data: - if items.find("password") > -1: - writeDataToFile.writelines(dataWritten) - else: - writeDataToFile.writelines(items) - - writeDataToFile.close() - - ### update password: - - data = open(mysql_virtual_mailboxes, "r").readlines() - - writeDataToFile = open(mysql_virtual_mailboxes, "w") - - dataWritten = "password = " + mysqlPassword + "\n" - - for items in data: - if items.find("password") > -1: - writeDataToFile.writelines(dataWritten) - else: - writeDataToFile.writelines(items) - - writeDataToFile.close() - - ### update password: - - data = open(mysql_virtual_email2email, "r").readlines() - - writeDataToFile = open(mysql_virtual_email2email, "w") - - dataWritten = "password = " + mysqlPassword + "\n" - - for items in data: - if items.find("password") > -1: - writeDataToFile.writelines(dataWritten) - else: - writeDataToFile.writelines(items) - - writeDataToFile.close() - - if self.remotemysql == 'ON': - command = "sed -i 's|host=localhost|host=%s|g' %s" % (self.mysqlhost, dovecotmysql) - preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR) - - command = "sed -i 's|port=3306|port=%s|g' %s" % (self.mysqlport, dovecotmysql) - preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR) - - ## - - command = "sed -i 's|localhost|%s:%s|g' %s" % (self.mysqlhost, self.mysqlport, mysql_virtual_domains) - preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR) - - command = "sed -i 's|localhost|%s:%s|g' %s" % ( - self.mysqlhost, self.mysqlport, mysql_virtual_forwardings) - preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR) - - command = "sed -i 's|localhost|%s:%s|g' %s" % ( - self.mysqlhost, self.mysqlport, mysql_virtual_mailboxes) - preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR) - - command = "sed -i 's|localhost|%s:%s|g' %s" % ( - self.mysqlhost, self.mysqlport, mysql_virtual_email2email) - preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR) - - logging.InstallLog.writeToFile("Authentication for Postfix and Dovecot set.") - - except BaseException as msg: - logging.InstallLog.writeToFile('[ERROR]' + str(msg) + " [setup_email_Passwords]") - return 0 - - return 1 - - def centos_lib_dir_to_ubuntu(self, filename, old, new): - try: - fd = open(filename, 'r') - lines = fd.readlines() - fd.close() - fd = open(filename, 'w') - centos_prefix = old - ubuntu_prefix = new - for line in lines: - index = line.find(centos_prefix) - if index != -1: - line = line[:index] + ubuntu_prefix + line[index + len(centos_prefix):] - fd.write(line) - fd.close() - except IOError as err: - self.stdOut( - "[ERROR] Error converting: " + filename + " from centos defaults to ubuntu defaults: " + str(err), 1, - 1, os.EX_OSERR) - - def setup_postfix_dovecot_config(self, mysql): - try: - logging.InstallLog.writeToFile("Configuring postfix and dovecot...") - - os.chdir(self.cwd) - - mysql_virtual_domains = "/etc/postfix/mysql-virtual_domains.cf" - mysql_virtual_forwardings = "/etc/postfix/mysql-virtual_forwardings.cf" - mysql_virtual_mailboxes = "/etc/postfix/mysql-virtual_mailboxes.cf" - mysql_virtual_email2email = "/etc/postfix/mysql-virtual_email2email.cf" - main = "/etc/postfix/main.cf" - master = "/etc/postfix/master.cf" - dovecot = "/etc/dovecot/dovecot.conf" - dovecotmysql = "/etc/dovecot/dovecot-sql.conf.ext" - - if os.path.exists(mysql_virtual_domains): - os.remove(mysql_virtual_domains) - - if os.path.exists(mysql_virtual_forwardings): - os.remove(mysql_virtual_forwardings) - - if os.path.exists(mysql_virtual_mailboxes): - os.remove(mysql_virtual_mailboxes) - - if os.path.exists(mysql_virtual_email2email): - os.remove(mysql_virtual_email2email) - - if os.path.exists(main): - os.remove(main) - - if os.path.exists(master): - os.remove(master) - - if os.path.exists(dovecot): - os.remove(dovecot) - - if os.path.exists(dovecotmysql): - os.remove(dovecotmysql) - - ###############Getting SSL - - command = 'openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com" -keyout /etc/postfix/key.pem -out /etc/postfix/cert.pem' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ## - - command = 'openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com" -keyout /etc/dovecot/key.pem -out /etc/dovecot/cert.pem' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - # Cleanup config files for ubuntu - if self.distro == ubuntu: - preFlightsChecks.stdOut("Cleanup postfix/dovecot config files", 1) - - self.centos_lib_dir_to_ubuntu("email-configs-one/master.cf", "/usr/libexec/", "/usr/lib/") - self.centos_lib_dir_to_ubuntu("email-configs-one/main.cf", "/usr/libexec/postfix", - "/usr/lib/postfix/sbin") - - ########### Copy config files - - shutil.copy("email-configs-one/mysql-virtual_domains.cf", "/etc/postfix/mysql-virtual_domains.cf") - shutil.copy("email-configs-one/mysql-virtual_forwardings.cf", - "/etc/postfix/mysql-virtual_forwardings.cf") - shutil.copy("email-configs-one/mysql-virtual_mailboxes.cf", "/etc/postfix/mysql-virtual_mailboxes.cf") - shutil.copy("email-configs-one/mysql-virtual_email2email.cf", - "/etc/postfix/mysql-virtual_email2email.cf") - shutil.copy("email-configs-one/main.cf", main) - shutil.copy("email-configs-one/master.cf", master) - shutil.copy("email-configs-one/dovecot.conf", dovecot) - shutil.copy("email-configs-one/dovecot-sql.conf.ext", dovecotmysql) - - ########### Set custom settings - - # We are going to leverage postconfig -e to edit the settings for hostname - command = "postconf -e 'myhostname = %s'" % (str(socket.getfqdn())) - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - # We are explicitly going to use sed to set the hostname default from "myhostname = server.example.com" - # to the fqdn from socket if the default is still found - command = "sed -i 's|server.example.com|%s|g' %s" % (str(socket.getfqdn()), main) - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ######################################## Permissions - - command = 'chmod o= /etc/postfix/mysql-virtual_domains.cf' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ## - - command = 'chmod o= /etc/postfix/mysql-virtual_forwardings.cf' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ## - - command = 'chmod o= /etc/postfix/mysql-virtual_mailboxes.cf' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ## - - command = 'chmod o= /etc/postfix/mysql-virtual_email2email.cf' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ## - - command = 'chmod o= ' + main - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ## - - command = 'chmod o= ' + master - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ####################################### - - command = 'chgrp postfix /etc/postfix/mysql-virtual_domains.cf' - - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ## - - command = 'chgrp postfix /etc/postfix/mysql-virtual_forwardings.cf' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - ## - - command = 'chgrp postfix /etc/postfix/mysql-virtual_mailboxes.cf' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ## - - command = 'chgrp postfix /etc/postfix/mysql-virtual_email2email.cf' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ## - - command = 'chgrp postfix ' + main - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ## - - command = 'chgrp postfix ' + master - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ######################################## users and groups - - command = 'groupadd -g 5000 vmail' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ## - - command = 'useradd -g vmail -u 5000 vmail -d /home/vmail -m' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ######################################## Further configurations - - # hostname = socket.gethostname() - - ################################### Restart postix - - command = 'systemctl enable postfix.service' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ## - - command = 'systemctl start postfix.service' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ######################################## Permissions - - command = 'chgrp dovecot /etc/dovecot/dovecot-sql.conf.ext' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ## - - command = 'chmod o= /etc/dovecot/dovecot-sql.conf.ext' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ################################### Restart dovecot - - command = 'systemctl enable dovecot.service' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ## - - command = 'systemctl start dovecot.service' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ## - - command = 'systemctl restart postfix.service' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ## chaging permissions for main.cf - - command = "chmod 755 " + main - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - if self.distro == ubuntu: - command = "mkdir -p /etc/pki/dovecot/private/" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = "mkdir -p /etc/pki/dovecot/certs/" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = "mkdir -p /etc/opendkim/keys/" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = "sed -i 's/auth_mechanisms = plain/#auth_mechanisms = plain/g' /etc/dovecot/conf.d/10-auth.conf" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ## Ubuntu 18.10 ssl_dh for dovecot 2.3.2.1 - - if get_Ubuntu_release() == 18.10: - dovecotConf = '/etc/dovecot/dovecot.conf' - - data = open(dovecotConf, 'r').readlines() - writeToFile = open(dovecotConf, 'w') - for items in data: - if items.find('ssl_key = -1: - writeToFile.writelines(items) - writeToFile.writelines('ssl_dh = -1: - writeToFile.writelines( - " $sCustomDataPath = '/usr/local/lscp/cyberpanel/rainloop/data';\n") - else: - writeToFile.writelines(items) - - writeToFile.close() - - except BaseException as msg: - logging.InstallLog.writeToFile('[ERROR] ' + str(msg) + " [downoad_and_install_rainloop]") - return 0 - - return 1 - - ###################################################### Email setup ends! - - def reStartLiteSpeed(self): - command = '%sbin/lswsctrl restart' % (self.server_root_path) - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - def removeUfw(self): - try: - preFlightsChecks.stdOut("Checking to see if ufw firewall is installed (will be removed)", 1) - status = subprocess.check_output(shlex.split('ufw status')).decode("utf-8") - preFlightsChecks.stdOut("ufw current status: " + status + "...will be removed") - except BaseException as msg: - preFlightsChecks.stdOut("[ERROR] Expected access to ufw not available, do not need to remove it", 1) - return True - try: - preFlightsChecks.call('apt-get -y remove ufw', self.distro, '[remove_ufw]', 'Remove ufw firewall ' + - '(using firewalld)', 1, 0, os.EX_OSERR) - except: - pass - return True - - def installFirewalld(self): - - if self.distro == ubuntu: - self.removeUfw() - - try: - preFlightsChecks.stdOut("Enabling Firewall!") - - if self.distro == ubuntu: - command = 'apt-get -y install firewalld' - else: - command = 'yum -y install firewalld' - - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ###### - if self.distro == centos: - # Not available in ubuntu - command = 'systemctl restart dbus' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = 'systemctl restart systemd-logind' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = 'systemctl start firewalld' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ########## - - command = 'systemctl enable firewalld' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - FirewallUtilities.addRule("tcp", "8090") - FirewallUtilities.addRule("tcp", "7080") - FirewallUtilities.addRule("tcp", "80") - FirewallUtilities.addRule("tcp", "443") - FirewallUtilities.addRule("tcp", "21") - FirewallUtilities.addRule("tcp", "25") - FirewallUtilities.addRule("tcp", "587") - FirewallUtilities.addRule("tcp", "465") - FirewallUtilities.addRule("tcp", "110") - FirewallUtilities.addRule("tcp", "143") - FirewallUtilities.addRule("tcp", "993") - FirewallUtilities.addRule("tcp", "995") - FirewallUtilities.addRule("udp", "53") - FirewallUtilities.addRule("tcp", "53") - FirewallUtilities.addRule("udp", "443") - FirewallUtilities.addRule("tcp", "40110-40210") - - logging.InstallLog.writeToFile("FirewallD installed and configured!") - preFlightsChecks.stdOut("FirewallD installed and configured!") - - except OSError as msg: - logging.InstallLog.writeToFile('[ERROR] ' + str(msg) + " [installFirewalld]") - return 0 - except ValueError as msg: - logging.InstallLog.writeToFile('[ERROR] ' + str(msg) + " [installFirewalld]") - return 0 - - return 1 - - ## from here - - def installLSCPD(self): - try: - - logging.InstallLog.writeToFile("Starting LSCPD installation..") - - os.chdir(self.cwd) - - if self.distro == ubuntu: - command = "apt-get -y install gcc g++ make autoconf rcs" - else: - command = 'yum -y install gcc gcc-c++ make autoconf glibc' - - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - if self.distro == ubuntu: - command = "apt-get -y install libpcre3 libpcre3-dev openssl libexpat1 libexpat1-dev libgeoip-dev" \ - " zlib1g zlib1g-dev libudns-dev whichman curl" - else: - command = 'yum -y install pcre-devel openssl-devel expat-devel geoip-devel zlib-devel udns-devel' - - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = 'tar zxf lscp.tar.gz -C /usr/local/' - preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR) - - ### - - lscpdPath = '/usr/local/lscp/bin/lscpd' - - command = 'cp -f /usr/local/CyberCP/lscpd-0.3.1 /usr/local/lscp/bin/lscpd-0.3.1' - preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR) - - command = 'rm -f /usr/local/lscp/bin/lscpd' - preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR) - - command = 'mv /usr/local/lscp/bin/lscpd-0.3.1 /usr/local/lscp/bin/lscpd' - preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR) - - command = 'chmod 755 %s' % (lscpdPath) - preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR) - - ## - - command = 'openssl req -newkey rsa:1024 -new -nodes -x509 -days 3650 -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com" -keyout /usr/local/lscp/conf/key.pem -out /usr/local/lscp/conf/cert.pem' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - try: - os.remove("/usr/local/lscp/fcgi-bin/lsphp") - shutil.copy("/usr/local/lsws/lsphp73/bin/lsphp", "/usr/local/lscp/fcgi-bin/lsphp") - except: - pass - - if self.distro == centos or self.distro == cent8: - command = 'adduser lscpd -M -d /usr/local/lscp' - else: - command = 'useradd lscpd -M -d /usr/local/lscp' - - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - if self.distro == centos or self.distro == cent8: - command = 'groupadd lscpd' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - # Added group in useradd for Ubuntu - - command = 'usermod -a -G lscpd lscpd' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = 'usermod -a -G lsadm lscpd' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - try: - os.mkdir('/usr/local/lscp/cyberpanel') - except: - pass - try: - os.mkdir('/usr/local/lscp/cyberpanel/logs') - except: - pass - - # self.setupComodoRules() - - logging.InstallLog.writeToFile("LSCPD successfully installed!") - - except BaseException as msg: - logging.InstallLog.writeToFile('[ERROR] ' + str(msg) + " [installLSCPD]") - - def setupComodoRules(self): - try: - os.chdir(self.cwd) - - extractLocation = "/usr/local/lscp/modsec" - - command = "mkdir -p /usr/local/lscp/modsec" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - try: - if os.path.exists('comodo.tar.gz'): - os.remove('comodo.tar.gz') - except: - pass - - command = "wget https://cyberpanel.net/modsec/comodo.tar.gz" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = "tar -zxf comodo.tar.gz -C /usr/local/lscp/modsec" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ### - - modsecConfPath = "/usr/local/lscp/conf/modsec.conf" - - modsecConfig = """ - module mod_security { - ls_enabled 0 - modsecurity on - modsecurity_rules ` - SecDebugLogLevel 0 - SecDebugLog /usr/local/lscp/logs/modsec.log - SecAuditEngine on - SecAuditLogRelevantStatus "^(?:5|4(?!04))" - SecAuditLogParts AFH - SecAuditLogType Serial - SecAuditLog /usr/local/lscp/logs/auditmodsec.log - SecRuleEngine Off - ` - modsecurity_rules_file /usr/local/lscp/modsec/comodo/modsecurity.conf - modsecurity_rules_file /usr/local/lscp/modsec/comodo/00_Init_Initialization.conf - modsecurity_rules_file /usr/local/lscp/modsec/comodo/01_Init_AppsInitialization.conf - modsecurity_rules_file /usr/local/lscp/modsec/comodo/02_Global_Generic.conf - modsecurity_rules_file /usr/local/lscp/modsec/comodo/03_Global_Agents.conf - modsecurity_rules_file /usr/local/lscp/modsec/comodo/04_Global_Domains.conf - modsecurity_rules_file /usr/local/lscp/modsec/comodo/05_Global_Backdoor.conf - modsecurity_rules_file /usr/local/lscp/modsec/comodo/06_XSS_XSS.conf - modsecurity_rules_file /usr/local/lscp/modsec/comodo/07_Global_Other.conf - modsecurity_rules_file /usr/local/lscp/modsec/comodo/08_Bruteforce_Bruteforce.conf - modsecurity_rules_file /usr/local/lscp/modsec/comodo/09_HTTP_HTTP.conf - modsecurity_rules_file /usr/local/lscp/modsec/comodo/10_HTTP_HTTPDoS.conf - modsecurity_rules_file /usr/local/lscp/modsec/comodo/11_HTTP_Protocol.conf - modsecurity_rules_file /usr/local/lscp/modsec/comodo/12_HTTP_Request.conf - modsecurity_rules_file /usr/local/lscp/modsec/comodo/13_Outgoing_FilterGen.conf - modsecurity_rules_file /usr/local/lscp/modsec/comodo/14_Outgoing_FilterASP.conf - modsecurity_rules_file /usr/local/lscp/modsec/comodo/15_Outgoing_FilterPHP.conf - modsecurity_rules_file /usr/local/lscp/modsec/comodo/16_Outgoing_FilterSQL.conf - modsecurity_rules_file /usr/local/lscp/modsec/comodo/17_Outgoing_FilterOther.conf - modsecurity_rules_file /usr/local/lscp/modsec/comodo/18_Outgoing_FilterInFrame.conf - modsecurity_rules_file /usr/local/lscp/modsec/comodo/19_Outgoing_FiltersEnd.conf - modsecurity_rules_file /usr/local/lscp/modsec/comodo/20_PHP_PHPGen.conf - modsecurity_rules_file /usr/local/lscp/modsec/comodo/21_SQL_SQLi.conf - modsecurity_rules_file /usr/local/lscp/modsec/comodo/22_Apps_Joomla.conf - modsecurity_rules_file /usr/local/lscp/modsec/comodo/23_Apps_JComponent.conf - modsecurity_rules_file /usr/local/lscp/modsec/comodo/24_Apps_WordPress.conf - modsecurity_rules_file /usr/local/lscp/modsec/comodo/25_Apps_WPPlugin.conf - modsecurity_rules_file /usr/local/lscp/modsec/comodo/26_Apps_WHMCS.conf - modsecurity_rules_file /usr/local/lscp/modsec/comodo/27_Apps_Drupal.conf - modsecurity_rules_file /usr/local/lscp/modsec/comodo/28_Apps_OtherApps.conf - } - """ - - writeToFile = open(modsecConfPath, 'w') - writeToFile.write(modsecConfig) - writeToFile.close() - - ### - - command = "chown -R lscpd:lscpd /usr/local/lscp/modsec" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - return 1 - - except BaseException as msg: - logging.InstallLog.writeToFile("[ERROR]" + str(msg)) - return 0 - - def setupPort(self): - try: - ### - bindConfPath = "/usr/local/lscp/conf/bind.conf" - - writeToFile = open(bindConfPath, 'w') - writeToFile.write("*:" + self.port) - writeToFile.close() - - except: - return 0 - - def setupPythonWSGI(self): - try: - - command = "wget http://www.litespeedtech.com/packages/lsapi/wsgi-lsapi-1.6.tgz" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = "tar xf wsgi-lsapi-1.6.tgz" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - os.chdir("wsgi-lsapi-1.6") - - command = "/usr/local/CyberPanel/bin/python ./configure.py" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = "make" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - if not os.path.exists('/usr/local/CyberCP/bin/'): - os.mkdir('/usr/local/CyberCP/bin/') - - command = "cp lswsgi /usr/local/CyberCP/bin/" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - os.chdir(self.cwd) - - except: - return 0 - - def setupLSCPDDaemon(self): - try: - - preFlightsChecks.stdOut("Trying to setup LSCPD Daemon!") - logging.InstallLog.writeToFile("Trying to setup LSCPD Daemon!") - - os.chdir(self.cwd) - - shutil.copy("lscpd/lscpd.service", "/etc/systemd/system/lscpd.service") - shutil.copy("lscpd/lscpdctrl", "/usr/local/lscp/bin/lscpdctrl") - - ## - - command = 'chmod +x /usr/local/lscp/bin/lscpdctrl' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ## - - path = "/usr/local/lscpd/admin/" - - command = "mkdir -p " + path - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - path = "/usr/local/CyberCP/conf/" - command = "mkdir -p " + path - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - path = "/usr/local/CyberCP/conf/token_env" - writeToFile = open(path, "w") - writeToFile.write("abc\n") - writeToFile.close() - - command = "chmod 600 " + path - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ## - command = 'systemctl enable lscpd.service' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ## - count = 0 - - # In Ubuntu, the library that lscpd looks for is libpcre.so.1, but the one it installs is libpcre.so.3... - if self.distro == ubuntu: - command = 'ln -s /lib/x86_64-linux-gnu/libpcre.so.3 /lib/x86_64-linux-gnu/libpcre.so.1' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ## - - command = 'systemctl start lscpd' - # preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - preFlightsChecks.stdOut("LSCPD Daemon Set!") - - logging.InstallLog.writeToFile("LSCPD Daemon Set!") - - except BaseException as msg: - logging.InstallLog.writeToFile('[ERROR] ' + str(msg) + " [setupLSCPDDaemon]") - return 0 - - return 1 - - def setup_cron(self): - - try: - ## first install crontab - - if self.distro == centos or self.distro == cent8: - command = 'yum install cronie -y' - else: - command = 'apt-get -y install cron' - - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - if self.distro == centos or self.distro == cent8: - command = 'systemctl enable crond' - else: - command = 'systemctl enable cron' - - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - if self.distro == centos or self.distro == cent8: - command = 'systemctl start crond' - else: - command = 'systemctl start cron' - - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ## - - CentOSPath = '/etc/redhat-release' - - if os.path.exists(CentOSPath): - cronPath = '/var/spool/cron/root' - else: - cronPath = '/var/spool/cron/crontabs/root' - - cronFile = open(cronPath, "w") - - content = """ -0 * * * * /usr/local/CyberCP/bin/python /usr/local/CyberCP/plogical/findBWUsage.py >/dev/null 2>&1 -0 * * * * /usr/local/CyberCP/bin/python /usr/local/CyberCP/postfixSenderPolicy/client.py hourlyCleanup >/dev/null 2>&1 -0 0 1 * * /usr/local/CyberCP/bin/python /usr/local/CyberCP/postfixSenderPolicy/client.py monthlyCleanup >/dev/null 2>&1 -0 2 * * * /usr/local/CyberCP/bin/python /usr/local/CyberCP/plogical/upgradeCritical.py >/dev/null 2>&1 -0 2 * * * /usr/local/CyberCP/bin/python /usr/local/CyberCP/plogical/renew.py >/dev/null 2>&1 -7 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null -0 0 * * * /usr/local/CyberCP/bin/python /usr/local/CyberCP/IncBackups/IncScheduler.py Daily -0 0 * * 0 /usr/local/CyberCP/bin/python /usr/local/CyberCP/IncBackups/IncScheduler.py Weekly -*/3 * * * * if ! find /home/*/public_html/ -maxdepth 2 -type f -newer /usr/local/lsws/cgid -name '.htaccess' -exec false {} +; then /usr/local/lsws/bin/lswsctrl restart; fi -""" - - cronFile.write(content) - cronFile.close() - - ### Check and remove OLS restart if lsws ent detected - - if not os.path.exists('/usr/local/lsws/bin/openlitespeed'): - - data = open(cronPath, 'r').readlines() - - writeToFile = open(cronPath, 'w') - - for items in data: - if items.find('-maxdepth 2 -type f -newer') > -1: - pass - else: - writeToFile.writelines(items) - - writeToFile.close() - - if not os.path.exists(CentOSPath): - command = 'chmod 600 %s' % (cronPath) - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - if self.distro == centos or self.distro == cent8: - command = 'systemctl restart crond.service' - else: - command = 'systemctl restart cron.service' - - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - except BaseException as msg: - logging.InstallLog.writeToFile('[ERROR] ' + str(msg) + " [setup_cron]") - return 0 - - def install_default_keys(self): - try: - path = "/root/.ssh" - - if not os.path.exists(path): - os.mkdir(path) - - command = "ssh-keygen -f /root/.ssh/cyberpanel -t rsa -N ''" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - except BaseException as msg: - logging.InstallLog.writeToFile('[ERROR] ' + str(msg) + " [install_default_keys]") - return 0 - - def install_rsync(self): - try: - if self.distro == centos or self.distro == cent8: - command = 'yum -y install rsync' - else: - command = 'apt-get -y install rsync' - - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - except BaseException as msg: - logging.InstallLog.writeToFile('[ERROR] ' + str(msg) + " [install_rsync]") - return 0 - - def test_Requests(self): - try: - import requests - getVersion = requests.get('https://cyberpanel.net/version.txt') - latest = getVersion.json() - except BaseException as msg: - - command = "pip uninstall --yes urllib3" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = "pip uninstall --yes requests" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = "pip install http://mirror.cyberpanel.net/urllib3-1.22.tar.gz" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = "pip install http://mirror.cyberpanel.net/requests-2.18.4.tar.gz" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - def installation_successfull(self): - print("###################################################################") - print(" CyberPanel Successfully Installed ") - print(" ") - - print(" ") - print(" ") - - print((" Visit: https://" + self.ipAddr + ":8090 ")) - print(" Username: admin ") - print(" Password: 1234567 ") - - print("###################################################################") - - def modSecPreReqs(self): - try: - - pathToRemoveGarbageFile = os.path.join(self.server_root_path, "modules/mod_security.so") - os.remove(pathToRemoveGarbageFile) - - except OSError as msg: - logging.InstallLog.writeToFile('[ERROR] ' + str(msg) + " [modSecPreReqs]") - return 0 - - def installOpenDKIM(self): - try: - if self.distro == centos: - command = 'yum -y install opendkim' - elif self.distro == cent8: - command = 'dnf install opendkim -y' - else: - command = 'apt-get -y install opendkim' - - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - if self.distro == ubuntu: - command = 'apt install opendkim-tools -y' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = 'mkdir -p /etc/opendkim/keys/' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - except BaseException as msg: - logging.InstallLog.writeToFile('[ERROR] ' + str(msg) + " [installOpenDKIM]") - return 0 - - return 1 - - def configureOpenDKIM(self): - try: - - ## Configure OpenDKIM specific settings - - openDKIMConfigurePath = "/etc/opendkim.conf" - - configData = """ -Mode sv -Canonicalization relaxed/simple -KeyTable refile:/etc/opendkim/KeyTable -SigningTable refile:/etc/opendkim/SigningTable -ExternalIgnoreList refile:/etc/opendkim/TrustedHosts -InternalHosts refile:/etc/opendkim/TrustedHosts -""" - - writeToFile = open(openDKIMConfigurePath, 'a') - writeToFile.write(configData) - writeToFile.close() - - ## Configure postfix specific settings - - postfixFilePath = "/etc/postfix/main.cf" - - configData = """ -smtpd_milters = inet:127.0.0.1:8891 -non_smtpd_milters = $smtpd_milters -milter_default_action = accept -""" - - writeToFile = open(postfixFilePath, 'a') - writeToFile.write(configData) - writeToFile.close() - - if self.distro == ubuntu: - data = open(openDKIMConfigurePath, 'r').readlines() - writeToFile = open(openDKIMConfigurePath, 'w') - for items in data: - if items.find('Socket') > -1 and items.find('local:') and items[0] != '#': - writeToFile.writelines('Socket inet:8891@localhost\n') - else: - writeToFile.writelines(items) - writeToFile.close() - - #### Restarting Postfix and OpenDKIM - - command = "systemctl start opendkim" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = "systemctl enable opendkim" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ## - - command = "systemctl start postfix" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - except BaseException as msg: - logging.InstallLog.writeToFile('[ERROR] ' + str(msg) + " [configureOpenDKIM]") - return 0 - - return 1 - - def setupCLI(self): - command = "ln -s /usr/local/CyberCP/cli/cyberPanel.py /usr/bin/cyberpanel" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = "chmod +x /usr/local/CyberCP/cli/cyberPanel.py" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - def setupPHPAndComposer(self): - try: - - if self.distro == ubuntu: - if not os.access('/usr/local/lsws/lsphp70/bin/php', os.R_OK): - if os.access('/usr/local/lsws/lsphp70/bin/php7.0', os.R_OK): - os.symlink('/usr/local/lsws/lsphp70/bin/php7.0', '/usr/local/lsws/lsphp70/bin/php') - if not os.access('/usr/local/lsws/lsphp71/bin/php', os.R_OK): - if os.access('/usr/local/lsws/lsphp71/bin/php7.1', os.R_OK): - os.symlink('/usr/local/lsws/lsphp71/bin/php7.1', '/usr/local/lsws/lsphp71/bin/php') - if not os.access('/usr/local/lsws/lsphp72/bin/php', os.R_OK): - if os.access('/usr/local/lsws/lsphp72/bin/php7.2', os.R_OK): - os.symlink('/usr/local/lsws/lsphp72/bin/php7.2', '/usr/local/lsws/lsphp72/bin/php') - - command = "cp /usr/local/lsws/lsphp71/bin/php /usr/bin/" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - os.chdir(self.cwd) - - command = "chmod +x composer.sh" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = "./composer.sh" - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - except OSError as msg: - logging.InstallLog.writeToFile('[ERROR] ' + str(msg) + " [setupPHPAndComposer]") - return 0 - - @staticmethod - def installOne(package): - res = subprocess.call(shlex.split('apt-get -y install ' + package)) - if res != 0: - preFlightsChecks.stdOut("Error #" + str(res) + ' installing:' + package + '. This may not be an issue ' \ - 'but may affect installation of something later', - 1) - - return res # Though probably not used - - @staticmethod - def enableDisableDNS(state): - try: - servicePath = '/home/cyberpanel/powerdns' - - if state == 'off': - - command = 'sudo systemctl stop pdns' - subprocess.call(shlex.split(command)) - - command = 'sudo systemctl disable pdns' - subprocess.call(shlex.split(command)) - - try: - os.remove(servicePath) - except: - pass - - else: - writeToFile = open(servicePath, 'w+') - writeToFile.close() - - except OSError as msg: - logging.InstallLog.writeToFile('[ERROR] ' + str(msg) + " [enableDisableDNS]") - return 0 - - @staticmethod - def enableDisableEmail(state): - try: - servicePath = '/home/cyberpanel/postfix' - - if state == 'off': - - command = 'sudo systemctl stop postfix' - subprocess.call(shlex.split(command)) - - command = 'sudo systemctl disable postfix' - subprocess.call(shlex.split(command)) - - try: - os.remove(servicePath) - except: - pass - - else: - writeToFile = open(servicePath, 'w+') - writeToFile.close() - - except OSError as msg: - logging.InstallLog.writeToFile('[ERROR] ' + str(msg) + " [enableDisableEmail]") - return 0 - - @staticmethod - def enableDisableFTP(state, distro): - try: - servicePath = '/home/cyberpanel/pureftpd' - - if state == 'off': - - command = 'sudo systemctl stop ' + preFlightsChecks.pureFTPDServiceName(distro) - subprocess.call(shlex.split(command)) - - command = 'sudo systemctl disable ' + preFlightsChecks.pureFTPDServiceName(distro) - subprocess.call(shlex.split(command)) - - try: - os.remove(servicePath) - except: - pass - - else: - writeToFile = open(servicePath, 'w+') - writeToFile.close() - - except OSError as msg: - logging.InstallLog.writeToFile('[ERROR] ' + str(msg) + " [enableDisableEmail]") - return 0 - - @staticmethod - def setUpFirstAccount(): - try: - command = 'python /usr/local/CyberCP/plogical/adminPass.py --password 1234567' - subprocess.call(shlex.split(command)) - except: - pass - - def installRestic(self): - try: - - CentOSPath = '/etc/redhat-release' - - if os.path.exists(CentOSPath): - command = 'yum install -y yum-plugin-copr' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - command = 'yum copr enable -y copart/restic' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - command = 'yum install -y restic' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - else: - command = 'apt-get update -y' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = 'apt-get install restic -y' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - except: - pass - - def installCLScripts(self): - try: - - CentOSPath = '/etc/redhat-release' - - if os.path.exists(CentOSPath): - command = 'mkdir -p /opt/cpvendor/etc/' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - content = """[integration_scripts] - -panel_info = /usr/local/CyberCP/CLScript/panel_info.py -packages = /usr/local/CyberCP/CLScript/CloudLinuxPackages.py -users = /usr/local/CyberCP/CLScript/CloudLinuxUsers.py -domains = /usr/local/CyberCP/CLScript/CloudLinuxDomains.py -resellers = /usr/local/CyberCP/CLScript/CloudLinuxResellers.py -admins = /usr/local/CyberCP/CLScript/CloudLinuxAdmins.py -db_info = /usr/local/CyberCP/CLScript/CloudLinuxDB.py - -[lvemanager_config] -ui_user_info =/usr/local/CyberCP/CLScript/UserInfo.py -base_path = /usr/local/lvemanager -run_service = 1 -service_port = 9000 -""" - - writeToFile = open('/opt/cpvendor/etc/integration.ini', 'w') - writeToFile.write(content) - writeToFile.close() - - command = 'mkdir -p /etc/cagefs/exclude' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - content = """cyberpanel -docker -ftpuser -lscpd -opendkim -pdns -vmail -""" - - writeToFile = open('/etc/cagefs/exclude/cyberpanelexclude', 'w') - writeToFile.write(content) - writeToFile.close() - - except: - pass - - def installAcme(self): - command = 'wget -O - https://get.acme.sh | sh' - subprocess.call(command, shell=True) - - command = '/root/.acme.sh/acme.sh --upgrade --auto-upgrade' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - def installRedis(self): - if self.distro == ubuntu: - command = 'apt install redis-server -y' - elif self.distro == centos: - command = 'yum install redis -y' - else: - command = 'dnf install redis -y' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - ## install redis conf - - redisConf = '/usr/local/lsws/conf/dvhost_redis.conf' - - writeToFile = open(redisConf, 'w') - writeToFile.write('127.0.0.1,6379,\n') - writeToFile.close() - - ## - - os.chdir(self.cwd) - - confPath = '/usr/local/lsws/conf/' - - if os.path.exists('%shttpd.conf' % (confPath)): - os.remove('%shttpd.conf' % (confPath)) - - shutil.copy('litespeed/httpd-redis.conf', '%shttpd.conf' % (confPath)) - - ## start and enable - - command = 'systemctl start redis' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - command = 'systemctl enable redis' - preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - - def disablePackegeUpdates(self): - if self.distro == centos: - mainConfFile = '/etc/yum.conf' - content = 'exclude=MariaDB-client MariaDB-common MariaDB-devel MariaDB-server MariaDB-shared ' \ - 'pdns pdns-backend-mysql dovecot dovecot-mysql postfix3 postfix3-ldap postfix3-mysql ' \ - 'postfix3-pcre restic opendkim libopendkim pure-ftpd ftp\n' - - writeToFile = open(mainConfFile, 'a') - writeToFile.write(content) - writeToFile.close() - - -def main(): - parser = argparse.ArgumentParser(description='CyberPanel Installer') - parser.add_argument('publicip', help='Please enter public IP for your VPS or dedicated server.') - parser.add_argument('--mysql', help='Specify number of MySQL instances to be used.') - parser.add_argument('--postfix', help='Enable or disable Email Service.') - parser.add_argument('--powerdns', help='Enable or disable DNS Service.') - parser.add_argument('--ftp', help='Enable or disable ftp Service.') - parser.add_argument('--ent', help='Install LS Ent or OpenLiteSpeed') - parser.add_argument('--serial', help='Install LS Ent or OpenLiteSpeed') - parser.add_argument('--port', help='LSCPD Port') - parser.add_argument('--redis', help='vHosts on Redis - Requires LiteSpeed Enterprise') - parser.add_argument('--remotemysql', help='Opt to choose local or remote MySQL') - parser.add_argument('--mysqlhost', help='MySQL host if remote is chosen.') - parser.add_argument('--mysqldb', help='MySQL DB if remote is chosen.') - parser.add_argument('--mysqluser', help='MySQL user if remote is chosen.') - parser.add_argument('--mysqlpassword', help='MySQL password if remote is chosen.') - parser.add_argument('--mysqlport', help='MySQL port if remote is chosen.') - - args = parser.parse_args() - - logging.InstallLog.ServerIP = args.publicip - logging.InstallLog.writeToFile("Starting CyberPanel installation..,10") - preFlightsChecks.stdOut("Starting CyberPanel installation..") - - if args.ent is None: - ent = 0 - preFlightsChecks.stdOut("OpenLiteSpeed web server will be installed.") - else: - if args.ent == 'ols': - ent = 0 - preFlightsChecks.stdOut("OpenLiteSpeed web server will be installed.") - else: - preFlightsChecks.stdOut("LiteSpeed Enterprise web server will be installed.") - ent = 1 - if args.serial is not None: - serial = args.serial - preFlightsChecks.stdOut("LiteSpeed Enterprise Serial detected: " + serial) - else: - preFlightsChecks.stdOut("Installation failed, please specify LiteSpeed Enterprise key using --serial") - os._exit(0) - - ## Writing public IP - - try: - os.mkdir("/etc/cyberpanel") - except: - pass - - machineIP = open("/etc/cyberpanel/machineIP", "w") - machineIP.writelines(args.publicip) - machineIP.close() - - cwd = os.getcwd() - - if args.remotemysql == 'ON': - remotemysql = args.remotemysql - mysqlhost = args.mysqlhost - mysqluser = args.mysqluser - mysqlpassword = args.mysqlpassword - mysqlport = args.mysqlport - mysqldb = args.mysqldb - - if preFlightsChecks.debug: - print('mysqlhost: %s, mysqldb: %s, mysqluser: %s, mysqlpassword: %s, mysqlport: %s' % ( - mysqlhost, mysqldb, mysqluser, mysqlpassword, mysqlport)) - time.sleep(10) - - else: - remotemysql = args.remotemysql - mysqlhost = '' - mysqluser = '' - mysqlpassword = '' - mysqlport = '' - mysqldb = '' - - distro = get_distro() - checks = preFlightsChecks("/usr/local/lsws/", args.publicip, "/usr/local", cwd, "/usr/local/CyberCP", distro, - remotemysql, mysqlhost, mysqldb, mysqluser, mysqlpassword, mysqlport) - checks.mountTemp() - - if args.port is None: - port = "8090" - else: - port = args.port - - if args.mysql is None: - mysql = 'One' - preFlightsChecks.stdOut("Single MySQL instance version will be installed.") - else: - mysql = args.mysql - preFlightsChecks.stdOut("Dobule MySQL instance version will be installed.") - - checks.checkPythonVersion() - checks.setup_account_cyberpanel() - checks.installCyberPanelRepo() - - import installCyberPanel - - if ent == 0: - installCyberPanel.Main(cwd, mysql, distro, ent, None, port, args.ftp, args.powerdns, args.publicip, remotemysql, - mysqlhost, mysqldb, mysqluser, mysqlpassword, mysqlport) - else: - installCyberPanel.Main(cwd, mysql, distro, ent, serial, port, args.ftp, args.powerdns, args.publicip, - remotemysql, mysqlhost, mysqldb, mysqluser, mysqlpassword, mysqlport) - - checks.setupPHPAndComposer() - checks.fix_selinux_issue() - checks.install_psmisc() - - if args.postfix is None: - checks.install_postfix_dovecot() - checks.setup_email_Passwords(installCyberPanel.InstallCyberPanel.mysqlPassword, mysql) - checks.setup_postfix_dovecot_config(mysql) - else: - if args.postfix == 'ON': - checks.install_postfix_dovecot() - checks.setup_email_Passwords(installCyberPanel.InstallCyberPanel.mysqlPassword, mysql) - checks.setup_postfix_dovecot_config(mysql) - - checks.install_unzip() - checks.install_zip() - checks.install_rsync() - - checks.installFirewalld() - checks.install_default_keys() - - checks.download_install_CyberPanel(installCyberPanel.InstallCyberPanel.mysqlPassword, mysql) - checks.downoad_and_install_raindloop() - checks.download_install_phpmyadmin() - checks.setupCLI() - checks.setup_cron() - checks.installRestic() - checks.installAcme() - - ## Install and Configure OpenDKIM. - - if args.postfix is None: - checks.installOpenDKIM() - checks.configureOpenDKIM() - else: - if args.postfix == 'ON': - checks.installOpenDKIM() - checks.configureOpenDKIM() - - checks.modSecPreReqs() - checks.installLSCPD() - checks.setupPort() - checks.setupPythonWSGI() - checks.setupLSCPDDaemon() - - if args.redis is not None: - checks.installRedis() - - if args.postfix is not None: - checks.enableDisableEmail(args.postfix.lower()) - else: - preFlightsChecks.stdOut("Postfix will be installed and enabled.") - checks.enableDisableEmail('on') - - if args.powerdns is not None: - checks.enableDisableDNS(args.powerdns.lower()) - else: - preFlightsChecks.stdOut("PowerDNS will be installed and enabled.") - checks.enableDisableDNS('on') - - if args.ftp is not None: - checks.enableDisableFTP(args.ftp.lower(), distro) - else: - preFlightsChecks.stdOut("Pure-FTPD will be installed and enabled.") - checks.enableDisableFTP('on', distro) - - checks.installCLScripts() - # checks.disablePackegeUpdates() - - try: - # command = 'mkdir -p /usr/local/lscp/cyberpanel/rainloop/data/data/default/configs/' - # subprocess.call(shlex.split(command)) - - writeToFile = open('/usr/local/lscp/cyberpanel/rainloop/data/_data_/_default_/configs/application.ini', 'a') - - writeToFile.write(""" -[security] -admin_login = "admin" -admin_password = "12345" -""") - writeToFile.close() - - import randomPassword - - content = """SetPassword('%s'); -echo $oConfig->Save() ? 'Done' : 'Error'; - -?>""" % (randomPassword.generate_pass()) - - writeToFile = open('/usr/local/CyberCP/public/rainloop.php', 'w') - writeToFile.write(content) - writeToFile.close() - - command = '/usr/local/lsws/lsphp72/bin/php /usr/local/CyberCP/public/rainloop.php' - subprocess.call(shlex.split(command)) - - command = "chown -R lscpd:lscpd /usr/local/lscp/cyberpanel/rainloop/data" - subprocess.call(shlex.split(command)) - except: - pass - - checks.fixCyberPanelPermissions() - - logging.InstallLog.writeToFile("CyberPanel installation successfully completed!,80") - - -if __name__ == "__main__": - main() diff --git a/install/installCyberPanel.py b/install/installCyberPanel.py index 6f39a6788..620c641a8 100644 --- a/install/installCyberPanel.py +++ b/install/installCyberPanel.py @@ -44,6 +44,62 @@ FetchCloudLinuxAlmaVersionVersion = install_utils.FetchCloudLinuxAlmaVersionVers class InstallCyberPanel: mysql_Root_password = "" mysqlPassword = "" + + def is_almalinux9(self): + """Check if running on AlmaLinux 9""" + if os.path.exists('/etc/almalinux-release'): + try: + with open('/etc/almalinux-release', 'r') as f: + content = f.read() + return 'release 9' in content + except: + return False + return False + + def fix_almalinux9_mariadb(self): + """Fix AlmaLinux 9 MariaDB installation issues""" + if not self.is_almalinux9(): + return + + self.stdOut("Applying AlmaLinux 9 MariaDB fixes...", 1) + + try: + # Disable problematic MariaDB MaxScale repository + self.stdOut("Disabling problematic MariaDB MaxScale repository...", 1) + command = "dnf config-manager --disable mariadb-maxscale 2>/dev/null || true" + install_utils.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) + + # Remove problematic repository files + self.stdOut("Removing problematic repository files...", 1) + problematic_repos = [ + '/etc/yum.repos.d/mariadb-maxscale.repo', + '/etc/yum.repos.d/mariadb-maxscale.repo.rpmnew' + ] + for repo_file in problematic_repos: + if os.path.exists(repo_file): + os.remove(repo_file) + self.stdOut(f"Removed {repo_file}", 1) + + # Clean DNF cache + self.stdOut("Cleaning DNF cache...", 1) + command = "dnf clean all" + install_utils.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) + + # Install MariaDB from official repository + self.stdOut("Setting up official MariaDB repository...", 1) + command = "curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | bash -s -- --mariadb-server-version='10.11'" + install_utils.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) + + # Install MariaDB packages + self.stdOut("Installing MariaDB packages...", 1) + mariadb_packages = "MariaDB-server MariaDB-client MariaDB-backup MariaDB-devel" + command = f"dnf install -y {mariadb_packages}" + install_utils.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) + + self.stdOut("AlmaLinux 9 MariaDB fixes completed", 1) + + except Exception as e: + self.stdOut(f"Error applying AlmaLinux 9 MariaDB fixes: {str(e)}", 0) CloudLinux8 = 0 def install_package(self, package_name, options=""): @@ -335,7 +391,7 @@ class InstallCyberPanel: return self.reStartLiteSpeed() def installAllPHPVersions(self): - php_versions = ['71', '72', '73', '74', '80', '81', '82', '83'] + php_versions = ['71', '72', '73', '74', '80', '81', '82', '83', '84', '85'] if self.distro == ubuntu: # Install base PHP 7.x packages @@ -563,6 +619,12 @@ gpgcheck=1 if self.remotemysql == 'OFF': ############## Start mariadb ###################### + + # Check if AlmaLinux 9 and apply fixes + if self.is_almalinux9(): + self.stdOut("AlmaLinux 9 detected - applying MariaDB fixes", 1) + self.fix_almalinux9_mariadb() + self.manage_service('mariadb', 'start') ############## Enable mariadb at system startup ###################### diff --git a/install/venvsetup.sh.bak b/install/venvsetup.sh.bak deleted file mode 100644 index 85ab9ab41..000000000 --- a/install/venvsetup.sh.bak +++ /dev/null @@ -1,1290 +0,0 @@ -#!/bin/bash - -#CyberPanel installer script for Ubuntu 18.04 and CentOS 7.X -DEV="OFF" -BRANCH="stable" -POSTFIX_VARIABLE="ON" -POWERDNS_VARIABLE="ON" -PUREFTPD_VARIABLE="ON" -PROVIDER="undefined" -SERIAL_NO="" -DIR=$(pwd) -TEMP=$(curl --silent https://cyberpanel.net/version.txt) -CP_VER1=${TEMP:12:3} -CP_VER2=${TEMP:25:1} -SERVER_OS="CentOS" -VERSION="OLS" -LICENSE_KEY="" -KEY_SIZE="" -ADMIN_PASS="1234567" -MEMCACHED="ON" -REDIS="ON" -TOTAL_RAM=$(free -m | awk '/Mem\:/ { print $2 }') - -license_validation() { -CURRENT_DIR=$(pwd) - -if [ -f /root/cyberpanel-tmp ] ; then -rm -rf /root/cyberpanel-tmp -fi - -mkdir /root/cyberpanel-tmp -cd /root/cyberpanel-tmp -wget -q https://$DOWNLOAD_SERVER/litespeed/lsws-$LSWS_STABLE_VER-ent-x86_64-linux.tar.gz -tar xzvf lsws-$LSWS_STABLE_VER-ent-x86_64-linux.tar.gz > /dev/null -cd /root/cyberpanel-tmp/lsws-$LSWS_STABLE_VER/conf -if [[ $LICENSE_KEY == "TRIAL" ]] ; then -wget -q http://license.litespeedtech.com/reseller/trial.key -sed -i "s|writeSerial = open('lsws-5.4.2/serial.no', 'w')|command = 'wget -q --output-document=./lsws-$LSWS_STABLE_VER/trial.key http://license.litespeedtech.com/reseller/trial.key'|g" $CURRENT_DIR/installCyberPanel.py -sed -i 's|writeSerial.writelines(self.serial)|subprocess.call(command, shell=True)|g' $CURRENT_DIR/installCyberPanel.py -sed -i 's|writeSerial.close()||g' $CURRENT_DIR/installCyberPanel.py -else -echo $LICENSE_KEY > serial.no -fi - -cd /root/cyberpanel-tmp/lsws-$LSWS_STABLE_VER/bin - -if [[ $LICENSE_KEY == "TRIAL" ]] ; then - if ./lshttpd -V |& grep "ERROR" ; then - echo -e "\n\nIt apeears to have some issue with license , please check above result..." - exit - fi - LICENSE_KEY="1111-2222-3333-4444" -else - if ./lshttpd -r |& grep "ERROR" ; then - ./lshttpd -r - echo -e "\n\nIt apeears to have some issue with license , please check above result..." - exit - fi -fi -echo -e "License seems valid..." -cd /root/cyberpanel-tmp -rm -rf lsws-$LSWS_STABLE_VER* -cd $CURRENT_DIR -rm -rf /root/cyberpanel-tmp -} - -special_change(){ -sed -i 's|cyberpanel.sh|'$DOWNLOAD_SERVER'|g' install.py -sed -i 's|mirror.cyberpanel.net|'$DOWNLOAD_SERVER'|g' install.py -sed -i 's|git clone https://github.com/usmannasir/cyberpanel|echo downloaded|g' install.py -#change to CDN first, regardless country -sed -i 's|http://|https://|g' install.py - -LATEST_URL="https://update.litespeedtech.com/ws/latest.php" -#LATEST_URL="https://cyberpanel.sh/latest.php" -curl --silent -o /tmp/lsws_latest $LATEST_URL 2>/dev/null -LSWS_STABLE_LINE=`cat /tmp/lsws_latest | grep LSWS_STABLE` -LSWS_STABLE_VER=`expr "$LSWS_STABLE_LINE" : '.*LSWS_STABLE=\(.*\) BUILD .*'` - -if [[ $SERVER_COUNTRY == "CN" ]] ; then -#line1="$(grep -n "github.com/usmannasir/cyberpanel" install.py | head -n 1 | cut -d: -f1)" -#line2=$((line1 - 1)) -#sed -i "${line2}i\ \ \ \ \ \ \ \ subprocess.call(command, shell=True)" install.py -#sed -i "${line2}i\ \ \ \ \ \ \ \ command = 'tar xzvf cyberpanel-git.tar.gz'" install.py -#sed -i "${line2}i\ \ \ \ \ \ \ \ subprocess.call(command, shell=True)" install.py -#sed -i "${line2}i\ \ \ \ \ \ \ \ command = 'wget cyberpanel.sh/cyberpanel-git.tar.gz'" install.py -sed -i 's|wget https://rpms.litespeedtech.com/debian/|wget --no-check-certificate https://rpms.litespeedtech.com/debian/|g' install.py -sed -i 's|https://repo.powerdns.com/repo-files/centos-auth-42.repo|https://'$DOWNLOAD_SERVER'/powerdns/powerdns.repo|g' installCyberPanel.py -sed -i 's|https://www.rainloop.net/repository/webmail/rainloop-community-latest.zip|https://'$DOWNLOAD_SERVER'/misc/rainloop-community-latest.zip|g' install.py - -sed -i 's|rpm -ivh https://rpms.litespeedtech.com/centos/litespeed-repo-1.1-1.el7.noarch.rpm|curl -o /etc/yum.repos.d/litespeed.repo https://'$DOWNLOAD_SERVER'/litespeed/litespeed.repo|g' install.py - - -sed -i 's|https://copr.fedorainfracloud.org/coprs/copart/restic/repo/epel-7/copart-restic-epel-7.repo|https://'$DOWNLOAD_SERVER'/restic/restic.repo|g' install.py - -sed -i 's|yum -y install https://cyberpanel.sh/gf-release-latest.gf.el7.noarch.rpm|wget -O /etc/yum.repos.d/gf.repo https://'$DOWNLOAD_SERVER'/gf-plus/gf.repo|g' install.py -sed -i 's|dovecot-2.3-latest|dovecot-2.3-latest-mirror|g' install.py -sed -i 's|git clone https://github.com/usmannasir/cyberpanel|wget https://cyberpanel.sh/cyberpanel-git.tar.gz \&\& tar xzvf cyberpanel-git.tar.gz|g' install.py -sed -i 's|https://repo.dovecot.org/ce-2.3-latest/centos/$releasever/RPMS/$basearch|https://'$DOWNLOAD_SERVER'/dovecot/|g' install.py -sed -i 's|'$DOWNLOAD_SERVER'|cyberpanel.sh|g' install.py -sed -i 's|https://www.litespeedtech.com/packages/5.0/lsws-5.4.2-ent-x86_64-linux.tar.gz|https://'$DOWNLOAD_SERVER'/litespeed/lsws-'$LSWS_STABLE_VER'-ent-x86_64-linux.tar.gz|g' installCyberPanel.py -# global change for CN , regardless provider and system - - if [[ $SERVER_OS == "CentOS" ]] ; then - DIR=$(pwd) - cd $DIR/mysql - echo "[mariadb-tsinghua] -name = MariaDB -baseurl = https://mirrors.tuna.tsinghua.edu.cn/mariadb/yum/10.1/centos7-amd64 -gpgkey = https://mirrors.tuna.tsinghua.edu.cn/mariadb/yum//RPM-GPG-KEY-MariaDB -gpgcheck = 1" > MariaDB.repo -#above to set mariadb db to Tsinghua repo - cd $DIR - sed -i 's|https://www.litespeedtech.com/packages/5.0/lsws-5.3.5-ent-x86_64-linux.tar.gz|https://cyberpanel.sh/packages/5.0/lsws-5.3.5-ent-x86_64-linux.tar.gz|g' installCyberPanel.py - mkdir /root/.pip - cat << EOF > /root/.pip/pip.conf -[global] -index-url = https://mirrors.aliyun.com/pypi/simple/ -EOF - echo -e "\nSet to Aliyun pip repo..." - cat << EOF > composer.sh -#!/usr/bin/env bash -php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" -php composer-setup.php -php -r "unlink('composer-setup.php');" -mv composer.phar /usr/bin/composer - -if [ ! -d /root/.config ]; then -mkdir /root/.config -fi - -if [ ! -d /root/.config/composer ]; then -mkdir /root/.config/composer -fi - -echo '{ - "bitbucket-oauth": {}, - "github-oauth": {}, - "gitlab-oauth": {}, - "gitlab-token": {}, - "http-basic": {} -} -' > /root/.config/composer/auth.json - -echo '{ - "config": {}, - "repositories": { - "packagist": { - "type": "composer", - "url": "https://mirrors.aliyun.com/composer/" - } - } -} -' > /root/.config/composer/config.json -composer clear-cache -EOF - fi - - - if [[ $SERVER_OS == "Ubuntu" ]] ; then - echo $'\n89.208.248.38 rpms.litespeedtech.com\n' >> /etc/hosts - echo -e "Mirror server set..." - pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/ - cat << EOF > /root/.pip/pip.conf -[global] -index-url = https://mirrors.aliyun.com/pypi/simple/ -EOF - echo -e "\nSet to Aliyun pip repo..." - if [[ $PROVIDER == "Tencent Cloud" ]] ; then - #tencent cloud and ubuntu system - echo -e "\n Tencent Cloud detected ... bypass default repository" - cp /etc/apt/sources.list /etc/apt/sources.list-backup - #backup original sources list - cat << 'EOF' > /etc/apt/sources.list -deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse -deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse -deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse -deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse -deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse -deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse -deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse -deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse -deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse -deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse -EOF - DEBIAN_FRONTEND=noninteractive apt update -y - pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/ - cat << EOF > composer.sh -#!/usr/bin/env bash -php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" -php composer-setup.php -php -r "unlink('composer-setup.php');" -mv composer.phar /usr/bin/composer - -if [ ! -d /root/.config ]; then -mkdir /root/.config -fi - -if [ ! -d /root/.config/composer ]; then -mkdir /root/.config/composer -fi - -echo '{ - "bitbucket-oauth": {}, - "github-oauth": {}, - "gitlab-oauth": {}, - "gitlab-token": {}, - "http-basic": {} -} -' > /root/.config/composer/auth.json - -echo '{ - "config": {}, - "repositories": { - "packagist": { - "type": "composer", - "url": "https://mirrors.cloud.tencent.com/composer/" - } - } -} -' > /root/.config/composer/config.json -composer clear-cache -EOF - else - cat << EOF > composer.sh -#!/usr/bin/env bash -php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" -php composer-setup.php -php -r "unlink('composer-setup.php');" -mv composer.phar /usr/bin/composer - -if [ ! -d /root/.config ]; then -mkdir /root/.config -fi - -if [ ! -d /root/.config/composer ]; then -mkdir /root/.config/composer -fi - -echo '{ - "bitbucket-oauth": {}, - "github-oauth": {}, - "gitlab-oauth": {}, - "gitlab-token": {}, - "http-basic": {} -} -' > /root/.config/composer/auth.json - -echo '{ - "config": {}, - "repositories": { - "packagist": { - "type": "composer", - "url": "https://packagist.phpcomposer.com" - } - } -} -' > /root/.config/composer/config.json -composer clear-cache -EOF - fi - fi -fi -} - - -system_tweak() { -if [[ $SERVER_OS == "CentOS" ]] ; then - setenforce 0 - sed -i 's/SELINUX=enforcing/SELINUX=permissive/g' /etc/selinux/config -fi - -if ! grep -q "pid_max" /etc/rc.local; then - if [[ $SERVER_OS == "CentOS" ]] ; then - echo "echo 1000000 > /proc/sys/kernel/pid_max -echo 1 > /sys/kernel/mm/ksm/run" >> /etc/rc.d/rc.local - chmod +x /etc/rc.d/rc.local - else - echo "echo 1000000 > /proc/sys/kernel/pid_max -echo 1 > /sys/kernel/mm/ksm/run" >> /etc/rc.local - chmod +x /etc/rc.local - fi - echo "fs.file-max = 65535" >> /etc/sysctl.conf - sysctl -p > /dev/null - echo "* soft nofile 65535 -* hard nofile 65535 -root soft nofile 65535 -root hard nofile 65535 -* soft nproc 65535 -* hard nproc 65535 -root soft nproc 65535 -root hard nproc 65535" >> /etc/security/limits.conf -fi - -#sed -i 's|#DefaultLimitNOFILE=|DefaultLimitNOFILE=65535|g' /etc/systemd/system.conf - - -TOTAL_SWAP=$(free -m | awk '/^Swap:/ { print $2 }') -SET_SWAP=$((TOTAL_RAM - TOTAL_SWAP)) -SWAP_FILE=/cyberpanel.swap - -if [ ! -f $SWAP_FILE ] ; then - if [[ $TOTAL_SWAP -gt $TOTAL_RAM ]] || [[ $TOTAL_SWAP -eq $TOTAL_RAM ]] ; then - echo "SWAP check..." - else - if [[ $SET_SWAP -gt "2049" ]] ; then - SET_SWAP="2048" - else - echo "Checking SWAP..." - fi - fallocate --length ${SET_SWAP}MiB $SWAP_FILE - chmod 600 $SWAP_FILE - mkswap $SWAP_FILE - swapon $SWAP_FILE - echo "${SWAP_FILE} swap swap sw 0 0" | sudo tee -a /etc/fstab - sysctl vm.swappiness=10 - echo "vm.swappiness = 10" >> /etc/sysctl.conf - echo "SWAP set..." - fi -fi -} - - -install_required() { -echo -e "\nInstalling necessary components..." -if [[ $SERVER_OS == "CentOS" ]] ; then - rpm --import https://$DOWNLOAD_SERVER/mariadb/RPM-GPG-KEY-MariaDB - rpm --import https://$DOWNLOAD_SERVER/litespeed/RPM-GPG-KEY-litespeed - rpm --import https://$DOWNLOAD_SERVER/powerdns/FD380FBB-pub.asc - rpm --import http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-7 - rpm --import https://$DOWNLOAD_SERVER/gf-plus/RPM-GPG-KEY-gf.el7 - rpm --import https://repo.dovecot.org/DOVECOT-REPO-GPG - rpm --import https://copr-be.cloud.fedoraproject.org/results/copart/restic/pubkey.gpg - yum autoremove epel-release -y - rm -f /etc/yum.repos.d/epel.repo - rm -f /etc/yum.repos.d/epel.repo.rpmsave - yum clean all - yum update -y - yum install epel-release -y - yum install -y wget strace htop net-tools telnet curl which bc telnet htop libevent-devel gcc python-devel libattr-devel xz-devel gpgme-devel mariadb-devel curl-devel python-pip git - if [[ $DEV == "ON" ]] ; then - yum -y install yum-utils - yum -y groupinstall development - yum -y install https://centos7.iuscommunity.org/ius-release.rpm - yum -y install python36u python36u-pip python36u-devel - fi -fi - -if [[ $SERVER_OS == "Ubuntu" ]] ; then - apt update -y - DEBIAN_FRONTEND=noninteractive apt upgrade -y - DEBIAN_FRONTEND=noninteractive apt install -y htop telnet python-mysqldb python-dev libcurl4-gnutls-dev libgnutls28-dev libgcrypt20-dev libattr1 libattr1-dev liblzma-dev libgpgme-dev libmariadbclient-dev libcurl4-gnutls-dev libssl-dev nghttp2 libnghttp2-dev idn2 libidn2-dev libidn2-0-dev librtmp-dev libpsl-dev nettle-dev libgnutls28-dev libldap2-dev libgssapi-krb5-2 libk5crypto3 libkrb5-dev libcomerr2 libldap2-dev python-gpg python python-minimal python-setuptools virtualenv python-dev python-pip git - if [[ $DEV == "ON" ]] ; then - DEBIAN_FRONTEND=noninteractive apt install -y python3-pip - DEBIAN_FRONTEND=noninteractive apt install -y build-essential libssl-dev libffi-dev python3-dev - DEBIAN_FRONTEND=noninteractive apt install -y python3-venv - fi -fi -} - -memcached_installation() { -if [[ $SERVER_OS == "CentOS" ]] ; then - yum install -y lsphp73-memcached lsphp72-memcached lsphp71-memcached lsphp70-memcached lsphp56-pecl-memcached lsphp55-pecl-memcached lsphp54-pecl-memcached - if [[ $TOTAL_RAM -eq "2048" ]] || [[ $TOTAL_RAM -gt "2048" ]] ; then - yum groupinstall "Development Tools" -y - yum install autoconf automake zlib-devel openssl-devel expat-devel pcre-devel libmemcached-devel cyrus-sasl* -y - wget https://$DOWNLOAD_SERVER/litespeed/lsmcd.tar.gz - tar xzvf lsmcd.tar.gz - DIR=$(pwd) - cd $DIR/lsmcd - ./fixtimestamp.sh - ./configure CFLAGS=" -O3" CXXFLAGS=" -O3" - make - make install - systemctl enable lsmcd - systemctl start lsmcd - cd $DIR - else - yum install -y memcached - sed -i 's|OPTIONS=""|OPTIONS="-l 127.0.0.1 -U 0"|g' /etc/sysconfig/memcached - systemctl enable memcached - systemctl start memcached - fi -fi -if [[ $SERVER_OS == "Ubuntu" ]] ; then - DEBIAN_FRONTEND=noninteractive apt install -y lsphp73-memcached lsphp72-memcached lsphp71-memcached lsphp70-memcached - if [[ $TOTAL_RAM -eq "2048" ]] || [[ $TOTAL_RAM -gt "2048" ]] ; then - DEBIAN_FRONTEND=noninteractive apt install build-essential zlib1g-dev libexpat1-dev openssl libssl-dev libsasl2-dev libpcre3-dev git -y - wget https://$DOWNLOAD/litespeed/lsmcd.tar.gz - tar xzvf lsmcd.tar.gz - DIR=$(pwd) - cd $DIR/lsmcd - ./fixtimestamp.sh - ./configure CFLAGS=" -O3" CXXFLAGS=" -O3" - make - make install - cd $DIR - systemctl enable lsmcd - systemctl start lsmcd - else - DEBIAN_FRONTEND=noninteractive apt install -y memcached - systemctl enable memcached - systemctl start memcached - fi -fi - -if ps -aux | grep "lsmcd" | grep -v grep ; then - echo -e "\n\nLiteSpeed Memcached installed and running..." -fi - -if ps -aux | grep "memcached" | grep -v grep ; then - echo -e "\n\nMemcached installed and running..." -fi - -} - -redis_installation() { -if [[ $SERVER_OS == "CentOS" ]] ; then - yum install -y lsphp73-redis lsphp72-redis lsphp71-redis lsphp70-redis lsphp56-redis lsphp55-redis lsphp54-redis redis -fi -if [[ $SERVER_OS == "Ubuntu" ]] ; then - DEBIAN_FRONTEND=noninteractive apt install -y lsphp73-redis lsphp72-redis lsphp71-redis lsphp70-redis redis -fi - -if ifconfig -a | grep inet6 ; then - echo -e "\n IPv6 detected..." -else - sed -i 's|bind 127.0.0.1 ::1|bind 127.0.0.1|g' /etc/redis/redis.conf - echo -e "\n no IPv6 detected..." -fi - -if [[ $SERVER_OS == "CentOS" ]] ; then - systemctl enable redis - systemctl start redis -fi - -if [[ $SERVER_OS == "Ubuntu" ]] ; then - systemctl enable redis-server - systemctl start redis-server -fi - -if ps -aux | grep "redis" | grep -v grep ; then - echo -e "\n\nRedis installed and running..." -fi -} - -check_provider() { - -if hash dmidecode > /dev/null 2>&1 ; then - if [ "$(dmidecode -s bios-vendor)" = 'Google' ] ; then - PROVIDER='Google Cloud Platform' - elif [ "$(dmidecode -s bios-vendor)" = 'DigitalOcean' ] ; then - PROVIDER='Digital Ocean' - elif [ "$(dmidecode -s system-product-name | cut -c 1-7)" = 'Alibaba' ] ; then - PROVIDER='Alibaba Cloud' - elif [ "$(dmidecode -s system-manufacturer)" = 'Microsoft Corporation' ] ; then - PROVIDER='Microsoft Azure' - elif [ -d /usr/local/qcloud ] ; then - PROVIDER='Tencent Cloud' - else - PROVIDER='undefined' - fi -else - PROVIDER='undefined' -fi - -if [ "$(cat /sys/devices/virtual/dmi/id/product_uuid | cut -c 1-3)" = 'EC2' ] && [ -d /home/ubuntu ]; then - PROVIDER='Amazon Web Service' -fi - -} - - -check_OS() { -echo -e "\nChecking OS..." -OUTPUT=$(cat /etc/*release) -if echo $OUTPUT | grep -q "CentOS Linux 7" ; then - echo -e "\nDetecting CentOS 7.X...\n" - SERVER_OS="CentOS" -elif echo $OUTPUT | grep -q "CloudLinux 7" ; then - echo -e "\nDetecting CloudLinux 7.X...\n" - SERVER_OS="CentOS" -elif echo $OUTPUT | grep -q "Ubuntu 18.04" ; then - echo -e "\nDetecting Ubuntu 18.04...\n" - SERVER_OS="Ubuntu" -else - cat /etc/*release - echo -e "\nUnable to detect your OS...\n" - echo -e "\nCyberPanel is supported on Ubuntu 18.04, CentOS 7.x and CloudLinux 7.x...\n" - exit 1 -fi -} - -check_root() { -echo -e "Checking root privileges...\n" -if [[ $(id -u) != 0 ]] > /dev/null; then - echo -e "You must use root account to do this" - echo -e "or run following command: (do NOT miss the quotes)" - echo -e "\e[31msudo su -c \"sh <(curl https://cyberpanel.sh || wget -O - https://cyberpanel.sh)\"\e[39m" - exit 1 -else - echo -e "You are runing as root...\n" -fi -} - -check_panel() { -if [ -d /usr/local/cpanel ]; then - echo -e "\ncPanel detected...exit...\n" - exit 1 -fi -if [ -d /opt/plesk ]; then - echo -e "\nPlesk detected...exit...\n" - exit 1 -fi -} - -check_process() { -if systemctl is-active --quiet httpd; then - systemctl disable httpd - systemctl stop httpd - echo -e "\nhttpd process detected, disabling...\n" -fi -if systemctl is-active --quiet apache2; then - systemctl disable apache2 - systemctl stop apache2 - echo -e "\napache2 process detected, disabling...\n" -fi -if systemctl is-active --quiet named; then - systemctl stop named - systemctl disable named - echo -e "\nnamed process detected, disabling...\n" -fi -if systemctl is-active --quiet exim; then - systemctl stop exim - systemctl disable exim - echo -e "\nexim process detected, disabling...\n" -fi -} - -show_help() { -echo -e "\nCyberPanel Installer Script Help\n" -echo -e "\nUsage: wget https://cyberpanel.sh/cyberpanel.sh" -echo -e "\nchmod +x cyberpanel.sh" -echo -e "\n./cyberpanel.sh -v ols/SERIAL_NUMBER -c 1 -a 1" -echo -e "\n -v or --version: choose to install CyberPanel OpenLiteSpeed or CyberPanel Enterprise, available options are \e[31mols\e[39m and \e[31mSERIAL_NUMBER\e[39m, default ols" -echo -e "\n Please be aware, this serial number must be obtained from LiteSpeed Store." -echo -e "\n And if this serial number has been used before, it must be released/migrated in Store first, otherwise it will fail to start." -echo -e "\n -a or --addons: install addons: memcached, redis, PHP extension for memcached and redis, 1 for install addons, 0 for not to install, default 0, only applicable for CentOS system." -echo -e "\n -p or --password: set password of new installation, empty for default 1234567, [r] or [random] for randomly generated 16 digital password, any other value besdies [d] and [r(andom)] will be accept as password, default use 1234567." -#echo -e "\n -m: set to minimal mode which will not install PowerDNS, Pure-FTPd and Postfix" -echo -e "\n Example:" -echo -e "\n ./cyberpanel.sh -v ols -p r or ./cyberpanel.sh --version ols --password random" -echo -e "\n This will install CyberPanel OpenLiteSpeed and randomly generate the password." -echo -e "\n ./cyberpanel.sh default" -echo -e "\n This will install everything default , which is OpenLiteSpeed and nothing more.\n" - -} - -license_input() { -VERSION="ENT" -echo -e "\nPlease note that your server has \e[31m$TOTAL_RAM\e[39m RAM" -echo -e "If you are using \e[31mFree Start\e[39m license, It will not start due to \e[31m2GB RAM limit\e[39m.\n" -echo -e "If you do not have any license, you can also use trial license (if server has not used trial license before), type \e[31mTRIAL\e[39m\n" - -printf "%s" "Please input your serial number for LiteSpeed WebServer Enterprise:" -read LICENSE_KEY -if [ -z "$LICENSE_KEY" ] ; then - echo -e "\nPlease provide license key\n" - exit -fi - -echo -e "The serial number you input is: \e[31m$LICENSE_KEY\e[39m" -printf "%s" "Please verify it is correct. [y/N]" -read TMP_YN -if [ -z "$TMP_YN" ] ; then - echo -e "\nPlease type \e[31my\e[39m\n" - exit -fi - -KEY_SIZE=${#LICENSE_KEY} -TMP=$(echo $LICENSE_KEY | cut -c5) -TMP2=$(echo $LICENSE_KEY | cut -c10) -TMP3=$(echo $LICENSE_KEY | cut -c15) - -if [[ $TMP == "-" ]] && [[ $TMP2 == "-" ]] && [[ $TMP3 == "-" ]] && [[ $KEY_SIZE == "19" ]] ; then - echo -e "\nLicense key set..." -elif [[ $LICENSE_KEY == "trial" ]] || [[ $LICENSE_KEY == "TRIAL" ]] || [[ $LICENSE_KEY == "Trial" ]] ; then - echo -e "\nTrial license set..." - LICENSE_KEY="TRIAL" -else - echo -e "\nLicense key seems incorrect, please verify\n" - echo -e "\nIf you are copying/pasting, please make sure you didn't paste blank space...\n" - exit -fi -} - -interactive_mode() { -echo -e " CyberPanel Installer v$CP_VER1$CP_VER2 - - 1. Install CyberPanel. - - 2. Addons and Miscellaneous - - 3. Exit. - - " -read -p " Please enter the number[1-3]: " num -echo "" -case "$num" in - 1) - interactive_install - ;; - 2) - interactive_others - ;; - 3) - exit - ;; - *) - echo -e " Please enter the right number [1-3]\n" - exit - ;; -esac -} - -interactive_others() { -if [ ! -e "/etc/cyberpanel/machineIP" ]; then -echo -e "\nYou don't have CyberPanel installed...\n" -exit -fi - -echo -e " CyberPanel Addons v$CP_VER1$CP_VER2 - - 1. Install Memcached extension and backend - - 2. Install Redis extension and backend - - 3. Return to main page. - - 4. Exit - " - -echo && read -p "Please enter the number[1-4]: " num -case "$num" in - 1) - memcached_installation - exit - ;; - 2) - redis_installation - exit - ;; - 3) - interactive_mode - ;; - 4) - exit - ;; - *) - echo -e "${Error} please enter the right number [1-4]" - ;; -esac -} - -interactive_install() { -RAM=$(free -m | awk 'NR==2{printf "%s/%sMB (%.2f%%)\n", $3,$2,$3*100/$2 }') -DISK=$(df -h | awk '$NF=="/"{printf "%d/%dGB (%s)\n", $3,$2,$5}') -#clear -echo -e " CyberPanel Installer v$CP_VER1$CP_VER2 - - RAM check : $RAM - - Disk check : $DISK (Minimal \e[31m10GB\e[39m free space) - - 1. Install CyberPanel with \e[31mOpenLiteSpeed\e[39m. - - 2. Install Cyberpanel with \e[31mLiteSpeed Enterprise\e[39m. - - 3. Exit. - - " -read -p " Please enter the number[1-3]: " num -echo "" -case "$num" in - 1) - VERSION="OLS" - ;; - 2) - license_input - ;; - 3) - exit - ;; - *) - echo -e " Please enter the right number [1-3]\n" - exit - ;; -esac - -< /dev/null; then - echo -e "\nCyberPanel installation sucessfully completed..." -else - echo -e "Oops, something went wrong..." - exit -fi - -if [[ $MEMCACHED == "ON" ]] ; then - memcached_installation -fi -if [[ $REDIS == "ON" ]] ; then - redis_installation -fi - after_install -fi -} - -pip_virtualenv() { -if [[ $DEV == "OFF" ]] ; then -if [[ $SERVER_COUNTRY == "CN" ]] ; then - mkdir /root/.pip -cat << EOF > /root/.pip/pip.conf -[global] -index-url = https://mirrors.aliyun.com/pypi/simple/ -EOF -fi - -if [[ $PROVIDER == "Alibaba Cloud" ]] ; then - pip install --upgrade pip - pip install setuptools==40.8.0 -fi - -pip install virtualenv -virtualenv --system-site-packages /usr/local/CyberPanel -source /usr/local/CyberPanel/bin/activate -rm -rf requirements.txt -wget -O requirements.txt https://raw.githubusercontent.com/usmannasir/cyberpanel/1.8.0/requirments.txt -pip install --ignore-installed -r requirements.txt -virtualenv --system-site-packages /usr/local/CyberPanel -fi - -if [[ $DEV == "ON" ]] ; then - #install dev branch - #wget https://raw.githubusercontent.com/usmannasir/cyberpanel/$BRANCH_NAME/requirments.txt - cd /usr/local/ - python3.6 -m venv CyberPanel - source /usr/local/CyberPanel/bin/activate - wget -O requirements.txt https://raw.githubusercontent.com/usmannasir/cyberpanel/$BRANCH_NAME/requirments.txt - pip3.6 install --ignore-installed -r requirements.txt -fi - -if [ -f requirements.txt ] && [ -d cyberpanel ] ; then - rm -rf cyberpanel - rm -f requirements.txt -fi - -if [[ $SERVER_COUNTRY == "CN" ]] ; then - wget https://cyberpanel.sh/cyberpanel-git.tar.gz - tar xzvf cyberpanel-git.tar.gz > /dev/null - cp -r cyberpanel /usr/local/cyberpanel - cd cyberpanel/install -else - if [[ $DEV == "ON" ]] ; then - git clone https://github.com/usmannasir/cyberpanel - cd cyberpanel - git checkout $BRANCH_NAME - cd - - cd cyberpanel/install - else - git clone https://github.com/usmannasir/cyberpanel - cd cyberpanel/install - fi -fi -curl https://cyberpanel.sh/?version -} - -after_install() { -if [ ! -d "/var/lib/php" ]; then - mkdir /var/lib/php -fi - -if [ ! -d "/var/lib/php/session" ]; then - mkdir /var/lib/php/session -fi - -chmod 1733 /var/lib/php/session - -if grep "\[ERROR\] We are not able to run ./install.sh return code: 1. Fatal error, see /var/log/installLogs.txt for full details" /var/log/installLogs.txt > /dev/null; then - cd ${DIR}/cyberpanel/install/lsws-* - ./install.sh - echo -e "\n\n\nIt seems LiteSpeed Enterprise has failed to install, please check your license key is valid" - echo -e "\nIf this license key has been used before, you may need to go to store to release it first." - exit -fi - - -if grep "CyberPanel installation successfully completed" /var/log/installLogs.txt > /dev/null; then - -if [[ $DEV == "ON" ]] ; then -python3.6 -m venv /usr/local/CyberCP -source /usr/local/CyberCP/bin/activate -wget -O requirements.txt https://raw.githubusercontent.com/usmannasir/cyberpanel/$BRANCH_NAME/requirments.txt -pip3.6 install --ignore-installed -r requirements.txt -systemctl restart lscpd -fi - -for version in $(ls /usr/local/lsws | grep lsphp); - do - php_ini=$(find /usr/local/lsws/$version/ -name php.ini) - version2=${version:5:2} - version2=$(awk "BEGIN { print "${version2}/10" }") - if [[ $version2 = "7" ]] ; then - version2="7.0" - fi - if [[ $SERVER_OS == "CentOS" ]] ; then - yum remove -y $version-mysql - yum install -y $version-mysqlnd - yum install -y $version-devel make gcc glibc-devel libmemcached-devel zlib-devel - if [[ ! -d /usr/local/lsws/$version/tmp ]] ; then - mkdir /usr/local/lsws/$version/tmp - fi - /usr/local/lsws/${version}/bin/pecl channel-update pecl.php.net; - /usr/local/lsws/${version}/bin/pear config-set temp_dir /usr/local/lsws/${version}/tmp - /usr/local/lsws/${version}/bin/pecl install timezonedb - echo "extension=timezonedb.so" > /usr/local/lsws/${version}/etc/php.d/20-timezone.ini - sed -i 's|expose_php = On|expose_php = Off|g' $php_ini - sed -i 's|mail.add_x_header = On|mail.add_x_header = Off|g' $php_ini - sed -i 's|;session.save_path = "/tmp"|session.save_path = "/var/lib/php/session"|g' $php_ini - fi - - if [[ $SERVER_OS == "Ubuntu" ]] ; then - if [[ ! -d /usr/local/lsws/cyberpanel-tmp ]] ; then - echo "yes" > /etc/pure-ftpd/conf/ChrootEveryone - systemctl restart pure-ftpd-mysql - DEBIAN_FRONTEND=noninteractive apt install libmagickwand-dev pkg-config build-essential -y - mkdir /usr/local/lsws/cyberpanel-tmp - cd /usr/local/lsws/cyberpanel-tmp - wget https://pecl.php.net/get/timezonedb-2019.3.tgz - tar xzvf timezonedb-2019.3.tgz - cd timezonedb-2019.3 - fi - /usr/local/lsws/${version}/bin/phpize - ./configure --with-php-config=/usr/local/lsws/${version}/bin/php-config${version2} - make - make install - echo "extension=timezonedb.so" > /usr/local/lsws/${version}/etc/php/${version2}/mods-available/20-timezone.ini - make clean - fi -done - -rm -rf /etc/profile.d/cyberpanel* -curl --silent -o /etc/profile.d/cyberpanel.sh https://cyberpanel.sh/?banner 2>/dev/null -chmod +x /etc/profile.d/cyberpanel.sh -RAM2=$(free -m | awk 'NR==2{printf "%s/%sMB (%.2f%%)\n", $3,$2,$3*100/$2 }') -DISK2=$(df -h | awk '$NF=="/"{printf "%d/%dGB (%s)\n", $3,$2,$5}') -ELAPSED="$(($SECONDS / 3600)) hrs $((($SECONDS / 60) % 60)) min $(($SECONDS % 60)) sec" -MYSQLPASSWD=$(cat /etc/cyberpanel/mysqlPassword) -echo "$ADMIN_PASS" > /etc/cyberpanel/adminPass -/usr/local/CyberPanel/bin/python2 /usr/local/CyberCP/plogical/adminPass.py --password $ADMIN_PASS -systemctl restart lscpd -systemctl restart lsws -echo "/usr/local/CyberPanel/bin/python2 /usr/local/CyberCP/plogical/adminPass.py --password \"\$@\"" > /usr/bin/adminPass -echo "systemctl restart lscpd" >> /usr/bin/adminPass -chmod +x /usr/bin/adminPass -if [[ $VERSION = "OLS" ]] ; then - WORD="OpenLiteSpeed" -# sed -i 's|maxConnections 10000|maxConnections 100000|g' /usr/local/lsws/conf/httpd_config.conf -# OLS_LATEST=$(curl https://openlitespeed.org/packages/release) -# wget https://openlitespeed.org/packages/openlitespeed-$OLS_LATEST.tgz -# tar xzvf openlitespeed-$OLS_LATEST.tgz -# cd openlitespeed -# ./install.sh - /usr/local/lsws/bin/lswsctrl stop - /usr/local/lsws/bin/lswsctrl start -# rm -f openlitespeed-$OLS_LATEST.tgz -# rm -rf openlitespeed -# cd .. -fi -if [[ $VERSION = "ENT" ]] ; then - WORD="LiteSpeed Enterprise" - if [[ $SERVER_COUNTRY != "CN" ]] ; then - /usr/local/lsws/admin/misc/lsup.sh -f -v $LSWS_STABLE_VER - fi -fi - -systemctl status lsws 2>&1>/dev/null -if [[ $? == "0" ]] ; then - echo "LSWS service is running..." -else - systemctl stop lsws - systemctl start lsws -fi - -clear -echo "###################################################################" -echo " CyberPanel Successfully Installed " -echo " " -echo " Current Disk usage : $DISK2 " -echo " " -echo " Current RAM usage : $RAM2 " -echo " " -echo " Installation time : $ELAPSED " -echo " " -echo " Visit: https://$SERVER_IP:8090 " -echo " Panel username: admin " -echo " Panel password: $ADMIN_PASS " -#echo " Mysql username: root " -#echo " Mysql password: $MYSQLPASSWD " -echo " " -echo " Please change your default admin password " -echo " If you need to reset your panel password, please run: " -echo " adminPass YOUR_NEW_PASSWORD " -echo " " -echo " If you change mysql password, please modify file in " -echo -e " \e[31m/etc/cyberpanel/mysqlPassword\e[39m with new password as well " -echo " " -echo " Website : https://www.cyberpanel.net " -echo " Forums : https://forums.cyberpanel.net " -echo " Wikipage: https://cyberpanel.net/KnowledgeBase/ " -echo " " -echo -e " Enjoy your accelerated Internet by " -echo -e " CyberPanel & $WORD " -echo "###################################################################" -if [[ $PROVIDER != "undefined" ]] ; then - echo -e "\033[0;32m$PROVIDER\033[39m detected..." - echo -e "This provider has a \e[31mnetwork-level firewall\033[39m" -else - echo -e "If your provider has a \e[31mnetwork-level firewall\033[39m" -fi - echo -e "Please make sure you have opened following port for both in/out:" - echo -e "\033[0;32mTCP: 8090\033[39m for CyberPanel" - echo -e "\033[0;32mTCP: 80\033[39m, \033[0;32mTCP: 443\033[39m and \033[0;32mUDP: 443\033[39m for webserver" - echo -e "\033[0;32mTCP: 21\033[39m and \033[0;32mTCP: 40110-40210\033[39m for FTP" - echo -e "\033[0;32mTCP: 25\033[39m, \033[0;32mTCP: 587\033[39m, \033[0;32mTCP: 465\033[39m, \033[0;32mTCP: 110\033[39m, \033[0;32mTCP: 143\033[39m and \033[0;32mTCP: 993\033[39m for mail service" - echo -e "\033[0;32mTCP: 53\033[39m and \033[0;32mUDP: 53\033[39m for DNS service" -if [[ $SERVER_COUNTRY = CN ]] ; then - if [[ $PROVIDER == "Tencent Cloud" ]] ; then - if [[ $SERVER_OS == "Ubuntu" ]] ; then - rm -f /etc/apt/sources.list - mv /etc/apt/sources.list-backup /etc/apt/sources.list -echo > "nameserver 127.0.0.53 -options edns0" /run/systemd/resolve/stub-resolv.conf -echo > "nameserver 127.0.0.53 -options edns0" /etc/resolv.conf - apt update -#revert the previous change on tencent cloud repo. - fi - fi - if [[ $VERSION = "ENT" ]] ; then - sed -i 's|https://www.litespeedtech.com/packages/5.0/lsws-5.3.5-ent-x86_64-linux.tar.gz|https://cyberpanel.sh/packages/5.0/lsws-5.3.5-ent-x86_64-linux.tar.gz|g' /usr/local/CyberCP/install/installCyberPanel.py - sed -i 's|https://www.litespeedtech.com/packages/5.0/lsws-5.3.8-ent-x86_64-linux.tar.gz|https://cyberpanel.sh/packages/5.0/lsws-5.3.8-ent-x86_64-linux.tar.gz|g' /usr/local/CyberCP/serverStatus/serverStatusUtil.py - sed -i 's|https://www.litespeedtech.com/packages/5.0/lsws-5.3.8-ent-x86_64-linux.tar.gz|https://'$DOWNLOAD_SERVER'/litespeed/lsws-'$LSWS_STABLE_VER'-ent-x86_64-linux.tar.gz|g' /usr/local/CyberCP/serverStatus/serverStatusUtil.py - echo -e "If you have install LiteSpeed Enterprise, please run \e[31m/usr/local/lsws/admin/misc/lsup.sh\033[39m to update it to latest." - fi -fi - -sed -i 's|lsws-5.3.8|lsws-'$LSWS_STABLE_VER'|g' /usr/local/CyberCP/serverStatus/serverStatusUtil.py -sed -i 's|lsws-5.4.2|lsws-'$LSWS_STABLE_VER'|g' /usr/local/CyberCP/serverStatus/serverStatusUtil.py -sed -i 's|lsws-5.3.5|lsws-'$LSWS_STABLE_VER'|g' /usr/local/CyberCP/serverStatus/serverStatusUtil.py - -if [[ $SILENT != "ON" ]] ; then -printf "%s" "Would you like to restart your server now? [y/N]: " -read TMP_YN - -if [[ "$TMP_YN" = "N" ]] || [[ "$TMP_YN" = "n" ]] || [[ -z "$TMP_YN" ]]; then -: -else -reboot -exit -fi - -exit -fi -#replace URL for CN - - - -else -echo "something went wrong..." -exit -fi -} - -argument_mode() { -KEY_SIZE=${#VERSION} -TMP=$(echo $VERSION | cut -c5) -TMP2=$(echo $VERSION | cut -c10) -TMP3=$(echo $VERSION | cut -c15) -if [[ $VERSION == "OLS" || $VERSION == "ols" ]] ; then - VERSION="OLS" - echo -e "\nSet to OpenLiteSpeed..." -elif [[ $VERSION == "Trial" ]] || [[ $VERSION == "TRIAL" ]] || [[ $VERSION == "trial" ]] ; then - VERSION="ENT" - LICENSE_KEY="TRIAL" - echo -e "\nLiteSpeed Enterprise trial license set..." -elif [[ $TMP == "-" ]] && [[ $TMP2 == "-" ]] && [[ $TMP3 == "-" ]] && [[ $KEY_SIZE == "19" ]] ; then - LICENSE_KEY=$VERSION - VERSION="ENT" - echo -e "\nLiteSpeed Enterprise license key set..." -else - echo -e "\nCan not recognize the input value \e[31m$VERSION\e[39m " - echo -e "\nPlease verify the input value..." - echo -e "\nPlease run with \e[31m-h\e[39m or \e[31m--help\e[39m for more detail." - exit -fi - -if [[ $ADMIN_PASS == "d" ]] ; then - ADMIN_PASS="1234567" - echo -e "\nSet to default password..." - echo -e "\nAdmin password will be set to \e[31m$ADMIN_PASS\e[39m" -elif [[ $ADMIN_PASS == "r" ]] ; then - ADMIN_PASS=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 16 ; echo '') - echo -e "\nSet to random-generated password..." - echo -e "\nAdmin password will be set to \e[31m$ADMIN_PASS\e[39m" - echo $ADMIN_PASS -else - echo -e "\nAdmin password will be set to \e[31m$ADMIN_PASS\e[39m" -fi -} - -if [ $# -eq 0 ] ; then - echo -e "\nInitializing...\n" -else - if [[ $1 == "help" ]] ; then - show_help - exit - elif [[ $1 == "dev" ]] ; then - DEV="ON" - DEV_ARG="ON" - SILENT="OFF" - elif [[ $1 == "default" ]] ; then - echo -e "\nThis will start default installation...\n" - SILENT="ON" - POSTFIX_VARIABLE="ON" - POWERDNS_VARIABLE="ON" - PUREFTPD_VARIABLE="ON" - VERSION="OLS" - ADMIN_PASS="1234567" - MEMCACHED="ON" - REDIS="ON" - else - while [ ! -z "${1}" ]; do - case $1 in - -v | --version) shift - if [ "${1}" = '' ]; then - show_help - exit - else - VERSION="${1}" - SILENT="ON" - fi - ;; - -p | --password) shift - if [[ "${1}" == '' ]]; then - ADMIN_PASS="1234567" - elif [[ "${1}" == 'r' ]] || [[ $1 == 'random' ]] ; then - ADMIN_PASS=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 16 ; echo '') - else - if [ ${1} -lt 8 ] ; then - echo -e "\nPassword lenth less than 8 digital, please choose a more complicated password.\n" - exit - fi - ADMIN_PASS="${1}" - fi - ;; - -a | --addons) - MEMCACHED="ON" - REDIS="ON" - ;; - -m | --minimal) - echo "minimal installation is still work in progress..." - exit - ;; - -h | --help) - show_help - exit - ;; - *) - echo "unknown argument..." - show_help - exit - ;; - esac - shift - done - fi -fi - - - -SERVER_IP=$(curl --silent --max-time 10 -4 https://cyberpanel.sh/?ip) -if [[ $SERVER_IP =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then - echo -e "Valid IP detected..." -else - echo -e "Can not detect IP, exit..." - exit -fi -SERVER_COUNTRY="unknow" -SERVER_COUNTRY=$(curl --silent --max-time 5 https://cyberpanel.sh/?country) -if [[ ${#SERVER_COUNTRY} == "2" ]] || [[ ${#SERVER_COUNTRY} == "6" ]] ; then - echo -e "\nChecking server..." - else - echo -e "\nChecking server..." - SERVER_COUNTRY="unknow" -fi -#SERVER_COUNTRY="CN" -#test string -if [[ $SERVER_COUNTRY == "CN" ]] ; then -DOWNLOAD_SERVER="cyberpanel.sh" -else -DOWNLOAD_SERVER="cdn.cyberpanel.sh" -fi - -check_OS -check_root -check_panel -check_process -check_provider - - - - - -if [[ $SILENT = "ON" ]] ; then -argument_mode -else -interactive_mode -fi - -SECONDS=0 -install_required - -pip_virtualenv - -system_tweak - -main_install \ No newline at end of file diff --git a/mailServer/mailserverManager.py.bak b/mailServer/mailserverManager.py.bak deleted file mode 100644 index 06c4bddfe..000000000 --- a/mailServer/mailserverManager.py.bak +++ /dev/null @@ -1,1713 +0,0 @@ -#!/usr/local/CyberCP/bin/python -# coding=utf-8 -import os.path -import sys -import django -from plogical.httpProc import httpProc -sys.path.append('/usr/local/CyberCP') -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "CyberCP.settings") -django.setup() -from django.http import HttpResponse -try: - from .models import Domains,EUsers - from loginSystem.views import loadLoginPage -except: - pass -import plogical.CyberCPLogFileWriter as logging -import json -import shlex -import subprocess -try: - from plogical.virtualHostUtilities import virtualHostUtilities - from plogical.mailUtilities import mailUtilities -except: - pass -import _thread -try: - from dns.models import Domains as dnsDomains - from dns.models import Records as dnsRecords - from mailServer.models import Forwardings, Pipeprograms - from plogical.acl import ACLManager - from plogical.dnsUtilities import DNS - from loginSystem.models import Administrator - from websiteFunctions.models import Websites -except: - pass -import os -from plogical.processUtilities import ProcessUtilities -import bcrypt -import threading as multi -import argparse - -class MailServerManager(multi.Thread): - - def __init__(self, request = None, function = None, extraArgs = None): - multi.Thread.__init__(self) - self.request = request - self.function = function - self.extraArgs = extraArgs - - def run(self): - try: - if self.function == 'RunServerLevelEmailChecks': - self.RunServerLevelEmailChecks() - except BaseException as msg: - logging.CyberCPLogFileWriter.writeToFile(str(msg) + ' [MailServerManager.run]') - - def loadEmailHome(self): - proc = httpProc(self.request, 'mailServer/index.html', - None, 'createEmail') - return proc.render() - - def createEmailAccount(self): - userID = self.request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - - if not os.path.exists('/home/cyberpanel/postfix'): - proc = httpProc(self.request, 'mailServer/createEmailAccount.html', - {"status": 0}, 'createEmail') - return proc.render() - - websitesName = ACLManager.findAllSites(currentACL, userID) - websitesName = websitesName + ACLManager.findChildDomains(websitesName) - - proc = httpProc(self.request, 'mailServer/createEmailAccount.html', - {'websiteList': websitesName, "status": 1}, 'createEmail') - return proc.render() - - def listEmails(self): - userID = self.request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - - if not os.path.exists('/home/cyberpanel/postfix'): - proc = httpProc(self.request, 'mailServer/listEmails.html', - {"status": 0}, 'listEmails') - return proc.render() - - websitesName = ACLManager.findAllSites(currentACL, userID) - websitesName = websitesName + ACLManager.findChildDomains(websitesName) - - proc = httpProc(self.request, 'mailServer/listEmails.html', - {'websiteList': websitesName, "status": 1}, 'listEmails') - return proc.render() - - def submitEmailCreation(self): - try: - - userID = self.request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - - if ACLManager.currentContextPermission(currentACL, 'createEmail') == 0: - return ACLManager.loadErrorJson('createEmailStatus', 0) - - data = json.loads(self.request.body) - domainName = data['domain'] - userName = data['username'].lower() - password = data['passwordByPass'] - - - admin = Administrator.objects.get(pk=userID) - if ACLManager.checkOwnership(domainName, admin, currentACL) == 1: - pass - else: - return ACLManager.loadErrorJson() - - - ## Create email entry - - result = mailUtilities.createEmailAccount(domainName, userName.lower(), password) - - if result[0] == 1: - data_ret = {'status': 1, 'createEmailStatus': 1, 'error_message': "None"} - json_data = json.dumps(data_ret) - return HttpResponse(json_data) - - else: - data_ret = {'status': 0, 'createEmailStatus': 0, 'error_message': result[1]} - json_data = json.dumps(data_ret) - return HttpResponse(json_data) - - except BaseException as msg: - data_ret = {'status': 0, 'createEmailStatus': 0, 'error_message': str(msg)} - json_data = json.dumps(data_ret) - return HttpResponse(json_data) - - def deleteEmailAccount(self): - userID = self.request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - - if not os.path.exists('/home/cyberpanel/postfix'): - proc = httpProc(self.request, 'mailServer/deleteEmailAccount.html', - {"status": 0}, 'deleteEmail') - return proc.render() - - websitesName = ACLManager.findAllSites(currentACL, userID) - websitesName = websitesName + ACLManager.findChildDomains(websitesName) - - proc = httpProc(self.request, 'mailServer/deleteEmailAccount.html', - {'websiteList': websitesName, "status": 1}, 'deleteEmail') - return proc.render() - - def getEmailsForDomain(self): - try: - userID = self.request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - - if ACLManager.currentContextPermission(currentACL, 'deleteEmail') == 0: - return ACLManager.loadErrorJson('fetchStatus', 0) - - data = json.loads(self.request.body) - domain = data['domain'] - - admin = Administrator.objects.get(pk=userID) - if ACLManager.checkOwnership(domain, admin, currentACL) == 1: - pass - else: - return ACLManager.loadErrorJson() - - try: - domain = Domains.objects.get(domain=domain) - except: - final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': "No email accounts exists!"} - final_json = json.dumps(final_dic) - return HttpResponse(final_json) - - emails = domain.eusers_set.all() - - if emails.count() == 0: - final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': "No email accounts exists!"} - final_json = json.dumps(final_dic) - return HttpResponse(final_json) - - json_data = "[" - checker = 0 - count = 1 - for items in emails: - dic = {'id': count, 'email': items.email} - count = count + 1 - - if checker == 0: - json_data = json_data + json.dumps(dic) - checker = 1 - else: - json_data = json_data + ',' + json.dumps(dic) - - json_data = json_data + ']' - final_dic = {'status': 1, 'fetchStatus': 1, 'error_message': "None", "data": json_data} - final_json = json.dumps(final_dic) - - return HttpResponse(final_json) - - except BaseException as msg: - data_ret = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)} - json_data = json.dumps(data_ret) - return HttpResponse(json_data) - - def submitEmailDeletion(self): - try: - - userID = self.request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - - if ACLManager.currentContextPermission(currentACL, 'deleteEmail') == 0: - return ACLManager.loadErrorJson('deleteEmailStatus', 0) - - data = json.loads(self.request.body) - email = data['email'] - - eUser = EUsers.objects.get(email=email) - - emailOwnerDomain = eUser.emailOwner - - admin = Administrator.objects.get(pk=userID) - if ACLManager.checkOwnership(eUser.emailOwner.domainOwner.domain, admin, currentACL) == 1: - pass - else: - return ACLManager.loadErrorJson() - - mailUtilities.deleteEmailAccount(email) - - if emailOwnerDomain.eusers_set.all().count() == 0: - emailOwnerDomain.delete() - - data_ret = {'status': 1, 'deleteEmailStatus': 1, 'error_message': "None"} - json_data = json.dumps(data_ret) - return HttpResponse(json_data) - - except BaseException as msg: - data_ret = {'status': 0, 'deleteEmailStatus': 0, 'error_message': str(msg)} - json_data = json.dumps(data_ret) - return HttpResponse(json_data) - - def fixMailSSL(self, data = None): - try: - - userID = self.request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - - if data == None: - data = json.loads(self.request.body) - selectedDomain = data['selectedDomain'] - else: - selectedDomain = data['websiteName'] - - - admin = Administrator.objects.get(pk=userID) - - if ACLManager.checkOwnership(selectedDomain, admin, currentACL) == 1: - pass - else: - return ACLManager.loadErrorJson('status', 0) - - website = Websites.objects.get(domain=selectedDomain) - - execPath = "/usr/local/CyberCP/bin/python " + virtualHostUtilities.cyberPanel + "/plogical/virtualHostUtilities.py" - execPath = '%s setupAutoDiscover --virtualHostName %s --websiteOwner %s' % (execPath, selectedDomain, website.admin.userName) - - ProcessUtilities.executioner(execPath) - - data_ret = {'status': 1, 'error_message': "None"} - json_data = json.dumps(data_ret) - return HttpResponse(json_data) - - except BaseException as msg: - data_ret = {'status': 0, 'error_message': str(msg)} - json_data = json.dumps(data_ret) - return HttpResponse(json_data) - - def emailForwarding(self): - userID = self.request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - - if not os.path.exists('/home/cyberpanel/postfix'): - proc = httpProc(self.request, 'mailServer/emailForwarding.html', - {"status": 0}, 'emailForwarding') - return proc.render() - - websitesName = ACLManager.findAllSites(currentACL, userID) - websitesName = websitesName + ACLManager.findChildDomains(websitesName) - - proc = httpProc(self.request, 'mailServer/emailForwarding.html', - {'websiteList': websitesName, "status": 1}, 'emailForwarding') - return proc.render() - - def fetchCurrentForwardings(self): - try: - - userID = self.request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - - if ACLManager.currentContextPermission(currentACL, 'emailForwarding') == 0: - return ACLManager.loadErrorJson('fetchStatus', 0) - - data = json.loads(self.request.body) - emailAddress = data['emailAddress'] - forwardingOption = data['forwardingOption'] - - if forwardingOption != "Pipe to program": - eUser = EUsers.objects.get(email=emailAddress) - - admin = Administrator.objects.get(pk=userID) - if ACLManager.checkOwnership(eUser.emailOwner.domainOwner.domain, admin, currentACL) == 1: - pass - else: - return ACLManager.loadErrorJson() - - currentForwardings = Forwardings.objects.filter(source=emailAddress) - - json_data = "[" - checker = 0 - id = 1 - for items in currentForwardings: - if items.source == items.destination: - continue - dic = {'id': id, - 'source': items.source, - 'destination': items.destination} - - id = id + 1 - - if checker == 0: - json_data = json_data + json.dumps(dic) - checker = 1 - else: - json_data = json_data + ',' + json.dumps(dic) - - json_data = json_data + ']' - final_dic = {'status': 1, 'fetchStatus': 1, 'error_message': "None", "data": json_data} - final_json = json.dumps(final_dic) - - return HttpResponse(final_json) - else: - - currentForwardings = Pipeprograms.objects.filter(source=emailAddress) - - json_data = "[" - checker = 0 - id = 1 - for items in currentForwardings: - if items.source == items.destination: - continue - dic = {'id': id, - 'source': items.source, - 'destination': items.destination} - - id = id + 1 - - if checker == 0: - json_data = json_data + json.dumps(dic) - checker = 1 - else: - json_data = json_data + ',' + json.dumps(dic) - - json_data = json_data + ']' - final_dic = {'status': 1, 'fetchStatus': 1, 'error_message': "None", "data": json_data} - final_json = json.dumps(final_dic) - - return HttpResponse(final_json) - - - except BaseException as msg: - data_ret = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)} - json_data = json.dumps(data_ret) - return HttpResponse(json_data) - - def submitForwardDeletion(self): - try: - userID = self.request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - if ACLManager.currentContextPermission(currentACL, 'emailForwarding') == 0: - return ACLManager.loadErrorJson('deleteForwardingStatus', 0) - - data = json.loads(self.request.body) - destination = data['destination'] - source = data['source'] - forwardingOption = data['forwardingOption'] - - eUser = EUsers.objects.get(email=source) - - admin = Administrator.objects.get(pk=userID) - if ACLManager.checkOwnership(eUser.emailOwner.domainOwner.domain, admin, currentACL) == 1: - pass - else: - return ACLManager.loadErrorJson() - - if forwardingOption == 'Forward to email': - for items in Forwardings.objects.filter(destination=destination, source=source): - items.delete() - else: - for items in Pipeprograms.objects.filter(destination=destination, source=source): - items.delete() - - ## Delete Email PIPE - sourceusername = source.split("@")[0] - virtualfilter = '%s FILTER %spipe:dummy' % (source, sourceusername) - command = "sed -i 's/^" + source + ".*//g' /etc/postfix/script_filter" - ProcessUtilities.executioner(command) - command = "sed -i 's/^" + sourceusername + "pipe.*//g' /etc/postfix/master.cf" - ProcessUtilities.executioner(command) - - #### Hashing filter Reloading Postfix - command = "postmap /etc/postfix/script_filter" - ProcessUtilities.executioner(command) - command = "postfix reload" - ProcessUtilities.executioner(command) - ## - - - data_ret = {'status': 1, 'deleteForwardingStatus': 1, 'error_message': "None", - 'successMessage': 'Successfully deleted!'} - json_data = json.dumps(data_ret) - return HttpResponse(json_data) - - except BaseException as msg: - data_ret = {'status': 0, 'deleteForwardingStatus': 0, 'error_message': str(msg)} - json_data = json.dumps(data_ret) - return HttpResponse(json_data) - - def submitEmailForwardingCreation(self): - try: - userID = self.request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - if ACLManager.currentContextPermission(currentACL, 'emailForwarding') == 0: - return ACLManager.loadErrorJson('createStatus', 0) - - data = json.loads(self.request.body) - source = data['source'] - destination = data['destination'] - forwardingOption = data['forwardingOption'] - - eUser = EUsers.objects.get(email=source) - - admin = Administrator.objects.get(pk=userID) - if ACLManager.checkOwnership(eUser.emailOwner.domainOwner.domain, admin, currentACL) == 1: - pass - else: - return ACLManager.loadErrorJson() - - if Forwardings.objects.filter(source=source, destination=destination).count() > 0: - data_ret = {'status': 0, 'createStatus': 0, - 'error_message': "You have already forwarded to this destination."} - json_data = json.dumps(data_ret) - return HttpResponse(json_data) - - if forwardingOption == 'Forward to email': - if Forwardings.objects.filter(source=source).count() == 0: - forwarding = Forwardings(source=source, destination=source) - forwarding.save() - - forwarding = Forwardings(source=source, destination=destination) - forwarding.save() - else: - forwarding = Pipeprograms(source=source, destination=destination) - forwarding.save() - - ## Create Email PIPE filter - ## example@domain.com FILTER support:dummy - sourceusername = source.split("@")[0] - virtualfilter = '%s FILTER %spipe:dummy' % (source, sourceusername) - command = "echo '" + virtualfilter + "' >> /etc/postfix/script_filter" - ProcessUtilities.executioner(command) - - ## support unix - n n - - pipe flags=Rq user=domain argv=/usr/bin/php -q /home/domain.com/public_html/ticket/api/pipe.php - ## Find Unix file owner of provided pipe - domainName = source.split("@")[1] - website = Websites.objects.get(domain=domainName) - externalApp = website.externalApp - pipeowner = externalApp - ## Add Filter pipe to postfix /etc/postfix/master.cf - filterpipe = '%spipe unix - n n - - pipe flags=Rq user=%s argv=%s -f $(sender) -- $(recipient)' % (sourceusername, pipeowner, destination) - command = "echo '" + filterpipe + "' >> /etc/postfix/master.cf" - ProcessUtilities.executioner(command) - ## Add Check Recipient Hash to postfix /etc/postfix/main.cf - command = "sed -i 's|^smtpd_recipient_restrictions =.*|smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, check_recipient_access hash:/etc/postfix/script_filter, permit|' /etc/postfix/main.cf" - ProcessUtilities.executioner(command) - - #### Hashing filter Reloading Postfix - command = "postmap /etc/postfix/script_filter" - ProcessUtilities.executioner(command) - command = "postfix reload" - ProcessUtilities.executioner(command) - ## - - - - data_ret = {'status': 1, 'createStatus': 1, 'error_message': "None", 'successMessage': 'Successfully Created!'} - json_data = json.dumps(data_ret) - return HttpResponse(json_data) - - except BaseException as msg: - data_ret = {'status': 0, 'createStatus': 0, 'error_message': str(msg)} - json_data = json.dumps(data_ret) - return HttpResponse(json_data) - - def fetchEmails(self): - try: - userID = self.request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - - if ACLManager.currentContextPermission(currentACL, 'listEmails') == 0: - return ACLManager.loadErrorJson('status', 0) - - data = json.loads(self.request.body) - selectedDomain = data['selectedDomain'] - - admin = Administrator.objects.get(pk=userID) - if ACLManager.checkOwnership(selectedDomain, admin, currentACL) == 1: - pass - else: - return ACLManager.loadErrorJson() - try: - - emailDomain = Domains.objects.get(domain=selectedDomain) - except: - raise BaseException('No emails exist for this domain.') - - postfixMapPath = '/etc/postfix/vmail_ssl.map' - - if os.path.exists(postfixMapPath): - - postfixMapData = open(postfixMapPath, 'r').read() - - if postfixMapData.find(selectedDomain) == -1: - mailConfigured = 0 - else: - mailConfigured = 1 - else: - mailConfigured = 0 - - records = emailDomain.eusers_set.all() - - json_data = "[" - checker = 0 - - for items in records: - dic = {'email': items.email, - } - - if checker == 0: - json_data = json_data + json.dumps(dic) - checker = 1 - else: - json_data = json_data + ',' + json.dumps(dic) - - json_data = json_data + ']' - final_json = json.dumps({'status': 1, 'fetchStatus': 1,'serverHostname': 'mail.%s' % (selectedDomain), 'mailConfigured': mailConfigured, 'error_message': "None", "data": json_data}) - return HttpResponse(final_json) - - except BaseException as msg: - final_dic = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)} - final_json = json.dumps(final_dic) - return HttpResponse(final_json) - - ####### - - def changeEmailAccountPassword(self): - userID = self.request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - - if not os.path.exists('/home/cyberpanel/postfix'): - proc = httpProc(self.request, 'mailServer/changeEmailPassword.html', - {"status": 0}, 'changeEmailPassword') - return proc.render() - - websitesName = ACLManager.findAllSites(currentACL, userID) - websitesName = websitesName + ACLManager.findChildDomains(websitesName) - - proc = httpProc(self.request, 'mailServer/changeEmailPassword.html', - {'websiteList': websitesName, "status": 1}, 'changeEmailPassword') - return proc.render() - - def submitPasswordChange(self): - try: - userID = self.request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - if ACLManager.currentContextPermission(currentACL, 'changeEmailPassword') == 0: - return ACLManager.loadErrorJson('passChangeStatus', 0) - - data = json.loads(self.request.body) - email = data['email'] - password = data['passwordByPass'] - - emailDB = EUsers.objects.get(email=email) - - admin = Administrator.objects.get(pk=userID) - try: - if ACLManager.checkOwnership(emailDB.emailOwner.domainOwner.domain, admin, currentACL) == 1: - pass - else: - return ACLManager.loadErrorJson() - except: - if ACLManager.checkOwnership(emailDB.emailOwner.childOwner.domain, admin, currentACL) == 1: - pass - else: - return ACLManager.loadErrorJson() - - CentOSPath = '/etc/redhat-release' - if os.path.exists(CentOSPath): - password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()) - password = '{CRYPT}%s' % (password.decode()) - emailDB.password = password - else: - password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()) - password = '{CRYPT}%s' % (password.decode()) - emailDB.password = password - - emailDB.save() - - - data_ret = {'status': 1, 'passChangeStatus': 1, 'error_message': "None"} - json_data = json.dumps(data_ret) - return HttpResponse(json_data) - - except BaseException as msg: - data_ret = {'status': 0, 'passChangeStatus': 0, 'error_message': str(msg)} - json_data = json.dumps(data_ret) - return HttpResponse(json_data) - - ####### - - def dkimManager(self): - userID = self.request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - - openDKIMInstalled = 1 - - websitesName = ACLManager.findAllSites(currentACL, userID) - websitesName = websitesName + ACLManager.findChildDomains(websitesName) - - proc = httpProc(self.request, 'mailServer/dkimManager.html', - {'websiteList': websitesName, 'openDKIMInstalled': openDKIMInstalled}, 'dkimManager') - return proc.render() - - def fetchDKIMKeys(self): - try: - userID = self.request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - - if ACLManager.currentContextPermission(currentACL, 'dkimManager') == 0: - return ACLManager.loadErrorJson('fetchStatus', 0) - - data = json.loads(self.request.body) - domainName = data['domainName'] - - admin = Administrator.objects.get(pk=userID) - if ACLManager.checkOwnership(domainName, admin, currentACL) == 1: - pass - else: - return ACLManager.loadError() - - try: - - command = 'chown cyberpanel:cyberpanel -R /usr/local/CyberCP/lib/python3.6/site-packages/tldextract/.suffix_cache' - ProcessUtilities.executioner(command) - - command = 'chown cyberpanel:cyberpanel -R /usr/local/CyberCP/lib/python3.8/site-packages/tldextract/.suffix_cache' - ProcessUtilities.executioner(command) - - import tldextract - - extractDomain = tldextract.extract(domainName) - domainName = extractDomain.domain + '.' + extractDomain.suffix - - path = "/etc/opendkim/keys/" + domainName + "/default.txt" - command = "sudo cat " + path - output = ProcessUtilities.outputExecutioner(command, 'opendkim') - leftIndex = output.index('(') + 2 - rightIndex = output.rindex(')') - 1 - - path = "/etc/opendkim/keys/" + domainName + "/default.private" - command = "sudo cat " + path - privateKey = ProcessUtilities.outputExecutioner(command, 'opendkim') - - DNS.createDKIMRecords(domainName) - - data_ret = {'status': 1, 'fetchStatus': 1, 'keysAvailable': 1, 'publicKey': output[leftIndex:rightIndex], - 'privateKey': privateKey, 'dkimSuccessMessage': 'Keys successfully fetched!', - 'error_message': "None"} - json_data = json.dumps(data_ret) - return HttpResponse(json_data) - - except BaseException as msg: - data_ret = {'status': 1, 'fetchStatus': 1, 'keysAvailable': 0, 'error_message': str(msg)} - json_data = json.dumps(data_ret) - return HttpResponse(json_data) - - except BaseException as msg: - data_ret = {'status': 0, 'fetchStatus': 0, 'error_message': str(msg)} - json_data = json.dumps(data_ret) - return HttpResponse(json_data) - - def generateDKIMKeys(self): - try: - userID = self.request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - - if ACLManager.currentContextPermission(currentACL, 'dkimManager') == 0: - return ACLManager.loadErrorJson('generateStatus', 0) - - data = json.loads(self.request.body) - domainName = data['domainName'] - - admin = Administrator.objects.get(pk=userID) - if ACLManager.checkOwnership(domainName, admin, currentACL) == 1: - pass - else: - return ACLManager.loadErrorJson() - - execPath = "/usr/local/CyberCP/bin/python " + virtualHostUtilities.cyberPanel + "/plogical/mailUtilities.py" - execPath = execPath + " generateKeys --domain " + domainName - output = ProcessUtilities.outputExecutioner(execPath) - - admin = Administrator.objects.get(pk=userID) - DNS.dnsTemplate(domainName, admin) - - if output.find("1,None") > -1: - - command = 'chown cyberpanel:cyberpanel -R /usr/local/CyberCP/lib/python3.6/site-packages/tldextract/.suffix_cache' - ProcessUtilities.executioner(command) - - command = 'chown cyberpanel:cyberpanel -R /usr/local/CyberCP/lib/python3.8/site-packages/tldextract/.suffix_cache' - ProcessUtilities.executioner(command) - - import tldextract - - extractDomain = tldextract.extract(domainName) - topLevelDomain = extractDomain.domain + '.' + extractDomain.suffix - - zone = dnsDomains.objects.get(name=topLevelDomain) - zone.save() - - path = "/etc/opendkim/keys/" + domainName + "/default.txt" - command = "cat " + path - output = ProcessUtilities.outputExecutioner(command) - leftIndex = output.index('(') + 2 - rightIndex = output.rindex(')') - 1 - - DNS.createDKIMRecords(domainName) - - record = dnsRecords(domainOwner=zone, - domain_id=zone.id, - name="default._domainkey." + domainName, - type="TXT", - content=output[leftIndex:rightIndex], - ttl=3600, - prio=0, - disabled=0, - auth=1) - record.save() - - data_ret = {'status': 1, 'generateStatus': 1, 'error_message': "None"} - json_data = json.dumps(data_ret) - return HttpResponse(json_data) - - else: - data_ret = {'status': 0, 'generateStatus': 0, 'error_message': output} - json_data = json.dumps(data_ret) - return HttpResponse(json_data) - - except BaseException as msg: - data_ret = {'status': 0, 'generateStatus': 0, 'error_message': str(msg)} - json_data = json.dumps(data_ret) - return HttpResponse(json_data) - - def installOpenDKIM(self): - try: - userID = self.request.session['userID'] - currentACL = ACLManager.loadedACL(userID) - if ACLManager.currentContextPermission(currentACL, 'dkimManager') == 0: - return ACLManager.loadErrorJson('installOpenDKIM', 0) - _thread.start_new_thread(mailUtilities.installOpenDKIM, ('Install', 'openDKIM')) - final_json = json.dumps({'installOpenDKIM': 1, 'error_message': "None"}) - return HttpResponse(final_json) - except BaseException as msg: - final_dic = {'installOpenDKIM': 0, 'error_message': str(msg)} - final_json = json.dumps(final_dic) - return HttpResponse(final_json) - - def installStatusOpenDKIM(self): - try: - command = "sudo cat " + mailUtilities.installLogPath - installStatus = subprocess.check_output(shlex.split(command)).decode("utf-8") - - if installStatus.find("[200]") > -1: - - execPath = "/usr/local/CyberCP/bin/python " + virtualHostUtilities.cyberPanel + "/plogical/mailUtilities.py" - execPath = execPath + " configureOpenDKIM" - - output = ProcessUtilities.outputExecutioner(execPath) - - if output.find("1,None") > -1: - pass - else: - final_json = json.dumps({ - 'error_message': "Failed to install OpenDKIM configurations.", - 'requestStatus': installStatus, - 'abort': 1, - 'installed': 0, - }) - return HttpResponse(final_json) - - final_json = json.dumps({ - 'error_message': "None", - 'requestStatus': installStatus, - 'abort': 1, - 'installed': 1, - }) - return HttpResponse(final_json) - elif installStatus.find("[404]") > -1: - - final_json = json.dumps({ - 'abort': 1, - 'installed': 0, - 'error_message': "None", - 'requestStatus': installStatus, - }) - return HttpResponse(final_json) - else: - final_json = json.dumps({ - 'abort': 0, - 'error_message': "None", - 'requestStatus': installStatus, - }) - return HttpResponse(final_json) - - except BaseException as msg: - final_dic = {'abort': 1, 'installed': 0, 'error_message': str(msg)} - final_json = json.dumps(final_dic) - return HttpResponse(final_json) - - ####### - - def checkIfMailServerSSLIssued(self): - postfixPath = '/etc/postfix/main.cf' - - postFixData = ProcessUtilities.outputExecutioner('cat %s' % (postfixPath)) - - if postFixData.find('myhostname = server.example.com') > -1: - return 0 - else: - try: - - postFixLines = ProcessUtilities.outputExecutioner('cat %s' % (postfixPath)).splitlines() - - for items in postFixLines: - if items.find('myhostname') > -1 and items[0] != '#': - self.mailHostName = items.split('=')[1].strip(' ') - self.MailSSL = 1 - except BaseException as msg: - logging.CyberCPLogFileWriter.writeToFile('%s. [checkIfMailServerSSLIssued:864]' % (str(msg))) - - ipFile = "/etc/cyberpanel/machineIP" - f = open(ipFile) - ipData = f.read() - ipAddress = ipData.split('\n', 1)[0] - - command = 'openssl s_client -connect %s:465' % (ipAddress) - result = ProcessUtilities.outputExecutioner(command) - - if result.find('18 (self signed certificate)') > -1: - return 0 - else: - return 1 - - def RunServerLevelEmailChecks(self): - try: - logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'], 'Checking if MailServer SSL issued..,10') - - reportFile = self.extraArgs['reportFile'] - - report = {} - report['MailSSL'] = self.checkIfMailServerSSLIssued() - - writeToFile = open(reportFile, 'w') - writeToFile.write(json.dumps(report)) - writeToFile.close() - - logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'], 'Completed [200].') - - except BaseException as msg: - final_dic = {'installOpenDKIM': 0, 'error_message': str(msg)} - final_json = json.dumps(final_dic) - return HttpResponse(final_json) - - def install_postfix_dovecot(self): - try: - if ProcessUtilities.decideDistro() == ProcessUtilities.centos or ProcessUtilities.decideDistro() == ProcessUtilities.cent8: - command = 'yum remove postfix -y' - ProcessUtilities.executioner(command) - elif ProcessUtilities.decideDistro() == ProcessUtilities.ubuntu: - command = 'apt-get -y remove postfix' - ProcessUtilities.executioner(command) - - logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'], 'Re-installing postfix..,10') - - if ProcessUtilities.decideDistro() == ProcessUtilities.centos: - command = 'yum install --enablerepo=gf-plus -y postfix3 postfix3-ldap postfix3-mysql postfix3-pcre' - elif ProcessUtilities.decideDistro() == ProcessUtilities.cent8: - - command = 'dnf --nogpg install -y https://mirror.ghettoforge.net/distributions/gf/el/8/gf/x86_64/gf-release-8-11.gf.el8.noarch.rpm' - ProcessUtilities.executioner(command) - - command = 'dnf install --enablerepo=gf-plus postfix3 postfix3-mysql -y' - ProcessUtilities.executioner(command) - else: - command = 'apt-get install -y debconf-utils' - ProcessUtilities.executioner(command) - file_name = 'pf.unattend.text' - pf = open(file_name, 'w') - pf.write('postfix postfix/mailname string ' + str(socket.getfqdn() + '\n')) - pf.write('postfix postfix/main_mailer_type string "Internet Site"\n') - pf.close() - command = 'debconf-set-selections ' + file_name - ProcessUtilities.executioner(command) - - command = 'apt-get -y install postfix' - # os.remove(file_name) - - ProcessUtilities.executioner(command) - - import socket - # We are going to leverage postconfig -e to edit the settings for hostname - command = '"postconf -e "myhostname = %s"' % (str(socket.getfqdn())) - ProcessUtilities.executioner(command) - command = '"postconf -e "myhostname = %s"' % (str(socket.getfqdn())) - ProcessUtilities.executioner(command) - - # We are explicitly going to use sed to set the hostname default from "myhostname = server.example.com" - # to the fqdn from socket if the default is still found - postfix_main = '/etc/postfix/main.cf' - command = "sed -i 's|server.example.com|%s|g' %s" % (str(socket.getfqdn()), postfix_main) - ProcessUtilities.executioner(command) - - logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'], 'Re-installing Dovecot..,15') - - if ProcessUtilities.decideDistro() == ProcessUtilities.centos or ProcessUtilities.decideDistro() == ProcessUtilities.cent8: - pass - else: - command = 'apt-get -y install dovecot-imapd dovecot-pop3d postfix-mysql' - - ProcessUtilities.executioner(command) - - ## - - if ProcessUtilities.decideDistro() == ProcessUtilities.centos: - command = 'yum --enablerepo=gf-plus -y install dovecot23 dovecot23-mysql' - elif ProcessUtilities.decideDistro() == ProcessUtilities.cent8: - command = 'dnf install --enablerepo=gf-plus dovecot23 dovecot23-mysql -y' - else: - command = 'apt-get -y install dovecot-mysql' - - ProcessUtilities.executioner(command) - - if ProcessUtilities.decideDistro() == ProcessUtilities.ubuntu: - - command = 'curl https://repo.dovecot.org/DOVECOT-REPO-GPG | gpg --import' - subprocess.call(command, shell=True) - - command = 'gpg --export ED409DA1 > /etc/apt/trusted.gpg.d/dovecot.gpg' - subprocess.call(command, shell=True) - - debPath = '/etc/apt/sources.list.d/dovecot.list' - writeToFile = open(debPath, 'w') - writeToFile.write('deb https://repo.dovecot.org/ce-2.3-latest/ubuntu/bionic bionic main\n') - writeToFile.close() - - try: - command = 'apt update -y' - subprocess.call(command, shell=True) - except: - pass - - try: - command = 'DEBIAN_FRONTEND=noninteractive DEBIAN_PRIORITY=critical sudo apt-get -q -y -o "Dpkg::Options::=--force-confdef" -o "Dpkg::Options::=--force-confold" --only-upgrade install dovecot-mysql -y' - subprocess.call(command, shell=True) - - command = 'dpkg --configure -a' - subprocess.call(command, shell=True) - - command = 'apt --fix-broken install -y' - subprocess.call(command, shell=True) - - command = 'DEBIAN_FRONTEND=noninteractive DEBIAN_PRIORITY=critical sudo apt-get -q -y -o "Dpkg::Options::=--force-confdef" -o "Dpkg::Options::=--force-confold" --only-upgrade install dovecot-mysql -y' - subprocess.call(command, shell=True) - except: - pass - - logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'], 'Postfix/dovecot reinstalled.,40') - - except BaseException as msg: - logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'], '%s [install_postfix_dovecot][404]' % (str(msg)), 10) - return 0 - - return 1 - - def setup_email_Passwords(self, mysqlPassword): - try: - - - mysql_virtual_domains = "/usr/local/CyberCP/install/email-configs-one/mysql-virtual_domains.cf" - mysql_virtual_forwardings = "/usr/local/CyberCP/install/email-configs-one/mysql-virtual_forwardings.cf" - mysql_virtual_mailboxes = "/usr/local/CyberCP/install/email-configs-one/mysql-virtual_mailboxes.cf" - mysql_virtual_email2email = "/usr/local/CyberCP/install/email-configs-one/mysql-virtual_email2email.cf" - dovecotmysql = "/usr/local/CyberCP/install/email-configs-one/dovecot-sql.conf.ext" - - ### update password: - - data = open(dovecotmysql, "r").readlines() - - writeDataToFile = open(dovecotmysql, "w") - - dataWritten = "connect = host=localhost dbname=cyberpanel user=cyberpanel password=" + mysqlPassword + " port=3306\n" - - for items in data: - if items.find("connect") > -1: - writeDataToFile.writelines(dataWritten) - else: - writeDataToFile.writelines(items) - - # if self.distro == ubuntu: - # os.fchmod(writeDataToFile.fileno(), stat.S_IRUSR | stat.S_IWUSR) - - writeDataToFile.close() - - ### update password: - - data = open(mysql_virtual_domains, "r").readlines() - - writeDataToFile = open(mysql_virtual_domains, "w") - - dataWritten = "password = " + mysqlPassword + "\n" - - for items in data: - if items.find("password") > -1: - writeDataToFile.writelines(dataWritten) - else: - writeDataToFile.writelines(items) - - # if self.distro == ubuntu: - # os.fchmod(writeDataToFile.fileno(), stat.S_IRUSR | stat.S_IWUSR) - - writeDataToFile.close() - - ### update password: - - data = open(mysql_virtual_forwardings, "r").readlines() - - writeDataToFile = open(mysql_virtual_forwardings, "w") - - dataWritten = "password = " + mysqlPassword + "\n" - - for items in data: - if items.find("password") > -1: - writeDataToFile.writelines(dataWritten) - else: - writeDataToFile.writelines(items) - - # if self.distro == ubuntu: - # os.fchmod(writeDataToFile.fileno(), stat.S_IRUSR | stat.S_IWUSR) - - writeDataToFile.close() - - ### update password: - - data = open(mysql_virtual_mailboxes, "r").readlines() - - writeDataToFile = open(mysql_virtual_mailboxes, "w") - - dataWritten = "password = " + mysqlPassword + "\n" - - for items in data: - if items.find("password") > -1: - writeDataToFile.writelines(dataWritten) - else: - writeDataToFile.writelines(items) - - # if self.distro == ubuntu: - # os.fchmod(writeDataToFile.fileno(), stat.S_IRUSR | stat.S_IWUSR) - - writeDataToFile.close() - - ### update password: - - data = open(mysql_virtual_email2email, "r").readlines() - - writeDataToFile = open(mysql_virtual_email2email, "w") - - dataWritten = "password = " + mysqlPassword + "\n" - - for items in data: - if items.find("password") > -1: - writeDataToFile.writelines(dataWritten) - else: - writeDataToFile.writelines(items) - - # if self.distro == ubuntu: - # os.fchmod(writeDataToFile.fileno(), stat.S_IRUSR | stat.S_IWUSR) - - writeDataToFile.close() - - if self.remotemysql == 'ON': - command = "sed -i 's|host=localhost|host=%s|g' %s" % (self.mysqlhost, dovecotmysql) - ProcessUtilities.executioner(command) - - command = "sed -i 's|port=3306|port=%s|g' %s" % (self.mysqlport, dovecotmysql) - ProcessUtilities.executioner(command) - - ## - - command = "sed -i 's|localhost|%s:%s|g' %s" % (self.mysqlhost, self.mysqlport, mysql_virtual_domains) - ProcessUtilities.executioner(command) - - command = "sed -i 's|localhost|%s:%s|g' %s" % ( - self.mysqlhost, self.mysqlport, mysql_virtual_forwardings) - ProcessUtilities.executioner(command) - - command = "sed -i 's|localhost|%s:%s|g' %s" % ( - self.mysqlhost, self.mysqlport, mysql_virtual_mailboxes) - ProcessUtilities.executioner(command) - - command = "sed -i 's|localhost|%s:%s|g' %s" % ( - self.mysqlhost, self.mysqlport, mysql_virtual_email2email) - ProcessUtilities.executioner(command) - except BaseException as msg: - logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'], - '%s [setup_email_Passwords][404]' % (str(msg)), 10) - return 0 - - return 1 - - def centos_lib_dir_to_ubuntu(self, filename, old, new): - try: - fd = open(filename, 'r') - lines = fd.readlines() - fd.close() - fd = open(filename, 'w') - centos_prefix = old - ubuntu_prefix = new - for line in lines: - index = line.find(centos_prefix) - if index != -1: - line = line[:index] + ubuntu_prefix + line[index + len(centos_prefix):] - fd.write(line) - fd.close() - except BaseException as msg: - logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'], - '%s [centos_lib_dir_to_ubuntu][404]' % (str(msg)), 10) - - def setup_postfix_dovecot_config(self): - try: - - mysql_virtual_domains = "/etc/postfix/mysql-virtual_domains.cf" - mysql_virtual_forwardings = "/etc/postfix/mysql-virtual_forwardings.cf" - mysql_virtual_mailboxes = "/etc/postfix/mysql-virtual_mailboxes.cf" - mysql_virtual_email2email = "/etc/postfix/mysql-virtual_email2email.cf" - main = "/etc/postfix/main.cf" - master = "/etc/postfix/master.cf" - dovecot = "/etc/dovecot/dovecot.conf" - dovecotmysql = "/etc/dovecot/dovecot-sql.conf.ext" - - if os.path.exists(mysql_virtual_domains): - os.remove(mysql_virtual_domains) - - if os.path.exists(mysql_virtual_forwardings): - os.remove(mysql_virtual_forwardings) - - if os.path.exists(mysql_virtual_mailboxes): - os.remove(mysql_virtual_mailboxes) - - if os.path.exists(mysql_virtual_email2email): - os.remove(mysql_virtual_email2email) - - if os.path.exists(main): - os.remove(main) - - if os.path.exists(master): - os.remove(master) - - if os.path.exists(dovecot): - os.remove(dovecot) - - if os.path.exists(dovecotmysql): - os.remove(dovecotmysql) - - ###############Getting SSL - - command = 'openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com" -keyout /etc/postfix/key.pem -out /etc/postfix/cert.pem' - ProcessUtilities.executioner(command) - - ## - - command = 'openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com" -keyout /etc/dovecot/key.pem -out /etc/dovecot/cert.pem' - ProcessUtilities.executioner(command) - - # Cleanup config files for ubuntu - if ProcessUtilities.decideDistro() == ProcessUtilities.ubuntu: - self.centos_lib_dir_to_ubuntu("/usr/local/CyberCP/install/email-configs-one/master.cf", "/usr/libexec/", "/usr/lib/") - self.centos_lib_dir_to_ubuntu("/usr/local/CyberCP/install/email-configs-one/main.cf", "/usr/libexec/postfix", - "/usr/lib/postfix/sbin") - - - ########### Copy config files - import shutil - - shutil.copy("/usr/local/CyberCP/install/email-configs-one/mysql-virtual_domains.cf", "/etc/postfix/mysql-virtual_domains.cf") - shutil.copy("/usr/local/CyberCP/install/email-configs-one/mysql-virtual_forwardings.cf", - "/etc/postfix/mysql-virtual_forwardings.cf") - shutil.copy("/usr/local/CyberCP/install/email-configs-one/mysql-virtual_mailboxes.cf", "/etc/postfix/mysql-virtual_mailboxes.cf") - shutil.copy("/usr/local/CyberCP/install/email-configs-one/mysql-virtual_email2email.cf", - "/etc/postfix/mysql-virtual_email2email.cf") - shutil.copy("/usr/local/CyberCP/install/email-configs-one/main.cf", main) - shutil.copy("/usr/local/CyberCP/install/email-configs-one/master.cf", master) - shutil.copy("/usr/local/CyberCP/install/email-configs-one/dovecot.conf", dovecot) - shutil.copy("/usr/local/CyberCP/install/email-configs-one/dovecot-sql.conf.ext", dovecotmysql) - - - ######################################## Permissions - - command = 'chmod o= /etc/postfix/mysql-virtual_domains.cf' - ProcessUtilities.executioner(command) - - ## - - command = 'chmod o= /etc/postfix/mysql-virtual_forwardings.cf' - ProcessUtilities.executioner(command) - - ## - - command = 'chmod o= /etc/postfix/mysql-virtual_mailboxes.cf' - ProcessUtilities.executioner(command) - - ## - - command = 'chmod o= /etc/postfix/mysql-virtual_email2email.cf' - ProcessUtilities.executioner(command) - - ## - - command = 'chmod o= ' + main - ProcessUtilities.executioner(command) - - ## - - command = 'chmod o= ' + master - ProcessUtilities.executioner(command) - - ####################################### - - command = 'chgrp postfix /etc/postfix/mysql-virtual_domains.cf' - ProcessUtilities.executioner(command) - - ## - - command = 'chgrp postfix /etc/postfix/mysql-virtual_forwardings.cf' - ProcessUtilities.executioner(command) - ## - - command = 'chgrp postfix /etc/postfix/mysql-virtual_mailboxes.cf' - ProcessUtilities.executioner(command) - - ## - - command = 'chgrp postfix /etc/postfix/mysql-virtual_email2email.cf' - ProcessUtilities.executioner(command) - - ## - - command = 'chgrp postfix ' + main - ProcessUtilities.executioner(command) - - ## - - command = 'chgrp postfix ' + master - ProcessUtilities.executioner(command) - - ######################################## users and groups - - command = 'groupadd -g 5000 vmail' - ProcessUtilities.executioner(command) - - ## - - command = 'useradd -g vmail -u 5000 vmail -d /home/vmail -m' - ProcessUtilities.executioner(command) - - ######################################## Further configurations - - # hostname = socket.gethostname() - - ################################### Restart postix - - command = 'systemctl enable postfix.service' - ProcessUtilities.executioner(command) - - ## - - command = 'systemctl start postfix.service' - ProcessUtilities.executioner(command) - - ######################################## Permissions - - command = 'chgrp dovecot /etc/dovecot/dovecot-sql.conf.ext' - ProcessUtilities.executioner(command) - - ## - - command = 'chmod o= /etc/dovecot/dovecot-sql.conf.ext' - ProcessUtilities.executioner(command) - - ################################### Restart dovecot - - command = 'systemctl enable dovecot.service' - ProcessUtilities.executioner(command) - - ## - - command = 'systemctl start dovecot.service' - ProcessUtilities.executioner(command) - - ## - - command = 'systemctl restart postfix.service' - ProcessUtilities.executioner(command) - - ## changing permissions for main.cf - - command = "chmod 755 " + main - ProcessUtilities.executioner(command) - - if ProcessUtilities.decideDistro() == ProcessUtilities.ubuntu: - command = "mkdir -p /etc/pki/dovecot/private/" - ProcessUtilities.executioner(command) - - command = "mkdir -p /etc/pki/dovecot/certs/" - ProcessUtilities.executioner(command) - - command = "mkdir -p /etc/opendkim/keys/" - ProcessUtilities.executioner(command) - - command = "sed -i 's/auth_mechanisms = plain/#auth_mechanisms = plain/g' /etc/dovecot/conf.d/10-auth.conf" - ProcessUtilities.executioner(command) - - ## Ubuntu 18.10 ssl_dh for dovecot 2.3.2.1 - - if ProcessUtilities.ubuntu: - dovecotConf = '/etc/dovecot/dovecot.conf' - - data = open(dovecotConf, 'r').readlines() - writeToFile = open(dovecotConf, 'w') - for items in data: - if items.find('ssl_key = -1: - writeToFile.writelines(items) - writeToFile.writelines('ssl_dh = -1 and items.find('local:') and items[0] != '#': - writeToFile.writelines('Socket inet:8891@localhost\n') - else: - writeToFile.writelines(items) - writeToFile.close() - - #### Restarting Postfix and OpenDKIM - - command = "systemctl start opendkim" - ProcessUtilities.executioner(command) - - command = "systemctl enable opendkim" - ProcessUtilities.executioner(command) - - ## - - command = "systemctl restart postfix" - ProcessUtilities.executioner(command) - - return 1 - - except BaseException as msg: - return 0 - - def fixCyberPanelPermissions(self): - - ###### fix Core CyberPanel permissions - command = "find /usr/local/CyberCP -type d -exec chmod 0755 {} \;" - ProcessUtilities.executioner(command) - - command = "find /usr/local/CyberCP -type f -exec chmod 0644 {} \;" - ProcessUtilities.executioner(command) - - command = "chmod -R 755 /usr/local/CyberCP/bin" - ProcessUtilities.executioner(command) - - ## change owner - - command = "chown -R root:root /usr/local/CyberCP" - ProcessUtilities.executioner(command) - - ########### Fix LSCPD - - command = "find /usr/local/lscp -type d -exec chmod 0755 {} \;" - ProcessUtilities.executioner(command) - - command = "find /usr/local/lscp -type f -exec chmod 0644 {} \;" - ProcessUtilities.executioner(command) - - command = "chmod -R 755 /usr/local/lscp/bin" - ProcessUtilities.executioner(command) - - command = "chmod -R 755 /usr/local/lscp/fcgi-bin" - ProcessUtilities.executioner(command) - - command = "chown -R lscpd:lscpd /usr/local/CyberCP/public/phpmyadmin/tmp" - ProcessUtilities.executioner(command) - - ## change owner - - command = "chown -R root:root /usr/local/lscp" - ProcessUtilities.executioner(command) - - command = "chown -R lscpd:lscpd /usr/local/lscp/cyberpanel/rainloop/data" - ProcessUtilities.executioner(command) - - command = "chmod 700 /usr/local/CyberCP/cli/cyberPanel.py" - ProcessUtilities.executioner(command) - - command = "chmod 700 /usr/local/CyberCP/plogical/upgradeCritical.py" - ProcessUtilities.executioner(command) - - command = "chmod 755 /usr/local/CyberCP/postfixSenderPolicy/client.py" - ProcessUtilities.executioner(command) - - command = "chmod 640 /usr/local/CyberCP/CyberCP/settings.py" - ProcessUtilities.executioner(command) - - command = "chown root:cyberpanel /usr/local/CyberCP/CyberCP/settings.py" - ProcessUtilities.executioner(command) - - files = ['/etc/yum.repos.d/MariaDB.repo', '/etc/pdns/pdns.conf', '/etc/systemd/system/lscpd.service', - '/etc/pure-ftpd/pure-ftpd.conf', '/etc/pure-ftpd/pureftpd-pgsql.conf', - '/etc/pure-ftpd/pureftpd-mysql.conf', '/etc/pure-ftpd/pureftpd-ldap.conf', - '/etc/dovecot/dovecot.conf', '/usr/local/lsws/conf/httpd_config.xml', - '/usr/local/lsws/conf/modsec.conf', '/usr/local/lsws/conf/httpd.conf'] - - for items in files: - command = 'chmod 644 %s' % (items) - ProcessUtilities.executioner(command) - - impFile = ['/etc/pure-ftpd/pure-ftpd.conf', '/etc/pure-ftpd/pureftpd-pgsql.conf', - '/etc/pure-ftpd/pureftpd-mysql.conf', '/etc/pure-ftpd/pureftpd-ldap.conf', - '/etc/dovecot/dovecot.conf', '/etc/pdns/pdns.conf', '/etc/pure-ftpd/db/mysql.conf', - '/etc/powerdns/pdns.conf'] - - for items in impFile: - command = 'chmod 600 %s' % (items) - ProcessUtilities.executioner(command) - - command = 'chmod 640 /etc/postfix/*.cf' - subprocess.call(command, shell=True) - - command = 'chmod 644 /etc/postfix/main.cf' - subprocess.call(command, shell=True) - - command = 'chmod 640 /etc/dovecot/*.conf' - subprocess.call(command, shell=True) - - command = 'chmod 644 /etc/dovecot/dovecot.conf' - subprocess.call(command, shell=True) - - command = 'chmod 640 /etc/dovecot/dovecot-sql.conf.ext' - subprocess.call(command, shell=True) - - command = 'chmod 644 /etc/postfix/dynamicmaps.cf' - subprocess.call(command, shell=True) - - fileM = ['/usr/local/lsws/FileManager/', '/usr/local/CyberCP/install/FileManager', - '/usr/local/CyberCP/serverStatus/litespeed/FileManager', '/usr/local/lsws/Example/html/FileManager'] - - for items in fileM: - try: - import shutil - shutil.rmtree(items) - except: - pass - - command = 'chmod 755 /etc/pure-ftpd/' - subprocess.call(command, shell=True) - - command = 'chmod +x /usr/local/CyberCP/plogical/renew.py' - ProcessUtilities.executioner(command) - - command = 'chmod +x /usr/local/CyberCP/CLManager/CLPackages.py' - ProcessUtilities.executioner(command) - - clScripts = ['/usr/local/CyberCP/CLScript/panel_info.py', '/usr/local/CyberCP/CLScript/CloudLinuxPackages.py', - '/usr/local/CyberCP/CLScript/CloudLinuxUsers.py', - '/usr/local/CyberCP/CLScript/CloudLinuxDomains.py' - , '/usr/local/CyberCP/CLScript/CloudLinuxResellers.py', '/usr/local/CyberCP/CLScript/CloudLinuxAdmins.py', - '/usr/local/CyberCP/CLScript/CloudLinuxDB.py', '/usr/local/CyberCP/CLScript/UserInfo.py'] - - for items in clScripts: - command = 'chmod +x %s' % (items) - ProcessUtilities.executioner(command) - - command = 'chmod 600 /usr/local/CyberCP/plogical/adminPass.py' - ProcessUtilities.executioner(command) - - command = 'chmod 600 /etc/cagefs/exclude/cyberpanelexclude' - ProcessUtilities.executioner(command) - - command = "find /usr/local/CyberCP/ -name '*.pyc' -delete" - ProcessUtilities.executioner(command) - - if ProcessUtilities.decideDistro() == ProcessUtilities.centos or ProcessUtilities.cent8: - - command = 'chown root:pdns /etc/pdns/pdns.conf' - ProcessUtilities.executioner(command) - - command = 'chmod 640 /etc/pdns/pdns.conf' - ProcessUtilities.executioner(command) - - command = 'chmod 640 /usr/local/lscp/cyberpanel/logs/access.log' - ProcessUtilities.executioner(command) - - ### - - def ResetEmailConfigurations(self): - try: - ### Check if remote or local mysql - - passFile = "/etc/cyberpanel/mysqlPassword" - - try: - jsonData = json.loads(ProcessUtilities.outputExecutioner('cat %s' % (passFile))) - - self.mysqluser = jsonData['mysqluser'] - self.mysqlpassword = jsonData['mysqlpassword'] - self.mysqlport = jsonData['mysqlport'] - self.mysqlhost = jsonData['mysqlhost'] - self.remotemysql = 'ON' - - if self.mysqlhost.find('rds.amazon') > -1: - self.RDS = 1 - - ## Also set localhost to this server - - ipFile = "/etc/cyberpanel/machineIP" - f = open(ipFile) - ipData = f.read() - ipAddressLocal = ipData.split('\n', 1)[0] - - self.LOCALHOST = ipAddressLocal - except BaseException as msg: - self.remotemysql = 'OFF' - - if os.path.exists(ProcessUtilities.debugPath): - logging.CyberCPLogFileWriter.writeToFile('%s. [setupConnection:75]' % (str(msg))) - - ### - - self.checkIfMailServerSSLIssued() - - logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'], 'Removing and re-installing postfix/dovecot..,5') - - if self.install_postfix_dovecot() == 0: - return 0 - - logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'], 'Resetting configurations..,40') - - import sys - sys.path.append('/usr/local/CyberCP') - os.environ.setdefault("DJANGO_SETTINGS_MODULE", "CyberCP.settings") - from CyberCP import settings - - if self.setup_email_Passwords(settings.DATABASES['default']['PASSWORD']) == 0: - return 0 - - logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'], 'Configurations reset..,70') - - if self.setup_postfix_dovecot_config() == 0: - logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'], 'setup_postfix_dovecot_config failed. [404].') - return 0 - - logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'], 'Restoreing OpenDKIM configurations..,70') - - if self.configureOpenDKIM() == 0: - logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'], 'configureOpenDKIM failed. [404].') - return 0 - - - if self.MailSSL: - logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'], 'Setting up Mail Server SSL if any..,75') - from plogical.virtualHostUtilities import virtualHostUtilities - virtualHostUtilities.issueSSLForMailServer(self.mailHostName, '/home/%s/public_html' % (self.mailHostName)) - - from websiteFunctions.models import ChildDomains - from plogical.virtualHostUtilities import virtualHostUtilities - for websites in Websites.objects.all(): - try: - child = ChildDomains.objects.get(domain='mail.%s' % (websites.domain)) - logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'], - 'Creating mail domain for %s..,80' % (websites.domain)) - virtualHostUtilities.setupAutoDiscover(1, '/dev/null', websites.domain, websites.admin) - except: - pass - - logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'], 'Fixing permissions..,90') - - self.fixCyberPanelPermissions() - - logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'], 'Completed [200].') - - except BaseException as msg: - final_dic = {'installOpenDKIM': 0, 'error_message': str(msg)} - final_json = json.dumps(final_dic) - return HttpResponse(final_json) - - def debugEmailForSite(self, websiteName): - - ipFile = "/etc/cyberpanel/machineIP" - f = open(ipFile) - ipData = f.read() - ipAddress = ipData.split('\n', 1)[0] - - try: - import socket - siteIPAddr = socket.gethostbyname('mail.%s' % (websiteName)) - - if siteIPAddr != ipAddress: - return 0, 'mail.%s does not point to %s.' % (websiteName, ipAddress) - except: - return 0, 'mail.%s does not point to %s.' % (websiteName, ipAddress) - - command = 'openssl s_client -connect mail.%s:993' % (websiteName) - result = ProcessUtilities.outputExecutioner(command) - - if result.find('18 (self signed certificate)') > -1: - return 0, 'No valid SSL on port 993.' - else: - return 1, 'All checks are OK.' - -def main(): - - parser = argparse.ArgumentParser(description='CyberPanel') - parser.add_argument('function', help='Specifiy a function to call!') - parser.add_argument('--tempStatusPath', help='Path of temporary status file.') - - args = parser.parse_args() - - if args.function == "ResetEmailConfigurations": - extraArgs = {'tempStatusPath': args.tempStatusPath} - background = MailServerManager(None, 'ResetEmailConfigurations', extraArgs) - background.ResetEmailConfigurations() - -if __name__ == "__main__": - main() diff --git a/mailServer/templates/mailServer/index.html.bak b/mailServer/templates/mailServer/index.html.bak deleted file mode 100644 index e0f619981..000000000 --- a/mailServer/templates/mailServer/index.html.bak +++ /dev/null @@ -1,121 +0,0 @@ -{% extends "baseTemplate/index.html" %} -{% load i18n %} -{% block title %}{% trans "Mail Functions - CyberPanel" %}{% endblock %} -{% block content %} - - {% load static %} - {% get_current_language as LANGUAGE_CODE %} - - -
-
-

{% trans "Mail Functions" %}

-

{% trans "Manage email accounts on this page." %}

-
- - - -
- - -{% endblock %} diff --git a/phpmyadmin_htaccess b/phpmyadmin_htaccess new file mode 100644 index 000000000..e316d5b8c --- /dev/null +++ b/phpmyadmin_htaccess @@ -0,0 +1,25 @@ +# CyberPanel phpMyAdmin Access Control +# Place this file as /usr/local/CyberCP/public/phpmyadmin/.htaccess + +# Enable rewrite engine +RewriteEngine On + +# Check if user is not authenticated and redirect to login +RewriteCond %{HTTP_COOKIE} !sessionid= +RewriteRule ^(.*)$ /base/ [R=302,L] + +# Additional security headers +Header always set X-Frame-Options DENY +Header always set X-Content-Type-Options nosniff +Header always set X-XSS-Protection "1; mode=block" + +# Prevent direct access to sensitive files + + Order Allow,Deny + Deny from all + + + + Order Allow,Deny + Deny from all + diff --git a/phpmyadmin_index_redirect.php b/phpmyadmin_index_redirect.php new file mode 100644 index 000000000..a6c8a0fa2 --- /dev/null +++ b/phpmyadmin_index_redirect.php @@ -0,0 +1,22 @@ + diff --git a/plogical/acl.py b/plogical/acl.py index 5fe1d1d16..071fc110c 100644 --- a/plogical/acl.py +++ b/plogical/acl.py @@ -1372,7 +1372,7 @@ echo $oConfig->Save() ? 'Done' : 'Error'; command = 'chmod 640 /usr/local/lscp/cyberpanel/logs/access.log' ProcessUtilities.executioner(command, 'root', True) - command = '/usr/local/lsws/lsphp72/bin/php /usr/local/CyberCP/public/snappymail.php' + command = '/usr/local/lsws/lsphp83/bin/php /usr/local/CyberCP/public/snappymail.php' ProcessUtilities.executioner(command, 'root', True) command = 'chmod 600 /usr/local/CyberCP/public/snappymail.php' diff --git a/plogical/filesPermsUtilities.py.bak b/plogical/filesPermsUtilities.py.bak deleted file mode 100644 index 8e71af9aa..000000000 --- a/plogical/filesPermsUtilities.py.bak +++ /dev/null @@ -1,190 +0,0 @@ -import os -import shutil -import pathlib -import stat - - -def mkdir_p(path, exist_ok=True): - """ - Creates the directory and paths leading up to it like unix mkdir -p . - Defaults to exist_ok so if it exists were not throwing fatal errors - https://docs.python.org/3.7/library/os.html#os.makedirs - """ - if not os.path.exists(path): - print('creating directory: ' + path) - os.makedirs(path, exist_ok) - - -def chmod_digit(file_path, perms): - """ - Helper function to chmod like you would in unix without having to preface 0o or converting to octal yourself. - Credits: https://stackoverflow.com/a/60052847/1621381 - """ - try: - os.chmod(file_path, int(str(perms), base=8)) - except: - print(f'Could not chmod : {file_path} to {perms}') - pass - - -def touch(filepath: str, exist_ok=True): - """ - Touches a file like unix `touch somefile` would. - """ - try: - pathlib.Path(filepath).touch(exist_ok) - except FileExistsError: - print('Could touch : ' + filepath) - pass - - -def symlink(src, dst): - """ - Symlink a path to another if the src exists. - """ - try: - if os.access(src, os.R_OK): - os.symlink(src, dst) - except: - print(f'Could not symlink Source: {src} > Destination: {dst}') - pass - - -def chown(path, user, group=-1): - """ - Chown file/path to user/group provided. Passing -1 to user or group will leave it unchanged. - Useful if just changing user or group vs both. - """ - try: - shutil.chown(path, user, group) - except PermissionError: - print(f'Could not change permissions for: {path} to {user}:{group}') - pass - - -def recursive_chown(path, owner, group=-1): - """ - Recursively chown a path and contents to owner. - https://docs.python.org/3/library/shutil.html - """ - for dirpath, dirnames, filenames in os.walk(path): - try: - shutil.chown(dirpath, owner, group) - except PermissionError: - print('Could not change permissions for: ' + dirpath + ' to: ' + owner) - pass - for filename in filenames: - try: - shutil.chown(os.path.join(dirpath, filename), owner, group) - except PermissionError: - print('Could not change permissions for: ' + os.path.join(dirpath, filename) + ' to: ' + owner) - pass - - -def recursive_permissions(path, dir_mode=755, file_mode=644, topdir=True): - """ - Recursively chmod a path and contents to mode. - Defaults to chmod top level directory but can be optionally - toggled off when you want to chmod only contents of like a user's homedir vs homedir itself - https://docs.python.org/3.6/library/os.html#os.walk - """ - - # Here we are converting the integers to string and then to octal. - # so this function doesn't need to be called with 0o prefixed for the file and dir mode - dir_mode = int(str(dir_mode), base=8) - file_mode = int(str(file_mode), base=8) - - if topdir: - # Set chmod on top level path - try: - os.chmod(path, dir_mode) - except: - print('Could not chmod :' + path + ' to ' + str(dir_mode)) - for root, dirs, files in os.walk(path): - for d in dirs: - try: - os.chmod(os.path.join(root, d), dir_mode) - except: - print('Could not chmod :' + os.path.join(root, d) + ' to ' + str(dir_mode)) - pass - for f in files: - try: - os.chmod(os.path.join(root, f), file_mode) - except: - print('Could not chmod :' + path + ' to ' + str(file_mode)) - pass - - -# Left intentionally here for reference. -# Set recursive chown for a path -# recursive_chown(my_path, 'root', 'root') -# for changing group recursively without affecting user -# recursive_chown('/usr/local/lscp/cyberpanel/rainloop/data', -1, 'lscpd') - -# explicitly set permissions for directories/folders to 0755 and files to 0644 -# recursive_permissions(my_path, 755, 644) - -# Fix permissions and use default values -# recursive_permissions(my_path) -# ========================================================= -# Below is a helper class for getting and working with permissions -# Original credits to : https://github.com/keysemble/perfm - -def perm_octal_digit(rwx): - digit = 0 - if rwx[0] == 'r': - digit += 4 - if rwx[1] == 'w': - digit += 2 - if rwx[2] == 'x': - digit += 1 - return digit - - -class FilePerm: - def __init__(self, filepath): - filemode = stat.filemode(os.stat(filepath).st_mode) - permissions = [filemode[-9:][i:i + 3] for i in range(0, len(filemode[-9:]), 3)] - self.filepath = filepath - self.access_dict = dict(zip(['user', 'group', 'other'], [list(perm) for perm in permissions])) - - def mode(self): - mode = 0 - for shift, digit in enumerate(self.octal()[::-1]): - mode += digit << (shift * 3) - return mode - - def digits(self): - """Get the octal chmod equivalent value 755 in single string""" - return "".join(map(str, self.octal())) - - def octal(self): - """Get the octal value in a list [7, 5, 5]""" - return [perm_octal_digit(p) for p in self.access_dict.values()] - - def access_bits(self, access): - if access in self.access_dict.keys(): - r, w, x = self.access_dict[access] - return [r == 'r', w == 'w', x == 'x'] - - def update_bitwise(self, settings): - def perm_list(read=False, write=False, execute=False): - pl = ['-', '-', '-'] - if read: - pl[0] = 'r' - if write: - pl[1] = 'w' - if execute: - pl[2] = 'x' - return pl - - self.access_dict = dict( - [(access, perm_list(read=r, write=w, execute=x)) for access, [r, w, x] in settings.items()]) - os.chmod(self.filepath, self.mode()) - -# project_directory = os.path.abspath(os.path.dirname(sys.argv[0])) -# home_directory = os.path.expanduser('~') -# print(f'Path: {home_directory} Mode: {FilePerm(home_directory).mode()} Octal: {FilePerm(home_directory).octal()} ' -# f'Digits: {FilePerm(home_directory).digits()}') -# Example: Output -# Path: /home/cooluser Mode: 493 Octal: [7, 5, 5] Digits: 755 \ No newline at end of file diff --git a/plogical/phpmyadminsignin.php b/plogical/phpmyadminsignin.php index 3b2f92d44..7076a8758 100644 --- a/plogical/phpmyadminsignin.php +++ b/plogical/phpmyadminsignin.php @@ -1,5 +1,12 @@ Save() ? 'Done' : 'Error'; command = 'chmod 640 /usr/local/lscp/cyberpanel/logs/access.log' Upgrade.executioner(command, 0) - command = '/usr/local/lsws/lsphp72/bin/php /usr/local/CyberCP/public/snappymail.php' + command = '/usr/local/lsws/lsphp83/bin/php /usr/local/CyberCP/public/snappymail.php' Upgrade.executioner_silent(command, 'Configure SnappyMail') command = 'chmod 600 /usr/local/CyberCP/public/snappymail.php' @@ -3182,44 +3182,221 @@ echo $oConfig->Save() ? 'Done' : 'Error'; command = '/root/.acme.sh/acme.sh --set-default-ca --server letsencrypt' Upgrade.executioner(command, command, 0) + @staticmethod + def check_package_availability(package_name): + """Check if a package is available in the repositories""" + try: + # Try to search for the package without installing + if os.path.exists('/etc/yum.repos.d/') or os.path.exists('/etc/dnf/dnf.conf'): + # RHEL-based systems + command = f"dnf search --quiet {package_name} 2>/dev/null | grep -q '^Last metadata expiration' || yum search --quiet {package_name} 2>/dev/null | head -1" + result = subprocess.run(command, shell=True, capture_output=True, text=True) + return result.returncode == 0 + else: + # Ubuntu/Debian systems + command = f"apt-cache search {package_name} 2>/dev/null | head -1" + result = subprocess.run(command, shell=True, capture_output=True, text=True) + return result.returncode == 0 and result.stdout.strip() != "" + except Exception as e: + Upgrade.stdOut(f"Error checking package availability for {package_name}: {str(e)}", 0) + return False + + @staticmethod + def is_almalinux9(): + """Check if running on AlmaLinux 9""" + if os.path.exists('/etc/almalinux-release'): + try: + with open('/etc/almalinux-release', 'r') as f: + content = f.read() + return 'release 9' in content + except: + return False + return False + + @staticmethod + def fix_almalinux9_mariadb(): + """Fix AlmaLinux 9 MariaDB installation issues""" + if not Upgrade.is_almalinux9(): + return + + Upgrade.stdOut("Applying AlmaLinux 9 MariaDB fixes...", 1) + + try: + # Disable problematic MariaDB MaxScale repository + Upgrade.stdOut("Disabling problematic MariaDB MaxScale repository...", 1) + command = "dnf config-manager --disable mariadb-maxscale 2>/dev/null || true" + subprocess.run(command, shell=True, capture_output=True) + + # Remove problematic repository files + Upgrade.stdOut("Removing problematic repository files...", 1) + problematic_repos = [ + '/etc/yum.repos.d/mariadb-maxscale.repo', + '/etc/yum.repos.d/mariadb-maxscale.repo.rpmnew' + ] + for repo_file in problematic_repos: + if os.path.exists(repo_file): + os.remove(repo_file) + Upgrade.stdOut(f"Removed {repo_file}", 1) + + # Clean DNF cache + Upgrade.stdOut("Cleaning DNF cache...", 1) + command = "dnf clean all" + subprocess.run(command, shell=True, capture_output=True) + + # Install MariaDB from official repository + Upgrade.stdOut("Setting up official MariaDB repository...", 1) + command = "curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | bash -s -- --mariadb-server-version='10.11'" + result = subprocess.run(command, shell=True, capture_output=True, text=True) + if result.returncode != 0: + Upgrade.stdOut(f"Warning: MariaDB repo setup failed: {result.stderr}", 0) + + # Install MariaDB packages + Upgrade.stdOut("Installing MariaDB packages...", 1) + mariadb_packages = "MariaDB-server MariaDB-client MariaDB-backup MariaDB-devel" + command = f"dnf install -y {mariadb_packages}" + result = subprocess.run(command, shell=True, capture_output=True, text=True) + if result.returncode != 0: + Upgrade.stdOut(f"Warning: MariaDB installation issues: {result.stderr}", 0) + + # Start and enable MariaDB service + Upgrade.stdOut("Starting MariaDB service...", 1) + services = ['mariadb', 'mysql', 'mysqld'] + for service in services: + try: + command = f"systemctl start {service}" + result = subprocess.run(command, shell=True, capture_output=True) + if result.returncode == 0: + command = f"systemctl enable {service}" + subprocess.run(command, shell=True, capture_output=True) + Upgrade.stdOut(f"MariaDB service started as {service}", 1) + break + except: + continue + + Upgrade.stdOut("AlmaLinux 9 MariaDB fixes completed", 1) + + except Exception as e: + Upgrade.stdOut(f"Error applying AlmaLinux 9 MariaDB fixes: {str(e)}", 0) + + @staticmethod + def get_available_php_versions(): + """Get list of available PHP versions based on OS""" + # Check for AlmaLinux 9+ first + if os.path.exists('/etc/almalinux-release'): + try: + with open('/etc/almalinux-release', 'r') as f: + content = f.read() + if 'release 9' in content or 'release 10' in content: + Upgrade.stdOut("AlmaLinux 9+ detected - checking available PHP versions", 1) + # AlmaLinux 9+ doesn't have PHP 7.1, 7.2, 7.3 + php_versions = ['74', '80', '81', '82', '83', '84', '85'] + else: + php_versions = ['71', '72', '73', '74', '80', '81', '82', '83', '84', '85'] + except: + php_versions = ['71', '72', '73', '74', '80', '81', '82', '83', '84', '85'] + else: + # Check other OS versions + os_info = Upgrade.findOperatingSytem() + if os_info in [Ubuntu24, CENTOS8]: + php_versions = ['74', '80', '81', '82', '83', '84', '85'] + else: + php_versions = ['71', '72', '73', '74', '80', '81', '82', '83', '84', '85'] + + # Check availability of each version + available_versions = [] + for version in php_versions: + if Upgrade.check_package_availability(f'lsphp{version}'): + available_versions.append(version) + else: + Upgrade.stdOut(f"PHP {version} not available on this OS", 0) + + return available_versions + + @staticmethod + def fixLiteSpeedConfig(): + """Fix LiteSpeed configuration issues by creating missing files""" + try: + Upgrade.stdOut("Checking and fixing LiteSpeed configuration...", 1) + + # Check if LiteSpeed is installed + if not os.path.exists('/usr/local/lsws'): + Upgrade.stdOut("LiteSpeed not found at /usr/local/lsws", 0) + return + + # Create missing configuration files + config_files = [ + "/usr/local/lsws/conf/httpd_config.xml", + "/usr/local/lsws/conf/httpd.conf", + "/usr/local/lsws/conf/modsec.conf" + ] + + for config_file in config_files: + if not os.path.exists(config_file): + Upgrade.stdOut(f"Missing LiteSpeed config: {config_file}", 0) + + # Create directory if it doesn't exist + os.makedirs(os.path.dirname(config_file), exist_ok=True) + + # Create minimal config file + if config_file.endswith('httpd_config.xml'): + with open(config_file, 'w') as f: + f.write('\n') + f.write('\n') + f.write(' \n') + f.write(' \n') + f.write(' Default\n') + f.write('
*:8088
\n') + f.write('
\n') + f.write('
\n') + elif config_file.endswith('httpd.conf'): + with open(config_file, 'w') as f: + f.write('# Minimal LiteSpeed HTTP configuration\n') + f.write('# This file will be updated by CyberPanel\n') + elif config_file.endswith('modsec.conf'): + with open(config_file, 'w') as f: + f.write('# ModSecurity configuration\n') + f.write('# This file will be updated by CyberPanel\n') + + Upgrade.stdOut(f"Created minimal config: {config_file}", 1) + else: + Upgrade.stdOut(f"LiteSpeed config exists: {config_file}", 1) + + except Exception as e: + Upgrade.stdOut(f"Error fixing LiteSpeed config: {str(e)}", 0) + @staticmethod def installPHP73(): try: - if Upgrade.installedOutput.find('lsphp73') == -1: - command = 'yum install -y lsphp73 lsphp73-json lsphp73-xmlrpc lsphp73-xml lsphp73-tidy lsphp73-soap lsphp73-snmp ' \ - 'lsphp73-recode lsphp73-pspell lsphp73-process lsphp73-pgsql lsphp73-pear lsphp73-pdo lsphp73-opcache ' \ - 'lsphp73-odbc lsphp73-mysqlnd lsphp73-mcrypt lsphp73-mbstring lsphp73-ldap lsphp73-intl lsphp73-imap ' \ - 'lsphp73-gmp lsphp73-gd lsphp73-enchant lsphp73-dba lsphp73-common lsphp73-bcmath' - Upgrade.executioner(command, 'Install PHP 73, 0') - - if Upgrade.installedOutput.find('lsphp74') == -1: - command = 'yum install -y lsphp74 lsphp74-json lsphp74-xmlrpc lsphp74-xml lsphp74-tidy lsphp74-soap lsphp74-snmp ' \ - 'lsphp74-recode lsphp74-pspell lsphp74-process lsphp74-pgsql lsphp74-pear lsphp74-pdo lsphp74-opcache ' \ - 'lsphp74-odbc lsphp74-mysqlnd lsphp74-mcrypt lsphp74-mbstring lsphp74-ldap lsphp74-intl lsphp74-imap ' \ - 'lsphp74-gmp lsphp74-gd lsphp74-enchant lsphp74-dba lsphp74-common lsphp74-bcmath' - - Upgrade.executioner(command, 'Install PHP 74, 0') - - if Upgrade.installedOutput.find('lsphp80') == -1: - command = 'yum install lsphp80* -y' - subprocess.call(command, shell=True) - - if Upgrade.installedOutput.find('lsphp81') == -1: - command = 'yum install lsphp81* -y' - subprocess.call(command, shell=True) - - if Upgrade.installedOutput.find('lsphp82') == -1: - command = 'yum install lsphp82* -y' - subprocess.call(command, shell=True) - - command = 'yum install lsphp83* -y' - subprocess.call(command, shell=True) - - command = 'yum install lsphp84* -y' - subprocess.call(command, shell=True) - - command = 'yum install lsphp85* -y' + Upgrade.stdOut("Installing PHP versions based on OS compatibility...", 1) + + # Get available PHP versions + available_versions = Upgrade.get_available_php_versions() + + if not available_versions: + Upgrade.stdOut("No PHP versions available for installation", 0) + return + + Upgrade.stdOut(f"Installing available PHP versions: {', '.join(available_versions)}", 1) + + for version in available_versions: + try: + if version in ['71', '72', '73', '74']: + # PHP 7.x versions with specific extensions + if Upgrade.installedOutput.find(f'lsphp{version}') == -1: + extensions = ['json', 'xmlrpc', 'xml', 'tidy', 'soap', 'snmp', 'recode', 'pspell', 'process', 'pgsql', 'pear', 'pdo', 'opcache', 'odbc', 'mysqlnd', 'mcrypt', 'mbstring', 'ldap', 'intl', 'imap', 'gmp', 'gd', 'enchant', 'dba', 'common', 'bcmath'] + package_list = f"lsphp{version} " + " ".join([f"lsphp{version}-{ext}" for ext in extensions]) + command = f"yum install -y {package_list}" + Upgrade.executioner(command, f'Install PHP {version}', 0) + else: + # PHP 8.x versions + if Upgrade.installedOutput.find(f'lsphp{version}') == -1: + command = f"yum install lsphp{version}* -y" subprocess.call(command, shell=True) + Upgrade.stdOut(f"Installed PHP {version}", 1) + + except Exception as e: + Upgrade.stdOut(f"Error installing PHP {version}: {str(e)}", 0) + continue except: command = 'DEBIAN_FRONTEND=noninteractive apt-get -y install ' \ @@ -3997,9 +4174,20 @@ pm.max_spare_servers = 3 @staticmethod def setupPHPSymlink(): try: - # Check if PHP 8.3 exists - if not os.path.exists('/usr/local/lsws/lsphp83/bin/php'): - Upgrade.stdOut("PHP 8.3 not found, installing it first...") + # Try to find available PHP version (prioritize modern stable versions) + # Priority: 8.3 (recommended), 8.2, 8.4, 8.5, 8.1, 8.0, then older versions + php_versions = ['83', '82', '84', '85', '81', '80', '74', '73', '72', '71'] + selected_php = None + + for version in php_versions: + if os.path.exists(f'/usr/local/lsws/lsphp{version}/bin/php'): + selected_php = version + Upgrade.stdOut(f"Found PHP {version}, using as default", 1) + break + + if not selected_php: + # Try to install PHP 8.3 as fallback (modern stable version) + Upgrade.stdOut("No PHP found, installing PHP 8.3 as fallback...") # Install PHP 8.3 based on OS if os.path.exists(Upgrade.CentOSPath) or os.path.exists(Upgrade.openEulerPath): @@ -4013,16 +4201,17 @@ pm.max_spare_servers = 3 if not os.path.exists('/usr/local/lsws/lsphp83/bin/php'): Upgrade.stdOut('[ERROR] Failed to install PHP 8.3') return 0 + selected_php = '83' # Remove existing PHP symlink if it exists if os.path.exists('/usr/bin/php'): os.remove('/usr/bin/php') - # Create symlink to PHP 8.3 - command = 'ln -s /usr/local/lsws/lsphp83/bin/php /usr/bin/php' - Upgrade.executioner(command, 'Setup PHP Symlink to 8.3', 0) + # Create symlink to selected PHP version + command = f'ln -s /usr/local/lsws/lsphp{selected_php}/bin/php /usr/bin/php' + Upgrade.executioner(command, f'Setup PHP Symlink to {selected_php}', 0) - Upgrade.stdOut("PHP symlink updated to PHP 8.3 successfully.") + Upgrade.stdOut(f"PHP symlink updated to PHP {selected_php} successfully.") except BaseException as msg: Upgrade.stdOut('[ERROR] ' + str(msg) + " [setupPHPSymlink]") @@ -4150,6 +4339,9 @@ pm.max_spare_servers = 3 Upgrade.manageServiceMigrations() Upgrade.enableServices() + # Apply AlmaLinux 9 fixes before other installations + Upgrade.fix_almalinux9_mariadb() + Upgrade.installPHP73() Upgrade.setupCLI() Upgrade.someDirectories() @@ -4158,6 +4350,9 @@ pm.max_spare_servers = 3 ## Fix Apache configuration issues after upgrade Upgrade.fixApacheConfiguration() + + # Fix LiteSpeed configuration files if missing + Upgrade.fixLiteSpeedConfig() ### General migrations are not needed any more @@ -4191,8 +4386,32 @@ pm.max_spare_servers = 3 except: pass - command = 'cp /usr/local/lsws/lsphp80/bin/lsphp %s' % (phpPath) + # Try to find available PHP binary in order of preference (modern stable first) + php_versions = ['83', '82', '84', '85', '81', '80', '74', '73', '72', '71'] + php_binary_found = False + + for version in php_versions: + php_binary = f'/usr/local/lsws/lsphp{version}/bin/lsphp' + if os.path.exists(php_binary): + command = f'cp {php_binary} {phpPath}' Upgrade.executioner(command, 0) + Upgrade.stdOut(f"Using PHP {version} for LSCPD", 1) + php_binary_found = True + break + + if not php_binary_found: + Upgrade.stdOut("Warning: No PHP binary found for LSCPD", 0) + # Try to create a symlink to any available PHP + try: + command = 'find /usr/local/lsws -name "lsphp" -type f 2>/dev/null | head -1' + result = subprocess.run(command, shell=True, capture_output=True, text=True) + if result.stdout.strip(): + php_binary = result.stdout.strip() + command = f'cp {php_binary} {phpPath}' + Upgrade.executioner(command, 0) + Upgrade.stdOut(f"Using found PHP binary: {php_binary}", 1) + except: + pass if Upgrade.SoftUpgrade == 0: try: @@ -4200,6 +4419,42 @@ pm.max_spare_servers = 3 Upgrade.executioner(command, 'Start LSCPD', 0) except: pass + + # Try to start other services if they exist + # Enhanced service startup with AlmaLinux 9 support + services_to_start = ['fastapi_ssh_server', 'cyberpanel'] + + # Special handling for AlmaLinux 9 MariaDB service + if Upgrade.is_almalinux9(): + Upgrade.stdOut("AlmaLinux 9 detected - applying enhanced service management", 1) + mariadb_services = ['mariadb', 'mysql', 'mysqld'] + for service in mariadb_services: + try: + check_command = f"systemctl list-unit-files | grep -q {service}" + result = subprocess.run(check_command, shell=True, capture_output=True) + if result.returncode == 0: + command = f"systemctl restart {service}" + Upgrade.executioner(command, f'Restart {service} for AlmaLinux 9', 0) + command = f"systemctl enable {service}" + Upgrade.executioner(command, f'Enable {service} for AlmaLinux 9', 0) + Upgrade.stdOut(f"MariaDB service managed as {service} on AlmaLinux 9", 1) + break + except Exception as e: + Upgrade.stdOut(f"Could not manage MariaDB service {service}: {str(e)}", 0) + continue + + for service in services_to_start: + try: + # Check if service exists + check_command = f"systemctl list-unit-files | grep -q {service}" + result = subprocess.run(check_command, shell=True, capture_output=True) + if result.returncode == 0: + command = f"systemctl start {service}" + Upgrade.executioner(command, f'Start {service}', 0) + else: + Upgrade.stdOut(f"Service {service} not found, skipping", 0) + except Exception as e: + Upgrade.stdOut(f"Could not start {service}: {str(e)}", 0) # Remove CSF if installed and restore firewalld (CSF is being discontinued on August 31, 2025) if os.path.exists('/etc/csf'): diff --git a/plogical/upgrade.py.bak b/plogical/upgrade.py.bak deleted file mode 100644 index 869740ef6..000000000 --- a/plogical/upgrade.py.bak +++ /dev/null @@ -1,2696 +0,0 @@ -import os -import os.path -import sys -import argparse -import pwd -import grp - -sys.path.append('/usr/local/CyberCP') -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "CyberCP.settings") -import shlex -import subprocess -import shutil -import time -import MySQLdb as mysql -from CyberCP import settings -import random -import string - -VERSION = '2.3' -BUILD = 1 - -CENTOS7 = 0 -CENTOS8 = 1 -Ubuntu18 = 2 -Ubuntu20 = 3 -CloudLinux7 = 4 -CloudLinux8 = 5 - - -class Upgrade: - logPath = "/usr/local/lscp/logs/upgradeLog" - cdn = 'cdn.cyberpanel.sh' - installedOutput = '' - CentOSPath = '/etc/redhat-release' - UbuntuPath = '/etc/lsb-release' - FromCloud = 0 - - AdminACL = '{"adminStatus":1, "versionManagement": 1, "createNewUser": 1, "listUsers": 1, "deleteUser":1 , "resellerCenter": 1, ' \ - '"changeUserACL": 1, "createWebsite": 1, "modifyWebsite": 1, "suspendWebsite": 1, "deleteWebsite": 1, ' \ - '"createPackage": 1, "listPackages": 1, "deletePackage": 1, "modifyPackage": 1, "createDatabase": 1, "deleteDatabase": 1, ' \ - '"listDatabases": 1, "createNameServer": 1, "createDNSZone": 1, "deleteZone": 1, "addDeleteRecords": 1, ' \ - '"createEmail": 1, "listEmails": 1, "deleteEmail": 1, "emailForwarding": 1, "changeEmailPassword": 1, ' \ - '"dkimManager": 1, "createFTPAccount": 1, "deleteFTPAccount": 1, "listFTPAccounts": 1, "createBackup": 1,' \ - ' "restoreBackup": 1, "addDeleteDestinations": 1, "scheduleBackups": 1, "remoteBackups": 1, "googleDriveBackups": 1, "manageSSL": 1, ' \ - '"hostnameSSL": 1, "mailServerSSL": 1 }' - - ResellerACL = '{"adminStatus":0, "versionManagement": 1, "createNewUser": 1, "listUsers": 1, "deleteUser": 1 , "resellerCenter": 1, ' \ - '"changeUserACL": 0, "createWebsite": 1, "modifyWebsite": 1, "suspendWebsite": 1, "deleteWebsite": 1, ' \ - '"createPackage": 1, "listPackages": 1, "deletePackage": 1, "modifyPackage": 1, "createDatabase": 1, "deleteDatabase": 1, ' \ - '"listDatabases": 1, "createNameServer": 1, "createDNSZone": 1, "deleteZone": 1, "addDeleteRecords": 1, ' \ - '"createEmail": 1, "listEmails": 1, "deleteEmail": 1, "emailForwarding": 1, "changeEmailPassword": 1, ' \ - '"dkimManager": 1, "createFTPAccount": 1, "deleteFTPAccount": 1, "listFTPAccounts": 1, "createBackup": 1,' \ - ' "restoreBackup": 1, "addDeleteDestinations": 0, "scheduleBackups": 0, "remoteBackups": 0, "googleDriveBackups": 1, "manageSSL": 1, ' \ - '"hostnameSSL": 0, "mailServerSSL": 0 }' - - UserACL = '{"adminStatus":0, "versionManagement": 1, "createNewUser": 0, "listUsers": 0, "deleteUser": 0 , "resellerCenter": 0, ' \ - '"changeUserACL": 0, "createWebsite": 0, "modifyWebsite": 0, "suspendWebsite": 0, "deleteWebsite": 0, ' \ - '"createPackage": 0, "listPackages": 0, "deletePackage": 0, "modifyPackage": 0, "createDatabase": 1, "deleteDatabase": 1, ' \ - '"listDatabases": 1, "createNameServer": 0, "createDNSZone": 1, "deleteZone": 1, "addDeleteRecords": 1, ' \ - '"createEmail": 1, "listEmails": 1, "deleteEmail": 1, "emailForwarding": 1, "changeEmailPassword": 1, ' \ - '"dkimManager": 1, "createFTPAccount": 1, "deleteFTPAccount": 1, "listFTPAccounts": 1, "createBackup": 1,' \ - ' "restoreBackup": 0, "addDeleteDestinations": 0, "scheduleBackups": 0, "remoteBackups": 0, "googleDriveBackups": 1, "manageSSL": 1, ' \ - '"hostnameSSL": 0, "mailServerSSL": 0 }' - - @staticmethod - def decideCentosVersion(): - - if open(Upgrade.CentOSPath, 'r').read().find('CentOS Linux release 8') > -1: - return CENTOS8 - else: - return CENTOS7 - - @staticmethod - def FindOperatingSytem(): - - if os.path.exists(Upgrade.CentOSPath): - result = open(Upgrade.CentOSPath, 'r').read() - - if result.find('CentOS Linux release 8') > -1 or result.find('CloudLinux release 8') > -1: - return CENTOS8 - else: - return CENTOS7 - else: - result = open(Upgrade.UbuntuPath, 'r').read() - - if result.find('20.04') > -1: - return Ubuntu20 - else: - return Ubuntu18 - - - @staticmethod - def stdOut(message, do_exit=0): - print("\n\n") - print(("[" + time.strftime( - "%m.%d.%Y_%H-%M-%S") + "] #########################################################################\n")) - print(("[" + time.strftime("%m.%d.%Y_%H-%M-%S") + "] " + message + "\n")) - print(("[" + time.strftime( - "%m.%d.%Y_%H-%M-%S") + "] #########################################################################\n")) - - if do_exit: - if Upgrade.FromCloud == 0: - os._exit(0) - - @staticmethod - def executioner(command, component, do_exit=0): - try: - FNULL = open(os.devnull, 'w') - count = 0 - while True: - res = subprocess.call(shlex.split(command), stderr=subprocess.STDOUT) - if res != 0: - count = count + 1 - Upgrade.stdOut(component + ' failed, trying again, try number: ' + str(count), 0) - if count == 3: - Upgrade.stdOut(component + ' failed.', do_exit) - return False - else: - Upgrade.stdOut(component + ' successful.', 0) - break - return True - except: - return False - - @staticmethod - def updateRepoURL(): - command = "sed -i 's|sgp.cyberpanel.sh|cdn.cyberpanel.sh|g' /etc/yum.repos.d/MariaDB.repo" - Upgrade.executioner(command, command, 0) - - command = "sed -i 's|lax.cyberpanel.sh|cdn.cyberpanel.sh|g' /etc/yum.repos.d/MariaDB.repo" - Upgrade.executioner(command, command, 0) - - command = "sed -i 's|fra.cyberpanel.sh|cdn.cyberpanel.sh|g' /etc/yum.repos.d/MariaDB.repo" - Upgrade.executioner(command, command, 0) - - command = "sed -i 's|mirror.cyberpanel.net|cdn.cyberpanel.sh|g' /etc/yum.repos.d/MariaDB.repo" - Upgrade.executioner(command, command, 0) - - command = "sed -i 's|sgp.cyberpanel.sh|cdn.cyberpanel.sh|g' /etc/yum.repos.d/litespeed.repo" - Upgrade.executioner(command, command, 0) - - command = "sed -i 's|lax.cyberpanel.sh|cdn.cyberpanel.sh|g' /etc/yum.repos.d/litespeed.repo" - Upgrade.executioner(command, command, 0) - - command = "sed -i 's|fra.cyberpanel.sh|cdn.cyberpanel.sh|g' /etc/yum.repos.d/litespeed.repo" - Upgrade.executioner(command, command, 0) - - command = "sed -i 's|mirror.cyberpanel.net|cdn.cyberpanel.sh|g' /etc/yum.repos.d/litespeed.repo" - Upgrade.executioner(command, command, 0) - - @staticmethod - def mountTemp(): - try: - - if os.path.exists("/usr/.tempdisk"): - return 0 - - command = "dd if=/dev/zero of=/usr/.tempdisk bs=100M count=15" - Upgrade.executioner(command, 'mountTemp', 0) - - command = "mkfs.ext4 -F /usr/.tempdisk" - Upgrade.executioner(command, 'mountTemp', 0) - - command = "mkdir -p /usr/.tmpbak/" - Upgrade.executioner(command, 'mountTemp', 0) - - command = "cp -pr /tmp/* /usr/.tmpbak/" - subprocess.call(command, shell=True) - - command = "mount -o loop,rw,nodev,nosuid,noexec,nofail /usr/.tempdisk /tmp" - Upgrade.executioner(command, 'mountTemp', 0) - - command = "chmod 1777 /tmp" - Upgrade.executioner(command, 'mountTemp', 0) - - command = "cp -pr /usr/.tmpbak/* /tmp/" - subprocess.call(command, shell=True) - - command = "rm -rf /usr/.tmpbak" - Upgrade.executioner(command, 'mountTemp', 0) - - command = "mount --bind /tmp /var/tmp" - Upgrade.executioner(command, 'mountTemp', 0) - - tmp = "/usr/.tempdisk /tmp ext4 loop,rw,noexec,nosuid,nodev,nofail 0 0\n" - varTmp = "/tmp /var/tmp none bind 0 0\n" - - fstab = "/etc/fstab" - writeToFile = open(fstab, "a") - writeToFile.writelines(tmp) - writeToFile.writelines(varTmp) - writeToFile.close() - - except BaseException as msg: - Upgrade.stdOut(str(msg) + " [mountTemp]", 0) - - @staticmethod - def dockerUsers(): - ### Docker User/group - try: - pwd.getpwnam('docker') - except KeyError: - command = "adduser docker" - Upgrade.executioner(command, 'adduser docker', 0) - - try: - grp.getgrnam('docker') - except KeyError: - command = 'groupadd docker' - Upgrade.executioner(command, 'adduser docker', 0) - - command = 'usermod -aG docker docker' - Upgrade.executioner(command, 'adduser docker', 0) - - command = 'usermod -aG docker cyberpanel' - Upgrade.executioner(command, 'adduser docker', 0) - - ### - - @staticmethod - def fixSudoers(): - try: - distroPath = '/etc/lsb-release' - - if os.path.exists(distroPath): - fileName = '/etc/sudoers' - data = open(fileName, 'r').readlines() - - writeDataToFile = open(fileName, 'w') - for line in data: - if line.find("%sudo ALL=(ALL:ALL)") > -1: - continue - else: - writeDataToFile.write(line) - writeDataToFile.close() - - else: - try: - path = "/etc/sudoers" - - data = open(path, 'r').readlines() - - writeToFile = open(path, 'w') - - for items in data: - if items.find("wheel") > -1 and items.find("ALL=(ALL)"): - continue - else: - writeToFile.writelines(items) - - writeToFile.close() - except: - pass - - command = "chsh -s /bin/false cyberpanel" - Upgrade.executioner(command, 0) - except IOError as err: - pass - - @staticmethod - def download_install_phpmyadmin(): - try: - cwd = os.getcwd() - - if not os.path.exists("/usr/local/CyberCP/public"): - os.mkdir("/usr/local/CyberCP/public") - - try: - shutil.rmtree("/usr/local/CyberCP/public/phpmyadmin") - except: - pass - - command = 'wget -O /usr/local/CyberCP/public/phpmyadmin.zip https://github.com/usmannasir/cyberpanel/raw/stable/phpmyadmin.zip' - Upgrade.executioner(command, 0) - - command = 'unzip /usr/local/CyberCP/public/phpmyadmin.zip -d /usr/local/CyberCP/public/' - Upgrade.executioner(command, 0) - - command = 'mv /usr/local/CyberCP/public/phpMyAdmin-*-all-languages /usr/local/CyberCP/public/phpmyadmin' - subprocess.call(command, shell=True) - - command = 'rm -f /usr/local/CyberCP/public/phpmyadmin.zip' - Upgrade.executioner(command, 0) - - ## Write secret phrase - - rString = ''.join([random.choice(string.ascii_letters + string.digits) for n in range(32)]) - - data = open('/usr/local/CyberCP/public/phpmyadmin/config.sample.inc.php', 'r').readlines() - - writeToFile = open('/usr/local/CyberCP/public/phpmyadmin/config.inc.php', 'w') - - writeE = 1 - - phpMyAdminContent = """ -$cfg['Servers'][$i]['AllowNoPassword'] = false; -$cfg['Servers'][$i]['auth_type'] = 'signon'; -$cfg['Servers'][$i]['SignonSession'] = 'SignonSession'; -$cfg['Servers'][$i]['SignonURL'] = 'phpmyadminsignin.php'; -$cfg['Servers'][$i]['LogoutURL'] = 'phpmyadminsignin.php?logout'; -""" - - for items in data: - if items.find('blowfish_secret') > -1: - writeToFile.writelines( - "$cfg['blowfish_secret'] = '" + rString + "'; /* YOU MUST FILL IN THIS FOR COOKIE AUTH! */\n") - elif items.find('/* Authentication type */') > -1: - writeToFile.writelines(items) - writeToFile.write(phpMyAdminContent) - writeE = 0 - elif items.find("$cfg['Servers'][$i]['AllowNoPassword']") > -1: - writeE = 1 - else: - if writeE: - writeToFile.writelines(items) - - writeToFile.writelines("$cfg['TempDir'] = '/usr/local/CyberCP/public/phpmyadmin/tmp';\n") - - writeToFile.close() - - os.mkdir('/usr/local/CyberCP/public/phpmyadmin/tmp') - - command = 'cp /usr/local/CyberCP/plogical/phpmyadminsignin.php /usr/local/CyberCP/public/phpmyadmin/phpmyadminsignin.php' - Upgrade.executioner(command, 0) - - passFile = "/etc/cyberpanel/mysqlPassword" - - try: - import json - jsonData = json.loads(open(passFile, 'r').read()) - - mysqluser = jsonData['mysqluser'] - mysqlpassword = jsonData['mysqlpassword'] - mysqlport = jsonData['mysqlport'] - mysqlhost = jsonData['mysqlhost'] - - command = "sed -i 's|localhost|%s|g' /usr/local/CyberCP/public/phpmyadmin/phpmyadminsignin.php" % ( - mysqlhost) - Upgrade.executioner(command, 0) - - except: - pass - - os.chdir(cwd) - - except BaseException as msg: - Upgrade.stdOut(str(msg) + " [download_install_phpmyadmin]", 0) - - @staticmethod - def setupComposer(): - - if os.path.exists('composer.sh'): - os.remove('composer.sh') - - command = "wget https://cyberpanel.sh/composer.sh" - Upgrade.executioner(command, 0) - - command = "chmod +x composer.sh" - Upgrade.executioner(command, 0) - - command = "./composer.sh" - Upgrade.executioner(command, 0) - - @staticmethod - def downoad_and_install_raindloop(): - try: - ####### - - if os.path.exists("/usr/local/CyberCP/public/snappymail"): - - if os.path.exists("/usr/local/lscp/cyberpanel/snappymail/data"): - pass - else: - command = "mv /usr/local/CyberCP/public/snappymail/data /usr/local/lscp/cyberpanel/snappymail/data" - Upgrade.executioner(command, 0) - - command = "chown -R lscpd:lscpd /usr/local/lscp/cyberpanel/snappymail/data" - Upgrade.executioner(command, 0) - - iPath = os.listdir('/usr/local/CyberCP/public/snappymail/snappymail/v/') - - path = "/usr/local/CyberCP/public/snappymail/snappymail/v/%s/include.php" % (iPath[0]) - - data = open(path, 'r').readlines() - writeToFile = open(path, 'w') - - for items in data: - if items.find("$sCustomDataPath = '';") > -1: - writeToFile.writelines( - " $sCustomDataPath = '/usr/local/lscp/cyberpanel/snappymail/data';\n") - else: - writeToFile.writelines(items) - - writeToFile.close() - return 0 - - cwd = os.getcwd() - - if not os.path.exists("/usr/local/CyberCP/public"): - os.mkdir("/usr/local/CyberCP/public") - - os.chdir("/usr/local/CyberCP/public") - - count = 1 - - while (1): - command = 'wget https://www.snappymail.net/repository/webmail/snappymail-community-latest.zip' - cmd = shlex.split(command) - res = subprocess.call(cmd) - if res != 0: - count = count + 1 - if count == 3: - break - else: - break - - ############# - - count = 0 - - while (1): - command = 'unzip snappymail-community-latest.zip -d /usr/local/CyberCP/public/snappymail' - - cmd = shlex.split(command) - res = subprocess.call(cmd) - if res != 0: - count = count + 1 - if count == 3: - break - else: - break - - os.remove("snappymail-community-latest.zip") - - ####### - - os.chdir("/usr/local/CyberCP/public/snappymail") - - count = 0 - - while (1): - command = 'find . -type d -exec chmod 755 {} \;' - cmd = shlex.split(command) - res = subprocess.call(cmd) - if res != 0: - count = count + 1 - if count == 3: - break - else: - break - - ############# - - count = 0 - - while (1): - command = 'find . -type f -exec chmod 644 {} \;' - cmd = shlex.split(command) - res = subprocess.call(cmd) - if res != 0: - count = count + 1 - if count == 3: - break - else: - break - ###### - - iPath = os.listdir('/usr/local/CyberCP/public/snappymail/snappymail/v/') - - path = "/usr/local/CyberCP/public/snappymail/snappymail/v/%s/include.php" % (iPath[0]) - - data = open(path, 'r').readlines() - writeToFile = open(path, 'w') - - for items in data: - if items.find("$sCustomDataPath = '';") > -1: - writeToFile.writelines( - " $sCustomDataPath = '/usr/local/lscp/cyberpanel/snappymail/data';\n") - else: - writeToFile.writelines(items) - - writeToFile.close() - - command = "mkdir -p /usr/local/lscp/cyberpanel/snappymail/data/_data_/_default_/configs/" - Upgrade.executioner(command, 'mkdir snappymail configs', 0) - - labsPath = '/usr/local/lscp/cyberpanel/snappymail/data/_data_/_default_/configs/application.ini' - - labsData = """[labs] -imap_folder_list_limit = 0 -""" - - writeToFile = open(labsPath, 'w') - writeToFile.write(labsData) - writeToFile.close() - - os.chdir(cwd) - - except BaseException as msg: - Upgrade.stdOut(str(msg) + " [downoad_and_install_raindloop]", 0) - - return 1 - - @staticmethod - def downloadLink(): - try: - version_number = VERSION - version_build = str(BUILD) - - try: - path = "/usr/local/CyberCP/version.txt" - writeToFile = open(path, 'w') - writeToFile.writelines(version_number + '\n') - writeToFile.writelines(version_build) - writeToFile.close() - except: - pass - - return (version_number + "." + version_build + ".tar.gz") - except BaseException as msg: - Upgrade.stdOut(str(msg) + ' [downloadLink]') - os._exit(0) - - @staticmethod - def setupCLI(): - try: - - command = "ln -s /usr/local/CyberCP/cli/cyberPanel.py /usr/bin/cyberpanel" - Upgrade.executioner(command, 'CLI Symlink', 0) - - command = "chmod +x /usr/local/CyberCP/cli/cyberPanel.py" - Upgrade.executioner(command, 'CLI Permissions', 0) - - except OSError as msg: - Upgrade.stdOut(str(msg) + " [setupCLI]") - return 0 - - @staticmethod - def staticContent(): - - command = "rm -rf /usr/local/CyberCP/public/static" - Upgrade.executioner(command, 'Remove old static content', 0) - - ## - - if not os.path.exists("/usr/local/CyberCP/public"): - os.mkdir("/usr/local/CyberCP/public") - - shutil.move("/usr/local/CyberCP/static", "/usr/local/CyberCP/public/") - - @staticmethod - def upgradeVersion(): - try: - - import django - os.environ.setdefault("DJANGO_SETTINGS_MODULE", "CyberCP.settings") - django.setup() - from baseTemplate.models import version - - vers = version.objects.get(pk=1) - vers.currentVersion = VERSION - vers.build = str(BUILD) - vers.save() - except: - pass - - @staticmethod - def setupConnection(db=None): - try: - passFile = "/etc/cyberpanel/mysqlPassword" - - f = open(passFile) - data = f.read() - password = data.split('\n', 1)[0] - - if db == None: - conn = mysql.connect(user='root', passwd=password) - else: - try: - conn = mysql.connect(db=db, user='root', passwd=password) - except: - try: - conn = mysql.connect(host='127.0.0.1', port=3307, db=db, user='root', passwd=password) - except: - dbUser = settings.DATABASES['default']['USER'] - password = settings.DATABASES['default']['PASSWORD'] - host = settings.DATABASES['default']['HOST'] - port = settings.DATABASES['default']['PORT'] - - if port == '': - conn = mysql.connect(host=host, port=3306, db=db, user=dbUser, passwd=password) - else: - conn = mysql.connect(host=host, port=int(port), db=db, user=dbUser, passwd=password) - - cursor = conn.cursor() - return conn, cursor - - except BaseException as msg: - Upgrade.stdOut(str(msg)) - return 0, 0 - - @staticmethod - def applyLoginSystemMigrations(): - try: - - connection, cursor = Upgrade.setupConnection('cyberpanel') - - try: - cursor.execute('CREATE TABLE `baseTemplate_cyberpanelcosmetic` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `MainDashboardCSS` longtext NOT NULL)') - except: - pass - - try: - cursor.execute( - 'CREATE TABLE `loginSystem_acl` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `name` varchar(50) NOT NULL UNIQUE, `adminStatus` integer NOT NULL DEFAULT 0, `versionManagement` integer NOT NULL DEFAULT 0, `createNewUser` integer NOT NULL DEFAULT 0, `deleteUser` integer NOT NULL DEFAULT 0, `resellerCenter` integer NOT NULL DEFAULT 0, `changeUserACL` integer NOT NULL DEFAULT 0, `createWebsite` integer NOT NULL DEFAULT 0, `modifyWebsite` integer NOT NULL DEFAULT 0, `suspendWebsite` integer NOT NULL DEFAULT 0, `deleteWebsite` integer NOT NULL DEFAULT 0, `createPackage` integer NOT NULL DEFAULT 0, `deletePackage` integer NOT NULL DEFAULT 0, `modifyPackage` integer NOT NULL DEFAULT 0, `createDatabase` integer NOT NULL DEFAULT 0, `deleteDatabase` integer NOT NULL DEFAULT 0, `listDatabases` integer NOT NULL DEFAULT 0, `createNameServer` integer NOT NULL DEFAULT 0, `createDNSZone` integer NOT NULL DEFAULT 0, `deleteZone` integer NOT NULL DEFAULT 0, `addDeleteRecords` integer NOT NULL DEFAULT 0, `createEmail` integer NOT NULL DEFAULT 0, `deleteEmail` integer NOT NULL DEFAULT 0, `emailForwarding` integer NOT NULL DEFAULT 0, `changeEmailPassword` integer NOT NULL DEFAULT 0, `dkimManager` integer NOT NULL DEFAULT 0, `createFTPAccount` integer NOT NULL DEFAULT 0, `deleteFTPAccount` integer NOT NULL DEFAULT 0, `listFTPAccounts` integer NOT NULL DEFAULT 0, `createBackup` integer NOT NULL DEFAULT 0, `restoreBackup` integer NOT NULL DEFAULT 0, `addDeleteDestinations` integer NOT NULL DEFAULT 0, `scheduleBackups` integer NOT NULL DEFAULT 0, `remoteBackups` integer NOT NULL DEFAULT 0, `manageSSL` integer NOT NULL DEFAULT 0, `hostnameSSL` integer NOT NULL DEFAULT 0, `mailServerSSL` integer NOT NULL DEFAULT 0)') - except: - pass - try: - cursor.execute('ALTER TABLE loginSystem_administrator ADD token varchar(500)') - except: - pass - - try: - cursor.execute("ALTER TABLE loginSystem_administrator ADD secretKey varchar(50) DEFAULT 'None'") - except: - pass - - try: - cursor.execute('alter table databases_databases drop index dbUser;') - except: - pass - - try: - cursor.execute("ALTER TABLE loginSystem_administrator ADD state varchar(15) DEFAULT 'ACTIVE'") - except: - pass - - try: - cursor.execute('ALTER TABLE loginSystem_administrator ADD securityLevel integer DEFAULT 1') - except: - pass - - try: - cursor.execute('ALTER TABLE loginSystem_administrator ADD twoFA integer DEFAULT 0') - except: - pass - - try: - cursor.execute('ALTER TABLE loginSystem_administrator ADD api integer') - except: - pass - - try: - cursor.execute('ALTER TABLE loginSystem_administrator ADD acl_id integer') - except: - pass - try: - cursor.execute( - 'ALTER TABLE loginSystem_administrator ADD FOREIGN KEY (acl_id) REFERENCES loginSystem_acl(id)') - except: - pass - - try: - cursor.execute("insert into loginSystem_acl (id, name, adminStatus) values (1,'admin',1)") - except: - pass - - try: - cursor.execute( - "insert into loginSystem_acl (id, name, adminStatus, createNewUser, deleteUser, createWebsite, resellerCenter, modifyWebsite, suspendWebsite, deleteWebsite, createPackage, deletePackage, modifyPackage, createNameServer, restoreBackup) values (2,'reseller',0,1,1,1,1,1,1,1,1,1,1,1,1)") - except: - pass - try: - cursor.execute( - "insert into loginSystem_acl (id, name, createDatabase, deleteDatabase, listDatabases, createDNSZone, deleteZone, addDeleteRecords, createEmail, deleteEmail, emailForwarding, changeEmailPassword, dkimManager, createFTPAccount, deleteFTPAccount, listFTPAccounts, createBackup, manageSSL) values (3,'user', 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)") - except: - pass - - try: - cursor.execute("UPDATE loginSystem_administrator SET acl_id = 1 where userName = 'admin'") - except: - pass - - try: - cursor.execute('ALTER TABLE loginSystem_acl ADD config longtext') - except: - pass - - try: - cursor.execute("UPDATE loginSystem_acl SET config = '%s' where name = 'admin'" % (Upgrade.AdminACL)) - except BaseException as msg: - print(str(msg)) - import sleep - sleep(10) - - try: - cursor.execute("UPDATE loginSystem_acl SET config = '%s' where name = 'reseller'" % (Upgrade.ResellerACL)) - except: - pass - - try: - cursor.execute("UPDATE loginSystem_acl SET config = '%s' where name = 'user'" % (Upgrade.UserACL)) - except: - pass - - try: - cursor.execute("alter table loginSystem_administrator drop initUserAccountsLimit") - except: - pass - - try: - cursor.execute( - "CREATE TABLE `websiteFunctions_aliasdomains` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `aliasDomain` varchar(75) NOT NULL)") - except: - pass - try: - cursor.execute("ALTER TABLE `websiteFunctions_aliasdomains` ADD COLUMN `master_id` integer NOT NULL") - except: - pass - try: - cursor.execute( - "ALTER TABLE `websiteFunctions_aliasdomains` ADD CONSTRAINT `websiteFunctions_ali_master_id_726c433d_fk_websiteFu` FOREIGN KEY (`master_id`) REFERENCES `websiteFunctions_websites` (`id`)") - except: - pass - - try: - cursor.execute('ALTER TABLE websiteFunctions_websites ADD config longtext') - except: - pass - - try: - cursor.execute("ALTER TABLE websiteFunctions_websites MODIFY externalApp varchar(30)") - except: - pass - - try: - cursor.execute("ALTER TABLE emailMarketing_smtphosts MODIFY userName varchar(200)") - except: - pass - - try: - cursor.execute("ALTER TABLE emailMarketing_smtphosts MODIFY password varchar(200)") - except: - pass - - try: - cursor.execute("ALTER TABLE websiteFunctions_backups MODIFY fileName varchar(200)") - except: - pass - - try: - cursor.execute("ALTER TABLE loginSystem_acl ADD COLUMN listUsers INT DEFAULT 0;") - except: - pass - - try: - cursor.execute("ALTER TABLE loginSystem_acl ADD COLUMN listEmails INT DEFAULT 1;") - except: - pass - - try: - cursor.execute("ALTER TABLE loginSystem_acl ADD COLUMN listPackages INT DEFAULT 0;") - except: - pass - - query = """CREATE TABLE `websiteFunctions_normalbackupdests` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(25) NOT NULL, - `config` longtext NOT NULL, - PRIMARY KEY (`id`) -)""" - try: - cursor.execute(query) - except: - pass - - query = """CREATE TABLE `cloudAPI_wpdeployments` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `config` longtext NOT NULL, - `owner_id` int(11) NOT NULL, - PRIMARY KEY (`id`), - KEY `cloudAPI_wpdeploymen_owner_id_506ddf01_fk_websiteFu` (`owner_id`), - CONSTRAINT `cloudAPI_wpdeploymen_owner_id_506ddf01_fk_websiteFu` FOREIGN KEY (`owner_id`) REFERENCES `websiteFunctions_websites` (`id`) -)""" - - try: - cursor.execute(query) - except: - pass - - query = """CREATE TABLE `websiteFunctions_normalbackupjobs` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(25) NOT NULL, - `config` longtext NOT NULL, - `owner_id` int(11) NOT NULL, - PRIMARY KEY (`id`), - KEY `websiteFunctions_nor_owner_id_3a7a13db_fk_websiteFu` (`owner_id`), - CONSTRAINT `websiteFunctions_nor_owner_id_3a7a13db_fk_websiteFu` FOREIGN KEY (`owner_id`) REFERENCES `websiteFunctions_normalbackupdests` (`id`) -)""" - - try: - cursor.execute(query) - except: - pass - - query = """CREATE TABLE `websiteFunctions_normalbackupsites` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `domain_id` int(11) NOT NULL, - `owner_id` int(11) NOT NULL, - PRIMARY KEY (`id`), - KEY `websiteFunctions_nor_domain_id_c03362bc_fk_websiteFu` (`domain_id`), - KEY `websiteFunctions_nor_owner_id_c6ece6cc_fk_websiteFu` (`owner_id`), - CONSTRAINT `websiteFunctions_nor_domain_id_c03362bc_fk_websiteFu` FOREIGN KEY (`domain_id`) REFERENCES `websiteFunctions_websites` (`id`), - CONSTRAINT `websiteFunctions_nor_owner_id_c6ece6cc_fk_websiteFu` FOREIGN KEY (`owner_id`) REFERENCES `websiteFunctions_normalbackupjobs` (`id`) -)""" - - try: - cursor.execute(query) - except: - pass - - query = """CREATE TABLE `websiteFunctions_normalbackupjoblogs` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `status` int(11) NOT NULL, - `message` longtext NOT NULL, - `owner_id` int(11) NOT NULL, - PRIMARY KEY (`id`), - KEY `websiteFunctions_nor_owner_id_69403e73_fk_websiteFu` (`owner_id`), - CONSTRAINT `websiteFunctions_nor_owner_id_69403e73_fk_websiteFu` FOREIGN KEY (`owner_id`) REFERENCES `websiteFunctions_normalbackupjobs` (`id`) -)""" - - try: - cursor.execute(query) - except: - pass - - try: - connection.close() - except: - pass - - except OSError as msg: - Upgrade.stdOut(str(msg) + " [applyLoginSystemMigrations]") - - @staticmethod - def s3BackupMigrations(): - try: - - connection, cursor = Upgrade.setupConnection('cyberpanel') - - query = """CREATE TABLE `s3Backups_backupplan` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(50) NOT NULL, - `bucket` varchar(50) NOT NULL, - `freq` varchar(50) NOT NULL, - `retention` int(11) NOT NULL, - `type` varchar(5) NOT NULL, - `lastRun` varchar(50) NOT NULL, - `owner_id` int(11) NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `name` (`name`), - KEY `s3Backups_backupplan_owner_id_7d058ced_fk_loginSyst` (`owner_id`), - CONSTRAINT `s3Backups_backupplan_owner_id_7d058ced_fk_loginSyst` FOREIGN KEY (`owner_id`) REFERENCES `loginSystem_administrator` (`id`) -)""" - - try: - cursor.execute(query) - except: - pass - - try: - cursor.execute('ALTER TABLE s3Backups_backupplan ADD config longtext') - except: - pass - - query = """CREATE TABLE `s3Backups_websitesinplan` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `domain` varchar(100) NOT NULL, - `owner_id` int(11) NOT NULL, - PRIMARY KEY (`id`), - KEY `s3Backups_websitesin_owner_id_0e9a4fe3_fk_s3Backups` (`owner_id`), - CONSTRAINT `s3Backups_websitesin_owner_id_0e9a4fe3_fk_s3Backups` FOREIGN KEY (`owner_id`) REFERENCES `s3Backups_backupplan` (`id`) -)""" - - try: - cursor.execute(query) - except: - pass - - query = """CREATE TABLE `s3Backups_backuplogs` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `timeStamp` varchar(200) NOT NULL, - `level` varchar(5) NOT NULL, - `msg` varchar(500) NOT NULL, - `owner_id` int(11) NOT NULL, - PRIMARY KEY (`id`), - KEY `s3Backups_backuplogs_owner_id_7b4653af_fk_s3Backups` (`owner_id`), - CONSTRAINT `s3Backups_backuplogs_owner_id_7b4653af_fk_s3Backups` FOREIGN KEY (`owner_id`) REFERENCES `s3Backups_backupplan` (`id`) -)""" - - try: - cursor.execute(query) - except: - pass - - query = """CREATE TABLE `s3Backups_backupplando` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(50) NOT NULL, - `bucket` varchar(50) NOT NULL, - `freq` varchar(50) NOT NULL, - `retention` int(11) NOT NULL, - `type` varchar(5) NOT NULL, - `region` varchar(5) NOT NULL, - `lastRun` varchar(50) NOT NULL, - `owner_id` int(11) NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `name` (`name`), - KEY `s3Backups_backupplan_owner_id_1a3ec86d_fk_loginSyst` (`owner_id`), - CONSTRAINT `s3Backups_backupplan_owner_id_1a3ec86d_fk_loginSyst` FOREIGN KEY (`owner_id`) REFERENCES `loginSystem_administrator` (`id`) -)""" - - try: - cursor.execute(query) - except: - pass - - query = """CREATE TABLE `s3Backups_websitesinplando` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `domain` varchar(100) NOT NULL, - `owner_id` int(11) NOT NULL, - PRIMARY KEY (`id`), - KEY `s3Backups_websitesin_owner_id_cef3ea04_fk_s3Backups` (`owner_id`), - CONSTRAINT `s3Backups_websitesin_owner_id_cef3ea04_fk_s3Backups` FOREIGN KEY (`owner_id`) REFERENCES `s3Backups_backupplando` (`id`) -)""" - - try: - cursor.execute(query) - except: - pass - - query = """CREATE TABLE `s3Backups_backuplogsdo` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `timeStamp` varchar(200) NOT NULL, - `level` varchar(5) NOT NULL, - `msg` varchar(500) NOT NULL, - `owner_id` int(11) NOT NULL, - PRIMARY KEY (`id`), - KEY `s3Backups_backuplogs_owner_id_c7cb5872_fk_s3Backups` (`owner_id`), - CONSTRAINT `s3Backups_backuplogs_owner_id_c7cb5872_fk_s3Backups` FOREIGN KEY (`owner_id`) REFERENCES `s3Backups_backupplando` (`id`) -)""" - - try: - cursor.execute(query) - except: - pass - - ## - - query = """CREATE TABLE `s3Backups_minionodes` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `endPointURL` varchar(200) NOT NULL, - `accessKey` varchar(200) NOT NULL, - `secretKey` varchar(200) NOT NULL, - `owner_id` int(11) NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `endPointURL` (`endPointURL`), - UNIQUE KEY `accessKey` (`accessKey`), - KEY `s3Backups_minionodes_owner_id_e50993d9_fk_loginSyst` (`owner_id`), - CONSTRAINT `s3Backups_minionodes_owner_id_e50993d9_fk_loginSyst` FOREIGN KEY (`owner_id`) REFERENCES `loginSystem_administrator` (`id`) -)""" - - try: - cursor.execute(query) - except: - pass - - query = """CREATE TABLE `s3Backups_backupplanminio` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(50) NOT NULL, - `freq` varchar(50) NOT NULL, - `retention` int(11) NOT NULL, - `lastRun` varchar(50) NOT NULL, - `minioNode_id` int(11) NOT NULL, - `owner_id` int(11) NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `name` (`name`), - KEY `s3Backups_backupplan_minioNode_id_a4eaf917_fk_s3Backups` (`minioNode_id`), - KEY `s3Backups_backupplan_owner_id_d6830e67_fk_loginSyst` (`owner_id`), - CONSTRAINT `s3Backups_backupplan_minioNode_id_a4eaf917_fk_s3Backups` FOREIGN KEY (`minioNode_id`) REFERENCES `s3Backups_minionodes` (`id`), - CONSTRAINT `s3Backups_backupplan_owner_id_d6830e67_fk_loginSyst` FOREIGN KEY (`owner_id`) REFERENCES `loginSystem_administrator` (`id`) -)""" - - try: - cursor.execute(query) - except: - pass - - query = """CREATE TABLE `s3Backups_websitesinplanminio` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `domain` varchar(100) NOT NULL, - `owner_id` int(11) NOT NULL, - PRIMARY KEY (`id`), - KEY `s3Backups_websitesin_owner_id_224ce049_fk_s3Backups` (`owner_id`), - CONSTRAINT `s3Backups_websitesin_owner_id_224ce049_fk_s3Backups` FOREIGN KEY (`owner_id`) REFERENCES `s3Backups_backupplanminio` (`id`) -)""" - - try: - cursor.execute(query) - except: - pass - - query = """CREATE TABLE `s3Backups_backuplogsminio` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `timeStamp` varchar(200) NOT NULL, - `level` varchar(5) NOT NULL, - `msg` varchar(500) NOT NULL, - `owner_id` int(11) NOT NULL, - PRIMARY KEY (`id`), - KEY `s3Backups_backuplogs_owner_id_f19e1736_fk_s3Backups` (`owner_id`), - CONSTRAINT `s3Backups_backuplogs_owner_id_f19e1736_fk_s3Backups` FOREIGN KEY (`owner_id`) REFERENCES `s3Backups_backupplanminio` (`id`) -)""" - - try: - cursor.execute(query) - except: - pass - - try: - connection.close() - except: - pass - - except OSError as msg: - Upgrade.stdOut(str(msg) + " [applyLoginSystemMigrations]") - - @staticmethod - def mailServerMigrations(): - try: - connection, cursor = Upgrade.setupConnection('cyberpanel') - - try: - cursor.execute( - 'ALTER TABLE `e_domains` ADD COLUMN `childOwner_id` integer') - except: - pass - - try: - cursor.execute( - 'ALTER TABLE e_users ADD mail varchar(200)') - except: - pass - - try: - cursor.execute( - 'ALTER TABLE e_users MODIFY password varchar(200)') - except: - pass - - try: - cursor.execute( - 'ALTER TABLE e_forwardings DROP PRIMARY KEY;ALTER TABLE e_forwardings ADD id INT AUTO_INCREMENT PRIMARY KEY') - except: - pass - - query = """CREATE TABLE `emailPremium_domainlimits` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `limitStatus` int(11) NOT NULL, - `monthlyLimit` int(11) NOT NULL, - `monthlyUsed` int(11) NOT NULL, - `domain_id` varchar(50) NOT NULL, - PRIMARY KEY (`id`), - KEY `emailPremium_domainlimits_domain_id_303ab297_fk_e_domains_domain` (`domain_id`), - CONSTRAINT `emailPremium_domainlimits_domain_id_303ab297_fk_e_domains_domain` FOREIGN KEY (`domain_id`) REFERENCES `e_domains` (`domain`) -)""" - try: - cursor.execute(query) - except: - pass - - query = """CREATE TABLE `emailPremium_emaillimits` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `limitStatus` int(11) NOT NULL, - `monthlyLimits` int(11) NOT NULL, - `monthlyUsed` int(11) NOT NULL, - `hourlyLimit` int(11) NOT NULL, - `hourlyUsed` int(11) NOT NULL, - `emailLogs` int(11) NOT NULL, - `email_id` varchar(80) NOT NULL, - PRIMARY KEY (`id`), - KEY `emailPremium_emaillimits_email_id_1c111df5_fk_e_users_email` (`email_id`), - CONSTRAINT `emailPremium_emaillimits_email_id_1c111df5_fk_e_users_email` FOREIGN KEY (`email_id`) REFERENCES `e_users` (`email`) -)""" - try: - cursor.execute(query) - except: - pass - - query = """CREATE TABLE `emailPremium_emaillogs` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `destination` varchar(200) NOT NULL, - `timeStamp` varchar(200) NOT NULL, - `email_id` varchar(80) NOT NULL, - PRIMARY KEY (`id`), - KEY `emailPremium_emaillogs_email_id_9ef49552_fk_e_users_email` (`email_id`), - CONSTRAINT `emailPremium_emaillogs_email_id_9ef49552_fk_e_users_email` FOREIGN KEY (`email_id`) REFERENCES `e_users` (`email`) -)""" - try: - cursor.execute(query) - except: - pass - - try: - connection.close() - except: - pass - except: - pass - - @staticmethod - def emailMarketingMigrationsa(): - try: - connection, cursor = Upgrade.setupConnection('cyberpanel') - - query = """CREATE TABLE `emailMarketing_emailmarketing` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `userName` varchar(50) NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `userName` (`userName`) -)""" - try: - cursor.execute(query) - except: - pass - - query = """CREATE TABLE `emailMarketing_emaillists` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `listName` varchar(50) NOT NULL, - `dateCreated` varchar(200) NOT NULL, - `owner_id` int(11) NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `listName` (`listName`), - KEY `emailMarketing_email_owner_id_bf1b4530_fk_websiteFu` (`owner_id`), - CONSTRAINT `emailMarketing_email_owner_id_bf1b4530_fk_websiteFu` FOREIGN KEY (`owner_id`) REFERENCES `websiteFunctions_websites` (`id`) -)""" - try: - cursor.execute(query) - except: - pass - - query = 'ALTER TABLE emailMarketing_emaillists ADD COLUMN verified INT DEFAULT 0' - - try: - cursor.execute(query) - except: - pass - - query = 'ALTER TABLE emailMarketing_emaillists ADD COLUMN notVerified INT DEFAULT 0' - - try: - cursor.execute(query) - except: - pass - - query = """CREATE TABLE `emailMarketing_emailsinlist` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `email` varchar(50) NOT NULL, - `firstName` varchar(20) NOT NULL, - `lastName` varchar(20) NOT NULL, - `verificationStatus` varchar(100) NOT NULL, - `dateCreated` varchar(200) NOT NULL, - `owner_id` int(11) NOT NULL, - PRIMARY KEY (`id`), - KEY `emailMarketing_email_owner_id_c5c27005_fk_emailMark` (`owner_id`), - CONSTRAINT `emailMarketing_email_owner_id_c5c27005_fk_emailMark` FOREIGN KEY (`owner_id`) REFERENCES `emailMarketing_emaillists` (`id`) -)""" - - try: - cursor.execute(query) - except: - pass - - query = """CREATE TABLE `emailMarketing_smtphosts` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `host` varchar(150) NOT NULL, - `port` varchar(10) NOT NULL, - `userName` varchar(50) NOT NULL, - `password` varchar(50) NOT NULL, - `owner_id` int(11) NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `host` (`host`), - KEY `emailMarketing_smtph_owner_id_8b2d4ac7_fk_loginSyst` (`owner_id`), - CONSTRAINT `emailMarketing_smtph_owner_id_8b2d4ac7_fk_loginSyst` FOREIGN KEY (`owner_id`) REFERENCES `loginSystem_administrator` (`id`) -)""" - - try: - cursor.execute(query) - except: - pass - - query = """CREATE TABLE `emailMarketing_emailtemplate` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(100) NOT NULL, - `subject` varchar(1000) NOT NULL, - `fromName` varchar(100) NOT NULL, - `fromEmail` varchar(150) NOT NULL, - `replyTo` varchar(150) NOT NULL, - `emailMessage` varchar(30000) NOT NULL, - `owner_id` int(11) NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `name` (`name`), - KEY `emailMarketing_email_owner_id_d27e1d00_fk_loginSyst` (`owner_id`), - CONSTRAINT `emailMarketing_email_owner_id_d27e1d00_fk_loginSyst` FOREIGN KEY (`owner_id`) REFERENCES `loginSystem_administrator` (`id`) -)""" - - try: - cursor.execute(query) - except: - pass - - query = """CREATE TABLE `emailMarketing_emailjobs` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `date` varchar(200) NOT NULL, - `host` varchar(1000) NOT NULL, - `totalEmails` int(11) NOT NULL, - `sent` int(11) NOT NULL, - `failed` int(11) NOT NULL, - `owner_id` int(11) NOT NULL, - PRIMARY KEY (`id`), - KEY `emailMarketing_email_owner_id_73ee4827_fk_emailMark` (`owner_id`), - CONSTRAINT `emailMarketing_email_owner_id_73ee4827_fk_emailMark` FOREIGN KEY (`owner_id`) REFERENCES `emailMarketing_emailtemplate` (`id`) -)""" - - try: - cursor.execute(query) - except: - pass - - query = """CREATE TABLE `mailServer_pipeprograms` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `source` varchar(80) NOT NULL, - `destination` longtext NOT NULL, - PRIMARY KEY (`id`) -)""" - - try: - cursor.execute(query) - except: - pass - - query = """CREATE TABLE `emailMarketing_validationlog` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `status` int(11) NOT NULL, - `message` longtext NOT NULL, - `owner_id` int(11) NOT NULL, - PRIMARY KEY (`id`), - KEY `emailMarketing_valid_owner_id_240ad36e_fk_emailMark` (`owner_id`), - CONSTRAINT `emailMarketing_valid_owner_id_240ad36e_fk_emailMark` FOREIGN KEY (`owner_id`) REFERENCES `emailMarketing_emaillists` (`id`) -)""" - - try: - cursor.execute(query) - except: - pass - - try: - connection.close() - except: - pass - except: - pass - - @staticmethod - def dockerMigrations(): - try: - connection, cursor = Upgrade.setupConnection('cyberpanel') - - query = """CREATE TABLE `dockerManager_containers` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(50) NOT NULL, - `cid` varchar(64) NOT NULL, - `image` varchar(50) NOT NULL, - `tag` varchar(50) NOT NULL, - `memory` int(11) NOT NULL, - `ports` longtext NOT NULL, - `env` longtext NOT NULL, - `startOnReboot` int(11) NOT NULL, - `admin_id` int(11) NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `name` (`name`), - KEY `dockerManager_contai_admin_id_58fb62b7_fk_loginSyst` (`admin_id`), - CONSTRAINT `dockerManager_contai_admin_id_58fb62b7_fk_loginSyst` FOREIGN KEY (`admin_id`) REFERENCES `loginSystem_administrator` (`id`) -)""" - try: - cursor.execute(query) - except: - pass - - try: - cursor.execute('ALTER TABLE loginSystem_administrator ADD config longtext') - except: - pass - - try: - cursor.execute('ALTER TABLE loginSystem_acl ADD config longtext') - except: - pass - - try: - cursor.execute('ALTER TABLE dockerManager_containers ADD volumes longtext') - except: - pass - - try: - connection.close() - except: - pass - except: - pass - - @staticmethod - def containerMigrations(): - try: - connection, cursor = Upgrade.setupConnection('cyberpanel') - - query = """CREATE TABLE `containerization_containerlimits` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `cpuPers` varchar(10) NOT NULL, - `IO` varchar(10) NOT NULL, - `IOPS` varchar(10) NOT NULL, - `memory` varchar(10) NOT NULL, - `networkSpeed` varchar(10) NOT NULL, - `networkHexValue` varchar(10) NOT NULL, - `enforce` int(11) NOT NULL, - `owner_id` int(11) NOT NULL, - PRIMARY KEY (`id`), - KEY `containerization_con_owner_id_494eb637_fk_websiteFu` (`owner_id`), - CONSTRAINT `containerization_con_owner_id_494eb637_fk_websiteFu` FOREIGN KEY (`owner_id`) REFERENCES `websiteFunctions_websites` (`id`) -)""" - try: - cursor.execute(query) - except: - pass - - try: - connection.close() - except: - pass - except: - pass - - @staticmethod - def CLMigrations(): - try: - connection, cursor = Upgrade.setupConnection('cyberpanel') - - query = """CREATE TABLE `CLManager_clpackages` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(50) NOT NULL, - `speed` varchar(50) NOT NULL, - `vmem` varchar(50) NOT NULL, - `pmem` varchar(50) NOT NULL, - `io` varchar(50) NOT NULL, - `iops` varchar(50) NOT NULL, - `ep` varchar(50) NOT NULL, - `nproc` varchar(50) NOT NULL, - `inodessoft` varchar(50) NOT NULL, - `inodeshard` varchar(50) NOT NULL, - `owner_id` int(11) NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `name` (`name`), - KEY `CLManager_clpackages_owner_id_9898c1e8_fk_packages_package_id` (`owner_id`), - CONSTRAINT `CLManager_clpackages_owner_id_9898c1e8_fk_packages_package_id` FOREIGN KEY (`owner_id`) REFERENCES `packages_package` (`id`) -)""" - try: - cursor.execute(query) - except: - pass - - query = "ALTER TABLE packages_package ADD COLUMN allowFullDomain INT DEFAULT 1;" - try: - cursor.execute(query) - except: - pass - - query = "ALTER TABLE packages_package ADD COLUMN enforceDiskLimits INT DEFAULT 0;" - try: - cursor.execute(query) - except: - pass - - try: - connection.close() - except: - pass - except: - pass - - @staticmethod - def manageServiceMigrations(): - try: - connection, cursor = Upgrade.setupConnection('cyberpanel') - - query = """CREATE TABLE `manageServices_pdnsstatus` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `serverStatus` int(11) NOT NULL, - `type` varchar(6) NOT NULL, - PRIMARY KEY (`id`) -)""" - try: - cursor.execute(query) - except: - pass - - try: - cursor.execute('alter table manageServices_pdnsstatus add masterServer varchar(200)') - except: - pass - - try: - cursor.execute('alter table manageServices_pdnsstatus add masterIP varchar(200)') - except: - pass - - try: - cursor.execute('ALTER TABLE `manageServices_pdnsstatus` CHANGE `type` `type` VARCHAR(10) NULL;') - except: - pass - - query = '''CREATE TABLE `databases_dbmeta` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `key` varchar(200) NOT NULL, - `value` longtext NOT NULL, - `database_id` int(11) NOT NULL, - PRIMARY KEY (`id`), - KEY `databases_dbmeta_database_id_777997bc_fk_databases_databases_id` (`database_id`), - CONSTRAINT `databases_dbmeta_database_id_777997bc_fk_databases_databases_id` FOREIGN KEY (`database_id`) REFERENCES `databases_databases` (`id`) -)''' - - try: - cursor.execute(query) - except: - pass - - query = """CREATE TABLE `filemanager_trash` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `originalPath` varchar(500) NOT NULL, - `fileName` varchar(200) NOT NULL, - `website_id` int(11) NOT NULL, - PRIMARY KEY (`id`), - KEY `filemanager_trash_website_id_e2762f3c_fk_websiteFu` (`website_id`), - CONSTRAINT `filemanager_trash_website_id_e2762f3c_fk_websiteFu` FOREIGN KEY (`website_id`) REFERENCES `websiteFunctions_websites` (`id`) -)""" - - try: - cursor.execute(query) - except: - pass - - query = """CREATE TABLE `databases_globaluserdb` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `username` varchar(200) NOT NULL, - `password` varchar(500) NOT NULL, - `token` varchar(20) NOT NULL, - PRIMARY KEY (`id`) -)""" - - try: - cursor.execute(query) - except: - pass - - query = "CREATE TABLE `databases_databasesusers` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `username` varchar(50) NOT NULL UNIQUE, `owner_id` integer NOT NULL)" - - try: - cursor.execute(query) - except: - pass - - query = "ALTER TABLE `databases_databasesusers` ADD CONSTRAINT `databases_databasesu_owner_id_908fc638_fk_databases` FOREIGN KEY (`owner_id`) REFERENCES `databases_databases` (`id`);" - - try: - cursor.execute(query) - except: - pass - - try: - connection.close() - except: - pass - except: - pass - - @staticmethod - def GeneralMigrations(): - try: - - cwd = os.getcwd() - os.chdir('/usr/local/CyberCP') - - command = '/usr/local/CyberPanel/bin/python manage.py makemigrations' - Upgrade.executioner(command, 'python manage.py makemigrations', 0) - - command = '/usr/local/CyberPanel/bin/python manage.py makemigrations' - Upgrade.executioner(command, '/usr/local/CyberPanel/bin/python manage.py migrate', 0) - - os.chdir(cwd) - - except: - pass - - @staticmethod - def IncBackupMigrations(): - try: - connection, cursor = Upgrade.setupConnection('cyberpanel') - - query = """CREATE TABLE `IncBackups_backupjob` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `destination` varchar(300) NOT NULL, - `frequency` varchar(50) NOT NULL, - `websiteData` int(11) NOT NULL, - `websiteDatabases` int(11) NOT NULL, - `websiteDataEmails` int(11) NOT NULL, - PRIMARY KEY (`id`) -)""" - try: - cursor.execute(query) - except: - pass - - - query = 'ALTER TABLE IncBackups_backupjob ADD retention integer DEFAULT 0' - - - try: - cursor.execute(query) - except: - pass - - query = """CREATE TABLE `IncBackups_incjob` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `date` datetime(6) NOT NULL, - `website_id` int(11) NOT NULL, - PRIMARY KEY (`id`), - KEY `IncBackups_incjob_website_id_aad31bf6_fk_websiteFu` (`website_id`), - CONSTRAINT `IncBackups_incjob_website_id_aad31bf6_fk_websiteFu` FOREIGN KEY (`website_id`) REFERENCES `websiteFunctions_websites` (`id`) -)""" - try: - cursor.execute(query) - except: - pass - - query = """CREATE TABLE `IncBackups_jobsites` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `website` varchar(300) NOT NULL, - `job_id` int(11) NOT NULL, - PRIMARY KEY (`id`), - KEY `IncBackups_jobsites_job_id_494a1f69_fk_IncBackups_backupjob_id` (`job_id`), - CONSTRAINT `IncBackups_jobsites_job_id_494a1f69_fk_IncBackups_backupjob_id` FOREIGN KEY (`job_id`) REFERENCES `IncBackups_backupjob` (`id`) -)""" - try: - cursor.execute(query) - except: - pass - - query = """CREATE TABLE `IncBackups_jobsnapshots` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `type` varchar(300) NOT NULL, - `snapshotid` varchar(50) NOT NULL, - `job_id` int(11) NOT NULL, - `destination` varchar(200) NOT NULL, - PRIMARY KEY (`id`), - KEY `IncBackups_jobsnapshots_job_id_a8237ca8_fk_IncBackups_incjob_id` (`job_id`), - CONSTRAINT `IncBackups_jobsnapshots_job_id_a8237ca8_fk_IncBackups_incjob_id` FOREIGN KEY (`job_id`) REFERENCES `IncBackups_incjob` (`id`) -)""" - try: - cursor.execute(query) - except: - pass - - query = """CREATE TABLE `websiteFunctions_gitlogs` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `date` datetime(6) NOT NULL, - `type` varchar(5) NOT NULL, - `message` longtext NOT NULL, - `owner_id` int(11) NOT NULL, - PRIMARY KEY (`id`), - KEY `websiteFunctions_git_owner_id_ce74c7de_fk_websiteFu` (`owner_id`), - CONSTRAINT `websiteFunctions_git_owner_id_ce74c7de_fk_websiteFu` FOREIGN KEY (`owner_id`) REFERENCES `websiteFunctions_websites` (`id`) -)""" - - try: - cursor.execute(query) - except: - pass - - query = """CREATE TABLE `websiteFunctions_backupjob` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `logFile` varchar(1000) NOT NULL, - `ipAddress` varchar(50) NOT NULL, - `port` varchar(15) NOT NULL, - `jobFailedSites` int(11) NOT NULL, - `jobSuccessSites` int(11) NOT NULL, - `location` int(11) NOT NULL, - PRIMARY KEY (`id`) -)""" - try: - cursor.execute(query) - except: - pass - - query = """CREATE TABLE `websiteFunctions_backupjoblogs` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `message` longtext NOT NULL, - `owner_id` int(11) NOT NULL, - `status` int(11) NOT NULL, - PRIMARY KEY (`id`), - KEY `websiteFunctions_bac_owner_id_af3d15f9_fk_websiteFu` (`owner_id`), - CONSTRAINT `websiteFunctions_bac_owner_id_af3d15f9_fk_websiteFu` FOREIGN KEY (`owner_id`) REFERENCES `websiteFunctions_backupjob` (`id`) -)""" - - try: - cursor.execute(query) - except: - pass - - query = """CREATE TABLE `websiteFunctions_gdrive` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(50) NOT NULL, - `auth` longtext NOT NULL, - `runTime` varchar(20) NOT NULL, - `owner_id` int(11) NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `name` (`name`), - KEY `websiteFunctions_gdr_owner_id_b5b1e86f_fk_loginSyst` (`owner_id`), - CONSTRAINT `websiteFunctions_gdr_owner_id_b5b1e86f_fk_loginSyst` FOREIGN KEY (`owner_id`) REFERENCES `loginSystem_administrator` (`id`) -)""" - - try: - cursor.execute(query) - except: - pass - - query = """CREATE TABLE `websiteFunctions_gdrivesites` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `domain` varchar(200) NOT NULL, - `owner_id` int(11) NOT NULL, - PRIMARY KEY (`id`), - KEY `websiteFunctions_gdr_owner_id_ff78b305_fk_websiteFu` (`owner_id`), - CONSTRAINT `websiteFunctions_gdr_owner_id_ff78b305_fk_websiteFu` FOREIGN KEY (`owner_id`) REFERENCES `websiteFunctions_gdrive` (`id`) -)""" - - try: - cursor.execute(query) - except: - pass - - query = """CREATE TABLE `websiteFunctions_gdrivejoblogs` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `status` int(11) NOT NULL, - `message` longtext NOT NULL, - `owner_id` int(11) NOT NULL, - PRIMARY KEY (`id`), - KEY `websiteFunctions_gdr_owner_id_4cf7983e_fk_websiteFu` (`owner_id`), - CONSTRAINT `websiteFunctions_gdr_owner_id_4cf7983e_fk_websiteFu` FOREIGN KEY (`owner_id`) REFERENCES `websiteFunctions_gdrive` (`id`) -)""" - - try: - cursor.execute(query) - except: - pass - - try: - connection.close() - except: - pass - except: - pass - - @staticmethod - def enableServices(): - try: - servicePath = '/home/cyberpanel/powerdns' - writeToFile = open(servicePath, 'w+') - writeToFile.close() - - servicePath = '/home/cyberpanel/postfix' - writeToFile = open(servicePath, 'w+') - writeToFile.close() - - servicePath = '/home/cyberpanel/pureftpd' - writeToFile = open(servicePath, 'w+') - writeToFile.close() - except: - pass - - @staticmethod - def downloadAndUpgrade(versionNumbring, branch): - try: - ## Download latest version. - - ## Backup settings file. - - Upgrade.stdOut("Backing up settings file.") - - ## CyberPanel DB Creds - dbName = settings.DATABASES['default']['NAME'] - dbUser = settings.DATABASES['default']['USER'] - password = settings.DATABASES['default']['PASSWORD'] - host = settings.DATABASES['default']['HOST'] - port = settings.DATABASES['default']['PORT'] - - ## Root DB Creds - - rootdbName = settings.DATABASES['rootdb']['NAME'] - rootdbdbUser = settings.DATABASES['rootdb']['USER'] - rootdbpassword = settings.DATABASES['rootdb']['PASSWORD'] - - ## Complete db string - - completDBString = """\nDATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.mysql', - 'NAME': '%s', - 'USER': '%s', - 'PASSWORD': '%s', - 'HOST': '%s', - 'PORT':'%s' - }, - 'rootdb': { - 'ENGINE': 'django.db.backends.mysql', - 'NAME': '%s', - 'USER': '%s', - 'PASSWORD': '%s', - 'HOST': '%s', - 'PORT': '%s', - }, -}\n""" % (dbName, dbUser, password, host, port, rootdbName, rootdbdbUser, rootdbpassword, host, port) - - settingsFile = '/usr/local/CyberCP/CyberCP/settings.py' - - Upgrade.stdOut("Settings file backed up.") - - ## Check git branch status - - os.chdir('/usr/local/CyberCP') - - command = 'git config --global user.email "support@cyberpanel.net"' - - if not Upgrade.executioner(command, command, 1): - return 0, 'Failed to execute %s' % (command) - - command = 'git config --global user.name "CyberPanel"' - - if not Upgrade.executioner(command, command, 1): - return 0, 'Failed to execute %s' % (command) - - command = 'git status' - currentBranch = subprocess.check_output(shlex.split(command)).decode() - - if currentBranch.find('On branch %s' % (branch)) > -1 and currentBranch.find( - 'On branch %s-dev' % (branch)) == -1: - - command = 'git stash' - if not Upgrade.executioner(command, command, 1): - return 0, 'Failed to execute %s' % (command) - - command = 'git pull' - if not Upgrade.executioner(command, command, 1): - return 0, 'Failed to execute %s' % (command) - - elif currentBranch.find('not a git repository') > -1: - - os.chdir('/usr/local') - - command = 'git clone https://github.com/usmannasir/cyberpanel' - if not Upgrade.executioner(command, command, 1): - return 0, 'Failed to execute %s' % (command) - - if os.path.exists('CyberCP'): - shutil.rmtree('CyberCP') - - shutil.move('cyberpanel', 'CyberCP') - - else: - - command = 'git fetch' - if not Upgrade.executioner(command, command, 1): - return 0, 'Failed to execute %s' % (command) - - command = 'git stash' - if not Upgrade.executioner(command, command, 1): - return 0, 'Failed to execute %s' % (command) - - command = 'git checkout %s' % (branch) - if not Upgrade.executioner(command, command, 1): - return 0, 'Failed to execute %s' % (command) - - command = 'git pull' - if not Upgrade.executioner(command, command, 1): - return 0, 'Failed to execute %s' % (command) - - ## Copy settings file - - settingsData = open(settingsFile, 'r').readlines() - - DATABASESCHECK = 0 - writeToFile = open(settingsFile, 'w') - - for items in settingsData: - if items.find('DATABASES = {') > -1: - DATABASESCHECK = 1 - - if DATABASESCHECK == 0: - writeToFile.write(items) - - if items.find('DATABASE_ROUTERS = [') > -1: - DATABASESCHECK = 0 - writeToFile.write(completDBString) - writeToFile.write(items) - - writeToFile.close() - - Upgrade.stdOut('Settings file restored!') - - Upgrade.staticContent() - - return 1, None - - except BaseException as msg: - return 0, str(msg) - - @staticmethod - def installLSCPD(branch): - try: - - Upgrade.stdOut("Starting LSCPD installation..") - - cwd = os.getcwd() - - os.chdir('/usr/local') - - command = 'yum -y install gcc gcc-c++ make autoconf glibc rcs' - Upgrade.executioner(command, 'LSCPD Pre-reqs [one]', 0) - - ## - - lscpdPath = '/usr/local/lscp/bin/lscpd' - - if os.path.exists(lscpdPath): - os.remove(lscpdPath) - - command = 'cp -f /usr/local/CyberCP/lscpd-0.3.1 /usr/local/lscp/bin/lscpd-0.3.1' - Upgrade.executioner(command, command, 0) - - command = 'rm -f /usr/local/lscp/bin/lscpd' - Upgrade.executioner(command, command, 0) - - command = 'mv /usr/local/lscp/bin/lscpd-0.3.1 /usr/local/lscp/bin/lscpd' - Upgrade.executioner(command, command, 0) - - command = f'chmod 755 {lscpdPath}' - Upgrade.executioner(command, 'LSCPD Download.', 0) - - command = 'yum -y install pcre-devel openssl-devel expat-devel geoip-devel zlib-devel udns-devel which curl' - Upgrade.executioner(command, 'LSCPD Pre-reqs [two]', 0) - - try: - pwd.getpwnam('lscpd') - except KeyError: - command = 'adduser lscpd -M -d /usr/local/lscp' - Upgrade.executioner(command, 'Add user LSCPD', 0) - - try: - grp.getgrnam('lscpd') - except KeyError: - command = 'groupadd lscpd' - Upgrade.executioner(command, 'Add group LSCPD', 0) - - command = 'usermod -a -G lscpd lscpd' - Upgrade.executioner(command, 'Add group LSCPD', 0) - - command = 'usermod -a -G lsadm lscpd' - Upgrade.executioner(command, 'Add group LSCPD', 0) - - command = 'systemctl daemon-reload' - Upgrade.executioner(command, 'daemon-reload LSCPD', 0) - - command = 'systemctl restart lscpd' - Upgrade.executioner(command, 'Restart LSCPD', 0) - - os.chdir(cwd) - - Upgrade.stdOut("LSCPD successfully installed!") - - except BaseException as msg: - Upgrade.stdOut(str(msg) + " [installLSCPD]") - - @staticmethod - def fixPermissions(): - try: - - try: - def generate_pass(length=14): - chars = string.ascii_uppercase + string.ascii_lowercase + string.digits - size = length - return ''.join(random.choice(chars) for x in range(size)) - - content = """SetPassword('%s'); -echo $oConfig->Save() ? 'Done' : 'Error'; - -?>""" % (generate_pass()) - - writeToFile = open('/usr/local/CyberCP/public/snappymail.php', 'w') - writeToFile.write(content) - writeToFile.close() - - command = "chown -R lscpd:lscpd /usr/local/lscp/cyberpanel/snappymail/data" - subprocess.call(shlex.split(command)) - - except: - pass - - Upgrade.stdOut("Fixing permissions..") - - command = "usermod -G lscpd,lsadm,nobody lscpd" - Upgrade.executioner(command, 'chown core code', 0) - - command = "usermod -G lscpd,lsadm,nogroup lscpd" - Upgrade.executioner(command, 'chown core code', 0) - - ###### fix Core CyberPanel permissions - - command = "find /usr/local/CyberCP -type d -exec chmod 0755 {} \;" - Upgrade.executioner(command, 'chown core code', 0) - - command = "find /usr/local/CyberCP -type f -exec chmod 0644 {} \;" - Upgrade.executioner(command, 'chown core code', 0) - - command = "chmod -R 755 /usr/local/CyberCP/bin" - Upgrade.executioner(command, 'chown core code', 0) - - ## change owner - - command = "chown -R root:root /usr/local/CyberCP" - Upgrade.executioner(command, 'chown core code', 0) - - ########### Fix LSCPD - - command = "find /usr/local/lscp -type d -exec chmod 0755 {} \;" - Upgrade.executioner(command, 'chown core code', 0) - - command = "find /usr/local/lscp -type f -exec chmod 0644 {} \;" - Upgrade.executioner(command, 'chown core code', 0) - - command = "chmod -R 755 /usr/local/lscp/bin" - Upgrade.executioner(command, 'chown core code', 0) - - command = "chmod -R 755 /usr/local/lscp/fcgi-bin" - Upgrade.executioner(command, 'chown core code', 0) - - command = "chown -R lscpd:lscpd /usr/local/CyberCP/public/phpmyadmin/tmp" - Upgrade.executioner(command, 'chown core code', 0) - - ## change owner - - command = "chown -R root:root /usr/local/lscp" - Upgrade.executioner(command, 'chown core code', 0) - - command = "chown -R lscpd:lscpd /usr/local/lscp/cyberpanel/snappymail/data" - Upgrade.executioner(command, 'chown core code', 0) - - command = "chmod 700 /usr/local/CyberCP/cli/cyberPanel.py" - Upgrade.executioner(command, 'chown core code', 0) - - command = "chmod 700 /usr/local/CyberCP/plogical/upgradeCritical.py" - Upgrade.executioner(command, 'chown core code', 0) - - command = "chmod 755 /usr/local/CyberCP/postfixSenderPolicy/client.py" - Upgrade.executioner(command, 'chown core code', 0) - - command = "chmod 640 /usr/local/CyberCP/CyberCP/settings.py" - Upgrade.executioner(command, 'chown core code', 0) - - command = "chown root:cyberpanel /usr/local/CyberCP/CyberCP/settings.py" - Upgrade.executioner(command, 'chown core code', 0) - - command = 'chmod +x /usr/local/CyberCP/CLManager/CLPackages.py' - Upgrade.executioner(command, 'chmod CLPackages', 0) - - files = ['/etc/yum.repos.d/MariaDB.repo', '/etc/pdns/pdns.conf', '/etc/systemd/system/lscpd.service', - '/etc/pure-ftpd/pure-ftpd.conf', '/etc/pure-ftpd/pureftpd-pgsql.conf', - '/etc/pure-ftpd/pureftpd-mysql.conf', '/etc/pure-ftpd/pureftpd-ldap.conf', - '/etc/dovecot/dovecot.conf', '/usr/local/lsws/conf/httpd_config.xml', - '/usr/local/lsws/conf/modsec.conf', '/usr/local/lsws/conf/httpd.conf'] - - for items in files: - command = 'chmod 644 %s' % (items) - Upgrade.executioner(command, 'chown core code', 0) - - impFile = ['/etc/pure-ftpd/pure-ftpd.conf', '/etc/pure-ftpd/pureftpd-pgsql.conf', - '/etc/pure-ftpd/pureftpd-mysql.conf', '/etc/pure-ftpd/pureftpd-ldap.conf', - '/etc/dovecot/dovecot.conf', '/etc/pdns/pdns.conf', '/etc/pure-ftpd/db/mysql.conf', - '/etc/powerdns/pdns.conf'] - - for items in impFile: - command = 'chmod 600 %s' % (items) - Upgrade.executioner(command, 'chown core code', 0) - - command = 'chmod 640 /etc/postfix/*.cf' - subprocess.call(command, shell=True) - - command = 'chmod 640 /etc/dovecot/*.conf' - subprocess.call(command, shell=True) - - command = 'chmod 640 /etc/dovecot/dovecot-sql.conf.ext' - subprocess.call(command, shell=True) - - fileM = ['/usr/local/lsws/FileManager/', '/usr/local/CyberCP/install/FileManager', - '/usr/local/CyberCP/serverStatus/litespeed/FileManager', - '/usr/local/lsws/Example/html/FileManager'] - - for items in fileM: - try: - shutil.rmtree(items) - except: - pass - - command = 'chmod 755 /etc/pure-ftpd/' - subprocess.call(command, shell=True) - - command = 'chmod 644 /etc/dovecot/dovecot.conf' - subprocess.call(command, shell=True) - - command = 'chmod 644 /etc/postfix/main.cf' - subprocess.call(command, shell=True) - - command = 'chmod 644 /etc/postfix/dynamicmaps.cf' - subprocess.call(command, shell=True) - - command = 'chmod +x /usr/local/CyberCP/plogical/renew.py' - Upgrade.executioner(command, command, 0) - - command = 'chmod +x /usr/local/CyberCP/CLManager/CLPackages.py' - Upgrade.executioner(command, command, 0) - - clScripts = ['/usr/local/CyberCP/CLScript/panel_info.py', - '/usr/local/CyberCP/CLScript/CloudLinuxPackages.py', - '/usr/local/CyberCP/CLScript/CloudLinuxUsers.py', - '/usr/local/CyberCP/CLScript/CloudLinuxDomains.py' - , '/usr/local/CyberCP/CLScript/CloudLinuxResellers.py', - '/usr/local/CyberCP/CLScript/CloudLinuxAdmins.py', - '/usr/local/CyberCP/CLScript/CloudLinuxDB.py', '/usr/local/CyberCP/CLScript/UserInfo.py'] - - for items in clScripts: - command = 'chmod +x %s' % (items) - Upgrade.executioner(command, 0) - - command = 'chmod 600 /usr/local/CyberCP/plogical/adminPass.py' - Upgrade.executioner(command, 0) - - command = 'chmod 600 /etc/cagefs/exclude/cyberpanelexclude' - Upgrade.executioner(command, 0) - - command = "find /usr/local/CyberCP/ -name '*.pyc' -delete" - Upgrade.executioner(command, 0) - - if os.path.exists(Upgrade.CentOSPath): - command = 'chown root:pdns /etc/pdns/pdns.conf' - Upgrade.executioner(command, 0) - - command = 'chmod 640 /etc/pdns/pdns.conf' - Upgrade.executioner(command, 0) - - command = 'chmod 640 /usr/local/lscp/cyberpanel/logs/access.log' - Upgrade.executioner(command, 0) - - command = '/usr/local/lsws/lsphp72/bin/php /usr/local/CyberCP/public/snappymail.php' - Upgrade.executioner(command, 0) - - command = 'chmod 600 /usr/local/CyberCP/public/snappymail.php' - Upgrade.executioner(command, 0) - - ### - - WriteToFile = open('/etc/fstab', 'a') - WriteToFile.write('proc /proc proc defaults,hidepid=2 0 0\n') - WriteToFile.close() - - command = 'mount -o remount,rw,hidepid=2 /proc' - Upgrade.executioner(command, 0) - - ### - - CentOSPath = '/etc/redhat-release' - - if not os.path.exists(CentOSPath): - group = 'nobody' - else: - group = 'nogroup' - - command = 'chown root:%s /usr/local/lsws/logs' % (group) - Upgrade.executioner(command, 0) - - command = 'chmod 750 /usr/local/lsws/logs' - Upgrade.executioner(command, 0) - - ## symlink protection - - writeToFile = open('/usr/lib/sysctl.d/50-default.conf', 'a') - writeToFile.writelines('fs.protected_hardlinks = 1\n') - writeToFile.writelines('fs.protected_symlinks = 1\n') - writeToFile.close() - - command = 'sysctl --system' - Upgrade.executioner(command, 0) - - command = 'chmod 700 %s' % ('/home/cyberpanel') - Upgrade.executioner(command, 0) - - destPrivKey = "/usr/local/lscp/conf/key.pem" - - command = 'chmod 600 %s' % (destPrivKey) - Upgrade.executioner(command, 0) - - Upgrade.stdOut("Permissions updated.") - - except BaseException as msg: - Upgrade.stdOut(str(msg) + " [installLSCPD]") - - @staticmethod - def AutoUpgradeAcme(): - command = '/root/.acme.sh/acme.sh --upgrade --auto-upgrade' - Upgrade.executioner(command, command, 0) - command = '/root/.acme.sh/acme.sh --set-default-ca --server letsencrypt' - Upgrade.executioner(command, command, 0) - - @staticmethod - def installPHP73(): - try: - if Upgrade.installedOutput.find('lsphp73') == -1: - command = 'yum install -y lsphp73 lsphp73-json lsphp73-xmlrpc lsphp73-xml lsphp73-tidy lsphp73-soap lsphp73-snmp ' \ - 'lsphp73-recode lsphp73-pspell lsphp73-process lsphp73-pgsql lsphp73-pear lsphp73-pdo lsphp73-opcache ' \ - 'lsphp73-odbc lsphp73-mysqlnd lsphp73-mcrypt lsphp73-mbstring lsphp73-ldap lsphp73-intl lsphp73-imap ' \ - 'lsphp73-gmp lsphp73-gd lsphp73-enchant lsphp73-dba lsphp73-common lsphp73-bcmath' - Upgrade.executioner(command, 'Install PHP 73, 0') - - if Upgrade.installedOutput.find('lsphp74') == -1: - command = 'yum install -y lsphp74 lsphp74-json lsphp74-xmlrpc lsphp74-xml lsphp74-tidy lsphp74-soap lsphp74-snmp ' \ - 'lsphp74-recode lsphp74-pspell lsphp74-process lsphp74-pgsql lsphp74-pear lsphp74-pdo lsphp74-opcache ' \ - 'lsphp74-odbc lsphp74-mysqlnd lsphp74-mcrypt lsphp74-mbstring lsphp74-ldap lsphp74-intl lsphp74-imap ' \ - 'lsphp74-gmp lsphp74-gd lsphp74-enchant lsphp74-dba lsphp74-common lsphp74-bcmath' - - Upgrade.executioner(command, 'Install PHP 74, 0') - - if Upgrade.installedOutput.find('lsphp80') == -1: - command = 'yum install lsphp80* -y' - subprocess.call(command, shell=True) - - if Upgrade.installedOutput.find('lsphp81') == -1: - command = 'yum install lsphp81* -y' - subprocess.call(command, shell=True) - - except: - command = 'DEBIAN_FRONTEND=noninteractive apt-get -y install ' \ - 'lsphp7? lsphp7?-common lsphp7?-curl lsphp7?-dev lsphp7?-imap lsphp7?-intl lsphp7?-json ' \ - 'lsphp7?-ldap lsphp7?-mysql lsphp7?-opcache lsphp7?-pspell lsphp7?-recode ' \ - 'lsphp7?-sqlite3 lsphp7?-tidy' - Upgrade.executioner(command, 'Install PHP 73, 0') - - command = 'DEBIAN_FRONTEND=noninteractive apt-get -y install lsphp80*' - os.system(command) - - command = 'DEBIAN_FRONTEND=noninteractive apt-get -y install lsphp81*' - os.system(command) - - CentOSPath = '/etc/redhat-release' - - if not os.path.exists(CentOSPath): - #command = 'cp /usr/local/lsws/lsphp71/bin/php /usr/bin/' - #Upgrade.executioner(command, 'Set default PHP 7.0, 0') - - @staticmethod - def someDirectories(): - command = "mkdir -p /usr/local/lscpd/admin/" - Upgrade.executioner(command, 0) - - command = "mkdir -p /usr/local/lscp/cyberpanel/logs" - Upgrade.executioner(command, 0) - - @staticmethod - def upgradeDovecot(): - try: - Upgrade.stdOut("Upgrading Dovecot..") - CentOSPath = '/etc/redhat-release' - - dovecotConfPath = '/etc/dovecot/' - postfixConfPath = '/etc/postfix/' - - ## Take backup of configurations - - configbackups = '/home/cyberpanel/configbackups' - - command = 'mkdir %s' % (configbackups) - Upgrade.executioner(command, 0) - - command = 'cp -pR %s %s' % (dovecotConfPath, configbackups) - Upgrade.executioner(command, 0) - - command = 'cp -pR %s %s' % (postfixConfPath, configbackups) - Upgrade.executioner(command, 0) - - if Upgrade.FindOperatingSytem() == CENTOS8 or Upgrade.FindOperatingSytem() == CENTOS7: - - command = "yum makecache -y" - Upgrade.executioner(command, 0) - - command = "yum update -y" - Upgrade.executioner(command, 0) - - if Upgrade.FindOperatingSytem() == CENTOS8: - command = 'dnf remove dovecot23 dovecot23-mysql -y' - Upgrade.executioner(command, 0) - - command = 'dnf install --enablerepo=gf-plus dovecot23 dovecot23-mysql -y' - Upgrade.executioner(command, 0) - - import django - os.environ.setdefault("DJANGO_SETTINGS_MODULE", "CyberCP.settings") - django.setup() - from mailServer.models import EUsers - - Upgrade.stdOut("Upgrading passwords...") - for items in EUsers.objects.all(): - if items.password.find('CRYPT') > -1: - continue - command = 'doveadm pw -p %s' % (items.password) - items.password = subprocess.check_output(shlex.split(command)).decode("utf-8").strip('\n') - items.save() - - command = "systemctl restart dovecot" - Upgrade.executioner(command, 0) - - ### Postfix Upgrade - - command = 'yum remove postfix -y' - Upgrade.executioner(command, 0) - - command = 'yum clean all' - Upgrade.executioner(command, 0) - - if Upgrade.FindOperatingSytem() == CENTOS7: - command = 'yum makecache fast' - else: - command = 'yum makecache -y' - - Upgrade.executioner(command, 0) - - if Upgrade.FindOperatingSytem() == CENTOS7: - command = 'yum install --enablerepo=gf-plus -y postfix3 postfix3-ldap postfix3-mysql postfix3-pcre' - else: - command = 'dnf install --enablerepo=gf-plus postfix3 postfix3-mysql -y' - - Upgrade.executioner(command, 0) - - ### Restore dovecot/postfix conf - - command = 'cp -pR %s/dovecot/ /etc/' % (configbackups) - Upgrade.executioner(command, 0) - - command = 'cp -pR %s/postfix/ /etc/' % (configbackups) - Upgrade.executioner(command, 0) - - ## Restored - - command = 'systemctl restart postfix' - Upgrade.executioner(command, 0) - elif Upgrade.FindOperatingSytem() == Ubuntu20: - - debPath = '/etc/apt/sources.list.d/dovecot.list' - # writeToFile = open(debPath, 'w') - # writeToFile.write('deb https://repo.dovecot.org/ce-2.3-latest/ubuntu/focal focal main\n') - # writeToFile.close() - # - # command = "apt update -y" - # Upgrade.executioner(command, command) - # - # command = 'dpkg --configure -a' - # subprocess.call(command, shell=True) - # - # command = 'apt --fix-broken install -y' - # subprocess.call(command, shell=True) - # - # command = 'DEBIAN_FRONTEND=noninteractive DEBIAN_PRIORITY=critical apt -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" upgrade -y' - # subprocess.call(command, shell=True) - - - dovecotConf = '/etc/dovecot/dovecot.conf' - - dovecotContent = open(dovecotConf, 'r').read() - - if dovecotContent.find('service stats') == -1: - writeToFile = open(dovecotConf, 'a') - - content = """\nservice stats { - unix_listener stats-reader { - user = vmail - group = vmail - mode = 0660 - } - unix_listener stats-writer { - user = vmail - group = vmail - mode = 0660 - } -}\n""" - - writeToFile.write(content) - writeToFile.close() - - command = 'systemctl restart dovecot' - Upgrade.executioner(command, command, 0) - - command = 'rm -rf %s' % (configbackups) - Upgrade.executioner(command, command, 0) - - Upgrade.stdOut("Dovecot upgraded.") - - except BaseException as msg: - Upgrade.stdOut(str(msg) + " [upgradeDovecot]") - - @staticmethod - def installRestic(): - CentOSPath = '/etc/redhat-release' - - if os.path.exists(CentOSPath): - if Upgrade.installedOutput.find('restic') == -1: - command = 'yum install restic -y' - Upgrade.executioner(command, 'Install Restic') - else: - - if Upgrade.installedOutput.find('restic/bionic,now 0.8') == -1: - command = 'apt-get update -y' - Upgrade.executioner(command, 'Install Restic') - - command = 'apt-get install restic -y' - Upgrade.executioner(command, 'Install Restic') - - @staticmethod - def UpdateMaxSSLCons(): - command = "sed -i 's|2000|10000|g' /usr/local/lsws/conf/httpd_config.xml" - Upgrade.executioner(command, 0) - - command = "sed -i 's|200|10000|g' /usr/local/lsws/conf/httpd_config.xml" - Upgrade.executioner(command, 0) - - @staticmethod - def installCLScripts(): - try: - - CentOSPath = '/etc/redhat-release' - - if os.path.exists(CentOSPath): - command = 'mkdir -p /opt/cpvendor/etc/' - Upgrade.executioner(command, 0) - - content = """[integration_scripts] - -panel_info = /usr/local/CyberCP/CLScript/panel_info.py -packages = /usr/local/CyberCP/CLScript/CloudLinuxPackages.py -users = /usr/local/CyberCP/CLScript/CloudLinuxUsers.py -domains = /usr/local/CyberCP/CLScript/CloudLinuxDomains.py -resellers = /usr/local/CyberCP/CLScript/CloudLinuxResellers.py -admins = /usr/local/CyberCP/CLScript/CloudLinuxAdmins.py -db_info = /usr/local/CyberCP/CLScript/CloudLinuxDB.py - -[lvemanager_config] -ui_user_info = /usr/local/CyberCP/CLScript/UserInfo.py -base_path = /usr/local/lvemanager -run_service = 1 -service_port = 9000 -""" - - if not os.path.exists('/opt/cpvendor/etc/integration.ini'): - writeToFile = open('/opt/cpvendor/etc/integration.ini', 'w') - writeToFile.write(content) - writeToFile.close() - - command = 'mkdir -p /etc/cagefs/exclude' - Upgrade.executioner(command, command, 0) - - content = """cyberpanel -docker -ftpuser -lscpd -opendkim -pdns -vmail -""" - - writeToFile = open('/etc/cagefs/exclude/cyberpanelexclude', 'w') - writeToFile.write(content) - writeToFile.close() - - except: - pass - - @staticmethod - def runSomeImportantBash(): - - # Remove invalid crons from /etc/crontab Reference: https://github.com/usmannasir/cyberpanel/issues/216 - command = """sed -i '/CyberCP/d' /etc/crontab""" - subprocess.call(command, shell=True) - - # Setup /usr/local/lsws/conf/httpd.conf to use new Logformat standard for better stats and accesslogs - command = """sed -i "s|^LogFormat.*|LogFormat '%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"' combined|g" /usr/local/lsws/conf/httpd.conf""" - subprocess.call(command, shell=True) - - # Fix all existing vhost confs to use new Logformat standard for better stats and accesslogs - command = """find /usr/local/lsws/conf/vhosts/ -type f -name 'vhost.conf' -exec sed -i "s/.*CustomLog.*/ LogFormat '%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"' combined\n&/g" {} \;""" - subprocess.call(command, shell=True) - - # Install any Cyberpanel missing crons to root crontab so its visible to users via crontab -l as root user - - # Install findBWUsage cron if missing - - CentOSPath = '/etc/redhat-release' - - if os.path.exists(CentOSPath): - cronPath = '/var/spool/cron/root' - else: - cronPath = '/var/spool/cron/crontabs/root' - - if os.path.exists(cronPath): - data = open(cronPath, 'r').read() - - if data.find('findBWUsage') == -1: - content = """ -0 * * * * /usr/local/CyberCP/bin/python /usr/local/CyberCP/plogical/findBWUsage.py >/dev/null 2>&1 -0 * * * * /usr/local/CyberCP/bin/python /usr/local/CyberCP/postfixSenderPolicy/client.py hourlyCleanup >/dev/null 2>&1 -0 0 1 * * /usr/local/CyberCP/bin/python /usr/local/CyberCP/postfixSenderPolicy/client.py monthlyCleanup >/dev/null 2>&1 -0 2 * * * /usr/local/CyberCP/bin/python /usr/local/CyberCP/plogical/upgradeCritical.py >/dev/null 2>&1 -0 2 * * * /usr/local/CyberCP/bin/python /usr/local/CyberCP/plogical/renew.py >/dev/null 2>&1 -7 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null -*/3 * * * * if ! find /home/*/public_html/ -maxdepth 2 -type f -newer /usr/local/lsws/cgid -name '.htaccess' -exec false {} +; then /usr/local/lsws/bin/lswsctrl restart; fi -""" - - writeToFile = open(cronPath, 'w') - writeToFile.write(content) - writeToFile.close() - - if data.find('IncScheduler.py') == -1: - content = """ -0 12 * * * /usr/local/CyberCP/bin/python /usr/local/CyberCP/IncBackups/IncScheduler.py Daily -0 0 * * 0 /usr/local/CyberCP/bin/python /usr/local/CyberCP/IncBackups/IncScheduler.py Weekly -""" - writeToFile = open(cronPath, 'a') - writeToFile.write(content) - writeToFile.close() - else: - content = """ -0 * * * * /usr/local/CyberCP/bin/python /usr/local/CyberCP/plogical/findBWUsage.py >/dev/null 2>&1 -0 * * * * /usr/local/CyberCP/bin/python /usr/local/CyberCP/postfixSenderPolicy/client.py hourlyCleanup >/dev/null 2>&1 -0 0 1 * * /usr/local/CyberCP/bin/python /usr/local/CyberCP/postfixSenderPolicy/client.py monthlyCleanup >/dev/null 2>&1 -0 2 * * * /usr/local/CyberCP/bin/python /usr/local/CyberCP/plogical/upgradeCritical.py >/dev/null 2>&1 -0 2 * * * /usr/local/CyberCP/bin/python /usr/local/CyberCP/plogical/renew.py >/dev/null 2>&1 -7 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null -0 0 * * * /usr/local/CyberCP/bin/python /usr/local/CyberCP/IncBackups/IncScheduler.py Daily -0 0 * * 0 /usr/local/CyberCP/bin/python /usr/local/CyberCP/IncBackups/IncScheduler.py Weekly -""" - writeToFile = open(cronPath, 'w') - writeToFile.write(content) - writeToFile.close() - - ### Check and remove OLS restart if lsws ent detected - - if not os.path.exists('/usr/local/lsws/bin/openlitespeed'): - - data = open(cronPath, 'r').readlines() - - writeToFile = open(cronPath, 'w') - - for items in data: - if items.find('-maxdepth 2 -type f -newer') > -1: - pass - else: - writeToFile.writelines(items) - - writeToFile.close() - - - if not os.path.exists(CentOSPath): - command = 'chmod 600 %s' % (cronPath) - Upgrade.executioner(command, 0) - - @staticmethod - def UpdateConfigOfCustomACL(): - sys.path.append('/usr/local/CyberCP') - os.environ.setdefault("DJANGO_SETTINGS_MODULE", "CyberCP.settings") - import django - django.setup() - from loginSystem.models import ACL - for acl in ACL.objects.all(): - if acl.name == 'admin' or acl.name == 'reseller' or acl.name == 'user': - continue - elif acl.config == '{}': - acl.config = '{"adminStatus":%s, "versionManagement": %s, "createNewUser": %s, "listUsers": %s, "deleteUser": %s, "resellerCenter": %s, "changeUserACL": %s, "createWebsite": %s, "modifyWebsite": %s, "suspendWebsite": %s, "deleteWebsite": %s, "createPackage": %s, "listPackages": %s, "deletePackage": %s, "modifyPackage": %s, "createDatabase": %s, "deleteDatabase": %s, "listDatabases": %s, "createNameServer": %s, "createDNSZone": %s, "deleteZone": %s, "addDeleteRecords": %s, "createEmail": %s, "listEmails": %s, "deleteEmail": %s, "emailForwarding": %s, "changeEmailPassword": %s, "dkimManager": %s, "createFTPAccount": %s, "deleteFTPAccount": %s, "listFTPAccounts": %s, "createBackup": %s, "restoreBackup": %s, "addDeleteDestinations": %s, "scheduleBackups": %s, "remoteBackups": %s, "googleDriveBackups": %s, "manageSSL": %s, "hostnameSSL": %s, "mailServerSSL": %s }' \ - % (str(acl.adminStatus), str(acl.versionManagement), str(acl.createNewUser), - str(acl.listUsers), str(acl.deleteUser), str(acl.resellerCenter), str(acl.changeUserACL), - str(acl.createWebsite), str(acl.modifyWebsite), str(acl.suspendWebsite), str(acl.deleteWebsite), - str(acl.createPackage), str(acl.listPackages), str(acl.deletePackage), str(acl.modifyPackage), - str(acl.createDatabase), str(acl.deleteDatabase), str(acl.listDatabases), str(acl.createNameServer), - str(acl.createDNSZone), str(acl.deleteZone), str(acl.addDeleteRecords), str(acl.createEmail), - str(acl.listEmails), str(acl.deleteEmail), str(acl.emailForwarding), str(acl.changeEmailPassword), - str(acl.dkimManager), str(acl.createFTPAccount), str(acl.deleteFTPAccount), str(acl.listFTPAccounts), - str(acl.createBackup), str(acl.restoreBackup), str(acl.addDeleteDestinations), str(acl.scheduleBackups), str(acl.remoteBackups), '1', - str(acl.manageSSL), str(acl.hostnameSSL), str(acl.mailServerSSL)) - acl.save() - - @staticmethod - def upgrade(branch): - - # Upgrade.stdOut("Upgrades are currently disabled") - # return 0 - - if os.path.exists(Upgrade.CentOSPath): - command = 'yum list installed' - Upgrade.installedOutput = subprocess.check_output(shlex.split(command)).decode() - else: - command = 'apt list' - Upgrade.installedOutput = subprocess.check_output(shlex.split(command)).decode() - - command = 'systemctl stop cpssh' - Upgrade.executioner(command, 'fix csf if there', 0) - - ## Add LSPHP7.4 TO LSWS Ent configs - - if not os.path.exists('/usr/local/lsws/bin/openlitespeed'): - - if os.path.exists('httpd_config.xml'): - os.remove('httpd_config.xml') - - command = 'wget https://raw.githubusercontent.com/usmannasir/cyberpanel/stable/install/litespeed/httpd_config.xml' - Upgrade.executioner(command, command, 0) - # os.remove('/usr/local/lsws/conf/httpd_config.xml') - # shutil.copy('httpd_config.xml', '/usr/local/lsws/conf/httpd_config.xml') - - postfixPath = '/home/cyberpanel/postfix' - pdns = '/home/cyberpanel/pdns' - pureftpd = '/home/cyberpanel/ftp' - - Upgrade.updateRepoURL() - - os.chdir("/usr/local") - - command = 'yum remove yum-plugin-priorities -y' - Upgrade.executioner(command, 'remove yum-plugin-priorities', 0) - - ## Current Version - - command = "systemctl stop lscpd" - Upgrade.executioner(command, 'stop lscpd', 0) - - Upgrade.fixSudoers() - Upgrade.mountTemp() - Upgrade.dockerUsers() - Upgrade.setupComposer() - - ## - - versionNumbring = Upgrade.downloadLink() - - if os.path.exists('/usr/local/CyberPanel.' + versionNumbring): - os.remove('/usr/local/CyberPanel.' + versionNumbring) - - ## - - Upgrade.downloadAndUpgrade(versionNumbring, branch) - Upgrade.download_install_phpmyadmin() - Upgrade.downoad_and_install_raindloop() - - ## - - ## - - Upgrade.mailServerMigrations() - Upgrade.emailMarketingMigrationsa() - Upgrade.dockerMigrations() - Upgrade.CLMigrations() - Upgrade.IncBackupMigrations() - Upgrade.installRestic() - - ## - - # Upgrade.setupVirtualEnv() - - ## - - Upgrade.applyLoginSystemMigrations() - - ## Put function here to update custom ACLs - - Upgrade.UpdateConfigOfCustomACL() - - Upgrade.s3BackupMigrations() - Upgrade.containerMigrations() - Upgrade.manageServiceMigrations() - Upgrade.enableServices() - - Upgrade.installPHP73() - Upgrade.setupCLI() - Upgrade.someDirectories() - Upgrade.installLSCPD(branch) - - ### General migrations are not needed any more - - # Upgrade.GeneralMigrations() - - # Upgrade.p3() - - ## Also disable email service upgrade - - # if os.path.exists(postfixPath): - # Upgrade.upgradeDovecot() - - - ## Upgrade version - - Upgrade.fixPermissions() - - ## - - ### Disable version upgrade too - - # Upgrade.upgradeVersion() - - Upgrade.UpdateMaxSSLCons() - - ## Update LSCPD PHP - - phpPath = '/usr/local/lscp/fcgi-bin/lsphp' - - try: - os.remove(phpPath) - except: - pass - - command = 'cp /usr/local/lsws/lsphp73/bin/lsphp %s' % (phpPath) - Upgrade.executioner(command, 0) - - try: - command = "systemctl start lscpd" - Upgrade.executioner(command, 'Start LSCPD', 0) - except: - pass - - command = 'csf -uf' - Upgrade.executioner(command, 'fix csf if there', 0) - command = 'systemctl stop cpssh' - Upgrade.executioner(command, 'fix csf if there', 0) - Upgrade.AutoUpgradeAcme() - Upgrade.installCLScripts() - Upgrade.runSomeImportantBash() - - ## Move static files - - imunifyPath = '/usr/local/CyberCP/public/imunify' - - if os.path.exists(imunifyPath): - command = "yum reinstall imunify360-firewall-generic -y" - Upgrade.executioner(command, command, 1) - - imunifyAVPath = '/etc/sysconfig/imunify360/integration.conf' - - if os.path.exists(imunifyAVPath): - command = "yum reinstall imunify-antivirus-generic -y" - Upgrade.executioner(command, command, 1) - - Upgrade.stdOut("Upgrade Completed.") - -def main(): - - parser = argparse.ArgumentParser(description='CyberPanel Installer') - parser.add_argument('branch', help='Install from branch name.') - - args = parser.parse_args() - - Upgrade.upgrade(args.branch) - - -if __name__ == "__main__": - main() diff --git a/rollback_phpmyadmin_redirect.sh b/rollback_phpmyadmin_redirect.sh new file mode 100644 index 000000000..159ec00a3 --- /dev/null +++ b/rollback_phpmyadmin_redirect.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +# CyberPanel phpMyAdmin Access Control Rollback Script +# This script reverts the phpMyAdmin access control changes + +echo "=== CyberPanel phpMyAdmin Access Control Rollback ===" + +# Check if running as root +if [ "$EUID" -ne 0 ]; then + echo "Please run this script as root" + exit 1 +fi + +# Find the most recent backup +LATEST_BACKUP=$(ls -t /usr/local/CyberCP/public/phpmyadmin/index.php.backup.* 2>/dev/null | head -n1) + +if [ -z "$LATEST_BACKUP" ]; then + echo "No backup found. Cannot rollback changes." + echo "You may need to reinstall phpMyAdmin or restore from your own backup." + exit 1 +fi + +echo "Found backup: $LATEST_BACKUP" +echo "Restoring original phpMyAdmin index.php..." + +# Restore the original index.php +cp "$LATEST_BACKUP" /usr/local/CyberCP/public/phpmyadmin/index.php + +# Remove the .htaccess file if it exists +if [ -f "/usr/local/CyberCP/public/phpmyadmin/.htaccess" ]; then + echo "Removing .htaccess file..." + rm /usr/local/CyberCP/public/phpmyadmin/.htaccess +fi + +# Set proper permissions +echo "Setting permissions..." +chown lscpd:lscpd /usr/local/CyberCP/public/phpmyadmin/index.php +chmod 644 /usr/local/CyberCP/public/phpmyadmin/index.php + +# Restart LiteSpeed to ensure changes take effect +echo "Restarting LiteSpeed..." +systemctl restart lscpd + +echo "=== Rollback Complete ===" +echo "" +echo "phpMyAdmin access control has been reverted!" +echo "phpMyAdmin should now work as it did before the changes." +echo "" +echo "Backup file used: $LATEST_BACKUP" diff --git a/run_migration.py b/run_migration.py new file mode 100644 index 000000000..913a3473f --- /dev/null +++ b/run_migration.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Migration script for UserNotificationPreferences model +Run this script to apply the database migration for notification preferences +""" + +import os +import sys +import django + +# Add the project directory to Python path +sys.path.append('/usr/local/CyberCP') + +# Set up Django environment +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'CyberCP.settings') +django.setup() + +from django.core.management import execute_from_command_line + +if __name__ == '__main__': + print("Running migration for UserNotificationPreferences...") + try: + execute_from_command_line(['manage.py', 'migrate', 'baseTemplate']) + print("Migration completed successfully!") + except Exception as e: + print(f"Migration failed: {e}") + sys.exit(1) diff --git a/testPlugin/OS_COMPATIBILITY.md b/testPlugin/OS_COMPATIBILITY.md index f616418de..b01441843 100644 --- a/testPlugin/OS_COMPATIBILITY.md +++ b/testPlugin/OS_COMPATIBILITY.md @@ -10,7 +10,9 @@ The CyberPanel Test Plugin is designed to work seamlessly across all CyberPanel- |------------------|---------|----------------|----------------|-----------------|-----------------| | **Ubuntu** | 22.04 | ✅ Full Support | 3.10+ | apt-get | systemctl | | **Ubuntu** | 20.04 | ✅ Full Support | 3.8+ | apt-get | systemctl | -| **Debian** | 11+ | ✅ Full Support | 3.9+ | apt-get | systemctl | +| **Debian** | 13 | ✅ Full Support | 3.11+ | apt-get | systemctl | +| **Debian** | 12 | ✅ Full Support | 3.10+ | apt-get | systemctl | +| **Debian** | 11 | ✅ Full Support | 3.9+ | apt-get | systemctl | | **AlmaLinux** | 10 | ✅ Full Support | 3.11+ | dnf | systemctl | | **AlmaLinux** | 9 | ✅ Full Support | 3.9+ | dnf | systemctl | | **AlmaLinux** | 8 | ✅ Full Support | 3.6+ | dnf/yum | systemctl | @@ -457,6 +459,6 @@ sudo rm -f /home/cyberpanel/plugins/testPlugin --- -**Last Updated**: December 2024 +**Last Updated**: September 2025 **Compatibility Version**: 1.0.0 -**Next Review**: March 2025 +**Next Review**: March 2026 diff --git a/test_debian13_support.sh b/test_debian13_support.sh new file mode 100644 index 000000000..81650f704 --- /dev/null +++ b/test_debian13_support.sh @@ -0,0 +1,430 @@ +#!/bin/bash + +# Debian 13 Support Test Script for CyberPanel +# This script tests the compatibility of CyberPanel with Debian 13 + +set -e + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Test results +TESTS_PASSED=0 +TESTS_FAILED=0 +TESTS_TOTAL=0 + +# Function to print colored output +print_status() { + echo -e "${BLUE}[INFO]${NC} $1" +} + +print_success() { + echo -e "${GREEN}[SUCCESS]${NC} $1" + ((TESTS_PASSED++)) +} + +print_warning() { + echo -e "${YELLOW}[WARNING]${NC} $1" +} + +print_error() { + echo -e "${RED}[ERROR]${NC} $1" + ((TESTS_FAILED++)) +} + +print_test_header() { + echo -e "\n${BLUE}=== $1 ===${NC}" + ((TESTS_TOTAL++)) +} + +# Function to run a test +run_test() { + local test_name="$1" + local test_command="$2" + local expected_result="$3" + + print_test_header "$test_name" + + if eval "$test_command" >/dev/null 2>&1; then + if [[ "$expected_result" == "success" ]]; then + print_success "$test_name passed" + return 0 + else + print_error "$test_name failed (unexpected success)" + return 1 + fi + else + if [[ "$expected_result" == "failure" ]]; then + print_success "$test_name passed (expected failure)" + return 0 + else + print_error "$test_name failed" + return 1 + fi + fi +} + +# Function to check OS detection +test_os_detection() { + print_test_header "OS Detection Test" + + # Check if we're on Debian 13 + if [[ -f /etc/os-release ]]; then + source /etc/os-release + if [[ "$ID" == "debian" && "$VERSION_ID" == "13" ]]; then + print_success "Debian 13 detected correctly" + else + print_warning "Not running on Debian 13 (Current: $ID $VERSION_ID)" + print_status "This test is designed for Debian 13, but will continue with current OS" + fi + else + print_error "Cannot detect OS - /etc/os-release not found" + return 1 + fi +} + +# Function to test CyberPanel OS detection logic +test_cyberpanel_os_detection() { + print_test_header "CyberPanel OS Detection Logic Test" + + # Test the OS detection logic from cyberpanel.sh + if grep -q -E "Debian GNU/Linux 11|Debian GNU/Linux 12|Debian GNU/Linux 13" /etc/os-release; then + print_success "CyberPanel OS detection logic recognizes Debian 11/12/13" + else + print_error "CyberPanel OS detection logic does not recognize current Debian version" + return 1 + fi +} + +# Function to test package manager compatibility +test_package_manager() { + print_test_header "Package Manager Compatibility Test" + + # Test apt-get availability + if command -v apt-get >/dev/null 2>&1; then + print_success "apt-get package manager is available" + else + print_error "apt-get package manager not found" + return 1 + fi + + # Test apt-get update (dry run) + if apt-get update --dry-run >/dev/null 2>&1; then + print_success "apt-get update works correctly" + else + print_warning "apt-get update failed (may be network related)" + fi +} + +# Function to test systemd compatibility +test_systemd_compatibility() { + print_test_header "Systemd Compatibility Test" + + # Test systemctl availability + if command -v systemctl >/dev/null 2>&1; then + print_success "systemctl is available" + else + print_error "systemctl not found" + return 1 + fi + + # Test systemd status + if systemctl is-system-running >/dev/null 2>&1; then + print_success "systemd is running" + else + print_warning "systemd status unclear" + fi +} + +# Function to test Python compatibility +test_python_compatibility() { + print_test_header "Python Compatibility Test" + + # Test Python 3 availability + if command -v python3 >/dev/null 2>&1; then + local python_version=$(python3 --version 2>&1 | cut -d' ' -f2) + print_success "Python 3 is available: $python_version" + + # Check if Python version is compatible (3.6+) + local major_version=$(echo "$python_version" | cut -d'.' -f1) + local minor_version=$(echo "$python_version" | cut -d'.' -f2) + + if [[ $major_version -ge 3 && $minor_version -ge 6 ]]; then + print_success "Python version is compatible (3.6+)" + else + print_warning "Python version may not be fully compatible (requires 3.6+)" + fi + else + print_error "Python 3 not found" + return 1 + fi + + # Test pip3 availability + if command -v pip3 >/dev/null 2>&1; then + print_success "pip3 is available" + else + print_warning "pip3 not found (may need to be installed)" + fi +} + +# Function to test web server compatibility +test_web_server_compatibility() { + print_test_header "Web Server Compatibility Test" + + # Test Apache2 availability + if command -v apache2 >/dev/null 2>&1; then + print_success "Apache2 is available" + else + print_warning "Apache2 not found (will be installed by CyberPanel)" + fi + + # Test if Apache2 can be installed + if apt-cache show apache2 >/dev/null 2>&1; then + print_success "Apache2 package is available in repositories" + else + print_error "Apache2 package not found in repositories" + return 1 + fi +} + +# Function to test required packages availability +test_required_packages() { + print_test_header "Required Packages Availability Test" + + local required_packages=( + "curl" + "wget" + "git" + "build-essential" + "python3-dev" + "python3-pip" + "python3-venv" + "software-properties-common" + "apt-transport-https" + "ca-certificates" + "gnupg" + ) + + local available_count=0 + local total_count=${#required_packages[@]} + + for package in "${required_packages[@]}"; do + if apt-cache show "$package" >/dev/null 2>&1; then + print_success "$package is available" + ((available_count++)) + else + print_warning "$package not found in repositories" + fi + done + + print_status "Available packages: $available_count/$total_count" + + if [[ $available_count -ge $((total_count * 8 / 10)) ]]; then + print_success "Most required packages are available" + else + print_warning "Many required packages are missing" + fi +} + +# Function to test LiteSpeed repository compatibility +test_litespeed_repo_compatibility() { + print_test_header "LiteSpeed Repository Compatibility Test" + + # Test if we can access LiteSpeed Debian repository + if curl -s --head "http://rpms.litespeedtech.com/debian/" | head -n 1 | grep -q "200 OK"; then + print_success "LiteSpeed Debian repository is accessible" + else + print_warning "LiteSpeed Debian repository may not be accessible" + fi + + # Test if we can download the repository setup script + if wget --spider "http://rpms.litespeedtech.com/debian/enable_lst_debian_repo.sh" 2>/dev/null; then + print_success "LiteSpeed repository setup script is available" + else + print_warning "LiteSpeed repository setup script may not be available" + fi +} + +# Function to test MariaDB compatibility +test_mariadb_compatibility() { + print_test_header "MariaDB Compatibility Test" + + # Test MariaDB repository accessibility + if curl -s --head "https://mariadb.org/mariadb_release_signing_key.pgp" | head -n 1 | grep -q "200 OK"; then + print_success "MariaDB signing key is accessible" + else + print_warning "MariaDB signing key may not be accessible" + fi + + # Test if MariaDB packages are available + if apt-cache show mariadb-server >/dev/null 2>&1; then + print_success "MariaDB packages are available in repositories" + else + print_warning "MariaDB packages not found in default repositories" + fi +} + +# Function to test network connectivity +test_network_connectivity() { + print_test_header "Network Connectivity Test" + + local test_urls=( + "https://github.com" + "https://pypi.org" + "http://rpms.litespeedtech.com" + "https://mariadb.org" + ) + + local accessible_count=0 + local total_count=${#test_urls[@]} + + for url in "${test_urls[@]}"; do + if curl -s --head "$url" >/dev/null 2>&1; then + print_success "$url is accessible" + ((accessible_count++)) + else + print_warning "$url is not accessible" + fi + done + + print_status "Accessible URLs: $accessible_count/$total_count" + + if [[ $accessible_count -ge $((total_count * 3 / 4)) ]]; then + print_success "Network connectivity is good" + else + print_warning "Network connectivity may be limited" + fi +} + +# Function to test system resources +test_system_resources() { + print_test_header "System Resources Test" + + # Test available memory + local total_memory=$(free -m | awk 'NR==2{print $2}') + if [[ $total_memory -ge 1024 ]]; then + print_success "Sufficient memory available: ${total_memory}MB" + else + print_warning "Low memory: ${total_memory}MB (recommended: 1GB+)" + fi + + # Test available disk space + local available_space=$(df / | awk 'NR==2{print $4}') + local available_gb=$((available_space / 1024 / 1024)) + if [[ $available_gb -ge 10 ]]; then + print_success "Sufficient disk space: ${available_gb}GB" + else + print_warning "Low disk space: ${available_gb}GB (recommended: 10GB+)" + fi + + # Test CPU cores + local cpu_cores=$(nproc) + if [[ $cpu_cores -ge 2 ]]; then + print_success "Sufficient CPU cores: $cpu_cores" + else + print_warning "Limited CPU cores: $cpu_cores (recommended: 2+)" + fi +} + +# Function to run all tests +run_all_tests() { + echo -e "${BLUE}========================================${NC}" + echo -e "${BLUE} CyberPanel Debian 13 Compatibility Test${NC}" + echo -e "${BLUE}========================================${NC}\n" + + test_os_detection + test_cyberpanel_os_detection + test_package_manager + test_systemd_compatibility + test_python_compatibility + test_web_server_compatibility + test_required_packages + test_litespeed_repo_compatibility + test_mariadb_compatibility + test_network_connectivity + test_system_resources + + echo -e "\n${BLUE}========================================${NC}" + echo -e "${BLUE} Test Results Summary${NC}" + echo -e "${BLUE}========================================${NC}" + echo -e "Total Tests: $TESTS_TOTAL" + echo -e "Passed: ${GREEN}$TESTS_PASSED${NC}" + echo -e "Failed: ${RED}$TESTS_FAILED${NC}" + + if [[ $TESTS_FAILED -eq 0 ]]; then + echo -e "\n${GREEN}✅ All tests passed! Debian 13 appears to be compatible with CyberPanel.${NC}" + return 0 + elif [[ $TESTS_FAILED -le 2 ]]; then + echo -e "\n${YELLOW}⚠️ Most tests passed. Debian 13 should be compatible with minor issues.${NC}" + return 0 + else + echo -e "\n${RED}❌ Multiple tests failed. Debian 13 may have compatibility issues.${NC}" + return 1 + fi +} + +# Function to show usage +show_usage() { + echo "Usage: $0 [OPTIONS]" + echo "" + echo "Options:" + echo " -h, --help Show this help message" + echo " -v, --verbose Enable verbose output" + echo " --quick Run only essential tests" + echo "" + echo "This script tests CyberPanel compatibility with Debian 13." + echo "Run as root for best results." +} + +# Main execution +main() { + local verbose=false + local quick=false + + # Parse command line arguments + while [[ $# -gt 0 ]]; do + case $1 in + -h|--help) + show_usage + exit 0 + ;; + -v|--verbose) + verbose=true + shift + ;; + --quick) + quick=true + shift + ;; + *) + echo "Unknown option: $1" + show_usage + exit 1 + ;; + esac + done + + # Check if running as root + if [[ $EUID -ne 0 ]]; then + print_warning "Not running as root. Some tests may fail." + print_status "Consider running: sudo $0" + fi + + # Run tests + if [[ "$quick" == "true" ]]; then + print_status "Running quick compatibility test..." + test_os_detection + test_cyberpanel_os_detection + test_package_manager + test_systemd_compatibility + else + run_all_tests + fi +} + +# Run main function +main "$@" diff --git a/to-do/SECURITY_INSTALLATION.md b/to-do/SECURITY_INSTALLATION.md deleted file mode 100644 index dd72886fa..000000000 --- a/to-do/SECURITY_INSTALLATION.md +++ /dev/null @@ -1,192 +0,0 @@ -# CyberPanel Secure Installation Guide - -## Overview - -This document describes the secure installation process for CyberPanel that eliminates hardcoded passwords and implements environment-based configuration. - -## Security Improvements - -### ✅ **Fixed Security Vulnerabilities** - -1. **Hardcoded Database Passwords** - Now generated securely during installation -2. **Hardcoded Django Secret Key** - Now generated using cryptographically secure random generation -3. **Environment Variables** - All sensitive configuration moved to `.env` file -4. **File Permissions** - `.env` file set to 600 (owner read/write only) - -### 🔐 **Security Features** - -- **Cryptographically Secure Passwords**: Uses Python's `secrets` module for password generation -- **Environment-based Configuration**: Sensitive data stored in `.env` file, not in code -- **Secure File Permissions**: Environment files protected with 600 permissions -- **Credential Backup**: Automatic backup of credentials for recovery -- **Fallback Security**: Maintains backward compatibility with fallback method - -## Installation Process - -### 1. **Automatic Secure Installation** - -The installation script now automatically: - -1. Generates secure random passwords for: - - MySQL root user - - CyberPanel database user - - Django secret key - -2. Creates `.env` file with secure configuration: - ```bash - # Generated during installation - SECRET_KEY=your_64_character_secure_key - DB_PASSWORD=your_24_character_secure_password - ROOT_DB_PASSWORD=your_24_character_secure_password - ``` - -3. Creates `.env.backup` file for credential recovery -4. Sets secure file permissions (600) on all environment files - -### 2. **Manual Installation** (if needed) - -If you need to manually generate environment configuration: - -```bash -cd /usr/local/CyberCP -python install/env_generator.py /usr/local/CyberCP -``` - -## File Structure - -``` -/usr/local/CyberCP/ -├── .env # Main environment configuration (600 permissions) -├── .env.backup # Credential backup (600 permissions) -├── .env.template # Template for manual configuration -├── .gitignore # Prevents .env files from being committed -└── CyberCP/ - └── settings.py # Updated to use environment variables -``` - -## Security Best Practices - -### ✅ **Do's** - -- Keep `.env` and `.env.backup` files secure -- Record credentials from `.env.backup` and delete the file after installation -- Use strong, unique passwords for production deployments -- Regularly rotate database passwords -- Monitor access to environment files - -### ❌ **Don'ts** - -- Never commit `.env` files to version control -- Don't share `.env` files via insecure channels -- Don't use default passwords in production -- Don't leave `.env.backup` files on the system after recording credentials - -## Recovery - -### **Lost Credentials** - -If you lose your database credentials: - -1. Check if `.env.backup` file exists: - ```bash - sudo cat /usr/local/CyberCP/.env.backup - ``` - -2. If backup doesn't exist, you'll need to reset MySQL passwords using MySQL recovery procedures - -### **Regenerate Environment** - -To regenerate environment configuration: - -```bash -cd /usr/local/CyberCP -sudo python install/env_generator.py /usr/local/CyberCP -``` - -## Configuration Options - -### **Environment Variables** - -| Variable | Description | Default | -|----------|-------------|---------| -| `SECRET_KEY` | Django secret key | Generated (64 chars) | -| `DB_PASSWORD` | CyberPanel DB password | Generated (24 chars) | -| `ROOT_DB_PASSWORD` | MySQL root password | Generated (24 chars) | -| `DEBUG` | Debug mode | False | -| `ALLOWED_HOSTS` | Allowed hosts | localhost,127.0.0.1,hostname | - -### **Custom Configuration** - -To use custom passwords during installation: - -```bash -python install/env_generator.py /usr/local/CyberCP "your_root_password" "your_db_password" -``` - -## Troubleshooting - -### **Installation Fails** - -If the new secure installation fails: - -1. Check installation logs for error messages -2. The system will automatically fallback to the original installation method -3. Verify Python dependencies are installed: - ```bash - pip install python-dotenv - ``` - -### **Environment Loading Issues** - -If Django can't load environment variables: - -1. Ensure `.env` file exists and has correct permissions: - ```bash - ls -la /usr/local/CyberCP/.env - # Should show: -rw------- 1 root root - ``` - -2. Install python-dotenv if missing: - ```bash - pip install python-dotenv - ``` - -## Migration from Old Installation - -### **Existing Installations** - -For existing CyberPanel installations with hardcoded passwords: - -1. **Backup current configuration**: - ```bash - cp /usr/local/CyberCP/CyberCP/settings.py /usr/local/CyberCP/CyberCP/settings.py.backup - ``` - -2. **Generate new environment configuration**: - ```bash - cd /usr/local/CyberCP - python install/env_generator.py /usr/local/CyberCP - ``` - -3. **Update settings.py** (already done in new installations): - - The settings.py file now supports environment variables - - It will fallback to hardcoded values if .env is not available - -4. **Test the configuration**: - ```bash - cd /usr/local/CyberCP - python manage.py check - ``` - -## Support - -For issues with the secure installation: - -1. Check the installation logs -2. Verify file permissions -3. Ensure all dependencies are installed -4. Review the fallback installation method if needed - ---- - -**Security Notice**: This installation method significantly improves security by eliminating hardcoded credentials. Always ensure proper file permissions and secure handling of environment files.