Posts Tagged with cpanel

posted by qubix on October 8, 2022

As we all know, Cpanel supports advertises POWERDNS for DNSSEC and not BIND. While this is weird enough, I will not go into it.

Recently I had the situation where a client transferred a .com domain to a different registrar and the website pointing to it to a new server. This domain was signed and since noone knew it, I suddenly was facing a serious problem in DNS propagation.

Since google public DNS had no record of this domain, I checked what the heck was happening and yes, then I found out that it was a signed domain.

The problem had two solutions:
1) Remove the signing
2) Implement DNSSEC for this domain at the server so the chain of trust would be valid again.

Unfortunately, the support of the registrar was terrible, I kept talking to people that clearly had no expertise on the matter, probably some call support center with fixed questions/answers. If you had the time and patience, I suppose eventually they would forward your case to some technical person.

But I didn't had the time. Every day that website was down, that client lost many many euros in revenue, and the complaints where escalating by the hour.

So I thought to myself, there must be someone that did this to a cpanel server...NOT! Cpanel forums had this question and the answer was always "we do not support BIND for DNSSEC". Feature requests where left unanswered.

Well no worries, I could do it on my own!

The problem now was that I didn't want all of my zones automatically signed by BIND, but I wanted manually to do it for only one domain.

I will not go into the pitfalls I got into but, thank the eGods, BIND had EDNS support in Cpanel and CloudNS could transfer the zone along with the DNSSEC records among other things.

So, here comes the actual fun!

===== linux cli steps ====
cd /var/named

#generate the two keys we will use to sign and validate our zone (it will take a loooong time to do it without something like haveged. Check #cat /proc/sys/kernel/random/entropy_avail to see what happens to entropy availability while generating keys...)

#generate ZSK
dnssec-keygen -a RSASHA256 -b 1280 -n ZONE 

#generate KSK
dnssec-keygen -a RSASHA256 -b 2048 -f KSK -n ZONE

#adjust ownership and rights to the two key files we generated
chgrp named*
chmod g=r,o=*

# copy them to a safe location just in case
cp* /root/

