Install Tomcat 7 on a cPanel Server

CPanel has soon promised that Tomcat 7 will be supported in a future EasyApache release. Until then, you can get easily get the support of Tomcat 7 with just a little bit of manual intervention.  I will mention that right now, Tomcat 7 is not supported by cPanel so there’s no guarantee that their integrated features for Tomcat will work as expected.


First, go ahead and run EasyApache and select the option to install Tomcat. This will indeed install Tomcat 5.5, but that’s OK.  Let EasyApache do the grunt work for you.


After it’s installed, you’ll need to put the Tomcat 7 files in place:

cd /usr/local/jakarta

wget http://apache.claz.org/tomcat/tomcat-7/v7.0.41/bin/apache-tomcat-7.0.41.tar.gz

tar -xvzf apache-tomcat-7.0.41.tar.gz

ln -sf ln -sf /usr/local/jakarta/apache-tomcat-7.0.41 /usr/local/jakarta/tomcat

Note:  The above example is based off of the latest version of Tomcat available at this time.  You can get the latest version at http://tomcat.apache.org/download-70.cgi .


While still in the jakarta folder, compile the daemon:

cd ./tomcat/bin

tar -xvzf tomcat-native.tar.gz

cd commons-daemon-*

cd unix



cp jsvc ../../

Now kill off tomcat and restart it:

killall java


And add the latter command to /etc/rc.local:

sed ‘/starttomcat/d’ -i /etc/rc.local

echo ‘/scripts/restartsrv_tomcat’ >> /etc/rc.local





cPanel Update Fails with Exit Code 6400

Since the release of cPanel 11.32, the cPanel update process has extended OS checks to ensure that you are only updating cPanel on a compatible system. Specifically, you can no longer upgrade past version 11.32 on CentOS 4, or 11.30 on Redhat 9.  Trying to do so will verbosely inform you that the upgrade is not possible.

However, if you’re running CentOS or RHEL 5 or 6 and still either see this error or a cryptic “exited with code 6400″ message as shown below, it’s usually a simple fix.
Running `/usr/local/cpanel/scripts/updatenow --upcp --log=/var/cpanel/updatelogs/update.1xxxxxx.log --force` failed, exited with code 6400

Firstly, if you run the updatenow command directly, you’ll see the error in its true form:

/usr/local/cpanel/scripts/updatenow –upcp

Results in:

Only Distro versions 5 and 6 supported in this version of cPanel & WHM

But, as you’ve already established, you are running version 5 or 6, but upcp doesn’t seem to recognize that.  To fix this, simply edit /var/cpanel/sysinfo.config and change the value of rpm_dist_ver to the major OS version you are running. For example, if you run CentOS/RHEL 6, you would do:


Then attempt to run the upgrade again, and it should be fine.  As to how it got this way, well, we’re not entirely sure. From thumbing through the code of the updatenow script, it appears to be trying to use the rpm headers to capture the OS version.  If your RPM database is/was corrupted at one point, the update process may have put an ‘unknown’ in there instead:

