diff --git a/CPScripts/mailscannerinstaller.sh b/CPScripts/mailscannerinstaller.sh index da9a2490d..6e324a22b 100644 --- a/CPScripts/mailscannerinstaller.sh +++ b/CPScripts/mailscannerinstaller.sh @@ -2,22 +2,21 @@ #systemctl stop firewalld check_return() { -#check previous command result , 0 = ok , non-0 = something wrong. -if [[ $? -eq "0" ]] ; then - : -else - echo -e "\ncommand failed, exiting..." - exit -fi + #check previous command result , 0 = ok , non-0 = something wrong. + if [[ $? -eq "0" ]]; then + : + else + echo -e "\ncommand failed, exiting..." + exit + fi } -echo 'backup configs'; -cp /etc/dovecot/dovecot.conf /etc/dovecot/dovecot.conf-bak_$(date '+%Y-%m-%d_%H_%M:%S'); -cp /etc/postfix/master.cf /etc/postfix/master.cf-bak_$(date '+%Y-%m-%d_%H_%M:%S'); -cp /etc/postfix/main.cf /etc/postfix/main.cf-bak_$(date '+%Y-%m-%d_%H_%M:%S'); +echo 'backup configs' +cp /etc/dovecot/dovecot.conf /etc/dovecot/dovecot.conf-bak_$(date '+%Y-%m-%d_%H_%M:%S') +cp /etc/postfix/master.cf /etc/postfix/master.cf-bak_$(date '+%Y-%m-%d_%H_%M:%S') +cp /etc/postfix/main.cf /etc/postfix/main.cf-bak_$(date '+%Y-%m-%d_%H_%M:%S') cp /etc/dovecot/dovecot-sql.conf.ext /etc/dovecot/dovecot-sql.conf.ext-bak_$(date '+%Y-%m-%d_%H_%M:%S') - ZONE=$(firewall-cmd --get-default-zone) firewall-cmd --zone=$ZONE --add-port=4190/tcp --permanent systemctl stop firewalld @@ -27,167 +26,131 @@ csf -x MAILSCANNER=/etc/MailScanner -if [ -d $MAILSCANNER ];then - -echo "MailScanner found. If you wish to reinstall then remove the package and revert" -echo "Postfix back to its original config at /etc/postfix/main.cf and remove" -echo "/etc/MailScanner and /usr/share/MailScanner directories" -exit +if [ -d $MAILSCANNER ]; then + echo "MailScanner found. If you wish to reinstall then remove the package and revert" + echo "Postfix back to its original config at /etc/postfix/main.cf and remove" + echo "/etc/MailScanner and /usr/share/MailScanner directories" + exit fi -if [ -f /etc/os-release ];then -OS=$(head -1 /etc/os-release) -UBUNTUVERSION=$(sed '6q;d' /etc/os-release) -CENTOSVERSION=$(sed '5q;d' /etc/os-release) -CLNVERSION=$(sed '3q;d' /etc/os-release) -fi - -if [ "$CENTOSVERSION" = "VERSION_ID=\"7\"" ];then - -setenforce 0 -yum install -y perl yum-utils perl-CPAN -yum install -y gcc cpp perl bzip2 zip make patch automake rpm-build perl-Archive-Zip perl-Filesys-Df perl-OLE-Storage_Lite perl-Sys-Hostname-Long perl-Sys-SigAction perl-Net-CIDR perl-DBI perl-MIME-tools perl-DBD-SQLite binutils glibc-devel perl-Filesys-Df zlib unzip zlib-devel wget mlocate clamav "perl(DBD::mysql)" - -rpm -Uvh https://forensics.cert.org/centos/cert/7/x86_64/unrar-5.4.0-1.el7.x86_64.rpm -export PERL_MM_USE_DEFAULT=1 -curl -L https://cpanmin.us | perl - App::cpanminus -perl -MCPAN -e 'install Encoding::FixLatin' -perl -MCPAN -e 'install Digest::SHA1' -perl -MCPAN -e 'install Geo::IP' -perl -MCPAN -e 'install Razor2::Client::Agent' -perl -MCPAN -e 'install Net::Patricia' - -freshclam -v -DIR=/etc/mail/spamassassin - -if [ -d "$DIR" ]; then -sa-update - -else - -echo "Please install spamassassin through the CyberPanel interface before proceeding" - -exit -fi - -elif [ "$CENTOSVERSION" = "VERSION_ID=\"8\"" ];then - -setenforce 0 -yum install -y perl yum-utils perl-CPAN -dnf --enablerepo=powertools install -y perl-IO-stringy -dnf --enablerepo=PowerTools install -y perl-IO-stringy -yum install -y gcc cpp perl bzip2 zip make patch automake rpm-build perl-Archive-Zip perl-Filesys-Df perl-OLE-Storage_Lite perl-Net-CIDR perl-DBI perl-MIME-tools perl-DBD-SQLite binutils glibc-devel perl-Filesys-Df zlib unzip zlib-devel wget mlocate clamav clamav-update "perl(DBD::mysql)" - -rpm -Uvh https://forensics.cert.org/centos/cert/8/x86_64/unrar-5.4.0-1.el8.x86_64.rpm - -export PERL_MM_USE_DEFAULT=1 -curl -L https://cpanmin.us | perl - App::cpanminus - -perl -MCPAN -e 'install Encoding::FixLatin' -perl -MCPAN -e 'install Digest::SHA1' -perl -MCPAN -e 'install Geo::IP' -perl -MCPAN -e 'install Razor2::Client::Agent' -perl -MCPAN -e 'install Sys::Hostname::Long' -perl -MCPAN -e 'install Sys::SigAction' - - - -freshclam -v +### Check SpamAssasin before moving forward DIR=/etc/mail/spamassassin -if [ -d "$DIR" ]; then -sa-update - +if [ -d "$DIR" ]; then + sa-update else - -echo "Please install spamassassin through the CyberPanel interface before proceeding" - -exit + echo "Please install spamassassin through the CyberPanel interface before proceeding" + exit fi -elif [ "$CLNVERSION" = "ID=\"cloudlinux\"" ];then - -setenforce 0 -yum install -y perl yum-utils perl-CPAN -yum install -y gcc cpp perl bzip2 zip make patch automake rpm-build perl-Archive-Zip perl-Filesys-Df perl-OLE-Storage_Lite perl-Sys-Hostname-Long perl-Sys-SigAction perl-Net-CIDR perl-DBI perl-MIME-tools perl-DBD-SQLite binutils glibc-devel perl-Filesys-Df zlib unzip zlib-devel wget mlocate clamav "perl(DBD::mysql)" - -rpm -Uvh https://forensics.cert.org/centos/cert/7/x86_64/unrar-5.4.0-1.el7.x86_64.rpm -export PERL_MM_USE_DEFAULT=1 -curl -L https://cpanmin.us | perl - App::cpanminus -perl -MCPAN -e 'install Encoding::FixLatin' -perl -MCPAN -e 'install Digest::SHA1' -perl -MCPAN -e 'install Geo::IP' -perl -MCPAN -e 'install Razor2::Client::Agent' -perl -MCPAN -e 'install Net::Patricia' - -freshclam -v -DIR=/etc/mail/spamassassin - -if [ -d "$DIR" ]; then -sa-update - -else - -echo "Please install spamassassin through the CyberPanel interface before proceeding" - -exit +if [ -f /etc/os-release ]; then + OS=$(head -1 /etc/os-release) + UBUNTUVERSION=$(sed '6q;d' /etc/os-release) + CENTOSVERSION=$(sed '5q;d' /etc/os-release) + CLNVERSION=$(sed '3q;d' /etc/os-release) fi -elif [ "$OS" = "NAME=\"Ubuntu\"" ];then +if [ "$CENTOSVERSION" = "VERSION_ID=\"7\"" ]; then - apt-get install -y libmysqlclient-dev + setenforce 0 + yum install -y perl yum-utils perl-CPAN + yum install -y gcc cpp perl bzip2 zip make patch automake rpm-build perl-Archive-Zip perl-Filesys-Df perl-OLE-Storage_Lite perl-Sys-Hostname-Long perl-Sys-SigAction perl-Net-CIDR perl-DBI perl-MIME-tools perl-DBD-SQLite binutils glibc-devel perl-Filesys-Df zlib unzip zlib-devel wget mlocate clamav "perl(DBD::mysql)" - apt-get install -y cpanminus gcc perl bzip2 zip make patch automake rpm libarchive-zip-perl libfilesys-df-perl libole-storage-lite-perl libsys-hostname-long-perl libsys-sigaction-perl libregexp-common-net-cidr-perl libmime-tools-perl libdbd-sqlite3-perl binutils build-essential libfilesys-df-perl zlib1g unzip mlocate clamav libdbd-mysql-perl unrar libclamav-dev libclamav-client-perl libclamunrar9 + rpm -Uvh https://forensics.cert.org/centos/cert/7/x86_64/unrar-5.4.0-1.el7.x86_64.rpm + export PERL_MM_USE_DEFAULT=1 + curl -L https://cpanmin.us | perl - App::cpanminus + perl -MCPAN -e 'install Encoding::FixLatin' + perl -MCPAN -e 'install Digest::SHA1' + perl -MCPAN -e 'install Geo::IP' + perl -MCPAN -e 'install Razor2::Client::Agent' + perl -MCPAN -e 'install Net::Patricia' -cpanm Encoding::FixLatin -cpanm Digest::SHA1 -cpanm Geo::IP -cpanm Razor2::Client::Agent -cpanm Net::Patricia -cpanm Net::CIDR + freshclam -v -sudo systemctl stop clamav-freshclam.service +elif [ "$CENTOSVERSION" = "VERSION_ID=\"8\"" ]; then -freshclam + setenforce 0 + yum install -y perl yum-utils perl-CPAN + dnf --enablerepo=powertools install -y perl-IO-stringy + dnf --enablerepo=PowerTools install -y perl-IO-stringy + yum install -y gcc cpp perl bzip2 zip make patch automake rpm-build perl-Archive-Zip perl-Filesys-Df perl-OLE-Storage_Lite perl-Net-CIDR perl-DBI perl-MIME-tools perl-DBD-SQLite binutils glibc-devel perl-Filesys-Df zlib unzip zlib-devel wget mlocate clamav clamav-update "perl(DBD::mysql)" -sudo systemctl start clamav-freshclam.service + rpm -Uvh https://forensics.cert.org/centos/cert/8/x86_64/unrar-5.4.0-1.el8.x86_64.rpm -DIR=/etc/spamassassin -if [ -d "$DIR" ]; then + export PERL_MM_USE_DEFAULT=1 + curl -L https://cpanmin.us | perl - App::cpanminus -apt-get -y install razor pyzor libencode-detect-perl libgeo-ip-perl libnet-patricia-perl -sa-update -else -echo "Please install spamassassin through the CyberPanel interface before proceeding" -exit -fi + perl -MCPAN -e 'install Encoding::FixLatin' + perl -MCPAN -e 'install Digest::SHA1' + perl -MCPAN -e 'install Geo::IP' + perl -MCPAN -e 'install Razor2::Client::Agent' + perl -MCPAN -e 'install Sys::Hostname::Long' + perl -MCPAN -e 'install Sys::SigAction' + + freshclam -v + +elif [ "$CLNVERSION" = "ID=\"cloudlinux\"" ]; then + + setenforce 0 + yum install -y perl yum-utils perl-CPAN + yum install -y gcc cpp perl bzip2 zip make patch automake rpm-build perl-Archive-Zip perl-Filesys-Df perl-OLE-Storage_Lite perl-Sys-Hostname-Long perl-Sys-SigAction perl-Net-CIDR perl-DBI perl-MIME-tools perl-DBD-SQLite binutils glibc-devel perl-Filesys-Df zlib unzip zlib-devel wget mlocate clamav "perl(DBD::mysql)" + + rpm -Uvh https://forensics.cert.org/centos/cert/7/x86_64/unrar-5.4.0-1.el7.x86_64.rpm + export PERL_MM_USE_DEFAULT=1 + curl -L https://cpanmin.us | perl - App::cpanminus + perl -MCPAN -e 'install Encoding::FixLatin' + perl -MCPAN -e 'install Digest::SHA1' + perl -MCPAN -e 'install Geo::IP' + perl -MCPAN -e 'install Razor2::Client::Agent' + perl -MCPAN -e 'install Net::Patricia' + + freshclam -v + +elif [ "$OS" = "NAME=\"Ubuntu\"" ]; then + + apt-get install -y libmysqlclient-dev + + apt-get install -y cpanminus gcc perl bzip2 zip make patch automake rpm libarchive-zip-perl libfilesys-df-perl libole-storage-lite-perl libsys-hostname-long-perl libsys-sigaction-perl libregexp-common-net-cidr-perl libmime-tools-perl libdbd-sqlite3-perl binutils build-essential libfilesys-df-perl zlib1g unzip mlocate clamav libdbd-mysql-perl unrar libclamav-dev libclamav-client-perl libclamunrar9 + + cpanm Encoding::FixLatin + cpanm Digest::SHA1 + cpanm Geo::IP + cpanm Razor2::Client::Agent + cpanm Net::Patricia + cpanm Net::CIDR + + sudo systemctl stop clamav-freshclam.service + + freshclam + + sudo systemctl start clamav-freshclam.service fi -echo "header_checks = regexp:/etc/postfix/header_checks" >> /etc/postfix/main.cf -echo "/^Received:/ HOLD" >> /etc/postfix/header_checks +echo "header_checks = regexp:/etc/postfix/header_checks" >>/etc/postfix/main.cf +echo "/^Received:/ HOLD" >>/etc/postfix/header_checks systemctl restart postfix -if [ "$OS" = "NAME=\"Ubuntu\"" ];then -wget https://github.com/MailScanner/v5/releases/download/5.3.3-1/MailScanner-5.3.3-1.noarch.deb -dpkg -i *.noarch.deb +if [ "$OS" = "NAME=\"Ubuntu\"" ]; then + wget https://github.com/MailScanner/v5/releases/download/5.3.3-1/MailScanner-5.3.3-1.noarch.deb + dpkg -i *.noarch.deb -mkdir /var/run/MailScanner -mkdir /var/lock/subsys -mkdir /var/lock/subsys/MailScanner -chown -R postfix:postfix /var/run/MailScanner -chown -R postfix:postfix /var/lock/subsys/MailScanner -chown -R postfix:postfix /var/spool/MailScanner + mkdir /var/run/MailScanner + mkdir /var/lock/subsys + mkdir /var/lock/subsys/MailScanner + chown -R postfix:postfix /var/run/MailScanner + chown -R postfix:postfix /var/lock/subsys/MailScanner + chown -R postfix:postfix /var/spool/MailScanner -elif [ "$OS" = "NAME=\"CentOS Linux\"" ];then -wget https://github.com/MailScanner/v5/releases/download/5.3.3-1/MailScanner-5.3.3-1.rhel.noarch.rpm -rpm -Uvh *.rhel.noarch.rpm +elif [ "$OS" = "NAME=\"CentOS Linux\"" ]; then + wget https://github.com/MailScanner/v5/releases/download/5.3.3-1/MailScanner-5.3.3-1.rhel.noarch.rpm + rpm -Uvh *.rhel.noarch.rpm -elif [ "$OS" = "NAME=\"CloudLinux\"" ];then -wget https://github.com/MailScanner/v5/releases/download/5.3.3-1/MailScanner-5.3.3-1.rhel.noarch.rpm -rpm -Uvh *.rhel.noarch.rpm +elif [ "$OS" = "NAME=\"CloudLinux\"" ]; then + wget https://github.com/MailScanner/v5/releases/download/5.3.3-1/MailScanner-5.3.3-1.rhel.noarch.rpm + rpm -Uvh *.rhel.noarch.rpm fi mkdir /var/spool/MailScanner/spamassassin @@ -234,8 +197,15 @@ PASSWORD=$(cat /etc/cyberpanel/mysqlPassword) USER=root DATABASE=mailscanner ADMINPASS=$(cat /etc/cyberpanel/adminPass) -mysql -u${USER} -p${PASSWORD} < "/usr/local/CyberCP/public/mailwatch/create.sql" -mysql -u${USER} -p${PASSWORD} -e "use mailscanner"; + +### Fix a bug in MailWatch SQL File + +sed -i 's/char(512)/char(255)/g' /usr/local/CyberCP/public/mailwatch/create.sql + +## + +mysql -u${USER} -p${PASSWORD} <"/usr/local/CyberCP/public/mailwatch/create.sql" +mysql -u${USER} -p${PASSWORD} -e "use mailscanner" mysql -u${USER} -D${DATABASE} -p${PASSWORD} -e "GRANT ALL ON mailscanner.* TO root@localhost IDENTIFIED BY '${PASSWORD}';" mysql -u${USER} -D${DATABASE} -p${PASSWORD} -e "FLUSH PRIVILEGES;" mysql -u${USER} -D${DATABASE} -p${PASSWORD} -e "INSERT INTO mailscanner.users SET username = 'admin', password = MD5('${ADMINPASS}'), fullname = 'admin', type = 'A';" @@ -247,11 +217,11 @@ sed -i "s/^define('DB_PASS',.*/define('DB_PASS','${PASSWORD}');/" /usr/local/Cyb sed -i "s/^define('MAILWATCH_HOME',.*/define(\'MAILWATCH_HOME\', \'\/usr\/local\/CyberCP\/public\/mailwatch\/mailscanner');/" /usr/local/CyberCP/public/mailwatch/mailscanner/conf.php MSDEFAULT=/etc/MailScanner/defaults -if [ -f "$MSDEFAULT" ];then -sed -i 's/^run_mailscanner=.*/run_mailscanner=1/' /etc/MailScanner/defaults -elif [ ! -f "$MSDEFAULT" ];then -touch /etc/MailScanner/defaults -echo "run_mailscanner=1" >> /etc/MailScanner/defaults +if [ -f "$MSDEFAULT" ]; then + sed -i 's/^run_mailscanner=.*/run_mailscanner=1/' /etc/MailScanner/defaults +elif [ ! -f "$MSDEFAULT" ]; then + touch /etc/MailScanner/defaults + echo "run_mailscanner=1" >>/etc/MailScanner/defaults fi cp /usr/local/CyberCP/public/mailwatch/MailScanner_perl_scripts/MailWatchConf.pm /usr/share/MailScanner/perl/custom/ @@ -268,125 +238,121 @@ systemctl restart mailscanner IPADDRESS=$(cat /etc/cyberpanel/machineIP) +### Furhter onwards is sieve configurations -echo 'Setting up spamassassin and sieve to deliver spam to Junk folder by default' -#echo "If you wish mailscanner/spamassassin to send spam email to a spam folder please follow the tutorial on the Cyberpanel Website" -echo 'Fix protocols' -sed -i 's/^protocols =.*/protocols = imap pop3 lmtp sieve/g' /etc/dovecot/dovecot.conf - - -sed -i "s|^user_query.*|user_query = SELECT '5000' as uid, '5000' as gid, '/home/vmail/%d/%n' as home,mail FROM e_users WHERE email='%u';|g" /etc/dovecot/dovecot-sql.conf.ext - -if [ "$OS" = "NAME=\"Ubuntu\"" ];then -if [ "$UBUNTUVERSION" = "VERSION_ID=\"18.04\"" ];then - apt-get install -y dovecot-managesieved dovecot-sieve dovecot-lmtpd net-tools pflogsumm -elif [ "$UBUNTUVERSION" = "VERSION_ID=\"20.04\"" ];then - apt-get install -y libmysqlclient-dev - sed -e '/deb/ s/^#*/#/' -i /etc/apt/sources.list.d/dovecot.list - apt install -y dovecot-lmtpd dovecot-managesieved dovecot-sieve net-tools pflogsumm -fi - -elif [ "$CENTOSVERSION" = "VERSION_ID=\"7\"" ];then - - yum install -y nano net-tools dovecot-pigeonhole postfix-perl-scripts - -elif [ "$CENTOSVERSION" = "VERSION_ID=\"8\"" ];then - - rpm -Uvh http://mirror.ghettoforge.org/distributions/gf/el/8/gf/x86_64/gf-release-8-11.gf.el8.noarch.rpm - dnf --enablerepo=gf-plus upgrade -y dovecot23* - dnf --enablerepo=gf-plus install -y dovecot23-pigeonhole - dnf install -y net-tools postfix-perl-scripts - -elif [ "$CLNVERSION" = "ID=\"cloudlinux\"" ];then - - yum install -y nano net-tools dovecot-pigeonhole postfix-perl-scripts -fi - - -# Create Sieve files -mkdir -p /etc/dovecot/sieve/global -touch /var/log/{dovecot-lda-errors.log,dovecot-lda.log} -touch /var/log/{dovecot-sieve-errors.log,dovecot-sieve.log} -touch /var/log/{dovecot-lmtp-errors.log,dovecot-lmtp.log} -touch /etc/dovecot/sieve/default.sieve -chown vmail: -R /etc/dovecot/sieve -chown vmail:mail /var/log/dovecot-* - -echo 'Create Sieve Default spam to Junk rule' -cat >> /etc/dovecot/sieve/default.sieve <> /etc/dovecot/dovecot.conf <>/etc/dovecot/sieve/default.sieve <>/etc/dovecot/dovecot.conf < -1: if request.session['ipAddr'] == ipAddr or admin.securityLevel == secMiddleware.LOW: @@ -25,20 +31,19 @@ class secMiddleware: else: del request.session['userID'] del request.session['ipAddr'] - logging.writeToFile(request.META.get('REMOTE_ADDR')) + logging.writeToFile(get_client_ip(request)) final_dic = {'error_message': "Session reuse detected, IPAddress logged.", "errorMessage": "Session reuse detected, IPAddress logged."} final_json = json.dumps(final_dic) return HttpResponse(final_json) else: - ipAddr = request.META.get('REMOTE_ADDR').split(':')[:3] - + ipAddr = get_client_ip(request).split(':')[:3] if request.session['ipAddr'] == ipAddr or admin.securityLevel == secMiddleware.LOW: pass else: del request.session['userID'] del request.session['ipAddr'] - logging.writeToFile(request.META.get('REMOTE_ADDR')) + logging.writeToFile(get_client_ip(request)) final_dic = {'error_message': "Session reuse detected, IPAddress logged.", "errorMessage": "Session reuse detected, IPAddress logged."} final_json = json.dumps(final_dic) @@ -117,4 +122,4 @@ class secMiddleware: response['X-Content-Type-Options'] = "nosniff" response['Referrer-Policy'] = "same-origin" - return response \ No newline at end of file + return response diff --git a/IncBackups/IncBackupsControl.py b/IncBackups/IncBackupsControl.py index 1aebbb7b9..d7adc34dc 100644 --- a/IncBackups/IncBackupsControl.py +++ b/IncBackups/IncBackupsControl.py @@ -135,7 +135,9 @@ class IncJobs(multi.Thread): secret = open(path, 'r').read() return key, secret - def awsFunction(self, fType, backupPath=None, snapshotID=None, bType=None): + ## Last argument delete is set when the snapshot is to be deleted from this repo, when this argument is set, any preceding argument is not used + + def awsFunction(self, fType, backupPath=None, snapshotID=None, bType=None, delete=None): try: if fType == 'backup': key, secret = self.getAWSData() @@ -144,8 +146,8 @@ class IncJobs(multi.Thread): backupExcludesFile = '/home/%s/backup-exclude.conf' % (self.website.domain) resticBackupExcludeCMD = ' --exclude-file=%s' % (backupExcludesFile) - command = 'export AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s && restic -r s3:s3.amazonaws.com/%s backup %s --password-file %s' % ( - key, secret, self.website.domain, backupPath, self.passwordFile) + command = 'export AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s && restic -r s3:s3.amazonaws.com/%s backup %s --password-file %s --exclude /home/%s/backup --exclude /home/%s/incbackup' % ( + key, secret, self.website.domain, backupPath, self.passwordFile, self.website.domain, self.website.domain) # If /home/%s/backup-exclude.conf file exists lets pass this to restic by appending the command to end. if os.path.isfile(backupExcludesFile): @@ -184,6 +186,27 @@ class IncJobs(multi.Thread): if result.find('restoring') == -1: logging.statusWriter(self.statusPath, 'Failed: %s. [5009]' % (result), 1) return 0 + elif delete: + + self.backupDestinations = self.jobid.destination + + key, secret = self.getAWSData() + + command = 'export AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s && restic -r s3:s3.amazonaws.com/%s forget %s --password-file %s' % ( + key, secret, self.website, snapshotID, self.passwordFile) + + result = ProcessUtilities.outputExecutioner(command) + + if result.find('removed snapshot') > -1 or result.find('deleted') > -1: + pass + else: + logging.statusWriter(self.statusPath, 'Failed: %s. [5009]' % (result), 1) + return 0 + + command = 'export AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s && restic -r s3:s3.amazonaws.com/%s prune --password-file %s' % ( + key, secret, self.website, self.passwordFile) + + ProcessUtilities.outputExecutioner(command) else: self.backupDestinations = self.jobid.destination @@ -205,14 +228,17 @@ class IncJobs(multi.Thread): logging.statusWriter(self.statusPath, "%s [88][5009]" % (str(msg)), 1) return 0 - def localFunction(self, backupPath, type, restore=None): + ## Last argument delete is set when the snapshot is to be deleted from this repo, when this argument is set, any preceding argument is not used + + def localFunction(self, backupPath, type, restore=None, delete=None): + if restore == None: # Define our excludes file for use with restic backupExcludesFile = '/home/%s/backup-exclude.conf' % (self.website.domain) resticBackupExcludeCMD = ' --exclude-file=%s' % (backupExcludesFile) - command = 'restic -r %s backup %s --password-file %s --exclude %s' % ( - self.repoPath, backupPath, self.passwordFile, self.repoPath) + command = 'restic -r %s backup %s --password-file %s --exclude %s --exclude /home/%s/backup' % ( + self.repoPath, backupPath, self.passwordFile, self.repoPath, self.website.domain) # If /home/%s/backup-exclude.conf file exists lets pass this to restic by appending the command to end. if os.path.isfile(backupExcludesFile): command = command + resticBackupExcludeCMD @@ -233,6 +259,23 @@ class IncJobs(multi.Thread): newSnapshot = JobSnapshots(job=self.jobid, type='%s:%s' % (type, backupPath), snapshotid=snapShotid, destination=self.backupDestinations) newSnapshot.save() + return 1 + elif delete: + + repoLocation = '/home/%s/incbackup' % (self.website) + + command = 'restic -r %s forget %s --password-file %s' % (repoLocation, self.jobid.snapshotid, self.passwordFile) + result = ProcessUtilities.outputExecutioner(command) + + if result.find('removed snapshot') > -1 or result.find('deleted') > -1: + pass + else: + logging.statusWriter(self.statusPath, 'Failed: %s. [5009]' % (result), 1) + return 0 + + command = 'restic -r %s prune --password-file %s' % (repoLocation, self.passwordFile) + ProcessUtilities.outputExecutioner(command) + return 1 else: repoLocation = '/home/%s/incbackup' % (self.website) @@ -247,14 +290,16 @@ class IncJobs(multi.Thread): return 1 - def sftpFunction(self, backupPath, type, restore=None): + ## Last argument delete is set when the snapshot is to be deleted from this repo, when this argument is set, any preceding argument is not used + + def sftpFunction(self, backupPath, type, restore=None, delete=None): if restore == None: # Define our excludes file for use with restic backupExcludesFile = '/home/%s/backup-exclude.conf' % (self.website.domain) resticBackupExcludeCMD = ' --exclude-file=%s' % (backupExcludesFile) remotePath = '/home/backup/%s' % (self.website.domain) - command = 'export PATH=${PATH}:/usr/bin && restic -r %s:%s backup %s --password-file %s --exclude %s' % ( - self.backupDestinations, remotePath, backupPath, self.passwordFile, self.repoPath) + command = 'export PATH=${PATH}:/usr/bin && restic -r %s:%s backup %s --password-file %s --exclude %s --exclude /home/%s/backup' % ( + self.backupDestinations, remotePath, backupPath, self.passwordFile, self.repoPath, self.website.domain) # If /home/%s/backup-exclude.conf file exists lets pass this to restic by appending the command to end. if os.path.isfile(backupExcludesFile): command = command + resticBackupExcludeCMD @@ -276,6 +321,20 @@ class IncJobs(multi.Thread): destination=self.backupDestinations) newSnapshot.save() return 1 + elif delete: + repoLocation = '/home/backup/%s' % (self.website) + command = 'export PATH=${PATH}:/usr/bin && restic -r %s:%s forget %s --password-file %s' % ( + self.jobid.destination, repoLocation, self.jobid.snapshotid, self.passwordFile) + result = ProcessUtilities.outputExecutioner(command) + + if result.find('removed snapshot') > -1 or result.find('deleted') > -1: + pass + else: + logging.statusWriter(self.statusPath, 'Failed: %s. [5009]' % (result), 1) + return 0 + + command = 'export PATH=${PATH}:/usr/bin && restic -r %s:%s prune --password-file %s' % (self.jobid.destination, repoLocation, self.passwordFile) + ProcessUtilities.outputExecutioner(command) else: if self.reconstruct == 'remote': repoLocation = '/home/backup/%s' % (self.website) @@ -437,6 +496,7 @@ class IncJobs(multi.Thread): def restorePoint(self): try: + self.statusPath = self.extraArgs['tempPath'] self.website = self.extraArgs['website'] jobid = self.extraArgs['jobid'] @@ -526,177 +586,29 @@ class IncJobs(multi.Thread): def prepareBackupMeta(self): try: - ######### Generating meta - - ## XML Generation - - metaFileXML = Element('metaFile') - - child = SubElement(metaFileXML, 'masterDomain') - child.text = self.website.domain - - child = SubElement(metaFileXML, 'phpSelection') - child.text = self.website.phpSelection - - child = SubElement(metaFileXML, 'externalApp') - child.text = self.website.externalApp - - childDomains = self.website.childdomains_set.all() - - databases = self.website.databases_set.all() - - ## Child domains XML - - childDomainsXML = Element('ChildDomains') - - for items in childDomains: - childDomainXML = Element('domain') - - child = SubElement(childDomainXML, 'domain') - child.text = items.domain - child = SubElement(childDomainXML, 'phpSelection') - child.text = items.phpSelection - child = SubElement(childDomainXML, 'path') - child.text = items.path - - childDomainsXML.append(childDomainXML) - - metaFileXML.append(childDomainsXML) - - ## Databases XML - - databasesXML = Element('Databases') - - for items in databases: - try: - dbuser = DBUsers.objects.get(user=items.dbUser) - userToTry = items.dbUser - except: - dbusers = DBUsers.objects.all().filter(user=items.dbUser) - for it in dbusers: - dbuser = it - break - - userToTry = mysqlUtilities.mysqlUtilities.fetchuser(items.dbName) - - if userToTry == 0 or userToTry == 1: - continue - - try: - dbuser = DBUsers.objects.get(user=userToTry) - except: - dbusers = DBUsers.objects.all().filter(user=userToTry) - for it in dbusers: - dbuser = it - break + ## Use the meta function from backup utils for future improvements. - databaseXML = Element('database') + if os.path.exists(ProcessUtilities.debugPath): + logging.writeToFile('Creating meta for %s. [IncBackupsControl.py]' % (self.website.domain)) - child = SubElement(databaseXML, 'dbName') - child.text = items.dbName - child = SubElement(databaseXML, 'dbUser') - child.text = userToTry - child = SubElement(databaseXML, 'password') - child.text = dbuser.password - - databasesXML.append(databaseXML) - - metaFileXML.append(databasesXML) - - ## Get Aliases - - aliasesXML = Element('Aliases') - - aliases = backupUtilities.getAliases(self.website.domain) - - for items in aliases: - child = SubElement(aliasesXML, 'alias') - child.text = items - - metaFileXML.append(aliasesXML) - - ## Finish Alias - - ## DNS Records XML - - try: - - dnsRecordsXML = Element("dnsrecords") - dnsRecords = DNS.getDNSRecords(self.website.domain) - - for items in dnsRecords: - dnsRecordXML = Element('dnsrecord') - - child = SubElement(dnsRecordXML, 'type') - child.text = items.type - child = SubElement(dnsRecordXML, 'name') - child.text = items.name - child = SubElement(dnsRecordXML, 'content') - child.text = items.content - child = SubElement(dnsRecordXML, 'priority') - child.text = str(items.prio) - - dnsRecordsXML.append(dnsRecordXML) - - metaFileXML.append(dnsRecordsXML) - - except BaseException as msg: - logging.statusWriter(self.statusPath, '%s. [158:prepMeta]' % (str(msg)), 1) - - ## Email accounts XML - - try: - emailRecordsXML = Element('emails') - eDomain = eDomains.objects.get(domain=self.website.domain) - emailAccounts = eDomain.eusers_set.all() - - for items in emailAccounts: - emailRecordXML = Element('emailAccount') - - child = SubElement(emailRecordXML, 'email') - child.text = items.email - child = SubElement(emailRecordXML, 'password') - child.text = items.password - - emailRecordsXML.append(emailRecordXML) - - metaFileXML.append(emailRecordsXML) - except BaseException as msg: - pass - #logging.statusWriter(self.statusPath, '%s. [warning:179:prepMeta]' % (str(msg)), 1) - - ## Email meta generated! - - def prettify(elem): - """Return a pretty-printed XML string for the Element. - """ - rough_string = ElementTree.tostring(elem, 'utf-8') - reparsed = minidom.parseString(rough_string) - return reparsed.toprettyxml(indent=" ") - - ## /home/example.com/backup/backup-example-06-50-03-Thu-Feb-2018/meta.xml -- metaPath - - metaPath = '/home/cyberpanel/%s' % (str(randint(1000, 9999))) - - xmlpretty = prettify(metaFileXML).encode('ascii', 'ignore') - metaFile = open(metaPath, 'w') - metaFile.write(xmlpretty.decode('utf-8')) - metaFile.close() - os.chmod(metaPath, 0o640) + from plogical.backupUtilities import backupUtilities + status, message, metaPath = backupUtilities.prepareBackupMeta(self.website.domain, None, None, None, 0) ## meta generated - logging.statusWriter(self.statusPath, 'Meta data is ready..', 1) - - metaPathNew = '/home/%s/meta.xml' % (self.website.domain) - command = 'mv %s %s' % (metaPath, metaPathNew) - ProcessUtilities.executioner(command) - - return 1 + if status == 1: + logging.statusWriter(self.statusPath, 'Meta data is ready..', 1) + metaPathNew = '/home/%s/meta.xml' % (self.website.domain) + command = 'mv %s %s' % (metaPath, metaPathNew) + ProcessUtilities.executioner(command) + return 1 + else: + logging.statusWriter(self.statusPath, "%s [544][5009]" % (message), 1) + return 0 except BaseException as msg: - logging.statusWriter(self.statusPath, "%s [207][5009]" % (str(msg)), 1) + logging.statusWriter(self.statusPath, "%s [548][5009]" % (str(msg)), 1) return 0 def backupData(self): @@ -728,6 +640,7 @@ class IncJobs(multi.Thread): databases = self.website.databases_set.all() for items in databases: + if mysqlUtilities.mysqlUtilities.createDatabaseBackup(items.dbName, '/home/cyberpanel') == 0: return 0 @@ -760,6 +673,7 @@ class IncJobs(multi.Thread): backupPath = '/home/vmail/%s' % (self.website.domain) if os.path.exists(backupPath): + if self.backupDestinations == 'local': if self.localFunction(backupPath, 'email') == 0: return 0 @@ -807,6 +721,10 @@ class IncJobs(multi.Thread): if self.backupDestinations == 'local': command = 'restic init --repo %s --password-file %s' % (self.repoPath, self.passwordFile) result = ProcessUtilities.outputExecutioner(command) + + if os.path.exists(ProcessUtilities.debugPath): + logging.writeToFile(result) + if result.find('config file already exists') == -1: logging.statusWriter(self.statusPath, result, 1) @@ -815,6 +733,10 @@ class IncJobs(multi.Thread): command = 'export PATH=${PATH}:/usr/bin && restic init --repo %s:%s --password-file %s' % ( self.backupDestinations, remotePath, self.passwordFile) result = ProcessUtilities.outputExecutioner(command) + + if os.path.exists(ProcessUtilities.debugPath): + logging.writeToFile(result) + if result.find('config file already exists') == -1: logging.statusWriter(self.statusPath, result, 1) else: @@ -822,9 +744,12 @@ class IncJobs(multi.Thread): command = 'export AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s && restic -r s3:s3.amazonaws.com/%s init --password-file %s' % ( key, secret, self.website.domain, self.passwordFile) result = ProcessUtilities.outputExecutioner(command) + + if os.path.exists(ProcessUtilities.debugPath): + logging.writeToFile(result) + if result.find('config file already exists') == -1: logging.statusWriter(self.statusPath, result, 1) - return 1 logging.statusWriter(self.statusPath, 'Repo %s initiated for %s.' % (self.backupDestinations, self.website.domain), 1) @@ -851,6 +776,7 @@ Subject: %s mailUtilities.SendEmail(sender, TO, message) def createBackup(self): + self.statusPath = self.extraArgs['tempPath'] website = self.extraArgs['website'] self.backupDestinations = self.extraArgs['backupDestinations'] @@ -861,6 +787,7 @@ Subject: %s ### Checking if restic is installed before moving on command = 'restic' + if ProcessUtilities.outputExecutioner(command).find('restic is a backup program which') == -1: try: @@ -916,6 +843,8 @@ Subject: %s if self.initiateRepo() == 0: return 0 + + if self.prepareBackupMeta() == 0: return 0 @@ -945,3 +874,38 @@ Subject: %s 'Failed to delete meta file: %s. [IncJobs.createBackup.591]' % str(msg), 1) logging.statusWriter(self.statusPath, 'Completed', 1) + + ### Delete Snapshot + + def DeleteSnapShot(self, inc_job): + try: + + self.statusPath = logging.fileName + + job_snapshots = inc_job.jobsnapshots_set.all() + + ### Fetch the website name from JobSnapshot object and set these variable as they are needed in called functions below + + self.website = job_snapshots[0].job.website.domain + self.passwordFile = '/home/%s/%s' % (self.website, self.website) + + for job_snapshot in job_snapshots: + + ## Functions above use the self.jobid varilable to extract information about this snapshot, so this below variable needs to be set + + self.jobid = job_snapshot + + if self.jobid.destination == 'local': + self.localFunction('none', 'none', 0, 1) + elif self.jobid.destination[:4] == 'sftp': + self.sftpFunction('none', 'none', 0, 1) + else: + self.awsFunction('restore', '', self.jobid.snapshotid, None, 1) + + return 1 + + except BaseException as msg: + logging.statusWriter(self.statusPath, "%s [903:DeleteSnapShot][5009]" % (str(msg)), 1) + return 0 + + diff --git a/IncBackups/views.py b/IncBackups/views.py index 191e65b2d..bca22263d 100644 --- a/IncBackups/views.py +++ b/IncBackups/views.py @@ -405,7 +405,12 @@ def delete_backup(request): backup_id = data['backupID'] - IncJob.objects.get(id=backup_id).delete() + inc_job = IncJob.objects.get(id=backup_id) + + job = IncJobs(None, None) + job.DeleteSnapShot(inc_job) + + inc_job.delete() final_dic = {'status': 1, 'error_message': 'None'} final_json = json.dumps(final_dic) @@ -450,7 +455,6 @@ def fetch_restore_points(request): final_json = json.dumps(final_dic) return HttpResponse(final_json) - def restore_point(request): try: user_id, current_acl = _get_user_acl(request) diff --git a/backup/backupManager.py b/backup/backupManager.py index 21314a4b2..c42b706d6 100755 --- a/backup/backupManager.py +++ b/backup/backupManager.py @@ -696,7 +696,7 @@ class BackupManager: finalDic['port'] = "22" try: - finalDic['user'] = data['user'] + finalDic['user'] = data['userName'] except: finalDic['user'] = "root" diff --git a/backup/templates/backup/backup.html b/backup/templates/backup/backup.html index 76dc4a5bc..86e35b2aa 100755 --- a/backup/templates/backup/backup.html +++ b/backup/templates/backup/backup.html @@ -22,7 +22,6 @@
-
diff --git a/baseTemplate/static/baseTemplate/assets/themes/admin/layout.css b/baseTemplate/static/baseTemplate/assets/themes/admin/layout.css index 5b602b8dc..704e7c221 100755 --- a/baseTemplate/static/baseTemplate/assets/themes/admin/layout.css +++ b/baseTemplate/static/baseTemplate/assets/themes/admin/layout.css @@ -528,9 +528,9 @@ body #nav-toggle.collapsed span { width: 100px; } .closed-sidebar #header-logo .logo-content-small { - width: 62px; + width: 50px; margin-left: 0; - left: 0px; + left: 15px; display: block; } .closed-sidebar #header-logo .logo-content-big { diff --git a/baseTemplate/templates/baseTemplate/index.html b/baseTemplate/templates/baseTemplate/index.html index 12bdef14e..70a269a00 100755 --- a/baseTemplate/templates/baseTemplate/index.html +++ b/baseTemplate/templates/baseTemplate/index.html @@ -76,7 +76,7 @@ - {% with version="2.1.1.1" %} + {% with version="2.1.2" %} @@ -90,7 +90,8 @@ - + {% block styles %} {% endblock %} @@ -115,11 +116,6 @@ -
- - - -
@@ -174,7 +170,6 @@
-
@@ -203,60 +198,20 @@
-
- -
-
- {$ one $} - {$ two $} - {$ three $} @@ -324,20 +279,19 @@ -
+
+
- -
+
@@ -737,7 +694,7 @@ {% endif %} -
+ {% if admin %} @@ -1044,10 +1001,8 @@ {% endif %} - -
@@ -1058,13 +1013,8 @@
- - - - - @@ -1081,7 +1031,6 @@ - diff --git a/baseTemplate/views.py b/baseTemplate/views.py index ce4631b23..b1ee88909 100755 --- a/baseTemplate/views.py +++ b/baseTemplate/views.py @@ -66,6 +66,8 @@ def getAdminStatus(request): def getSystemStatus(request): try: + val = request.session['userID'] + currentACL = ACLManager.loadedACL(val) HTTPData = SystemInformation.getSystemInformation() json_data = json.dumps(HTTPData) return HttpResponse(json_data) @@ -195,4 +197,4 @@ def upgradeVersion(request): return HttpResponse("Version upgrade OK.") except BaseException as msg: logging.CyberCPLogFileWriter.writeToFile(str(msg)) - return HttpResponse(str(msg)) \ No newline at end of file + return HttpResponse(str(msg)) diff --git a/cloudAPI/cloudManager.py b/cloudAPI/cloudManager.py index 3f51e466d..84e36e4e5 100755 --- a/cloudAPI/cloudManager.py +++ b/cloudAPI/cloudManager.py @@ -1492,7 +1492,7 @@ class CloudManager: writeToFile.write('Starting..,0') writeToFile.close() - execPath = "/usr/local/CyberCP/bin/python " + virtualHostUtilities.cyberPanel + "/mailServer/mailserverManager.py" + execPath = "/usr/local/CyberCP/bin/python " + virtualHostUtilities.cyberPanel + "/plogical/mailUtilities.py" execPath = execPath + ' ResetEmailConfigurations --tempStatusPath %s' % (tempStatusPath) ProcessUtilities.popenExecutioner(execPath) @@ -2843,6 +2843,9 @@ class CloudManager: zones = cf.zones.get(params = {'per_page':100}) + command = 'chown cyberpanel:cyberpanel -R /usr/local/CyberCP/lib/python3.6/site-packages/tldextract/.suffix_cache' + ProcessUtilities.executioner(command) + for website in Websites.objects.all(): import tldextract extractDomain = tldextract.extract(website.domain) @@ -2882,6 +2885,9 @@ class CloudManager: ### For child domainsa + command = 'chown cyberpanel:cyberpanel -R /usr/local/CyberCP/lib/python3.6/site-packages/tldextract/.suffix_cache' + ProcessUtilities.executioner(command) + from websiteFunctions.models import ChildDomains for website in ChildDomains.objects.all(): diff --git a/cyberpanel.sh b/cyberpanel.sh index 7c6a8afde..a3045e7c1 100644 --- a/cyberpanel.sh +++ b/cyberpanel.sh @@ -987,9 +987,12 @@ if [[ "$Server_OS" = "CentOS" ]] ; then else apt update -y DEBIAN_FRONTEND=noninteractive apt upgrade -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" +<<<<<<< HEAD if [[ "$Server_Provider" = "Alibaba Cloud" ]] ; then apt install -y --allow-downgrades libgnutls30=3.6.13-2ubuntu1.3 fi +======= +>>>>>>> v2.1.1 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 diff --git a/emailPremium/views.py b/emailPremium/views.py index 47299efe9..535c438c5 100755 --- a/emailPremium/views.py +++ b/emailPremium/views.py @@ -1129,6 +1129,16 @@ def installMailScanner(request): return ACLManager.loadErrorJson() try: + ### Check selinux + + if ProcessUtilities.decideDistro() == ProcessUtilities.centos or ProcessUtilities.decideDistro() == ProcessUtilities.cent8: + command = 'sestatus' + result = ProcessUtilities.outputExecutioner(command) + + if result.find('disabled') == -1: + final_json = json.dumps({'status': 0, 'error_message': "Disable selinux before installing MailScanner."}) + return HttpResponse(final_json) + execPath = "/usr/local/CyberCP/bin/python " + virtualHostUtilities.cyberPanel + "/plogical/mailUtilities.py" execPath = execPath + " installMailScanner" ProcessUtilities.popenExecutioner(execPath) diff --git a/filemanager/templates/filemanager/index.html b/filemanager/templates/filemanager/index.html index 9d85987e4..00fba9a4f 100755 --- a/filemanager/templates/filemanager/index.html +++ b/filemanager/templates/filemanager/index.html @@ -41,7 +41,7 @@