#change section in /etc/named.conf
zone "" {
        type master;

        file  "/var/named/";

    allow-query { any; };

        # DNSSEC keys Location (we could use a separate folder here)
        key-directory "/var/named/";

        # Publish and Activate DNSSEC keys
        auto-dnssec maintain;

        # Use Inline Signing
        inline-signing yes;

#add to /etc/named.conf
        dnssec-enable yes;
        dnssec-validation auto;
        //dnssec-lookaside auto; //this is not valid for newer versions of BIND

        //lets setup logging for dnssec only
        channel dnssec_log {
                file "/var/log/named/dnssec.log";
                severity debug 3;
        category dnssec { dnssec_log; };

#now before signing the zone, we must put the public keys into our zone file so the sign tools knows from which key to sign the zone
for key in `ls*.key`
echo "\$INCLUDE $key">>

#sign the zone
dnssec-signzone -A -3 $(head -c 1000 /dev/random | sha1sum | cut -b 1-16) -N INCREMENT -o -t

#you should get something like
#Verifying the zone using the following algorithms: RSASHA256.
#Zone fully signed:
#Algorithm: RSASHA256: KSKs: 1 active, 0 stand-by, 0 revoked
#                      ZSKs: 1 active, 0 stand-by, 0 revoked
#Signatures generated:                       65
#Signatures retained:                         0
#Signatures dropped:                          0
#Signatures successfully verified:            0
#Signatures unsuccessfully verified:          0
#Signing time in seconds:                 0.012
#Signatures per second:                5054.039
#Runtime in seconds:                      0.019

#chmod signed zone file
chmod named.named example.db.signed

#reload bind
systemctl reload named

#ds signatures to put into registrar interface (from file created during the signing. They can be also obtained by running #dnssec-dsfromkey        IN DS 35056 8 1 B10CCE8B8C94F46E22451F66E860B7F804D2AC69        IN DS 35056 8 2 296446D4769D4B38175B11ED71767483AD5BD9697AE9C1DD21A3BE9E 670D54EE

#check validation
(; k=$(printf '%05d' "$(dig @ +norecurse "$d". DNSKEY | dnssec-dsfromkey -f - "$d" | awk '{print $4;}' | sort -u)"); delv @ -a <(sed -e '/^;/d;s/[ \t]\{1,\}/ /g;s/ [0-9]\{1,\} IN DNSKEY / IN DNSKEY /;s/ IN DNSKEY / /;s/^[^ ]* [^ ]* [^ ]* [^ ]* /&"/;:s;/"[^ ]*$/b t;s/\("[^ ]*\) /\1/;b s;:t;s/$/";/;H;$!d;x;s/^\n//;s/.*/trusted-keys {\n    &\n};/' /var/named/"$k".key) +root="$d" "$d". SOA +multiline)
; fully validated        86400 IN SOA (
                                2022100118 ; serial
                                3600       ; refresh (1 hour)
                                1800       ; retry (30 minutes)
                                1209600    ; expire (2 weeks)
                                86400      ; minimum (1 day)
                                )        86400 IN RRSIG SOA 8 2 86400 (
                                20221101074125 20221002064125 60423
                                WlIc4hYdolcN2z4o+UoPsSTVOZTj9fBSzRB63w== )

Two excellent tools to use for checking DNS status and the chain of trust are:


posted by qubix on February 7, 2022

Recently I faced a problem with a vps in which the autossl did not wanted to generate a request for the vps's hostname.

After cleaning crap off the apropriate dns zone and after fixing an ns record pointing to a non-functioning dns server I thought yeah we're good to go!

But cpanel had other certificate AGAIN and /usr/local/cpanel/bin/checkallsslcerts gave me a weird error: [WARN] The system failed to acquire a signed certificate from the cPanel Store. at bin/ line 653.

Putting aside that there is NO such Perl file, it came to me that maybe because of the wrong NS record along with other crap I found, there is a certificate CSR for the hostname left over and cpanel did not erase it for some reason.

And yes, there is one in /var/cpanel/hostname_cert_csrs.

Removed it and now runs without an error.

Or does it?? Now throws a subtle [Note] (why??) that the hostname isn't covered by any of the subdomains

Finally, the solution was mv /var/cpanel/hostname_cert_csrs{,.cpbkp} -v

For some reason the whole directory should be backup up and then the checkallsslcert will run correctly issuing a certificate for the hostname!

posted by qubix on November 23, 2020

Σας ειδοποιεί κάποιος πελάτης που βρίσκεται σε cpanel shared hosting πως του έρχονται συχνά-πυκνά emails που του λένε πως δεν παραδόθηκε το mail σε κάποια άγνωστη διεύθυνση.

Ο λόγος που μπορεί να συμβαίνει αυτό είναι αν κάπως κάπου έχει μπει στο account ένας άγνωστος forwarder που δεν έχει βάλει κάνεις. Το πως μπήκε εκεί μπορεί να είναι από hacked server, hacked cpanel account, hacked pc του πελάτη που μπαίνει από το webmail.

Τα παρακάτω βήματα είναι για να δούμε αν όντως πρόκειται για μια τέτοια περίπτωση:

1) check email forwarders από το cpanel account

2) check email filters

Αχα! Ενα mail filter με την ονομασία "." ώστε να μην το προσέξει κάποιος, είχε βάλει έναν forwarder στο email του πελάτη.

Mystery Solved!

Η φυσική τοποθεσία του φίλτρου ήταν στο: /home/user/etc/domain.tld/emailuser/filter.yaml

Περιεχόμενα του φίλτρου:

        action: deliver
        dest: bogus@host.tld
        action: save
        dest: $home/mail/user/info/INBOX
    filtername: .
        match: contains
        opt: or
        part: "$header_from:"
        val: "@"
    unescaped: 1
version: '2.2'

posted by qubix on April 1, 2018

install drush on cpanel based servers with EA4 per account

1) cpanel already has composer if EA4 /opt/cpanel/composer/bin

2) enable jailed shell access to account

3) ssh to server with account creds or keys or root and then su to user

4) composer require drush/drush:7.*

5) go to .bashrc and make an alias

alias drush-master=~/.config/composer/vendor/drush/drush/drush

6) source .bashrc to make changes immidiately availabe

7) go to drush folder and do composer install to fetch dependencies

8) drush-master status to check it is working

9) change tmp to be inside USER home just in case

go to .bashrc and put the line


if you cannot edit .bashrc write this on cli EXPORT TEMP=~/tmp

you can see the change in drush-master status