if ( -e $sys_info_file && ( !$locked_values{'rpm_dist_ver'} && !$new_conf{'rpm_dist_ver'} or $new_conf{'rpm_dist'} eq 'unknown' ) ) {
print "ERROR: Refusing to update $sys_info_file since I cannot determine your distro's major version\n";
print "Please run: " . q{rpm -qf --queryformat '%{VERSION}\n' /etc/redhat-release} . "\n";

If your cPanel update eventually completed, you’re probably fine.  If you have RPM issues still, the quick and dirty way to fix this is as so:

rm -rf /var/lib/rpm/__db.00*
yum clean all

Note:  Don’t try to trick the system by setting rpm_dist_ver to something that you’re not running, especially if you’re trying to force cPanel to update on your CentOS 4 system.  We’ve tried it, and it doesn’t work.


Fixing cPanel Locale Errors

If you receive an “Internal Death” (generic cPanel speak for “something broke”) when accessing WHM and/or cPanel, the first thing you should do is check the cPanel error logs at /usr/local/cpanel/logs/error_log.  You may see something like this:

die [Internal Death while parsing [stdin] xxxxx] Read of CDB_File failed: Protocol error at /usr/local/cpanel/Cpanel/CPAN/Locale/Maketext.pm line 217.
Cpanel::CPAN::Locale::Maketext::maketext() called at /usr/local/cpanel/whostmgr/docroot/templates/menu/root.tmpl line 53

This is almost always an issue with the locale database, and tends to occur when a cPanel update failed due to outside conditions – such as a server running of our disk space, memory, etc during the update.  To fix this, simply move the locale files out of the way:

mv /var/cpanel/locale /var/cpanel/bad_locale

If you have custom locales installed, you can go ahead and move the files back in (unless, of course, the custom locales were what was causing the problem).

Then run:

/usr/local/cpanel/bin/build_locale_databases –force

If your cPanel update did indeed fail, it’s a good idea to run it again.


Restoring DNS Zones on a cPanel Server

In rare situations, the DNS zones located in /var/named might disappear. We’ve heard of this happening after certain bind package updates, or simply due to administrator error. In either case, it may be possible to restore or at least recreate the missing zones.  Even if the server in question does not act as a nameserver, certain functions within cPanel require the zones to exist locally.  These instructions are geared toward a hosting server (not solely a nameserver) that may or may not be clustered with a cPanel DNSONLY server.  For more information about clustering, see this article.

Restoring from the DNS cluster


Firstly, if your server is clustered with another cPanel server, your job is going to be easy. All you have to do is have cPanel sync the zones from one of the other clustered server(s).  Here’s a very simple Python script that will pull out a list of main, addon, and parked domains from the cPanel data and sync them back to the server.  For this to work, you’ll need to make sure your remote DNS cluster is set to “synchronize” status.  To do this, you can either:


1) Log into WHM -> Configure Cluster and set the cluster’s role to “Synchronize changes“  OR

2) Run the following command, replacing $ip with the IP address of your DNS cluster (noting also that ‘root’ implies that this is the cluster config for the server itself. If you’re a reseller, replace “root” with your reseller username)

echo -n “sync” > /var/cpanel/cluster/root/config/$ip-dnsrole

Now create a file on your server called, for example, synczones.py and chmod it to 755.  Paste in the following contents:

#!/usr/bin/env python
import os
import subprocess
import yaml
data_dir = '/var/cpanel/userdata'
user_list = os.listdir('/var/cpanel/users')
for user in user_list:
    data_file = '%s/%s/main' % (data_dir, user)
    data_map = None
        f = open(data_file, 'r')
        data_map = yaml.load(f)
    if data_map is not None:
        domains = []
        for addon in data_map['addon_domains']:
        for domain in domains:
            subprocess.call(['/scripts/dnscluster', 'synczone', domain])

Now, simply run the script and your zones will be copied from the remote cluster to the local server.  If this server is standalone and/or is a nameserver that does not have another clustered server attached to it, you basically only have the choice of either restoring from a backup or recreating the zones.


Restoring from Backups


Assuming you use the cPanel backup feature and have the system files backed up, you can find them in your cPanel backup directory.  If you’re not sure where they are being stored, look in cPanel -> Configure Backup where the “Backup Destination” value is set. Or simply:

grep BACKUPDIR /etc/cpbackup.conf

Assuming the backup location is /backup, you will find the files in /backup/cpbackup/weekly/dirs (for a weekly backup – it could also be named ‘daily’ or ‘monthly’).

To restore, go to the dirs folder mentioned above and run:

tar -C / -xvf _var_named.tar.gz


Recreating Zones


If you don’t have backups, your only choice may be to recreate the zones.  To do this, you can use the adddns script provided by cPanel:

/scripts/adddns $domain [$Ip]

If the $ip parameter is not passed, the main shared IP will be used instead.  Keep in mind that if you recreate the zone using this method, a default zone using cPanel’s zone template will be used – so any DNS modifications that were previously made to the zones will be lost.  You can use a similar script to the one above to do all domains on your server:

