diff --git a/README.md b/README.md index ff9c97e70..845eaf0f6 100755 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Webhosting control panel that uses OpenLiteSpeed as web server. * FTP Server. * Light weight DNS Server (PowerDNS). * PHPMYAdmin. -* Email Support (Rainloop). +* Email Support (SnappyMail). * FileManager. * PHP Managment. * Firewall (FirewallD & ConfigServer Firewall Intregration). diff --git a/README.md.bak b/README.md.bak new file mode 100644 index 000000000..ff9c97e70 --- /dev/null +++ b/README.md.bak @@ -0,0 +1,52 @@ +# CyberPanel + +Webhosting control panel that uses OpenLiteSpeed as web server. + +## Features + +* Different Level Of users. +* Auto SSL. +* FTP Server. +* Light weight DNS Server (PowerDNS). +* PHPMYAdmin. +* Email Support (Rainloop). +* FileManager. +* PHP Managment. +* Firewall (FirewallD & ConfigServer Firewall Intregration). +* One click Backup and Restore. + +# Supported PHPs + +* PHP 5.3 +* PHP 5.4 +* PHP 5.5 +* PHP 5.6 +* PHP 7.0 +* PHP 7.1 +* PHP 7.2 +* PHP 7.3 +* PHP 7.4 +* PHP 8.0 + +# Installation Instructions + + +``` +sh <(curl https://cyberpanel.net/install.sh || wget -O - https://cyberpanel.net/install.sh) +``` + +# Upgrading + + +``` +sh <(curl https://raw.githubusercontent.com/usmannasir/cyberpanel/stable/preUpgrade.sh || wget -O - https://raw.githubusercontent.com/usmannasir/cyberpanel/stable/preUpgrade.sh) +``` + +# Resources + +* [Official Site.](https://cyberpanel.net) +* [Documentation.](https://docs.cyberpanel.net) +* [Forums.](https://forums.cyberpanel.net) +* [Discord.](https://discord.gg/g8k8Db3) +* [Facebook Group.](https://www.facebook.com/groups/cyberpanel) + diff --git a/baseTemplate/templates/baseTemplate/index.html b/baseTemplate/templates/baseTemplate/index.html index b84d941e8..b0e6292ff 100755 --- a/baseTemplate/templates/baseTemplate/index.html +++ b/baseTemplate/templates/baseTemplate/index.html @@ -584,7 +584,7 @@ {% endif %} {% if admin or createEmail %} -
  • {% trans "Access Webmail" %}
  • {% endif %} diff --git a/baseTemplate/templates/baseTemplate/index.html.bak b/baseTemplate/templates/baseTemplate/index.html.bak new file mode 100644 index 000000000..b84d941e8 --- /dev/null +++ b/baseTemplate/templates/baseTemplate/index.html.bak @@ -0,0 +1,1102 @@ +{% load i18n %} +{% get_current_language as LANGUAGE_CODE %} + + + + + + + + + + {% block title %}Page Title{% endblock %} + + + + + {% load static %} + + + + + + + {% with version="2.1.2" %} + + + + + + + + + + + + + {% block styles %} + {% endblock %} + + + + + + + {% block header_scripts %} + {% endblock %} + + + + + + + + + + +
    +
    +
    + + +
    + + + + +
    + +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    + +
    + +
    +
    + +
    +
    +
    +
    + + + {% block content %} + {% endblock %} + +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {% endwith %} + + + {% block footer_scripts %} + {% endblock %} + + diff --git a/cyberpanel.sh b/cyberpanel.sh index 052bb20d6..f0129fc4d 100644 --- a/cyberpanel.sh +++ b/cyberpanel.sh @@ -1282,7 +1282,7 @@ sed -i "s|https://www.litespeedtech.com/|https://cyberpanel.sh/www.litespeedtech sed -i 's|composer.sh|composer_cn.sh|g' install.py sed -i 's|./composer_cn.sh|COMPOSER_ALLOW_SUPERUSER=1 ./composer_cn.sh|g' install.py sed -i 's|http://www.litespeedtech.com|https://cyberpanel.sh/www.litespeedtech.com|g' install.py -sed -i 's|https://www.rainloop.net/repository/webmail/rainloop-community-latest.zip|https://cyberpanel.sh/www.rainloop.net/repository/webmail/rainloop-community-latest.zip|g' install.py +sed -i 's|https://snappymail.eu/repository/latest.tar.gz|https://cyberpanel.sh/www.snappymail.eu/repository/latest.tar.gz|g' install.py sed -i "s|rep.cyberpanel.net|cyberpanel.sh/rep.cyberpanel.net|g" installCyberPanel.py sed -i "s|rep.cyberpanel.net|cyberpanel.sh/rep.cyberpanel.net|g" install.py @@ -1617,7 +1617,7 @@ fi } Post_Install_Display_Final_Info() { -RainloopAdminPass=$(grep SetPassword /usr/local/CyberCP/public/rainloop.php| sed -e 's|$oConfig->SetPassword(||g' -e "s|');||g" -e "s|'||g") +snappymailAdminPass=$(grep SetPassword /usr/local/CyberCP/public/snappymail.php| sed -e 's|$oConfig->SetPassword(||g' -e "s|');||g" -e "s|'||g") Elapsed_Time="$((Time_Count / 3600)) hrs $(((SECONDS / 60) % 60)) min $((Time_Count % 60)) sec" echo "###################################################################" echo " CyberPanel Successfully Installed " @@ -1639,9 +1639,9 @@ fi #echo " WebAdmin console username: admin " #echo " WebAdmin console password: $Webadmin_Pass " #echo " " -#echo " Visit: https://$Server_IP:8090/rainloop/?admin " -#echo " Rainloop Admin username: admin " -#echo " Rainloop Admin password: $RainloopAdminPass " +#echo " Visit: https://$Server_IP:8090/snappymail/?admin " +#echo " snappymail Admin username: admin " +#echo " snappymail Admin password: $snappymailAdminPass " echo " " echo -e " Run \e[31mcyberpanel help\e[39m to get FAQ info" echo -e " Run \e[31mcyberpanel upgrade\e[39m to upgrade it to latest version." diff --git a/cyberpanel.sh.bak b/cyberpanel.sh.bak new file mode 100644 index 000000000..557b3d496 --- /dev/null +++ b/cyberpanel.sh.bak @@ -0,0 +1,1963 @@ +#!/bin/bash + +#set -e -o pipefail +#set -x +#set -u + + +#CyberPanel installer script for CentOS 7.X, CentOS 8.X, CloudLinux 7.X, RockyLinux 8.X, Ubuntu 18.04, Ubuntu 20.04 , Ubuntu 20.10 and AlmaLinux 8.X +#For whoever may edit this script, please follow : +#Please use Pre_Install_xxx() and Post_Install_xxx() if you want to something respectively before or after the panel installation +#and update below accordingly +#Please use variable/functions name as MySomething or My_Something, and please try not to use too-short abbreviation :) +#Please use On/Off, True/False, Yes/No. + +#workflow: +#Set_Default_Variables() ---> set some default variable for later use +#Check_Root() ---> check for root +#Check_Server_IP() ---> check for server IP and geolocation at country level +#Check_OS() ---> check system , support on centos7/8, rockylinux 8.x , almalinux 8.x ubutnu18/20 and cloudlinux 7 , 8 is untested. +#Check_Virtualization() ---> check for virtualizaon , #LXC not supported# , some edit needed on OVZ +#Check_Panel() ---> check to make sure no other panel is installed +#Check_Process() ---> check no other process like Apache is running +#Check_Provider() ---> check the provider, certain provider like Alibaba or Tencent Yun may need some special change +#Check_Argument() ---> parse argument and go to Argument_Mode() or Interactive_Mode() respectively +#Pre_Install_Setup_Repository() ---> setup/install repositories for centos system. +#go to Pre_Install_Setup_CN_Repository() if server is within China. +#Pre_Install_Setup_Git_URL() ---> form up github URL , use Gitee for servers within China. +#Pre_Install_Required_Components() ---> install required softwares and git clone it +#Pre_Install_System_Tweak() ---> set up SWAP and apply some system tweak depends on providers +#Main_Installation() ---> change some code within python files for CN servers and start to install +#Post_Install_Addon_Memcached() ---> Install Memcached extension and process +#Post_Install_Addon_Redis() ---> Install Redis extension and process +#Post_Install_Required_Components() ---> install some required softwares. +#Post_Install_PHP_Session_Setup() ---> set up PHP session +#Post_Install_PHP_TimezoneDB() ---> set up PHP timezoneDB +#Post_Install_Regenerate_Cert() ---> regenerate cert for :7080 and :8090 to avoid Chrome on MacOS blocking. +#Post_Install_Regenerate_Webadmin_Console_Passwd() ---> regenerate the webadmin console password +#Post_Install_Setup_Watchdog() ---> set up watchdog script for webserver and MariaDB. +#Post_Install_Setup_Utility() ---> set up utility script for some handy features +#Post_Install_Tweak() ---> some patches/fixes on certain systems +#Post_Install_Display_Final_Info() ---> display installation successful information. + + +Sudo_Test=$(set) +#for SUDO check + +Set_Default_Variables() { + +echo -e "Fetching latest data from CyberPanel server...\n" +echo -e "This may take few seconds..." + +Silent="Off" +Server_Edition="OLS" +Admin_Pass="1234567" + +Memcached="Off" +Redis="Off" + +Postfix_Switch="On" +PowerDNS_Switch="On" +PureFTPd_Switch="On" + +Server_IP="" +Server_Country="Unknow" +Server_OS="" +Server_OS_Version="" +Server_Provider='Undefined' + +Watchdog="On" +Redis_Hosting="No" +Temp_Value=$(curl --silent --max-time 30 -4 https://cyberpanel.net/version.txt) +Panel_Version=${Temp_Value:12:3} +Panel_Build=${Temp_Value:25:1} + +Branch_Name="v${Panel_Version}.${Panel_Build}" + +if [[ $Branch_Name = v*.*.* ]] ; then + echo -e "\nBranch name fetched...$Branch_Name" +else + echo -e "\nUnable to fetch Branch name..." + echo -e "\nPlease try again in few moments, if this error still happens, please contact support" + exit +fi + +Base_Number="1.9.3" + +Total_RAM=$(free -m | awk '/Mem:/ { print $2 }') + +Remote_MySQL="Off" + +Final_Flags=() + +Git_User="" +Git_Content_URL="" +Git_Clone_URL="" + +LSWS_Latest_URL="https://cyberpanel.sh/update.litespeedtech.com/ws/latest.php" +LSWS_Tmp=$(curl --silent --max-time 30 -4 "$LSWS_Latest_URL") +LSWS_Stable_Line=$(echo "$LSWS_Tmp" | grep "LSWS_STABLE") +LSWS_Stable_Version=$(expr "$LSWS_Stable_Line" : '.*LSWS_STABLE=\(.*\) BUILD .*') +#grab the LSWS latest stable version. + +Enterprise_Flag="" +License_Key="" +Debug_Log2 "Starting installation..,1" + +} + +Debug_Log() { +echo -e "\n${1}=${2}\n" >> "/var/log/cyberpanel_debug_$(date +"%Y-%m-%d")_${Random_Log_Name}.log" +} + +Debug_Log2() { +Check_Server_IP "$@" >/dev/null 2>&1 +echo -e "\n${1}" >> /var/log/installLogs.txt +curl --max-time 20 -d '{"ipAddress": "'"$Server_IP"'", "InstallCyberPanelStatus": "'"$1"'"}' -H "Content-Type: application/json" -X POST https://cloud.cyberpanel.net/servers/RecvData >/dev/null 2>&1 +} + +Branch_Check() { +if [[ "$1" = *.*.* ]]; then + #check input if it's valid format as X.Y.Z + Output=$(awk -v num1="$Base_Number" -v num2="${1//[[:space:]]/}" ' + BEGIN { + print "num1", (num1 < num2 ? "<" : ">="), "num2" + } + ') + if [[ $Output = *">="* ]]; then + echo -e "\nYou must use version number higher than 1.9.4" + exit + else + Branch_Name="v${1//[[:space:]]/}" + echo -e "\nSet branch name to $Branch_Name..." + fi +else + echo -e "\nPlease input a valid format version number." + exit +fi +} + +License_Check() { +License_Key="$1" +echo -e "\nChecking LiteSpeed Enterprise license key..." +if echo "$License_Key" | grep -q "^....-....-....-....$" && [[ ${#License_Key} = "19" ]]; then + echo -e "\nLicense key set...\n" +elif [[ ${License_Key,,} = "trial" ]] ; then + echo -e "\nTrial license set..." + License_Key="Trial" +else + echo -e "\nLicense key seems incorrect, please verify" + echo -e "\nIf you are copying/pasting, please make sure you didn't paste blank space...\n" + exit +fi +} + +Check_Return() { + #check previous command result , 0 = ok , non-0 = something wrong. +# shellcheck disable=SC2181 +if [[ $? != "0" ]]; then + if [[ -n "$1" ]] ; then + echo -e "\n\n\n$1" + fi + echo -e "above command failed..." + Debug_Log2 "command failed, exiting. For more information read /var/log/installLogs.txt [404]" + if [[ "$2" = "no_exit" ]] ; then + echo -e"\nRetrying..." + else + exit + fi +fi +} +# check command success or not + +Retry_Command() { +# shellcheck disable=SC2034 +for i in {1..50}; +do + if [[ "$i" = "50" ]] ; then + echo "command $1 failed for 50 times, exit..." + exit 2 + else + $1 && break || echo -e "\n$1 has failed for $i times\nWait for 3 seconds and try again...\n"; sleep 3; + fi +done +} + +Check_Root() { +echo -e "\nChecking root privileges..." + if echo "$Sudo_Test" | grep SUDO >/dev/null; then + echo -e "\nYou are using SUDO , please run as root user...\n" + echo -e "\nIf you don't have direct access to root user, please run \e[31msudo su -\e[39m command (do NOT miss the \e[31m-\e[39m at end or it will fail) and then run installation command again." + exit + fi + + if [[ $(id -u) != 0 ]] >/dev/null; then + echo -e "\nYou must run on root user to install CyberPanel...\n" + 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 "\nYou are runing as root...\n" + fi +} + +Check_Server_IP() { +Server_IP=$(curl --silent --max-time 30 -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..." + Debug_Log2 "Can not detect IP. [404]" + exit + fi + +echo -e "\nChecking server location...\n" + +if [[ "$Server_Country" != "CN" ]] ; then + Server_Country=$(curl --silent --max-time 10 -4 https://cyberpanel.sh/?country) + if [[ ${#Server_Country} != "2" ]] ; then + Server_Country="Unknow" + fi +fi +#to avoid repeated check_ip called by debug_log2 to break force mirror for CN servers. + +if [[ "$Debug" = "On" ]] ; then + Debug_Log "Server_IP" "$Server_IP" + Debug_Log "Server_Country" "$Server_Country" +fi + +if [[ "$*" = *"--mirror"* ]] ; then + Server_Country="CN" + echo -e "Force to use mirror server due to --mirror argument...\n" +fi + +if [[ "$Server_Country" = *"CN"* ]] ; then + Server_Country="CN" + echo -e "Setting up to use mirror server...\n" +fi +} + +Check_OS() { +if [[ ! -f /etc/os-release ]] ; then + echo -e "Unable to detect the operating system...\n" + exit +fi + +# Reference: https://unix.stackexchange.com/questions/116539/how-to-detect-the-desktop-environment-in-a-bash-script +if [ -z "$XDG_CURRENT_DESKTOP" ]; then + echo -e "Desktop OS not detected. Proceeding\n" +else + echo "$XDG_CURRENT_DESKTOP defined appears to be a desktop OS. Bailing as CyberPanel is incompatible." + echo -e "\nCyberPanel is supported on server OS types only. Such as Ubuntu 18.04 x86_64, Ubuntu 20.04 x86_64, Ubuntu 20.10 x86_64, CentOS 7.x, CentOS 8.x, AlmaLinux 8.x and CloudLinux 7.x...\n" + exit +fi + + +if ! uname -m | grep -q x86_64 ; then + echo -e "x86_64 system is required...\n" + exit +fi + +if grep -q -E "CentOS Linux 7|CentOS Linux 8" /etc/os-release ; then + Server_OS="CentOS" +elif grep -q "AlmaLinux-8" /etc/os-release ; then + Server_OS="AlmaLinux" +elif grep -q -E "CloudLinux 7|CloudLinux 8" /etc/os-release ; then + Server_OS="CloudLinux" +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" /etc/os-release ; then + Server_OS="Ubuntu" +else + echo -e "Unable to detect your system..." + echo -e "\nCyberPanel is supported on Ubuntu 18.04 x86_64, Ubuntu 20.04 x86_64, Ubuntu 20.10 x86_64, CentOS 7.x, CentOS 8.x, AlmaLinux 8.x, RockyLinux 8.x, CloudLinux 7.x, CloudLinux 8.x...\n" + Debug_Log2 "CyberPanel is supported on Ubuntu 18.04 x86_64, Ubuntu 20.04 x86_64, Ubuntu 20.10 x86_64, CentOS 7.x, CentOS 8.x, AlmaLinux 8.x, RockyLinux 8.x, CloudLinux 7.x, CloudLinux 8.x... [404]" + exit +fi + +Server_OS_Version=$(grep VERSION_ID /etc/os-release | awk -F[=,] '{print $2}' | tr -d \" | head -c2 | tr -d . ) +#to make 20.04 display as 20 + +echo -e "System: $Server_OS $Server_OS_Version detected...\n" + +if [[ $Server_OS = "CloudLinux" ]] || [[ "$Server_OS" = "AlmaLinux" ]] || [[ "$Server_OS" = "RockyLinux" ]] ; then + Server_OS="CentOS" + #CloudLinux gives version id like 7.8 , 7.9 , so cut it to show first number only + #treat CL , Rocky and Alma as CentOS +fi + +if [[ "$Debug" = "On" ]] ; then + Debug_Log "Server_OS" "$Server_OS $Server_OS_Version" +fi + +} + +Check_Virtualization() { +echo -e "Checking virtualization type..." +#if hostnamectl | grep -q "Virtualization: lxc"; then +# echo -e "\nLXC detected..." +# echo -e "CyberPanel does not support LXC" +# echo -e "Exiting..." +# Debug_Log2 "CyberPanel does not support LXC.. [404]" +# exit +#fi +#remove per https://github.com/usmannasir/cyberpanel/issues/589 + +if hostnamectl | grep -q "Virtualization: openvz"; then + echo -e "OpenVZ detected...\n" + + if [[ ! -d /etc/systemd/system/pure-ftpd.service.d ]]; then + mkdir /etc/systemd/system/pure-ftpd.service.d + echo "[Service] +PIDFile=/run/pure-ftpd.pid" >/etc/systemd/system/pure-ftpd.service.d/override.conf + echo -e "PureFTPd service file modified for OpenVZ..." + fi + + if [[ ! -d /etc/systemd/system/lshttpd.service.d ]]; then + mkdir /etc/systemd/system/lshttpd.service.d + echo "[Service] +PIDFile=/tmp/lshttpd/lshttpd.pid" >/etc/systemd/system/lshttpd.service.d/override.conf + echo -e "LiteSPeed service file modified for OpenVZ..." + fi + + if [[ ! -d /etc/systemd/system/spamassassin.service.d ]]; then + mkdir /etc/systemd/system/spamassassin.service.d + echo "[Service] +PIDFile=/run/spamassassin.pid" >/etc/systemd/system/spamassassin.service.d/override.conf + echo -e "SpamAssassin service file modified for OpenVZ..." + fi +fi + +if [[ "$Debug" = "On" ]] ; then + Debug_Log "Server_Virtualization" "$(hostnamectl | grep "Virtualization")" +fi +} + +Check_Panel() { +if [[ -d /usr/local/cpanel ]]; then + echo -e "\ncPanel detected...\n" + Debug_Log2 "cPanel detected...exit... [404]" + exit +elif [[ -d /usr/local/directadmin ]]; then + echo -e "\nDirectAdmin detected...\n" + Debug_Log2 "DirectAdmin detected...exit... [404]" + exit +elif [[ -d /etc/httpd/conf/plesk.conf.d/ ]] || [[ -d /etc/apache2/plesk.conf.d/ ]]; then + echo -e "\nPlesk detected...\n" + Debug_Log2 "Plesk detected...exit... [404]" + exit +fi +} + +Check_Process() { +if systemctl is-active --quiet httpd; then + systemctl disable httpd + systemctl stop httpd + systemctl mask httpd + echo -e "\nhttpd process detected, disabling...\n" +fi +if systemctl is-active --quiet apache2; then + systemctl disable apache2 + systemctl stop apache2 + systemctl mask apache2 + echo -e "\napache2 process detected, disabling...\n" +fi +if systemctl is-active --quiet named; then + systemctl stop named + systemctl disable named + systemctl mask named + echo -e "\nnamed process detected, disabling...\n" +fi +if systemctl is-active --quiet exim; then + systemctl stop exim + systemctl disable exim + systemctl mask exim + echo -e "\nexim process detected, disabling...\n" +fi +} + +Check_Provider() { +if hash dmidecode >/dev/null 2>&1; then + if [[ "$(dmidecode -s bios-vendor)" = "Google" ]]; then + Server_Provider="Google Cloud Platform" + elif [[ "$(dmidecode -s bios-vendor)" = "DigitalOcean" ]]; then + Server_Provider="Digital Ocean" + elif [[ "$(dmidecode -s system-product-name | cut -c 1-7)" = "Alibaba" ]]; then + Server_Provider="Alibaba Cloud" + elif [[ "$(dmidecode -s system-manufacturer)" = "Microsoft Corporation" ]]; then + Server_Provider="Microsoft Azure" + elif [[ -d /usr/local/qcloud ]]; then + Server_Provider="Tencent Cloud" + else + Server_Provider="Undefined" + fi +else + Server_Provider='Undefined' +fi + +if [[ -f /sys/devices/virtual/dmi/id/product_uuid ]]; then + if [[ "$(cut -c 1-3 /sys/devices/virtual/dmi/id/product_uuid)" = 'EC2' ]] && [[ -d /home/ubuntu ]]; then + Server_Provider='Amazon Web Service' + fi +fi + +if [[ "$Debug" = "On" ]] ; then + Debug_Log "Server_Provider" "$Server_Provider" +fi +} + +Show_Help() { +echo -e "\nCyberPanel Installer Script Help\n" +echo -e "\nUsage: sh <(curl cyberpanel.sh) --argument" +echo -e "\n\e[31m-v\e[39m or \e[31m--version\e[39m : choose to install CyberPanel OpenLiteSpeed or CyberPanel Enterprise, available options are \e[31mols\e[39m , \e[31mTRIAL\e[39m and \e[31mSERIAL_NUMBER\e[39m, default ols" +echo -e "Please be aware, this serial number must be obtained from LiteSpeed Store." +echo -e "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\e[31m-a\e[39m or \e[31m--addons\e[39m : install addons: memcached, redis, PHP extension for memcached and redis" +echo -e "\n\e[31m-p\e[39m or \e[31m--password\e[39m : set password of new installation, empty for default 1234567, [r] or [random] for randomly generated 16 digital password, any other value besides [d] and [r(andom)] will be accept as password, default use 1234567." +echo -e "e.g. \e[31m-p r\e[39m will generate a random password" +echo -e " \e[31m-p 123456789\e[39m will set password to 123456789" +echo -e "\n\e[31m-m\e[39m or \e[31m--minimal\e[39m : set to minimal mode which will not install PowerDNS, Pure-FTPd and Postfix" +echo -e "\n\e[31m-m postfix/pureftpd/powerdns\e[39m will do minimal install also with compoenent given" +echo -e "e.g. \e[31m-m postfix\e[39m will do minimal install also with Postfix" +echo -e " \e[31m-m powerdns\e[39m will do minimal install also with PowerDNS" +echo -e " \e[31m-m postfix\e[39m powerdns will do minimal install also with Postfix and PowerDNS" +echo -e "\n\e[31m-b\e[39m or \e[31m--branch\e[39m : install with given branch/version , must be higher than 1.9.4" +echo -e "e.g. \e[31m-b 2.0.2\e[39m will install 2.0.2 version" +echo -e "\n\e[31m--mirror\e[39m : this argument force to use mirror server for majority of repositories, only suggest to use for servers within China" +echo -e "\nExample:" +echo -e "\nsh <(curl cyberpanel.sh) -v ols -p r or ./cyberpanel.sh --version ols --password random" +echo -e "\nThis will install CyberPanel OpenLiteSpeed and randomly generate the password." +echo -e "\nsh <(curl cyberpanel.sh) -v LICENSE_KEY -a -p my_pass_word" +echo -e "\nThis will install LiteSpeed Enterise , replace LICENSE_KEY to actual license key and set password to my_pass_word\n" +} + +Check_Argument() { +if [[ "$#" = "0" ]] || [[ "$#" = "1" && "$1" = "--debug" ]] || [[ "$#" = "1" && "$1" = "--mirror" ]]; then + echo -e "\nInitialized...\n" +else + if [[ $1 = "help" ]]; then + Show_Help + exit + elif [[ $1 = "default" ]]; then + echo -e "\nThis will start default installation...\n" + Silent="On" + Postfix_Switch="On" + PowerDNS_Switch="On" + PureFTPd_Switch="On" + Server_Edition="OLS" + Admin_Pass="1234567" + Memcached="On" + Redis="On" + else + while [[ -n "${1}" ]]; do + case $1 in + -v | --version) + shift + if [[ "${1}" = "" ]]; then + Show_Help + exit + elif [[ "${1^^}" = "OLS" ]] ; then + Server_Edition="OLS" + Silent="On" + echo -e "\nSet to use OpenLiteSpeed..." + else + Server_Edition="Enterprise" + License_Key="${1}" + Silent="On" + echo -e "\nSet to use LiteSpeed Enterprise..." + echo -e "\nSet to use license key ${1}..." + 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 '' + ) + elif [[ ${1} = "d" ]]; then + Admin_Pass="1234567" + else + if [[ ${#1} -lt 8 ]]; then + echo -e "\nPassword length less than 8 digital, please choose a more complicated password.\n" + exit + fi + Admin_Pass="${1}" + fi + echo -e "\nSet to use password ${1}..." + ;; + -b | --branch) + shift + Branch_Check "${1}" + ;; + -m | --minimal) + if ! echo "$@" | grep -q -i "postfix\|pureftpd\|powerdns" ; then + Postfix_Switch="Off" + PowerDNS_Switch="Off" + PureFTPd_Switch="Off" + echo -e "\nSet to use minimal installation..." + else + if [[ "${*^^}" = *"POSTFIX"* ]] ; then + Postfix_Switch="On" + echo -e "\nEnable Postfix..." + fi + if [[ "${*^^}" = *"PUREFTPD"* ]] ; then + PureFTPd_Switch="On" + echo -e "\nEnable PureFTPd..." + fi + if [[ "${*^^}" = *"POWERDNS"* ]] ; then + PowerDNS_Switch="On" + echo -e "\nEnable PowerDNS..." + fi + fi + ;; + -a | --addons) + Memcached="On" + Redis="On" + echo -e "\nEnable Addons..." + ;; + -h | --help) + Show_Help + exit + ;; + --debug) + echo -e "\nEnable Debug log...\n" + ;; + --mirror) + echo -e "\nForce to use mirror server...\n" + ;; + *) + if [[ "${1^^}" = *"POSTFIX"* ]] || [[ "${1^^}" = *"PUREFTPD"* ]] || [[ "${1^^}" = *"POWERDNS"* ]] ; then + : + #this is ugly workaround , leave it for now , to-do for further improvement. + else + echo -e "\nUnknown argument...\n" + Show_Help + exit + fi + ;; + esac + shift + done + fi +fi + +if [[ "$Debug" = "On" ]] ; then + Debug_Log "Arguments" "${@}" +fi + +Debug_Log2 "Initialization completed..,2" +} + +Argument_Mode() { +if [[ "${Server_Edition^^}" = "OLS" ]] ; then + Server_Edition="OLS" + echo -e "\nSet to OpenLiteSpeed..." +else + License_Check "$License_Key" +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\n" +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" +else + echo -e "\nAdmin password will be set to \e[31m$Admin_Pass\e[39m" +fi +} + +Interactive_Mode() { +echo -e " CyberPanel Installer v$Panel_Version.$Panel_Build + +1. Install CyberPanel. + +2. Exit. + +" +read -r -p " Please enter the number[1-2]: " Input_Number +echo "" +case "$Input_Number" in + 1) + Interactive_Mode_Set_Parameter + ;; + 2) + exit + ;; + *) + echo -e " Please enter the right number [1-2]\n" + exit + ;; +esac +} + + +Interactive_Mode_Set_Parameter() { +echo -e " CyberPanel Installer v$Panel_Version.$Panel_Build + +RAM check : $(free -m | awk 'NR==2{printf "%s/%sMB (%.2f%%)\n", $3,$2,$3*100/$2 }') + +Disk check : $(df -h | awk '$NF=="/"{printf "%d/%dGB (%s)\n", $3,$2,$5}') (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 -r -p " Please enter the number[1-3]: " Input_Number +echo "" +case "$Input_Number" in + 1) + Server_Edition="OLS" + ;; + 2) + Interactive_Mode_License_Input + ;; + 3) + exit + ;; + *) + echo -e " Please enter the right number [1-3]\n" + exit + ;; +esac + +echo -e "\nInstall Full service for CyberPanel? This will include PowerDNS, Postfix and Pure-FTPd." +echo -e "" +printf "%s" "Full installation [Y/n]: " +read -r Tmp_Input +if [[ $(expr "x$Tmp_Input" : 'x[Yy]') -gt 1 ]] || [[ $Tmp_Input = "" ]]; then + echo -e "\nFull installation selected..." + Postfix_Switch="On" + PowerDNS_Switch="On" + PureFTPd_Switch="On" +else + echo -e "" + printf "%s" "Install Postfix? [Y/n]: " + read -r Tmp_Input + if [[ $Tmp_Input =~ ^(no|n|N) ]]; then + Postfix_Switch="Off" + else + Postfix_Switch="On" + fi + echo -e "" + printf "%s" "Install PowerDNS? [Y/n]: " + read -r Tmp_Input + if [[ $Tmp_Input =~ ^(no|n|N) ]]; then + PowerDNS_Switch="Off" + else + PowerDNS_Switch="On" + fi + echo -e "" + printf "%s" "Install PureFTPd? [Y/n]: " + read -r Tmp_Input + if [[ $Tmp_Input =~ ^(no|n|N) ]]; then + PureFTPd_Switch="Off" + else + PureFTPd_Switch="On" + fi +fi + + ### Ask if you want to set up this CyberPanel with remote MySQL + +echo -e "\nDo you want to setup Remote MySQL? (This will skip installation of local MySQL)" +echo -e "" +printf "%s" "(Default = No) Remote MySQL [y/N]: " +read -r Tmp_Input +if [[ $(expr "x$Tmp_Input" : 'x[Yy]') -gt 1 ]]; then + echo -e "\nRemote MySQL selected..." + Remote_MySQL="On" + + echo -e "" + printf "%s" "Remote MySQL Hostname: " + read -r MySQL_Host + + echo -e "" + printf "%s" "Remote MySQL Database that contains meta information regarding MYSQL. (usually mysql): " + read -r MySQL_DB + + echo -e "" + printf "%s" "Remote MySQL Username: " + read -r MySQL_User + + echo -e "" + printf "%s" "Remote MySQL Password: " + read -r -s -p "Password: " MySQL_Password + + echo -e "" + printf "%s" "Remote MySQL Port: " + read -r MySQL_Port +else + echo -e "\nLocal MySQL selected..." +fi + +echo -e "\nPress \e[31mEnter\e[39m key to continue with latest version or Enter specific version such as: \e[31m1.9.4\e[39m , \e[31m2.0.1\e[39m , \e[31m2.0.2\e[39m ...etc" +printf "%s" "" +read -r Tmp_Input + +if [[ $Tmp_Input = "" ]]; then + echo -e "Branch name set to $Branch_Name" +else + Branch_Check "$Tmp_Input" +fi + +echo -e "\nPlease choose to use default admin password \e[31m1234567\e[39m, randomly generate one \e[31m(recommended)\e[39m or specify the admin password?" +printf "%s" "Choose [d]fault, [r]andom or [s]et password: [d/r/s] " +read -r Tmp_Input + +if [[ $Tmp_Input =~ ^(d|D| ) ]] || [[ -z $Tmp_Input ]]; then + Admin_Pass="1234567" + echo -e "\nAdmin password will be set to $Admin_Pass\n" +elif [[ $Tmp_Input =~ ^(r|R) ]]; then + Admin_Pass=$( + head /dev/urandom | tr -dc A-Za-z0-9 | head -c 16 + echo '' + ) + echo -e "\nAdmin password will be provided once installation is completed...\n" +elif [[ $Tmp_Input =~ ^(s|S) ]]; then + Custom_Pass="True" + echo -e "\nPlease enter your password:" + printf "%s" "" + read -r -s -p "Password: " Tmp_Input + if [[ -z "$Tmp_Input" ]]; then + echo -e "\nPlease do not use empty string...\n" + exit + fi + if [[ ${#Tmp_Input} -lt 8 ]]; then + echo -e "\nPassword length less than 8 digital, please choose a more complicated password.\n" + exit + fi + Tmp_Input1=$Tmp_Input + read -r -s -p "Confirm Password:" Tmp_Input + if [[ -z "$Tmp_Input" ]]; then + echo -e "\nPlease do not use empty string...\n" + exit + fi + if [[ "$Tmp_Input" = "$Tmp_Input1" ]]; then + Admin_Pass=$Tmp_Input + else + echo -e "\nRepeated password didn't match , please check...\n" + exit + fi +else + Admin_Pass="1234567" + echo -e "\nAdmin password will be set to $Admin_Pass\n" +fi + +echo -e "\nDo you wish to install Memcached process and its PHP extension?" +printf "%s" "Please select [Y/n]: " +read -r Tmp_Input +if [[ $Tmp_Input =~ ^(no|n|N) ]]; then + Memcached="Off" +else + Memcached="On" + echo -e "\nInstall Memcached process and its PHP extension set to Yes...\n" +fi + +echo -e "\nDo you wish to install Redis process and its PHP extension?" +printf "%s" "Please select [Y/n]: " +read -r Tmp_Input +if [[ $Tmp_Input =~ ^(no|n|N) ]]; then + Redis="Off" +else + Redis="On" + echo -e "\nInstall Redis process and its PHP extension set to Yes...\n" +fi + +echo -e "\nWould you like to set up a WatchDog \e[31m(beta)\e[39m for Web service and Database service ?" +echo -e "The watchdog script will be automatically started up after installation and server reboot" +echo -e "If you want to kill the watchdog , run \e[31mwatchdog kill\e[39m" +echo -e "Please type Yes or no (with capital \e[31mY\e[39m, default Yes): " +read -r Tmp_Input +if [[ $Tmp_Input = "Yes" ]] || [[ $Tmp_Input = "" ]]; then + Watchdog="On" + echo -e "\nInstall Watchdog set to Yes...\n" +else + Watchdog="Off" +fi +} + +Interactive_Mode_License_Input() { +Server_Edition="Enterprise" +echo -e "\nPlease note that your server has \e[31m$Total_RAM MB\e[39m RAM" +echo -e "REMINDER: The \e[31mFree Start\e[39m license requires \e[31m2GB or less\e[39m of RAM and the \e[31mSite Owner\e[39m and \e[31mWeb Host Lite\e[39m licenses require \e[31m8GB or less\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 -r 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\n" +printf "%s" "Please verify it is correct. [y/N]: " +read -r Tmp_Input +if [[ -z "$Tmp_Input" ]]; then + echo -e "\nPlease type \e[31my\e[39m\n" + exit +fi + +License_Check "$License_Key" + +#echo -e "\nWould you like use Redis Mass Hosting?" +#echo -e "Please type Yes or No (with capital \e[31mY\e[39m, default No):" +#read -r Redis_Hosting + +#if [[ "$Redis_Hosting" = "Yes" ]]; then +# echo -e "\nRedis Mass Hosting is set to Yes...\n" +#fi +# hide it for now +} + +Pre_Install_Setup_Repository() { +if [[ $Server_OS = "CentOS" ]] ; then + rpm --import https://cyberpanel.sh/rpms.litespeedtech.com/centos/RPM-GPG-KEY-litespeed + #import the LiteSpeed GPG key + + yum clean all + yum autoremove -y epel-release + rm -f /etc/yum.repos.d/epel.repo + rm -f /etc/yum.repos.d/epel.repo.rpmsave + + yum install -y yum-plugin-copr + Check_Return "yum repo" "no_exit" + yum copr enable -y copart/restic + Check_Return "yum repo" "no_exit" + + + if [[ "$Server_OS_Version" = "8" ]]; then + rpm --import https://cyberpanel.sh/www.centos.org/keys/RPM-GPG-KEY-CentOS-Official + rpm --import https://cyberpanel.sh/dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-8 + yum install -y https://cyberpanel.sh/dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm + Check_Return "yum repo" "no_exit" + + sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-* > /dev/null 2>&1 + sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-* > /dev/null 2>&1 + # ref: https://stackoverflow.com/questions/70926799/centos-through-vm-no-urls-in-mirrorlist + + dnf config-manager --set-enabled PowerTools > /dev/null 2>&1 + dnf config-manager --set-enabled powertools > /dev/null 2>&1 + +# cat </etc/yum.repos.d/CentOS-PowerTools-CyberPanel.repo +#[powertools-for-cyberpanel] +#name=CentOS Linux \$releasever - PowerTools +#mirrorlist=http://mirrorlist.centos.org/?release=\$releasever&arch=\$basearch&repo=PowerTools&infra=\$infra +#baseurl=http://mirror.centos.org/\$contentdir/\$releasever/PowerTools/\$basearch/os/ +#gpgcheck=1 +#enabled=1 +#gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial +#EOF + fi + + if [[ "$Server_OS_Version" = "7" ]]; then + rpm --import https://cyberpanel.sh/dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-7 + yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm + Check_Return "yum repo" "no_exit" + + yum install -y yum-plugin-priorities + Check_Return "yum repo" "no_exit" + curl -o /etc/yum.repos.d/powerdns-auth-43.repo https://cyberpanel.sh/repo.powerdns.com/repo-files/centos-auth-43.repo + Check_Return "yum repo" "no_exit" + + cat </etc/yum.repos.d/MariaDB.repo +# MariaDB 10.4 CentOS repository list - created 2021-08-06 02:01 UTC +# http://downloads.mariadb.org/mariadb/repositories/ +[mariadb] +name = MariaDB +baseurl = http://yum.mariadb.org/10.4/centos7-amd64 +gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB +gpgcheck=1 +EOF + + yum install --nogpg -y https://cyberpanel.sh/mirror.ghettoforge.org/distributions/gf/gf-release-latest.gf.el7.noarch.rpm + Check_Return "yum repo" "no_exit" + + rpm -ivh https://cyberpanel.sh/repo.iotti.biz/CentOS/7/noarch/lux-release-7-1.noarch.rpm + Check_Return "yum repo" "no_exit" + + rpm -ivh https://cyberpanel.sh/repo.ius.io/ius-release-el7.rpm + Check_Return "yum repo" "no_exit" + fi +fi +Debug_Log2 "Setting up repositories...,1" + +if [[ "$Server_Country" = "CN" ]] ; then + Pre_Install_Setup_CN_Repository + Debug_Log2 "Setting up repositories for CN server...,1" +fi + +if [[ "$Server_Country" = "CN" ]] || [[ "$Server_Provider" = "Alibaba Cloud" ]] || [[ "$Server_Provider" = "Tencent Cloud" ]]; then + Setup_Pip +fi + +} + +Setup_Pip() { + +rm -rf /root/.pip +mkdir -p /root/.pip +cat </root/.pip/pip.conf +[global] +index-url=https://cyberpanel.sh/pip-repo/pypi/simple/ +EOF +#default to self-host pip for CN + +if [[ "$Server_Provider" = "Alibaba Cloud" ]] ; then +sed -i 's|https://cyberpanel.sh/pip-repo/pypi/simple/|http://mirrors.cloud.aliyuncs.com/pypi/simple/|g' /root/.pip/pip.conf +echo "trusted-host = mirrors.cloud.aliyuncs.com" >> /root/.pip/pip.conf +fi + +if [[ "$Server_Provider" = "Tencent Cloud" ]] ; then +sed -i 's|https://cyberpanel.sh/pip-repo/pypi/simple/|https://mirrors.cloud.tencent.com/pypi/simple/|g' /root/.pip/pip.conf +fi +#set Alibaba and Tencent to their private mirror + + +Debug_Log2 "Setting up PIP repo...,3" +#set up pip for Alibaba, Tencent worldwide and Chinese server + +if [[ "$Debug" = "On" ]] ; then + Debug_Log "Pip Source" "$(grep "index-url" /root/.pip/pip.conf)" +fi +} + +Pre_Install_Setup_CN_Repository() { +if [[ "$Server_OS" = "CentOS" ]] && [[ "$Server_OS_Version" = "7" ]]; then + + sed -i 's|http://yum.mariadb.org|https://cyberpanel.sh/yum.mariadb.org|g' /etc/yum.repos.d/MariaDB.repo + sed -i 's|https://yum.mariadb.org/RPM-GPG-KEY-MariaDB|https://cyberpanel.sh/yum.mariadb.org/RPM-GPG-KEY-MariaDB|g' /etc/yum.repos.d/MariaDB.repo + # use MariaDB Mirror + + sed -i 's|https://download.copr.fedorainfracloud.org|https://cyberpanel.sh/download.copr.fedorainfracloud.org|g' /etc/yum.repos.d/_copr_copart-restic.repo + + sed -i 's|http://repo.iotti.biz|https://cyberpanel.sh/repo.iotti.biz|g' /etc/yum.repos.d/frank.repo + + sed -i "s|mirrorlist=http://mirrorlist.ghettoforge.org/el/7/gf/\$basearch/mirrorlist|baseurl=https://cyberpanel.sh/mirror.ghettoforge.org/distributions/gf/el/7/gf/x86_64/|g" /etc/yum.repos.d/gf.repo + sed -i "s|mirrorlist=http://mirrorlist.ghettoforge.org/el/7/plus/\$basearch/mirrorlist|baseurl=https://cyberpanel.sh/mirror.ghettoforge.org/distributions/gf/el/7/plus/x86_64/|g" /etc/yum.repos.d/gf.repo + + sed -i 's|https://repo.ius.io|https://cyberpanel.sh/repo.ius.io|g' /etc/yum.repos.d/ius.repo + + sed -i 's|http://repo.iotti.biz|https://cyberpanel.sh/repo.iotti.biz|g' /etc/yum.repos.d/lux.repo + + sed -i 's|http://repo.powerdns.com|https://cyberpanel.sh/repo.powerdns.com|g' /etc/yum.repos.d/powerdns-auth-43.repo + sed -i 's|https://repo.powerdns.com|https://cyberpanel.sh/repo.powerdns.com|g' /etc/yum.repos.d/powerdns-auth-43.repo +fi +# sed -i 's|http://mirrors.tencentyun.com/ubuntu/|https://cyberpanel.sh/us.archive.ubuntu.com/ubuntu/|g' /etc/apt/sources.list + +Debug_Log2 "Setting up repositories for CN server...,1" +} + +Download_Requirement() { +for i in {1..50} ; + do + wget -O /usr/local/requirments.txt "${Git_Content_URL}/${Branch_Name}/requirments.txt" + if grep -q "Django==" /usr/local/requirments.txt ; then + break + else + echo -e "\n Requirement list has failed to download for $i times..." + echo -e "Wait for 30 seconds and try again...\n" + sleep 30 + fi +done +#special made function for Gitee.com , for whatever reason , sometimes it fails to download this file +} + +Pre_Install_Required_Components() { + +Debug_Log2 "Installing necessary components..,3" + +if [[ "$Server_OS" = "CentOS" ]] ; then + yum update -y + if [[ "$Server_OS_Version" = "7" ]] ; then + yum install -y wget strace net-tools curl which bc telnet htop libevent-devel gcc libattr-devel xz-devel gpgme-devel curl-devel git socat openssl-devel MariaDB-shared mariadb-devel yum-utils python36u python36u-pip python36u-devel zip unzip bind-utils + Check_Return + yum -y groupinstall development + Check_Return + elif [[ "$Server_OS_Version" = "8" ]] ; then + dnf install -y libnsl zip wget strace net-tools curl which bc telnet htop libevent-devel gcc libattr-devel xz-devel mariadb-devel curl-devel git platform-python-devel tar socat python3 zip unzip bind-utils + Check_Return + dnf install -y gpgme-devel + Check_Return + fi + ln -s /usr/bin/pip3 /usr/bin/pip +else + apt update -y + DEBIAN_FRONTEND=noninteractive apt upgrade -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" + if [[ "$Server_Provider" = "Alibaba Cloud" ]] ; then + apt install -y --allow-downgrades libgnutls30=3.6.13-2ubuntu1.3 + fi + + DEBIAN_FRONTEND=noninteracitve apt install -y dnsutils net-tools htop telnet 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 virtualenv git socat vim unzip zip + Check_Return + + DEBIAN_FRONTEND=noninteractive apt install -y python3-pip + Check_Return + + ln -s /usr/bin/pip3 /usr/bin/pip3.6 + ln -s /usr/bin/pip3.6 /usr/bin/pip + + DEBIAN_FRONTEND=noninteractive apt install -y build-essential libssl-dev libffi-dev python3-dev + Check_Return + DEBIAN_FRONTEND=noninteractive apt install -y python3-venv + Check_Return + + DEBIAN_FRONTEND=noninteractive apt install -y locales + locale-gen "en_US.UTF-8" + update-locale LC_ALL="en_US.UTF-8" +fi + +Debug_Log2 "Installing required virtual environment,3" + +export LC_CTYPE=en_US.UTF-8 +export LC_ALL=en_US.UTF-8 +#need to set lang to address some pip module installation issue. + +Retry_Command "pip install --default-timeout=3600 virtualenv==16.7.9" + +Download_Requirement + +virtualenv -p /usr/bin/python3 /usr/local/CyberPanel + Check_Return + +if [[ "$Server_OS" = "Ubuntu" ]] && [[ "$Server_OS_Version" != "20" ]] ; then + # shellcheck disable=SC1091 + source /usr/local/CyberPanel/bin/activate +else + # shellcheck disable=SC1091 + . /usr/local/CyberPanel/bin/activate +fi + +Debug_Log2 "Installing requirments..,3" + +Retry_Command "pip install --default-timeout=3600 -r /usr/local/requirments.txt" + Check_Return "requirments" "no_exit" + +rm -rf cyberpanel +echo -e "\nFetching files from ${Git_Clone_URL}...\n" + +Debug_Log2 "Getting CyberPanel code..,4" + +Retry_Command "git clone ${Git_Clone_URL}" + Check_Return "git clone ${Git_Clone_URL}" + +echo -e "\nCyberPanel source code downloaded...\n" + +cd cyberpanel || exit +git checkout "$Branch_Name" + Check_Return "git checkout" +cd - || exit +cp -r cyberpanel /usr/local/cyberpanel +cd cyberpanel/install || exit + +Debug_Log2 "Necessary components installed..,5" +} + +Pre_Install_System_Tweak() { +Debug_Log2 "Setting up system tweak...,20" +Line_Number=$(grep -n "127.0.0.1" /etc/hosts | cut -d: -f 1) +My_Hostname=$(hostname) + +if [[ -n $Line_Number ]]; then + for Line_Number2 in $Line_Number ; do + String=$(sed "${Line_Number2}q;d" /etc/hosts) + if [[ $String != *"$My_Hostname"* ]]; then + New_String="$String $My_Hostname" + sed -i "${Line_Number2}s/.*/${New_String}/" /etc/hosts + fi + done +else + echo "127.0.0.1 $My_Hostname " >>/etc/hosts +fi + #this should address on "sudo: unable to resolve host ..." on Ubuntu , it's not issue but annoying. + +if [[ "$Server_OS" = "CentOS" ]] ; then + setenforce 0 || true + sed -i 's/SELINUX=enforcing/SELINUX=permissive/g' /etc/selinux/config + #disable SELinux + + if [[ "$Server_OS_Version" = "7" ]] ; then + : + fi + #CentOS 7 specific change + if [[ "$Server_OS_Version" = "8" ]] ; then + if grep -q -E "Rocky Linux" /etc/os-release ; then + if [[ "$Server_Country" = "CN" ]] ; then + sed -i 's|rpm -Uvh http://rpms.litespeedtech.com/centos/litespeed-repo-1.1-1.el8.noarch.rpm|curl -o /etc/yum.repos.d/litespeed.repo https://cyberpanel.sh/litespeed/litespeed_cn.repo|g' install.py + else + sed -i 's|rpm -Uvh http://rpms.litespeedtech.com/centos/litespeed-repo-1.1-1.el8.noarch.rpm|curl -o /etc/yum.repos.d/litespeed.repo https://cyberpanel.sh/litespeed/litespeed.repo|g' install.py + fi + fi + fi + #CentOS 8 specific change + +elif [[ "$Server_OS" = "Ubuntu" ]] ; then + if [[ "$Server_OS_Version" = "20" ]] ; then + sed -i 's|ce-2.3-latest/ubuntu/bionic bionic main|ce-2.3-latest/ubuntu/focal focal main|g' install.py + fi + #Ubuntu 20 specific change. + + if [[ "$Server_OS_Version" = "18" ]] ; then + : + fi + #Ubuntu 18 specific change. +fi + +if ! grep -q "pid_max" /etc/rc.local 2>/dev/null ; 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 + if [[ -f /etc/rc.local ]] ; then + echo -e "#!/bin/bash\n$(cat /etc/rc.local)" > /etc/rc.local + else + echo "#!/bin/bash" > /etc/rc.local + fi + echo "echo 1000000 > /proc/sys/kernel/pid_max + echo 1 > /sys/kernel/mm/ksm/run" >>/etc/rc.local + chmod +x /etc/rc.local + systemctl enable rc-local >/dev/null 2>&1 + systemctl start rc-local >/dev/null 2>&1 + fi + if grep -q "nf_conntrack_max" /etc/sysctl.conf ; then + sysctl -w net.netfilter.nf_conntrack_max=2097152 > /dev/null + sysctl -w net.nf_conntrack_max=2097152 > /dev/null + echo "net.netfilter.nf_conntrack_max=2097152" >> /etc/sysctl.conf + echo "net.nf_conntrack_max=2097152" >> /etc/sysctl.conf + 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 + #raise the file limit for systemd process + + 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 -e "Check SWAP...\n" + else + if [[ $Set_SWAP -gt "2049" ]]; then + #limit it to 2GB as max size + Set_SWAP="2048" + fi + fallocate --length ${Set_SWAP}MiB $SWAP_File + chmod 600 $SWAP_File + mkswap $SWAP_File + swapon $SWAP_File + echo -e "${SWAP_File} swap swap sw 0 0" | sudo tee -a /etc/fstab + sysctl vm.swappiness=10 + echo -e "vm.swappiness = 10" >> /etc/sysctl.conf + echo -e "\nSWAP set...\n" + fi + fi + + if [[ "$Server_Provider" = "Tencent Cloud" ]] ; then + echo "$(host mirrors.tencentyun.com | awk '{print $4}') mirrors.tencentyun.com " >> /etc/hosts + fi + if [[ "$Server_Provider" = "Alibaba Cloud" ]] ; then + echo "$(host mirrors.cloud.aliyuncs.com | awk '{print $4}') mirrors.cloud.aliyuncs.com " >> /etc/hosts + fi + #add internal repo server to host file before systemd-resolved is disabled + + if grep -i -q "systemd-resolve" /etc/resolv.conf ; then + systemctl stop systemd-resolved >/dev/null 2>&1 + systemctl disable systemd-resolved >/dev/null 2>&1 + systemctl mask systemd-resolved >/dev/null 2>&1 + fi + + rm -f /etc/resolv.conf + + if [[ "$Server_Provider" = "Tencent Cloud" ]] ; then + echo -e "nameserver 183.60.83.19" > /etc/resolv.conf + echo -e "nameserver 183.60.82.98" >> /etc/resolv.conf + elif [[ "$Server_Provider" = "Alibaba Cloud" ]] ; then + echo -e "nameserver 100.100.2.136" > /etc/resolv.conf + echo -e "nameserver 100.100.2.138" >> /etc/resolv.conf + else + echo -e "nameserver 1.1.1.1" > /etc/resolv.conf + echo -e "nameserver 8.8.8.8" >> /etc/resolv.conf + fi + + systemctl restart systemd-networkd >/dev/null 2>&1 + sleep 3 + #take a break ,or installer will break + +cp /etc/resolv.conf /etc/resolv.conf-tmp + +Line1="$(grep -n "f.write('nameserver 8.8.8.8')" installCyberPanel.py | head -n 1 | cut -d: -f1)" +sed -i "${Line1}i\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ subprocess.call\(command, shell=True)" installCyberPanel.py +sed -i "${Line1}i\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ command = 'cat /etc/resolv.conf-tmp > /etc/resolv.conf'" installCyberPanel.py +} + +License_Validation() { +Debug_Log2 "Validating LiteSpeed license...,40" +Current_Dir=$(pwd) + +if [ -f /root/cyberpanel-tmp ]; then + rm -rf /root/cyberpanel-tmp +fi + +mkdir /root/cyberpanel-tmp +cd /root/cyberpanel-tmp || exit + +Retry_Command "wget https://cyberpanel.sh/www.litespeedtech.com/packages/${LSWS_Stable_Version:0:1}.0/lsws-$LSWS_Stable_Version-ent-x86_64-linux.tar.gz" +tar xzvf "lsws-$LSWS_Stable_Version-ent-x86_64-linux.tar.gz" >/dev/null +cd "/root/cyberpanel-tmp/lsws-$LSWS_Stable_Version/conf" || exit +if [[ "$License_Key" = "Trial" ]]; then + Retry_Command "wget -q https://cyberpanel.sh/license.litespeedtech.com/reseller/trial.key" + sed -i "s|writeSerial = open('lsws-6.0/serial.no', 'w')|command = 'wget -q --output-document=./lsws-$LSWS_Stable_Version/trial.key https://cyberpanel.sh/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_Version/bin" || exit + +if [[ "$License_Key" = "Trial" ]]; then + License_Key="1111-2222-3333-4444" +else + ./lshttpd -r +fi + +if ./lshttpd -V |& grep "ERROR" || ./lshttpd -V |& grep "expire in 0 days" ; then + echo -e "\n\nThere appears to be an issue with license , please check above result..." + Debug_Log2 "There appears to be an issue with LiteSpeed License, make sure you are using correct serial key. [404]" + exit +fi + +echo -e "\nLicense seems valid..." +cd "$Current_Dir" || exit +rm -rf /root/cyberpanel-tmp + #clean up the temp files +} + +Pre_Install_CN_Replacement() { +if [[ "$Server_OS" = "Ubuntu" ]] ; then + sed -i 's|wget http://rpms.litespeedtech.com/debian/|wget https://cyberpanel.sh/litespeed/|g' install.py + sed -i 's|https://repo.dovecot.org/|https://cyberpanel.sh/repo.dovecot.org/|g' install.py +fi + #replace litespeed repo on ubuntu 18/20 + +if [[ "$Server_OS" = "CentOS" ]] ; then + sed -i 's|rpm -ivh http://rpms.litespeedtech.com/centos/litespeed-repo-1.2-1.el7.noarch.rpm|curl -o /etc/yum.repos.d/litespeed.repo https://cyberpanel.sh/litespeed/litespeed_cn.repo|g' install.py + sed -i 's|rpm -Uvh http://rpms.litespeedtech.com/centos/litespeed-repo-1.1-1.el8.noarch.rpm|curl -o /etc/yum.repos.d/litespeed.repo https://cyberpanel.sh/litespeed/litespeed_cn.repo|g' install.py + sed -i 's|https://mirror.ghettoforge.org/distributions|https://cyberpanel.sh/mirror.ghettoforge.org/distributions|g' install.py + + if [[ "$Server_OS_Version" = "8" ]] ; then + sed -i 's|dnf --nogpg install -y https://mirror.ghettoforge.org/distributions/gf/gf-release-latest.gf.el8.noarch.rpm|echo gf8|g' install.py + sed -i 's|dnf --nogpg install -y https://cyberpanel.sh/mirror.ghettoforge.org/distributions/gf/gf-release-latest.gf.el8.noarch.rpm|echo gf8|g' install.py + + Retry_Command "dnf --nogpg install -y https://cyberpanel.sh/mirror.ghettoforge.org/distributions/gf/gf-release-latest.gf.el8.noarch.rpm" + sed -i "s|mirrorlist=http://mirrorlist.ghettoforge.org/el/8/gf/\$basearch/mirrorlist|baseurl=https://cyberpanel.sh/mirror.ghettoforge.org/distributions/gf/el/8/gf/x86_64/|g" /etc/yum.repos.d/gf.repo + sed -i "s|mirrorlist=http://mirrorlist.ghettoforge.org/el/8/plus/\$basearch/mirrorlist|baseurl=https://cyberpanel.sh/mirror.ghettoforge.org/distributions/gf/el/8/plus/x86_64/|g" /etc/yum.repos.d/gf.repo + #get this set up beforehand. + fi + +fi + +sed -i "s|https://www.litespeedtech.com/|https://cyberpanel.sh/www.litespeedtech.com/|g" installCyberPanel.py +sed -i 's|composer.sh|composer_cn.sh|g' install.py +sed -i 's|./composer_cn.sh|COMPOSER_ALLOW_SUPERUSER=1 ./composer_cn.sh|g' install.py +sed -i 's|http://www.litespeedtech.com|https://cyberpanel.sh/www.litespeedtech.com|g' install.py +sed -i 's|https://snappymail.eu/repository/latest.tar.gz|https://cyberpanel.sh/www.snappymail.eu/repository/latest.tar.gz|g' install.py + +sed -i "s|rep.cyberpanel.net|cyberpanel.sh/rep.cyberpanel.net|g" installCyberPanel.py +sed -i "s|rep.cyberpanel.net|cyberpanel.sh/rep.cyberpanel.net|g" install.py + + +Debug_Log2 "Setting up URLs for CN server...,1" + + +sed -i 's|wget -O - https://get.acme.sh \| sh|echo acme|g' install.py +sed -i 's|/root/.acme.sh/acme.sh --upgrade --auto-upgrade|echo acme2|g' install.py + +Current_Dir=$(pwd) +Retry_Command "git clone https://gitee.com/neilpang/acme.sh.git" +cd acme.sh || exit +./acme.sh --install +cd "$Current_Dir" || exit +rm -rf acme.sh + +# shellcheck disable=SC2016 +sed -i 's|$PROJECT/archive/$BRANCH.tar.gz|https://cyberpanel.sh/codeload.github.com/acmesh-official/acme.sh/tar.gz/master|g' /root/.acme.sh/acme.sh + +Retry_Command "/root/.acme.sh/acme.sh --upgrade --auto-upgrade" +#install acme and upgrade it beforehand, to prevent gitee fail +} + +Main_Installation() { +Debug_Log2 "Starting main installation..,30" +if [[ -d /usr/local/CyberCP ]] ; then + echo -e "\n CyberPanel already installed, exiting..." + Debug_Log2 "CyberPanel already installed, exiting... [404]" + exit +fi + +if [[ $Server_Edition = "Enterprise" ]] ; then + echo -e "\nValidating the license..." + echo -e "\nThis may take a minute..." + echo -e "\nPlease be patient...\n" + + License_Validation + + sed -i "s|lsws-5.4.2|lsws-$LSWS_Stable_Version|g" installCyberPanel.py + sed -i "s|lsws-5.3.5|lsws-$LSWS_Stable_Version|g" installCyberPanel.py + sed -i "s|lsws-6.0|lsws-$LSWS_Stable_Version|g" installCyberPanel.py + #this sed must be done after license validation + + Enterprise_Flag="--ent ent --serial " +fi + +sed -i 's|git clone https://github.com/usmannasir/cyberpanel|echo downloaded|g' install.py +sed -i 's|mirror.cyberpanel.net|cyberpanel.sh|g' install.py + + +if [[ $Server_Country = "CN" ]] ; then + Pre_Install_CN_Replacement +else + sed -i 's|wget -O - https://get.acme.sh \| sh|echo acme|g' install.py + sed -i 's|/root/.acme.sh/acme.sh --upgrade --auto-upgrade|echo acme2|g' install.py + + Current_Dir=$(pwd) + Retry_Command "git clone https://github.com/acmesh-official/acme.sh.git" + cd acme.sh || exit + ./acme.sh --install + cd "$Current_Dir" || exit + rm -rf acme.sh + + Retry_Command "/root/.acme.sh/acme.sh --upgrade --auto-upgrade" + #install acme and upgrade it beforehand, to prevent gitee fail +fi + #install acme.sh before main installation for issues #705 #707 #708 #709 + +echo -e "Preparing...\n" + +Final_Flags=() +Final_Flags+=("$Server_IP") +Final_Flags+=(${Enterprise_Flag:+$Enterprise_Flag}) +Final_Flags+=(${License_Key:+$License_Key}) +Final_Flags+=(--postfix "${Postfix_Switch^^}") +Final_Flags+=(--powerdns "${PowerDNS_Switch^^}") +Final_Flags+=(--ftp "${PureFTPd_Switch^^}") + +if [[ "$Redis_Hosting" = "Yes" ]] ; then + Final_Flags+=(--redis enable) +fi + +if [[ "$Remote_MySQL" = "On" ]] ; then + Final_Flags+=(--remotemysql "${Remote_MySQL^^}") + Final_Flags+=(--mysqlhost "$MySQL_Host") + Final_Flags+=(--mysqldb "$MySQL_DB") + Final_Flags+=(--mysqluser "$MySQL_User") + Final_Flags+=(--mysqlpassword "$MySQL_Password") + Final_Flags+=(--mysqlport "$MySQL_Port") +else + Final_Flags+=(--remotemysql "${Remote_MySQL^^}") +fi + #form up the final agurment for install.py +if [[ "$Debug" = "On" ]] ; then + Debug_Log "Final_Flags" "${Final_Flags[@]}" +fi + +/usr/local/CyberPanel/bin/python install.py "${Final_Flags[@]}" + + +if grep "CyberPanel installation successfully completed" /var/log/installLogs.txt >/dev/null; then + echo -e "\nCyberPanel installation sucessfully completed...\n" + Debug_Log2 "Main installation completed...,70" +else + echo -e "Oops, something went wrong..." + Debug_Log2 "Oops, something went wrong... [404]" + exit +fi +} + +Post_Install_Addon_Mecached_LSMCD() { +if [[ $Server_OS = "CentOS" ]]; then + yum groupinstall "Development Tools" -y + yum install autoconf automake zlib-devel openssl-devel expat-devel pcre-devel libmemcached-devel cyrus-sasl* -y + wget -O lsmcd-master.zip https://cyberpanel.sh/codeload.github.com/litespeedtech/lsmcd/zip/master + unzip lsmcd-master.zip + Current_Dir=$(pwd) + cd "$Current_Dir/lsmcd-master" || exit + ./fixtimestamp.sh + ./configure CFLAGS=" -O3" CXXFLAGS=" -O3" + make + make install + systemctl enable lsmcd + systemctl start lsmcd + cd "$Current_Dir" || exit +else + DEBIAN_FRONTEND=noninteractive apt install build-essential zlib1g-dev libexpat1-dev openssl libssl-dev libsasl2-dev libpcre3-dev git -y + wget -O lsmcd-master.zip https://cyberpanel.sh/codeload.github.com/litespeedtech/lsmcd/zip/master + unzip lsmcd-master.zip + Current_Dir=$(pwd) + cd "$Current_Dir/lsmcd-master" || exit + ./fixtimestamp.sh + ./configure CFLAGS=" -O3" CXXFLAGS=" -O3" + make + make install + cd "$Current_Dir" || exit + systemctl enable lsmcd + systemctl start lsmcd +fi +} + +Post_Install_Addon_Memcached() { +if [[ $Server_OS = "CentOS" ]]; then + yum install -y lsphp??-memcached lsphp??-pecl-memcached + if [[ $Total_RAM -eq "2048" ]] || [[ $Total_RAM -gt "2048" ]]; then + Post_Install_Addon_Mecached_LSMCD + else + yum install -y memcached + sed -i 's|OPTIONS=""|OPTIONS="-l 127.0.0.1 -U 0"|g' /etc/sysconfig/memcached + #turn off UDP and bind to 127.0.0.1 only + systemctl enable memcached + systemctl start memcached + fi +fi +if [[ $Server_OS = "Ubuntu" ]]; then + DEBIAN_FRONTEND=noninteractive apt install -y "lsphp*-memcached" + + if [[ "$Total_RAM" -eq "2048" ]] || [[ "$Total_RAM" -gt "2048" ]]; then + Post_Install_Addon_Mecached_LSMCD + else + DEBIAN_FRONTEND=noninteractive apt install -y memcached + systemctl enable memcached + systemctl start memcached + fi +fi + +if pgrep "lsmcd" ; then + echo -e "\n\nLiteSpeed Memcached installed and running..." +fi + +if pgrep "memcached" ; then + echo -e "\n\nMemcached installed and running..." +fi +} + +Post_Install_Addon_Redis() { +if [[ "$Server_OS" = "CentOS" ]]; then + if [[ "$Server_OS_Version" = "8" ]]; then + yum install -y lsphp??-redis redis + else + yum -y install http://rpms.remirepo.net/enterprise/remi-release-7.rpm + yum-config-manager --disable remi + yum-config-manager --disable remi-safe + yum -y --enablerepo=remi install redis + fi +fi + +if [[ $Server_OS = "Ubuntu" ]]; then + DEBIAN_FRONTEND=noninteractive apt install -y "lsphp*-redis" redis +fi + +if ifconfig -a | grep inet6; then + echo -e "\nIPv6 detected...\n" +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 = "Ubuntu" ]]; then + systemctl stop redis-server + rm -f /var/run/redis/redis-server.pid + systemctl enable redis-server + systemctl start redis-server +else + systemctl enable redis + systemctl start redis +fi + +if pgrep "redis" ; then + echo -e "\n\nRedis installed and running..." + touch /home/cyberpanel/redis +fi +} + +Post_Install_PHP_Session_Setup() { +echo -e "\nSetting up PHP session storage path...\n" +wget -O /root/php_session_script.sh "${Git_Content_URL}/stable/CPScripts/setup_php_sessions.sh" +chmod +x /root/php_session_script.sh +bash /root/php_session_script.sh +rm -f /root/php_session_script.sh +Debug_Log2 "Setting up PHP session conf...,90" +} + +Post_Install_PHP_TimezoneDB() { +Current_Dir="$(pwd)" +rm -f /usr/local/lsws/cyberpanel-tmp +mkdir /usr/local/lsws/cyberpanel-tmp +cd /usr/local/lsws/cyberpanel-tmp || exit +wget -O timezonedb.tgz https://cyberpanel.sh/pecl.php.net/get/timezonedb +tar xzvf timezonedb.tgz +cd timezonedb-* || exit + +if [[ "$Server_OS" = "Ubuntu" ]] ; then + DEBIAN_FRONTEND=noninteractive apt install libmagickwand-dev pkg-config build-essential -y + DEBIAN_FRONTEND=noninteractive apt install -y lsphp*-dev +else + yum remove -y lsphp??-mysql + yum install -y lsphp??-mysqlnd + yum install -y lsphp??-devel make gcc glibc-devel libmemcached-devel zlib-devel +fi + +for PHP_Version in /usr/local/lsws/lsphp?? ; + do + PHP_INI_Path=$(find "$PHP_Version" -name php.ini) + + if [[ "$Server_OS" = "CentOS" ]]; then + if [[ ! -d "${PHP_Version}/tmp" ]]; then + mkdir "${PHP_Version}/tmp" + fi + "${PHP_Version}"/bin/pecl channel-update pecl.php.net + "${PHP_Version}"/bin/pear config-set temp_dir "${PHP_Version}/tmp" + "${PHP_Version}"/bin/phpize + ./configure --with-php-config="${PHP_Version}"/bin/php-config + make + make install + echo "extension=timezonedb.so" > "${PHP_Version}/etc/php.d/20-timezone.ini" + make clean + sed -i 's|expose_php = On|expose_php = Off|g' "$PHP_INI_Path" + sed -i 's|mail.add_x_header = On|mail.add_x_header = Off|g' "$PHP_INI_Path" + else + "${PHP_Version}"/bin/phpize + ./configure --with-php-config="${PHP_Version}"/bin/php-config + make + make install + echo "extension=timezonedb.so" > "/usr/local/lsws/${PHP_Version: 16:7}/etc/php/${PHP_Version: 21:1}.${PHP_Version: 22:1}/mods-available/20-timezone.ini" + make clean + sed -i 's|expose_php = On|expose_php = Off|g' "$PHP_INI_Path" + sed -i 's|mail.add_x_header = On|mail.add_x_header = Off|g' "$PHP_INI_Path" + fi + done +rm -rf /usr/local/lsws/cyberpanel-tmp +cd "$Current_Dir" || exit +Debug_Log2 "Installing timezoneDB...,95" +} + +Post_Install_Regenerate_Webadmin_Console_Passwd() { +if [[ "$Server_Edition" = "OLS" ]]; then + PHP_Command="admin_php" +else + PHP_Command="admin_php5" +fi + +Webadmin_Pass=$( + head /dev/urandom | tr -dc A-Za-z0-9 | head -c 16 + echo '' + ) + +Encrypt_string=$(/usr/local/lsws/admin/fcgi-bin/${PHP_Command} /usr/local/lsws/admin/misc/htpasswd.php "${Webadmin_Pass}") +echo "" >/usr/local/lsws/admin/conf/htpasswd +echo "admin:$Encrypt_string" > /usr/local/lsws/admin/conf/htpasswd +chown lsadm:lsadm /usr/local/lsws/admin/conf/htpasswd +chmod 600 /usr/local/lsws/admin/conf/htpasswd +echo "${Webadmin_Pass}" >/etc/cyberpanel/webadmin_passwd +chmod 600 /etc/cyberpanel/webadmin_passwd +} + +Post_Install_Setup_Watchdog() { +if [[ "$Watchdog" = "On" ]]; then + wget -O /etc/cyberpanel/watchdog.sh "${Git_Content_URL}/stable/CPScripts/watchdog.sh" + chmod 700 /etc/cyberpanel/watchdog.sh + ln -s /etc/cyberpanel/watchdog.sh /usr/local/bin/watchdog + #shellcheck disable=SC2009 + pid=$(ps aux | grep "watchdog lsws" | grep -v grep | awk '{print $2}') + if [[ $pid = "" ]]; then + nohup watchdog lsws >/dev/null 2>&1 & + fi + echo -e "Checking MariaDB ..." + #shellcheck disable=SC2009 + pid=$(ps aux | grep "watchdog mariadb" | grep -v grep | awk '{print $2}') + if [[ $pid = "" ]]; then + nohup watchdog mariadb >/dev/null 2>&1 & + fi + + if [[ "$Server_OS" = "CentOS" ]]; then + echo "nohup watchdog lsws > /dev/null 2>&1 & +nohup watchdog mariadb > /dev/null 2>&1 &" >>/etc/rc.d/rc.local + else + echo "nohup watchdog lsws > /dev/null 2>&1 & +nohup watchdog mariadb > /dev/null 2>&1 &" >>/etc/rc.local + fi + echo -e "\nSetting up WatchDog..." +fi +} + +Post_Install_Setup_Utility() { +if [[ ! -f /usr/bin/cyberpanel_utility ]]; then + wget -q -O /usr/bin/cyberpanel_utility https://cyberpanel.sh/misc/cyberpanel_utility.sh + chmod 700 /usr/bin/cyberpanel_utility +fi +} + +Post_Install_Display_Final_Info() { +RainloopAdminPass=$(grep SetPassword /usr/local/CyberCP/public/rainloop.php| sed -e 's|$oConfig->SetPassword(||g' -e "s|');||g" -e "s|'||g") +Elapsed_Time="$((Time_Count / 3600)) hrs $(((SECONDS / 60) % 60)) min $((Time_Count % 60)) sec" +echo "###################################################################" +echo " CyberPanel Successfully Installed " +echo " " +echo " Current Disk usage : $(df -h | awk '$NF=="/"{printf "%d/%dGB (%s)\n", $3,$2,$5}') " +echo " " +echo " Current RAM usage : $(free -m | awk 'NR==2{printf "%s/%sMB (%.2f%%)\n", $3,$2,$3*100/$2 }') " +echo " " +echo " Installation time : $Elapsed_Time " +echo " " +echo " Visit: https://$Server_IP:8090 " +echo " Panel username: admin " +if [[ "$Custom_Pass" = "True" ]]; then +echo " Panel password: ***** " +else +echo " Panel password: $Admin_Pass " +fi +#echo " Visit: https://$Server_IP:7080 " +#echo " WebAdmin console username: admin " +#echo " WebAdmin console password: $Webadmin_Pass " +#echo " " +#echo " Visit: https://$Server_IP:8090/rainloop/?admin " +#echo " Rainloop Admin username: admin " +#echo " Rainloop Admin password: $RainloopAdminPass " +echo " " +echo -e " Run \e[31mcyberpanel help\e[39m to get FAQ info" +echo -e " Run \e[31mcyberpanel upgrade\e[39m to upgrade it to latest version." +echo -e " Run \e[31mcyberpanel utility\e[39m to access some handy tools ." +echo " " +echo " Website : https://www.cyberpanel.net " +echo " Forums : https://forums.cyberpanel.net " +echo " Wikipage: https://docs.cyberpanel.net " +echo " Docs : https://cyberpanel.net/docs/ " +echo " " +echo -e " Enjoy your accelerated Internet by " +echo -e " CyberPanel & $Word " +echo "###################################################################" + +if [[ "$Server_Provider" != "Undefined" ]]; then + echo -e "\033[0;32m$Server_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 ! timeout 3 telnet mx.zoho.com 25 | grep "Escape" >/dev/null 2>&1; then + echo -e "Your provider seems \e[31mblocked\033[39m port 25 , E-mail sending may \e[31mnot\033[39m work properly." +fi + +Debug_Log2 "Completed [200]" + +if [[ "$Silent" != "On" ]]; then + printf "%s" "Would you like to restart your server now? [y/N]: " + read -r Tmp_Input + + if [[ "${Tmp_Input^^}" = *Y* ]] ; then + reboot + fi +fi + +} + + +Post_Install_Regenerate_Cert() { +cat </root/cyberpanel/cert_conf +[req] +prompt=no +distinguished_name=cyberpanel +[cyberpanel] +commonName = www.example.com +countryName = CP +localityName = CyberPanel +organizationName = CyberPanel +organizationalUnitName = CyberPanel +stateOrProvinceName = CP +emailAddress = mail@example.com +name = CyberPanel +surname = CyberPanel +givenName = CyberPanel +initials = CP +dnQualifier = CyberPanel +[server_exts] +extendedKeyUsage = 1.3.6.1.5.5.7.3.1 +EOF +openssl req -x509 -config /root/cyberpanel/cert_conf -extensions 'server_exts' -nodes -days 820 -newkey rsa:2048 -keyout /usr/local/lscp/conf/key.pem -out /usr/local/lscp/conf/cert.pem + +if [[ "$Server_Edition" = "OLS" ]]; then + Key_Path="/usr/local/lsws/admin/conf/webadmin.key" + Cert_Path="/usr/local/lsws/admin/conf/webadmin.crt" +else + Key_Path="/usr/local/lsws/admin/conf/cert/admin.key" + Cert_Path="/usr/local/lsws/admin/conf/cert/admin.crt" +fi +openssl req -x509 -config /root/cyberpanel/cert_conf -extensions 'server_exts' -nodes -days 820 -newkey rsa:2048 -keyout "$Key_Path" -out "$Cert_Path" +rm -f /root/cyberpanel/cert_conf +} + +Post_Install_Required_Components() { +Debug_Log2 "Finalization..,80" +virtualenv -p /usr/bin/python3 /usr/local/CyberCP + +if [[ "$Server_OS" = "Ubuntu" ]] && [[ "$Server_OS_Version" = "20" ]] ; then + # shellcheck disable=SC1091 + . /usr/local/CyberCP/bin/activate + Check_Return +else + # shellcheck disable=SC1091 + source /usr/local/CyberCP/bin/activate + Check_Return + +fi + +Retry_Command "pip install --default-timeout=3600 -r /usr/local/requirments.txt" + Check_Return "requirments.txt" "no_exit" + +chown -R cyberpanel:cyberpanel /usr/local/CyberCP/lib +chown -R cyberpanel:cyberpanel /usr/local/CyberCP/lib64 || true +} + +Pre_Install_Setup_Git_URL() { +if [[ $Server_Country != "CN" ]] ; then + Git_User="usmannasir" + Git_Content_URL="https://raw.githubusercontent.com/${Git_User}/cyberpanel" + Git_Clone_URL="https://github.com/${Git_User}/cyberpanel.git" +else + Git_User="qtwrk" + Git_Content_URL="https://gitee.com/${Git_User}/cyberpanel/raw" + Git_Clone_URL="https://gitee.com/${Git_User}/cyberpanel.git" +fi + +if [[ "$Debug" = "On" ]] ; then + Debug_Log "Git_URL" "$Git_Content_URL" +fi +} + +Post_Install_Tweak() { +if [[ -d /etc/pure-ftpd/conf ]]; then + echo "yes" >/etc/pure-ftpd/conf/ChrootEveryone + systemctl restart pure-ftpd-mysql +fi + +if [[ -f /etc/pure-ftpd/pure-ftpd.conf ]]; then + sed -i 's|NoAnonymous no|NoAnonymous yes|g' /etc/pure-ftpd/pure-ftpd.conf +fi + +sed -i "s|lsws-5.3.8|lsws-$LSWS_Stable_Version|g" /usr/local/CyberCP/serverStatus/serverStatusUtil.py +sed -i "s|lsws-5.4.2|lsws-$LSWS_Stable_Version|g" /usr/local/CyberCP/serverStatus/serverStatusUtil.py +sed -i "s|lsws-5.3.5|lsws-$LSWS_Stable_Version|g" /usr/local/CyberCP/serverStatus/serverStatusUtil.py + + +if [[ ! -f /usr/bin/cyberpanel_utility ]]; then + wget -q -O /usr/bin/cyberpanel_utility https://cyberpanel.sh/misc/cyberpanel_utility.sh + chmod 700 /usr/bin/cyberpanel_utility +fi + +rm -rf /etc/profile.d/cyberpanel* +curl --silent -o /etc/profile.d/cyberpanel.sh https://cyberpanel.sh/?banner 2>/dev/null +chmod 700 /etc/profile.d/cyberpanel.sh +echo "$Admin_Pass" > /etc/cyberpanel/adminPass +chmod 600 /etc/cyberpanel/adminPass +/usr/local/CyberPanel/bin/python /usr/local/CyberCP/plogical/adminPass.py --password "$Admin_Pass" +mkdir -p /etc/opendkim + +echo '/usr/local/CyberPanel/bin/python /usr/local/CyberCP/plogical/adminPass.py --password $@' > /usr/bin/adminPass +echo "systemctl restart lscpd" >> /usr/bin/adminPass +chmod 700 /usr/bin/adminPass + +rm -f /usr/bin/php +ln -s /usr/local/lsws/lsphp74/bin/php /usr/bin/php + +if [[ "$Server_OS" = "CentOS" ]] ; then +#all centos7/8 post change goes here + + sed -i 's|error_reporting = E_ALL \& ~E_DEPRECATED \& ~E_STRICT|error_reporting = E_ALL \& ~E_DEPRECATED \& ~E_STRICT|g' /usr/local/lsws/{lsphp72,lsphp73}/etc/php.ini +#fix php.ini & issue + sed -i 's|/usr/local/lsws/bin/lswsctrl restart|systemctl restart lsws|g' /var/spool/cron/root + + if [[ "$Server_OS_Version" = "7" ]] ; then + #all centos 7 specific post change goes here + if ! yum list installed lsphp74-devel ; then + yum install -y lsphp74-devel + fi + if [[ ! -f /usr/local/lsws/lsphp74/lib64/php/modules/zip.so ]] ; then + if yum list installed libzip-devel >/dev/null 2>&1 ; then + yum remove -y libzip-devel + fi + yum install -y https://cyberpanel.sh/misc/libzip-0.11.2-6.el7.psychotic.x86_64.rpm + yum install -y https://cyberpanel.sh/misc/libzip-devel-0.11.2-6.el7.psychotic.x86_64.rpm + yum install lsphp74-devel + if [[ ! -d /usr/local/lsws/lsphp74/tmp ]]; then + mkdir /usr/local/lsws/lsphp74/tmp + fi + /usr/local/lsws/lsphp74/bin/pecl channel-update pecl.php.net + /usr/local/lsws/lsphp74/bin/pear config-set temp_dir /usr/local/lsws/lsphp74/tmp + if /usr/local/lsws/lsphp74/bin/pecl install zip ; then + echo "extension=zip.so" >/usr/local/lsws/lsphp74/etc/php.d/20-zip.ini + chmod 755 /usr/local/lsws/lsphp74/lib64/php/modules/zip.so + else + echo -e "\nlsphp74-zip compilation failed..." + fi + #fix compile lsphp74-zip on centos 7 + fi + fi + + if [[ "$Server_OS_Version" = "8" ]] ; then + #all centos 8 specific post change goes here + : + fi + +elif [[ "$Server_OS" = "Ubuntu" ]] ; then +#all ubuntu18/20 post change goes here + + sed -i 's|/usr/local/lsws/bin/lswsctrl restart|systemctl restart lsws|g' /var/spool/cron/crontabs/root + + if [[ ! -f /usr/sbin/ipset ]] ; then + ln -s /sbin/ipset /usr/sbin/ipset + fi + + if [[ "$Server_OS_Version" = "18" ]] ; then + #all ubuntu 18 specific post change goes here + : + fi + + if [[ "$Server_OS_Version" = "20" ]] ; then + #all ubuntu 20 specific post change goes here + : + fi + +fi + + +if [[ "$Server_Edition" = "OLS" ]]; then + Word="OpenLiteSpeed" +else + Word="LiteSpeed Enterprise" + sed -i 's|Include /usr/local/lsws/conf/rules.conf||g' /usr/local/lsws/conf/modsec.conf +fi + +systemctl restart lscpd >/dev/null 2>&1 +/usr/local/lsws/bin/lswsctrl stop >/dev/null 2>&1 +systemctl stop lsws >/dev/null 2>&1 +systemctl start lsws >/dev/null 2>&1 +echo -e "\nFinalizing...\n" +echo -e "Cleaning up...\n" +rm -rf /root/cyberpanel + +if [[ "$Server_Country" = "CN" ]] ; then +Post_Install_CN_Replacement +fi + +# If valid hostname is set that resolves externally we can issue an ssl. This will create the hostname as a website so we can issue the SSL and do our first login without SSL warnings or exceptions needed. +HostName=$(hostname --fqdn); [ -n "$(dig @1.1.1.1 +short "$HostName")" ] && echo "$HostName resolves to valid IP. Setting up hostname SSL" && cyberpanel createWebsite --package Default --owner admin --domainName $(hostname --fqdn) --email root@localhost --php 7.4 && cyberpanel hostNameSSL --domainName $(hostname --fqdn) + + +} + +Post_Install_CN_Replacement() { +sed -i 's|wp core download|wp core download https://cyberpanel.sh/wordpress.org/latest.tar.gz|g' /usr/local/CyberCP/plogical/applicationInstaller.py +sed -i 's|https://raw.githubusercontent.com/|https://cyberpanel.sh/raw.githubusercontent.com/|g' /usr/local/CyberCP/plogical/applicationInstaller.py +sed -i 's|wp plugin install litespeed-cache|wp plugin install https://cyberpanel.sh/downloads.wordpress.org/plugin/litespeed-cache.zip|g' /usr/local/CyberCP/plogical/applicationInstaller.py + +sed -i 's|https://www.litespeedtech.com/|https://cyberpanel.sh/www.litespeedtech.com/|g' /usr/local/CyberCP/serverStatus/serverStatusUtil.py +sed -i 's|http://license.litespeedtech.com/|https://cyberpanel.sh/license.litespeedtech.com/|g' /usr/local/CyberCP/serverStatus/serverStatusUtil.py +} + +echo -e "\nInitializing...\n" + +if [[ "$*" = *"--debug"* ]] ; then + Debug="On" + find /var/log -name 'cyberpanel_debug_*' -exec rm {} + + Random_Log_Name=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 5) + echo -e "$(date)" > "/var/log/cyberpanel_debug_$(date +"%Y-%m-%d")_${Random_Log_Name}.log" + chmod 600 "/var/log/cyberpanel_debug_$(date +"%Y-%m-%d")_${Random_Log_Name}.log" +fi + +Set_Default_Variables + +Check_Root + +Check_Server_IP "$@" + +Check_OS + +Check_Virtualization + +Check_Panel + +Check_Process + +Check_Provider + +Check_Argument "$@" + +if [[ $Silent = "On" ]]; then + Argument_Mode +else + Interactive_Mode +fi + +Time_Count="0" + +Pre_Install_Setup_Repository + +Pre_Install_Setup_Git_URL + +Pre_Install_Required_Components + +Pre_Install_System_Tweak + +Main_Installation +#Python install in here + +if [[ "$Memcached" = "On" ]] ; then + Post_Install_Addon_Memcached +fi + +if [[ "$Redis" = "On" ]] ; then + Post_Install_Addon_Redis +fi + +Post_Install_Required_Components + +Post_Install_PHP_Session_Setup + +Post_Install_PHP_TimezoneDB + +Post_Install_Regenerate_Cert + +Post_Install_Regenerate_Webadmin_Console_Passwd + +Post_Install_Setup_Watchdog + +Post_Install_Setup_Utility + +Post_Install_Tweak + +Post_Install_Display_Final_Info diff --git a/install/filesPermsUtilities.py b/install/filesPermsUtilities.py index 07261326b..3856fb61b 100644 --- a/install/filesPermsUtilities.py +++ b/install/filesPermsUtilities.py @@ -119,7 +119,7 @@ def recursive_permissions(path, dir_mode=755, file_mode=644, topdir=True): # 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') +# recursive_chown('/usr/local/lscp/cyberpanel/snappymail/data', -1, 'lscpd') # explicitly set permissions for directories/folders to 0755 and files to 0644 # recursive_permissions(my_path, 755, 644) diff --git a/install/filesPermsUtilities.py.bak b/install/filesPermsUtilities.py.bak new file mode 100644 index 000000000..07261326b --- /dev/null +++ b/install/filesPermsUtilities.py.bak @@ -0,0 +1,190 @@ +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 5f3f0e5fc..5a058e6d6 100755 --- a/install/install.py +++ b/install/install.py @@ -546,7 +546,7 @@ password="%s" 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" + command = "chown -R lscpd:lscpd /usr/local/lscp/cyberpanel/snappymail/data" preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) command = "chmod 700 /usr/local/CyberCP/cli/cyberPanel.py" @@ -648,11 +648,11 @@ password="%s" 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/' + command = 'mkdir -p/usr/local/lscp/cyberpanel/snappymail/data/_data_/_default_/configs/' - rainloopinipath = '/usr/local/lscp/cyberpanel/rainloop/data/_data_/_default_/configs/application.ini' + snappymailinipath = '/usr/local/lscp/cyberpanel/snappymail/data/_data_/_default_/configs/application.ini' - command = 'chmod 600 /usr/local/CyberCP/public/rainloop.php' + command = 'chmod 600 /usr/local/CyberCP/public/snappymail.php' preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) ### @@ -1236,24 +1236,24 @@ $cfg['Servers'][$i]['LogoutURL'] = 'phpmyadminsignin.php?logout'; if not os.path.exists("/usr/local/CyberCP/public"): os.mkdir("/usr/local/CyberCP/public") - if os.path.exists("/usr/local/CyberCP/public/rainloop"): + if os.path.exists("/usr/local/CyberCP/public/snappymail"): return 0 os.chdir("/usr/local/CyberCP/public") - command = 'wget https://www.rainloop.net/repository/webmail/rainloop-community-latest.zip' + command = 'wget https://snappymail.eu/repository/latest.tar.gz' preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR) ############# - command = 'unzip rainloop-community-latest.zip -d /usr/local/CyberCP/public/rainloop' + command = 'unzip latest.tar.gz -d /usr/local/CyberCP/public/snappymail' preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR) - os.remove("rainloop-community-latest.zip") + os.remove("latest.tar.gz") ####### - os.chdir("/usr/local/CyberCP/public/rainloop") + os.chdir("/usr/local/CyberCP/public/snappymail") command = 'find . -type d -exec chmod 755 {} \;' preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) @@ -1265,15 +1265,15 @@ $cfg['Servers'][$i]['LogoutURL'] = 'phpmyadminsignin.php?logout'; ###### - command = "mkdir -p /usr/local/lscp/cyberpanel/rainloop/data" + command = "mkdir -p /usr/local/lscp/cyberpanel/snappymail/data" preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) ### Enable sub-folders - command = "mkdir -p /usr/local/lscp/cyberpanel/rainloop/data/_data_/_default_/configs/" + command = "mkdir -p /usr/local/lscp/cyberpanel/snappymail/data/_data_/_default_/configs/" preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) - labsPath = '/usr/local/lscp/cyberpanel/rainloop/data/_data_/_default_/configs/application.ini' + labsPath = '/usr/local/lscp/cyberpanel/snappymail/data/_data_/_default_/configs/application.ini' labsData = """[labs] imap_folder_list_limit = 0 @@ -1283,9 +1283,9 @@ imap_folder_list_limit = 0 writeToFile.write(labsData) writeToFile.close() - iPath = os.listdir('/usr/local/CyberCP/public/rainloop/rainloop/v/') + iPath = os.listdir('/usr/local/CyberCP/public/snappymail/snappymail/v/') - path = "/usr/local/CyberCP/public/rainloop/rainloop/v/%s/include.php" % (iPath[0]) + path = "/usr/local/CyberCP/public/snappymail/snappymail/v/%s/include.php" % (iPath[0]) data = open(path, 'r').readlines() writeToFile = open(path, 'w') @@ -1293,14 +1293,14 @@ imap_folder_list_limit = 0 for items in data: if items.find("$sCustomDataPath = '';") > -1: writeToFile.writelines( - " $sCustomDataPath = '/usr/local/lscp/cyberpanel/rainloop/data';\n") + " $sCustomDataPath = '/usr/local/lscp/cyberpanel/snappymail/data';\n") else: writeToFile.writelines(items) writeToFile.close() except BaseException as msg: - logging.InstallLog.writeToFile('[ERROR] ' + str(msg) + " [downoad_and_install_rainloop]") + logging.InstallLog.writeToFile('[ERROR] ' + str(msg) + " [downoad_and_install_snappymail]") return 0 return 1 @@ -2337,10 +2337,10 @@ def main(): # checks.disablePackegeUpdates() try: - # command = 'mkdir -p /usr/local/lscp/cyberpanel/rainloop/data/data/default/configs/' + # command = 'mkdir -p /usr/local/lscp/cyberpanel/snappymail/data/data/default/configs/' # subprocess.call(shlex.split(command)) - writeToFile = open('/usr/local/lscp/cyberpanel/rainloop/data/_data_/_default_/configs/application.ini', 'a') + writeToFile = open('/usr/local/lscp/cyberpanel/snappymail/data/_data_/_default_/configs/application.ini', 'a') writeToFile.write(""" [security] @@ -2353,23 +2353,23 @@ admin_password = "12345" content = """SetPassword('%s'); echo $oConfig->Save() ? 'Done' : 'Error'; ?>""" % (randomPassword.generate_pass()) - writeToFile = open('/usr/local/CyberCP/public/rainloop.php', 'w') + writeToFile = open('/usr/local/CyberCP/public/snappymail.php', 'w') writeToFile.write(content) writeToFile.close() - command = '/usr/local/lsws/lsphp72/bin/php /usr/local/CyberCP/public/rainloop.php' + command = '/usr/local/lsws/lsphp72/bin/php /usr/local/CyberCP/public/snappymail.php' subprocess.call(shlex.split(command)) - command = "chown -R lscpd:lscpd /usr/local/lscp/cyberpanel/rainloop/data" + command = "chown -R lscpd:lscpd /usr/local/lscp/cyberpanel/snappymail/data" subprocess.call(shlex.split(command)) except: pass diff --git a/install/install.py.bak b/install/install.py.bak new file mode 100644 index 000000000..5f3f0e5fc --- /dev/null +++ b/install/install.py.bak @@ -0,0 +1,2383 @@ +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.org/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/venvsetup.sh b/install/venvsetup.sh index b32d97fe7..0bc90cf9a 100644 --- a/install/venvsetup.sh +++ b/install/venvsetup.sh @@ -86,7 +86,7 @@ if [[ $SERVER_COUNTRY == "CN" ]] ; then #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|https://snappymail.eu/repository/latest.tar.gz|https://'$DOWNLOAD_SERVER'/repository/latest.tar.gz|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 diff --git a/install/venvsetup.sh.bak b/install/venvsetup.sh.bak new file mode 100644 index 000000000..b32d97fe7 --- /dev/null +++ b/install/venvsetup.sh.bak @@ -0,0 +1,1290 @@ +#!/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=noninteracitve 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://docs.cyberpanel.net " +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 b/mailServer/mailserverManager.py index dc26fef9c..17315f840 100755 --- a/mailServer/mailserverManager.py +++ b/mailServer/mailserverManager.py @@ -1475,7 +1475,7 @@ milter_default_action = accept command = "chown -R root:root /usr/local/lscp" ProcessUtilities.executioner(command) - command = "chown -R lscpd:lscpd /usr/local/lscp/cyberpanel/rainloop/data" + command = "chown -R lscpd:lscpd /usr/local/lscp/cyberpanel/snappymail/data" ProcessUtilities.executioner(command) command = "chmod 700 /usr/local/CyberCP/cli/cyberPanel.py" diff --git a/mailServer/mailserverManager.py.bak b/mailServer/mailserverManager.py.bak new file mode 100644 index 000000000..dc26fef9c --- /dev/null +++ b/mailServer/mailserverManager.py.bak @@ -0,0 +1,1713 @@ +#!/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.org/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 b/mailServer/templates/mailServer/index.html index 240fd02d9..e0f619981 100755 --- a/mailServer/templates/mailServer/index.html +++ b/mailServer/templates/mailServer/index.html @@ -96,7 +96,7 @@
    -
    {% trans "Access Webmail" %} diff --git a/mailServer/templates/mailServer/index.html.bak b/mailServer/templates/mailServer/index.html.bak new file mode 100644 index 000000000..e0f619981 --- /dev/null +++ b/mailServer/templates/mailServer/index.html.bak @@ -0,0 +1,121 @@ +{% extends "baseTemplate/index.html" %} +{% load i18n %} +{% block title %}{% trans "Mail Functions - CyberPanel" %}{% endblock %} +{% block content %} + + {% load static %} + {% get_current_language as LANGUAGE_CODE %} + + + + + +{% endblock %} diff --git a/phpmyadmin.zip b/phpmyadmin.zip index 729b5389d..65b7e289a 100644 Binary files a/phpmyadmin.zip and b/phpmyadmin.zip differ diff --git a/plogical/filesPermsUtilities.py b/plogical/filesPermsUtilities.py index 8e71af9aa..9070e5c33 100644 --- a/plogical/filesPermsUtilities.py +++ b/plogical/filesPermsUtilities.py @@ -119,7 +119,7 @@ def recursive_permissions(path, dir_mode=755, file_mode=644, topdir=True): # 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') +# recursive_chown('/usr/local/lscp/cyberpanel/snappymail/data', -1, 'lscpd') # explicitly set permissions for directories/folders to 0755 and files to 0644 # recursive_permissions(my_path, 755, 644) diff --git a/plogical/filesPermsUtilities.py.bak b/plogical/filesPermsUtilities.py.bak new file mode 100644 index 000000000..8e71af9aa --- /dev/null +++ b/plogical/filesPermsUtilities.py.bak @@ -0,0 +1,190 @@ +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/upgrade.py b/plogical/upgrade.py index 7ac13c973..ae82dba27 100755 --- a/plogical/upgrade.py +++ b/plogical/upgrade.py @@ -366,20 +366,20 @@ $cfg['Servers'][$i]['LogoutURL'] = 'phpmyadminsignin.php?logout'; try: ####### - if os.path.exists("/usr/local/CyberCP/public/rainloop"): + if os.path.exists("/usr/local/CyberCP/public/snappymail"): - if os.path.exists("/usr/local/lscp/cyberpanel/rainloop/data"): + if os.path.exists("/usr/local/lscp/cyberpanel/snappymail/data"): pass else: - command = "mv /usr/local/CyberCP/public/rainloop/data /usr/local/lscp/cyberpanel/rainloop/data" + 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/rainloop/data" + command = "chown -R lscpd:lscpd /usr/local/lscp/cyberpanel/snappymail/data" Upgrade.executioner(command, 0) - iPath = os.listdir('/usr/local/CyberCP/public/rainloop/rainloop/v/') + iPath = os.listdir('/usr/local/CyberCP/public/snappymail/snappymail/v/') - path = "/usr/local/CyberCP/public/rainloop/rainloop/v/%s/include.php" % (iPath[0]) + path = "/usr/local/CyberCP/public/snappymail/snappymail/v/%s/include.php" % (iPath[0]) data = open(path, 'r').readlines() writeToFile = open(path, 'w') @@ -387,7 +387,7 @@ $cfg['Servers'][$i]['LogoutURL'] = 'phpmyadminsignin.php?logout'; for items in data: if items.find("$sCustomDataPath = '';") > -1: writeToFile.writelines( - " $sCustomDataPath = '/usr/local/lscp/cyberpanel/rainloop/data';\n") + " $sCustomDataPath = '/usr/local/lscp/cyberpanel/snappymail/data';\n") else: writeToFile.writelines(items) @@ -404,7 +404,7 @@ $cfg['Servers'][$i]['LogoutURL'] = 'phpmyadminsignin.php?logout'; count = 1 while (1): - command = 'wget https://www.rainloop.net/repository/webmail/rainloop-community-latest.zip' + command = 'wget https://www.snappymail.net/repository/webmail/snappymail-community-latest.zip' cmd = shlex.split(command) res = subprocess.call(cmd) if res != 0: @@ -419,7 +419,7 @@ $cfg['Servers'][$i]['LogoutURL'] = 'phpmyadminsignin.php?logout'; count = 0 while (1): - command = 'unzip rainloop-community-latest.zip -d /usr/local/CyberCP/public/rainloop' + command = 'unzip snappymail-community-latest.zip -d /usr/local/CyberCP/public/snappymail' cmd = shlex.split(command) res = subprocess.call(cmd) @@ -430,11 +430,11 @@ $cfg['Servers'][$i]['LogoutURL'] = 'phpmyadminsignin.php?logout'; else: break - os.remove("rainloop-community-latest.zip") + os.remove("snappymail-community-latest.zip") ####### - os.chdir("/usr/local/CyberCP/public/rainloop") + os.chdir("/usr/local/CyberCP/public/snappymail") count = 0 @@ -465,9 +465,9 @@ $cfg['Servers'][$i]['LogoutURL'] = 'phpmyadminsignin.php?logout'; break ###### - iPath = os.listdir('/usr/local/CyberCP/public/rainloop/rainloop/v/') + iPath = os.listdir('/usr/local/CyberCP/public/snappymail/snappymail/v/') - path = "/usr/local/CyberCP/public/rainloop/rainloop/v/%s/include.php" % (iPath[0]) + path = "/usr/local/CyberCP/public/snappymail/snappymail/v/%s/include.php" % (iPath[0]) data = open(path, 'r').readlines() writeToFile = open(path, 'w') @@ -475,16 +475,16 @@ $cfg['Servers'][$i]['LogoutURL'] = 'phpmyadminsignin.php?logout'; for items in data: if items.find("$sCustomDataPath = '';") > -1: writeToFile.writelines( - " $sCustomDataPath = '/usr/local/lscp/cyberpanel/rainloop/data';\n") + " $sCustomDataPath = '/usr/local/lscp/cyberpanel/snappymail/data';\n") else: writeToFile.writelines(items) writeToFile.close() - command = "mkdir -p /usr/local/lscp/cyberpanel/rainloop/data/_data_/_default_/configs/" - Upgrade.executioner(command, 'mkdir rainloop configs', 0) + command = "mkdir -p /usr/local/lscp/cyberpanel/snappymail/data/_data_/_default_/configs/" + Upgrade.executioner(command, 'mkdir snappymail configs', 0) - labsPath = '/usr/local/lscp/cyberpanel/rainloop/data/_data_/_default_/configs/application.ini' + labsPath = '/usr/local/lscp/cyberpanel/snappymail/data/_data_/_default_/configs/application.ini' labsData = """[labs] imap_folder_list_limit = 0 @@ -1906,20 +1906,20 @@ imap_folder_list_limit = 0 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/rainloop.php', 'w') + writeToFile = open('/usr/local/CyberCP/public/snappymail.php', 'w') writeToFile.write(content) writeToFile.close() - command = "chown -R lscpd:lscpd /usr/local/lscp/cyberpanel/rainloop/data" + command = "chown -R lscpd:lscpd /usr/local/lscp/cyberpanel/snappymail/data" subprocess.call(shlex.split(command)) except: @@ -1971,7 +1971,7 @@ echo $oConfig->Save() ? 'Done' : 'Error'; command = "chown -R root:root /usr/local/lscp" Upgrade.executioner(command, 'chown core code', 0) - command = "chown -R lscpd:lscpd /usr/local/lscp/cyberpanel/rainloop/data" + 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" @@ -2079,10 +2079,10 @@ echo $oConfig->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/rainloop.php' + command = '/usr/local/lsws/lsphp72/bin/php /usr/local/CyberCP/public/snappymail.php' Upgrade.executioner(command, 0) - command = 'chmod 600 /usr/local/CyberCP/public/rainloop.php' + command = 'chmod 600 /usr/local/CyberCP/public/snappymail.php' Upgrade.executioner(command, 0) ### diff --git a/plogical/upgrade.py.bak b/plogical/upgrade.py.bak new file mode 100644 index 000000000..7ac13c973 --- /dev/null +++ b/plogical/upgrade.py.bak @@ -0,0 +1,2696 @@ +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/rainloop"): + + if os.path.exists("/usr/local/lscp/cyberpanel/rainloop/data"): + pass + else: + command = "mv /usr/local/CyberCP/public/rainloop/data /usr/local/lscp/cyberpanel/rainloop/data" + Upgrade.executioner(command, 0) + + command = "chown -R lscpd:lscpd /usr/local/lscp/cyberpanel/rainloop/data" + Upgrade.executioner(command, 0) + + iPath = os.listdir('/usr/local/CyberCP/public/rainloop/rainloop/v/') + + path = "/usr/local/CyberCP/public/rainloop/rainloop/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/rainloop/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.rainloop.net/repository/webmail/rainloop-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 rainloop-community-latest.zip -d /usr/local/CyberCP/public/rainloop' + + cmd = shlex.split(command) + res = subprocess.call(cmd) + if res != 0: + count = count + 1 + if count == 3: + break + else: + break + + os.remove("rainloop-community-latest.zip") + + ####### + + os.chdir("/usr/local/CyberCP/public/rainloop") + + 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/rainloop/rainloop/v/') + + path = "/usr/local/CyberCP/public/rainloop/rainloop/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/rainloop/data';\n") + else: + writeToFile.writelines(items) + + writeToFile.close() + + command = "mkdir -p /usr/local/lscp/cyberpanel/rainloop/data/_data_/_default_/configs/" + Upgrade.executioner(command, 'mkdir rainloop configs', 0) + + labsPath = '/usr/local/lscp/cyberpanel/rainloop/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/rainloop.php', 'w') + writeToFile.write(content) + writeToFile.close() + + command = "chown -R lscpd:lscpd /usr/local/lscp/cyberpanel/rainloop/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/rainloop/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/rainloop.php' + Upgrade.executioner(command, 0) + + command = 'chmod 600 /usr/local/CyberCP/public/rainloop.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()