10) now go to ~/public_html/sites/default/

execute drush status and see that drush sees your website

posted by qubix on April 30, 2016

Αν διαχειρίζεστε cpanel server και λάβετε email σχετικά με κάποιο process upcp που ήδη τρέχει τα πράγματα είναι απλά:

μην πάτε να κλείσετε το process! Εκτός από κάποιες κουφές περιπτώσεις όπου το cpanel update process έχει κολλήσει από την προηγούμενη φορά που έτρεξε, το πιθανότερο είναι απλά να έχει ξεμείνει κάποιο process του crond.


ps aux | grep crond

και αν δείτε παραπάνω από ένα process ή σκοτώστε αυτό που νομίζετε πως είναι περιττό ή σκοτώστε τα όλα και τρέξτε ξανά το crond

easy ;)

posted by qubix on October 24, 2015

Ως γνωστόν το plain FTP θεωρείται και είναι ανασφαλές. Στο πνεύμα αυτό λοιπόν, το filezilla αποφάσισε και καλά έκανε να βάλει default τη σύνδεση με FTP over TLS...

Κάπου εκεί λοιπόν ανακάλυψα πως ο server στον οποίο ήθελα να συνδεθώ, μετά από ένα warning για το tls certificate, όταν έφτανε στην εντολή MLSD για να δείξει τα περιεχόμενα του directory (PWD -> TYPE I -> PASV -> MLSD) πέταξε ένα ωραιότατο timeout..

Προφανώς το πρόβλημα ήταν στην PASV όπου προσπαθούσε να συνάψει σύνδεση σε passive mode(*). Έλα που όμως δεν υπήρχαν πόρτες ανοιχτές για το σκοπό αυτό...

O server αυτός έτρεχε cpanel και pureftpd οπότε ήταν απλά ..θέμα configuration:

1) κάνουμε uncomment τη γραμμή
PassivePortRange 30000 50000

στο αρχείο /etc/pure-ftpd.conf

προφανώς μπορούμε να βάλουμε οποιοδήποτε port range θέλουμε

2) κάνουμε restart τον pureftp daemon

/etc/init.d/pureftpd restart

3) για να κάνουμε τις αλλαγές μόνιμα πρέπει να πειράξουμε το conf του cpanel για τον pureftpd


προσθέτουμε τη γραμμή

PassivePortRange: '30000 50000'

4) σιγουρευόμαστε πως οι πόρτες είναι ανοιχτές στο firewall

- αν δεν χρησιμοποιούμε κάποιο plugin (πχ csf)
iptables -t filter -I INPUT -p tcp –dport 30000:50000 -j ACCEPT

- αν χρησιμοποιούμε το csf (ή οποιοδήποτε άλλο plugin) πάμε στο interface του και σετάρουμε από εκεί τις πόρτες

5) δοκιμάζουμε τη νέα μας ασφαλή FTP over TLS σύνδεση :]

Τις παραπάνω εντολές τις τρέχουμε ως root ή ως privileged user

(*) passive ftp mode είναι ο τρόπος σύνδεσης ενός client με τον ftp server κατά τον οποίο ο client συνδέεται ο ίδιος με τον server και στο command channel και στο data channel σε κάποιες τυχαίες unprivileged ports, σε αντίθεση με τον active mοde, στον οποίο ο server συνδέεται με τον client στο data channel, πράγμα το οποίο συνήθως δεν επιτρέπουν τα firewalls και πρόβλημα το οποίο λύνει ο passive τρόπος σύνδεσης.

posted by qubix on October 11, 2015

I tried some days ago to transfer some accounts from a plesk vps to a cpanel one. Having root access to both machines and using cpanel's transfer tool I thought it would be a simple task but upon the first transfer something went wrong..

Starting “TRANSFER” for “Account” “asdasd”.
Copy Destination: /home
Remote server type: “plesk”.
Packaging the account with the command: /scripts/ asdasd '' --split --compressed --mysql 5.5 --allow-multiple …
Unknown option: compressed
Unknown option: mysql
MySQL error: ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO) at /tmp/.perl-ppk-Kh2FBV/lib/Cpanel/Foreign/Plesk/ line 117.
Target “/home” on host “” has 412 GB free and requires at least 0 bytes free, which includes space for temporary files.
WARNING: The remote server failed to send the location of the transfer archive.
WARNING: Attempting to guess the location of the remote transfer archive.
Fetching md5sum of “/home/cpmove-asdasd.tar.gz” from the remote server … …
Removing copied archive on remote server. …