#!/usr/bin/env python
import os
import subprocess
import yaml
data_dir = '/var/cpanel/userdata'
user_list = os.listdir('/var/cpanel/users')
for user in user_list:
    data_file = '%s/%s/main' % (data_dir, user)
    f = open(data_file, 'r')
    data_map = yaml.load(f)
    domains = []
    for addon in data_map['addon_domains']:
    for domain in domains:
        subprocess.call(['/scripts/adddns', domain])
Fixes // Hacks // Mail // Misc

Exclude Domains from RBL Checks for Incoming Email

Update: This feature is automatically enabled as of cPanel

If you have RBL’s enabled globally on your server, there may be times when you want to keep certain domains from having their mail scanned against an RBL. While cPanel supports excluding sender IP addresses from these checks, some manual Exim modifications are needed to exclude recipient domains.

First, create a file that we’ll use to list the domains to exclude:

touch /etc/skiprbldomains

Next, you’ll need to apply a custom patch to one of the Exim perl modules used by cPanel.  You can view the patch here.


wget -O  /usr/local/cpanel/src/skip_rbl_domains.patch \


patch < /usr/local/cpanel/src/skip_rbl_domains.patch


service exim restart


Now to exclude domains from RBL checks, simply list them in /etc/skiprbldomains
When cPanel updates, this perl module will be overwritten.  In this case we do not recommend setting the file to be immutable or adding it to /etc/cpanelsync.exclude, but rather adding a simple script hook to re-apply the patch after every Exim update:


echo “patch < /usr/local/cpanel/src/skip_rbl_domains.patch” >> /scripts/posteximup

chmod  700 /scripts/posteximup


Note: The information used in this post was provided as a cumulative effort between our staff, one of our clients, and the cPanel developers.

Using Skeleton Directories in cPanel

The skeleton (aka “skel”) directory is one of the frequently ignored features on Linux servers, especially for hosting providers.  With the skel directory, you can easily configure a default set of files to be automatically copied into new user accounts, which is particularly useful for customizing the holding pages for new customer websites.


On a bare Linux server, the skeleton folder can be found in /etc/skel.  On cPanel servers, the directory will be in “cpanel3-skel” in the home directory of the user that owns the account being created.  For example, if you’re the root user and you’re creating an account on the server, that account’s default files will be copied from /root/cpanel3-skel.  If you’re a reseller, it will be in your home folder, ie /home/yourusername/cpanel3-skel.


Let’s say when new users are created on your server, you want their websites to automatically show a basic index.html page that says “coming soon”.  You may also want the user to have a customized .bashrc file for their SSH sessions.  If you are root, you’ll create the following files:


  • /root/cpanel3-skel/public_html/index.html
  • /root/cpanel3-skel/.bashrc


Now, when user accounts are created, their accounts will automatically contain .bashrc and public_html/index.html.



How to Change the Location of MySQL on cPanel

There may be some situations where you have to move the location of MySQL, for example, if you’re out of disk space or perhaps looking to host it on another device to increase performance. Whatever the reason, moving MySQL is simple and has no impact ct on cPanel’s functionality.


1) Create a backup


This should go without saying, but never mess with your data without making a backup of it. One simple way:

tar -cvf mysql.tar /var/lib/mysql


2) Modify my.cnf


In the [mysqld] section of /etc/my.cnf, add/modify this line:




For example, if you are moving MySQL from /var/lib/mysql to /home2/mysql:




Don’t restart MySQL yet.


3) Sync the data


Now migrate the data to the new location using rsync. Typically you’ll want to stop MySQL, sync the data, then start it up again. If you have a lot of data and know the sync will take a while, do several syncs while the server is running, until they take less time. However, your last sync should always be done with MySQL stopped, especially if you have InnoDB tables. Here’s the command to sync with the example of MySQL being moved to /home2/mysql:

rsync -av /var/lib/mysql /home2

Now, relink the socket:

ln -sf /home2/mysql/mysql.sock /tmp


4) Restart MySQL


Since you already added the datadir entry to my.cnf, all you need to do is restart again and everything should be working.


Why Softaculous is More Fantastic than Fantastico

I don’t mean to offend anyone who still uses Fantastico. Some people prefer to stick to what they’re used to, and Fantastico is the original open-source auto-installer built for cPanel and has a pretty solid name in the hosting industry. But geez – what happened? Where did all their developers go, and what are the chances of having all these buggy, exploitable open source applications updated sometime this year? A lot of hosts are swapping out the smiley face for Softaculous, and here’s why:

(at the time of this post, Fantastico 3 has been short of being released in beta for at least 6 months)


More applications


Softaculous has support for over 280 applications at the time of this post, and they are regularly seeking out and adding more. Compare this to the ~50 that Fantastico offers.


Frequent updates


Open-source website applications are the bain of every administrator’s existence. They get hacked, exploited, spammed, and abused. One publicized exploit can leave thousands of websites vulnerable, so it’s imperative that the software be updated when developer patches are released so the end users that rely on auto-installers like Fantastico and Softaculous can upgrade as soon as possible. With Fantastico, you could be waiting days, weeks, or even months to even see these upgrades. In most all cases, Softaculous has implemented vendor updates within a day or two.


Prettier interface


While not exactly relevant, I want to point out that the Fantastico interface looks like it was designed in 1998 and isn’t very customizable. Softaculous has a much more modern interface, and the ability to create your own themes.


Better support


In my years of dealing with Fantastico, the few times I really needed to contact their support, they were really disappointing. Not only did it take 12-24 hours to get a response, but often time the response was along the lines of “please provide this non-relevant information so I can further stall this ticket instead of resolving it for you.” Ok, not quite in those words, but you get the idea. Every time I’ve contacted Softaculous, I’ve received a response within a couple hours.


Perhaps as claimed by the developers, Fantastico 3 will have all of these issues addressed. Perhaps, but I currently fail to see how their new product will measure up to other auto-installers. I guess we’ll just have to wait and see.


5 Ways to Get a User’s Disk Usage

This may seem pretty simple, but I see a lot of questions about how to get a user’s disk space usage on a cPanel user. I put together a quick list of 5 simple ways for the average admin:


1) Good ole’ cPanel/WHM. You can see the usage on the left-hand side of cPanel, or in the ‘List Accounts’ view of WHM


2) Quota cache:

egrep “^${user} ” /var/cpanel/repquota.cache

3) Actual quota:

quota -v | egrep “^${user} “

4) Manual du:

du -h /home/$user

5) cPanel datastore:

cat /home/$user/.cpanel/datastore/_usr_bin_quota_-v



Upgrading MySQL Without Breaking PHP

There’s a dilemma amongst system administrators of high-traffic servers when it comes to doing updates – downtime. Most upgrades on a Linux/cPanel server can be done without interruption, but when it comes to upgrading MySQL, some get quite a surprise.

Now, upgrading the release within a minor MySQL version (like 5.0.81 to 5.0.85) is pretty seamless. However, going from 5.0 to 5.1, or 5.1 to 5.5 is just as easy, but requires a little extra TLC to prevent PHP-driven websites from going down. Many administrators are unaware that upgrading MySQL on a cPanel server will break PHP. This is because PHP is compiled with the system MySQL libraries, and when MySQL is upgraded to a different minor version, the old libraries for that version are removed and replaced with the new ones. If PHP is compiled with MySQL support, it can’t execute because the libraries it’s looking for are now gone. The only way to properly fix this is to recompile PHP via EasyApache or downgrade back the version of MySQL you were running in the first place.

We’ve devised a simple way to run a MySQL upgrade without breaking PHP on your server. You will still need to run EasyApache to fully complete the upgrades, but this process will keep your websites running in the meantime. We’ve formulated the concept into an easy-to-read bash script that will do all the work for you.

You can download the script from our Github repo.

Update 2/14/14:  Happy Valentine’s Day!  I updated the script to work on cPanel 11.36+ and MySQL 5.6.  I also added a –runeasy option to automatically invoke EasyApache after the upgrade.