Failed: The remote execution of “” was not sucessful, or the requested account, “asdasd” was not found on the server: “IP ADDRESS”.

as we can see, the process stopped because the migration script could not connect to plesks mysql.

trying to find out what happened I realized that I couldn't connect either manually.

In plesk the password is stored in a file: /etc/psa/.psa.shadow
that ".shadow" doesn't look good and indeed tha password in that file is AES encrypted,something like

According to plesk documentation you can see the password with the command:
/usr/local/psa/bin/admin --show-password

Amazingly it worked. What it didn't work is logging into mysql with it...again the same error trying
mysql -uadmin -ptheabovepassword

It turns out that mysql in plesk wants the encrypted version of it not the plaintext.So the correct command would be:
mysql -uadmin -p`cat /etc/psa/.psa.shadow`

well..that was weird :P

Now you can populate the file /root/.my.cnf with the correct credentials so cpanel can connect to plesk mysql and account transfer be completed successfully!

And the contents of .my.cnf file (place them without the lines!)

posted by qubix on February 19, 2015

Πρόσφατα χρειάστηκε να μεταφέρω κάποια mail accounts με αρκετά gbytes μέγεθος και κάποια χιλιάδες mail το καθένα από έναν cpanel server σε έναν ubuntu based zimbra.
Αρχικά πήγα με την "πεπατημένη" οδό, το imapsync αλλά δυστυχώς στο ubuntu έπαψε να υπάρχει στα repos από την έκδοση 11.10 και εγώ είχα μπροστά μου έναν 14.04, οπότε πήγα με το imapcopy, ένα παλαιό utility γραμμένο σε ..pascal το οποίο υπήρχε στα repos μιας που γίνεται crosscompile με τη freepascal

Προφανώς για να γίνει το migration πρέπει να έχουμε δημιουργήσει τα accounts που θέλουμε και στον zimbra server, ίδια με του cpanel

Ενημερωτικά, τα logs που μας ενδιαφέρουν είναι:

όταν και αν κάτι προκύψει μπορούμε να ίσως να βρούμε άκρη κοιτάζοντας τα εν λόγω logs

apt-get install imapcopy

πολύ απλά γράφουμε ένα αρχείο το imapcopy.cfg όπου νομίζουμε πχ στο /root/imapcopy/

τα περιεχόμενα έχουν ως εξής:
SourceServer imap.server.tld
SourcePort 143

DestServer imap.server.tld
DestPort 143

# SourceUser SourcePassword DestinationUser DestinationPassword

Copy "user@domain.tld" "Passowrd" "user@domain.tld" "Password"
Copy "user2@domain.tld" "Passowrd" "user2@domain.tld" "Password"

και εκτελούμε από εκεί την εντολή
imapcopy -t

για να τεστάρουμε πως οι συνδέσεις γίνονται κανονικά

σε περίπτωση που έχουμε προβλήματα και βλέπουμε μηνύματα αποτυχίας σύνδεσης χρειάζεται να γνωρίζουμε 2 πράγματα:
1) στον zimbra πρέπει να είναι ενεργοποιημένη η επιλογή "Enable Cleartext Login" για τον server (home->configure->servers->o_server_mas->edit (κλίκ πάνω στον σέρβερ)->IMAP
2) για κάποιο λόγο όταν το password αρχίζει με συγκεκριμένους χαρακτήρες δεν μπορεί να γίνει login οπότε καλύτερα στα passwords στα accounts του zimbra να είναι της μορφής 123456 ή κάτι ανάλογο "ασφαλές" :P

Αν όλα πάνε καλά λοιπόν μπορούμε να προχωρήσουμε στο migration των email. Αλλά πριν το κάνουμε, για να αποφύγουμε μηνύματα του στυλ

BAD maximum literal size exceeded

χρειάζεται να αλλάξουμε τα διάφορα default size restrictions που χρησιμοποιεί το zimbra

1) γινόμαστε zimbra user
su zimbra

2) εκτελούμε τις παρακάτω εντολές και σημειώνουμε κάπου τα default values
zmprov getConfig zimbraFileUploadMaxSize
zmprov getConfig zimbraImapMaxRequestSize
zmprov getConfig zimbraMailContentMaxSize
zmprov getConfig zimbraMtaMaxMessageSize

3) βάζουμε κάποιο μεγάλο limit σε όλα (εδώ είναι 150Μ)
zmprov modifyConfig zimbraFileUploadMaxSize 150000000
zmprov modifyConfig zimbraImapMaxRequestSize 150000000
zmprov modifyConfig zimbraMailContentMaxSize 150000000
zmprov modifyConfig zimbraMtaMaxMessageSize 150000000

4) κάνουμε restart τον postfix και το mailbox
postfix reload
zmmailboxdctl restart

5) βεβαιωνόμαστε πως περάσανε οι νέες τιμές
zmprov getConfig zimbraFileUploadMaxSize
zmprov getConfig zimbraImapMaxRequestSize
zmprov getConfig zimbraMailContentMaxSize
zmprov getConfig zimbraMtaMaxMessageSize
postconf message_size_limit

6) βγαίνουμε από zimbra user και εκτελούμε το imagecopy. Λογικά τώρα η μεταφορά θα γίνει χωρίς απρόοπτα!

posted by qubix on April 18, 2014

Πάμε τώρα να εγκαταστήσουμε το snmp σε έναν centos server, ώστε με κάποιο cacti πχ να κάνουμε monitoring εκ του μακρώθεν...
Αρχίζουμε με τα βασικά, δηλαδή να εγκαταστήσουμε τα απαραίτητα πακέτα στο σύστημα:

yum install net-snmp net-snmp-utils

αφού μπούν τα πακέτα και κάνα δυο εξαρτήσεις, πάμε να βάλουμε τον snmp daemon να ξεκινά με την κάθε εκκίνηση του συστήματος:
chkconfig snmpd on

τώρα στα ενδιαφέροντα πράγματα, το configuration. Χωρίς πολλά πολλά αυτό είναι ένα minimal configuration:

rwuser   noauth
rouser   noauth
rocommunity  mycommunity
syslocation  "datacenter"
proc  init 1 1
proc  httpd 10 1
disk  /
load  12 12 12

Όπως λοιπόν είναι προφανές:
- δεν έχουμε authentication
- βάλαμε μια community read-only η οποία είναι συγκεκριμένη ip και της δώσαμε το όνομα mycommunity
- και καλά το location είναι το "datacenter", προφανώς μπορεί να έχει κάποιο όνομα με ..νόημα!
- τσεκάρουμε την init process ώστε να ξέρουμε αν τρέχει ο server
- τσεκάρουμε την process του web server και βάζουμε όρια να τρέχουν 10 το πολύ και μία το λιγότερο processes
- τσεκάρουμε το μέγεθος του root partition, προφανώς μπορούμε να προσθέσουμε και άλλα partions/δισκους/arrays σε ανάλογες directives
- και τέλος τσεκάρουμε το load με 1minute, 5minutes, 15minutes max averages

μετά από αυτά, κάνουμε restart τον snmpd και βλέπουμε αν όλα παίζουν καλά από το remote cacti μας

προφανώς πρέπει να έχουμε ανοίξει την 161 udp port για να παίξει το οτιδήποτε!

posted by qubix on March 7, 2014

Ξαφνικά και ενώ πήγαιναν όλα καλά, το cpanel το οποίο συνδέεται με το mysql server μέσω ενός socket file, πέταξε το μήνυμα
cpanel Can't connect to local MySQL server through socket '/tmp/mysql.sock' (111)
Μετά τον αρχικό πανικό, διαπίστωσα πως τα site στον server έπαιζαν κανονικά, o mysql server ήταν επάνω χωρίς προβλήματα..άρα..σε κάποιο update του cpanel κάτι άλλαξε..

Τέλος πάντων, η λύση είναι στο /tmp να γίνει symlink ένα mysql.sock στο /var/lib/mysql/mysql.sock . Το ωραίο είναι πως στο /tmp υπήρχε ένα mysql.sock αρχείο το οποίο όμως δεν ήταν ούτε socket, ούτε symlink στο socket. Συνεπώς:

rm /tmp/mysql.sock ln -s /var/lib/mysql/mysql.sock /tmp/mysql.sock chown mysql.mysql /tmp/mysql.sock