IT Admins Group | Where you decide the content...

Froxlor Love! ;)

The situation: I have been working with Froxlor for years (since the fork from syscp) and have even contributed at times to the code base. Over the years I have constantly re-evaluated other UI’s to ensure there wasn’t a better fit for our use pattern. Important are the following features:

1. Able to be easily adjusted to the distribution version in use.

    a. Debian Squeeze
    b. Debian Wheezy
    c. Debian Jessie

2. Able to be easily adjusted to the needed software stack.

    a. Apache 2.2/2.4 & NginX
    c. Courier & Exim4

3. Active development.
4. Active community.
5. Readily available Debian binary (yes. not REALLY binary) and source packages.
6. Cluster Support (cmon/corosync)
7. Easily extended capabilities with 3rd party plugins/modules.

Based on the above list Froxlor comes the closest and has kept that edge for years.

The Pros: Froxlor supports –

WEB: Apache, NginX and Lighttpd
CGI: Perl, PHP (mod_php, PHP-FPM and FCGID)
FTP: ProFTPD and PureFTP
DNS: Bind9 and PowerDNS
Mail: Postfix, Exim4, Courier and Dovecot

The development team is constantly working on improvements and new releases are constant. Debian packages are released shortly after source tarballs hit the site and are very stable. The community is pretty active and helpful, which includes the developers chiming in when needed.

The Cons: As previously stated, the developers are constantly working on Froxlor. This is a great situation and should be commended. However, there are certain aspects of the project that are off putting.

1. Package dependencies are slightly incorrect (not just my opinion)
2. Missing 3rd party plugin/module support
3. Missing Cluster support (my opinion)
4. Jails

Points 2 and 3, the missing Cluster and 3rd party plugin/module support is not a deal killer. I have figured out a clean way to get my plugins integrated into Froxlor without having to modify any core code. This allows me to integrate Cluster and services control support in Froxlor without having to worry about the next update. Granted, my plugin support is not able to change core features but I can get new features added. I also cannot use the existing Froxlor database without running the risk of losing information or breaking the install when I perform the next Froxlor upgrade. Thus, I have extra menu entries for my plugins and use either a separate database or flat file the info for the plugin. Some plugins, of course, have no need of stored data and thus are free of the second limitation. Once I figure out how to cleanly get changes into the core without having to fear the next upgrade I will let you know.

The first point regarding the package dependencies is basically a disagreement between myself and the project developers on the basis of logic. Below I have listed the current Debian package dependencies and recommendations.

Depends: apache2 | lighttpd | nginx, php5 | php5-cgi, php5-cli, php5-mysqlnd | php5-mysql, mysql-server | mariadb-server, mysql-client | mariadb-client, mysql-common | mariadb-common, webalizer | awstats
Recommends: postfix-mysql | exim4-daemon-heavy, libsasl2-modules-sql, maildrop, courier-authlib-mysql | dovecot-common, courier-imap | dovecot-imapd, courier-pop | dovecot-pop3d, php5-gd, php5-imap, proftpd-mod-mysql | pure-ftpd-mysql, bind9 | pdns-server

As you can clearly see, they are limiting the application of froxlor due to an unneeded and illogical dependency on either mariadb-server or mysql-server installed on the local system. This is fine for small hosting companies but a nightmare for medium to large companies. A simple change to the package control file, rebuild of the package and an upload to a local debian repo solves the issue for anyone wanting to do some serious and professional web hosting with Froxlor. A simple change to have the DB server a recommendation and a change to the readme to reflect the 2 different install options would clear the matter up.

Point 4 is a bit more problematic but still one that can be fixed. As we all know, FTP should be avoided like the plague it is. FTPS, SCP and SFTP are clearly superior and therefore should be used if at all possible. Added to that should be chroot’ed jails to help ensure the security of the server.

Conclusion: After trying a lot of different options (Ajenti, DTC, ISPConfig, Syscp, Web-CP, Confixx, cPanel, Plesk and a few others) Froxlor is about the best bang for the buck. No real software lock-in due to multiple options for each service you need. Great response times on questions and problems. Rapid development and frequent build releases, coupled with competent security means you server is in good hands. However, as stated, if you are needing to do real hosting you will need to put in a bit more work to reap the rewards.

In my next piece I will be showing you how to run Froxlor on a separate Lighttpd service (Apache 2.4 being the virtual-hosting server) to guarantee Froxlor access even when problems occur. And how to add plugins without losing you work when upgrading or having to change Froxlor code to add new features. A following piece will outline how to get Froxlor working great in a corosync+pacemaker 5 tier cluster.



Short list of must have tools

Over the course of ones carrier as a System or Network Administrator one will encounter a quite a few utilities to “help” in the excution of ones work. A large majority of those tools are either flawed in logic or execution, incomplete or just generally useless. However, every once in a while a tool will surface that fits just perfectly in just about every admins toolbox. Here is a list (in alphabetical order) of some of my favorites. If you have any that should be listed just let me know.

1. autojump: This is a replacement/improvement on the standard “cd” (change directory) command in Linux. It can actually learn how you move on the system and even offers autocompletion. A very handy time saver for all admins.

2. dtrx: The Intelligent archive extraction utility is just awsome. Extracts tar, zip, cpio, deb, rpm, gem, 7z, cab, lzh, rar, gz, bz2, lzma, xz, and many kinds of exe files, including Microsoft Cabinet archives, InstallShield archives, and self-extracting zip files all in one command. It even handles archives without it’s own destination directory instead of dumping everything in your download or home directory. Give it a shot and you will soon have no need to check man pages for the differing formats. drtx Home

3. iotop: This one is pretty much in every distro but this thing is so helpful I figured I would list in just in case you happened to have the misfortune of working with a distro that does not offer it.

4. liquidprompt: Over the years I have refined and honed my shell prompt as well as my .bashrc to include a lot of small extras that just come in handy. Recently I ran across liquidprompt and fell promptly in love with it. Yes, at times it can lag a bit (mostly in repository directories) but otherwise it is a great addition to any toolbox and brings a lot to the table.

5. prettyping: Pretty Ping I ran across tonight and just had to have it. As a matter of fact, I have installed this on every system I admin (gotta love Puppet). Make no mistake, this tool is a keeper as long as you can figure out how to adjust your locales. 😉

6. testdisk: nuff said.


PHP-FPM Processor Load

I run just about everything in Proxmox/OpenVZ containers. Recently I noticed after doing a fresh install of PHP-FPM that the pools for PHP-FPM were eating up a LOT of CPU time. That PHP-FPM can eat up a processor is nothing new. However, the pools were doing absolutely nothing. They were just idling there and were causing ca. 40% load on the processor.

First I had to find out why PHP-FPM was eating up my processor and therefore the use of “strace” was called for.

ps auxf
strace -ffttTo strace.txt -p 8766

Basically I grabbed the PID of a running php-fpm process that was causing massive load and fed that to strace. After that I noticed the following in the file:

12:32:14.981209 gettimeofday({1380364334, 981222}, NULL) = 0 <0.000008>
12:32:14.981249 gettimeofday({1380364334, 981261}, NULL) = 0 <0.000008>
12:32:14.981297 gettimeofday({1380364334, 981310}, NULL) = 0 <0.000009>
12:32:14.981337 gettimeofday({1380364334, 981350}, NULL) = 0 <0.000009>
12:32:14.981379 gettimeofday({1380364334, 981392}, NULL) = 0 <0.000008>
12:32:14.981418 gettimeofday({1380364334, 981431}, NULL) = 0 <0.000008>
12:32:14.981464 gettimeofday({1380364334, 981477}, NULL) = 0 <0.000009>
12:32:14.981504 gettimeofday({1380364334, 981517}, NULL) = 0 <0.000008>
12:32:14.981545 gettimeofday({1380364334, 981558}, NULL) = 0 <0.000010>
12:32:14.981588 gettimeofday({1380364334, 981601}, NULL) = 0 <0.000008>
12:32:14.981633 gettimeofday({1380364334, 981646}, NULL) = 0 <0.000009>
12:32:14.981673 gettimeofday({1380364334, 981685}, NULL) = 0 <0.000008>
12:32:14.981714 gettimeofday({1380364334, 981727}, NULL) = 0 <0.000008>
12:32:14.981753 gettimeofday({1380364334, 981766}, NULL) = 0 <0.000008>
12:32:14.981798 gettimeofday({1380364334, 981810}, NULL) = 0 <0.000008>
12:32:14.981837 gettimeofday({1380364334, 981850}, NULL) = 0 <0.000008>
12:32:14.981879 gettimeofday({1380364334, 981891}, NULL) = 0 <0.000009>
12:32:14.981917 gettimeofday({1380364334, 981930}, NULL) = 0 <0.000008>
12:32:14.981963 gettimeofday({1380364334, 981976}, NULL) = 0 <0.000008>
12:32:14.982003 gettimeofday({1380364334, 982016}, NULL) = 0 <0.000009>
12:32:14.982044 gettimeofday({1380364334, 982057}, NULL) = 0 <0.000009>
12:32:14.982084 gettimeofday({1380364334, 982096}, NULL) = 0 <0.000009>
12:32:14.982130 gettimeofday({1380364334, 982143}, NULL) = 0 <0.000008>
12:32:14.982170 gettimeofday({1380364334, 982182}, NULL) = 0 <0.000009>
12:32:14.982211 gettimeofday({1380364334, 982223}, NULL) = 0 <0.000008>
12:32:14.982250 gettimeofday({1380364334, 982263}, NULL) = 0 <0.000008>
12:32:14.982296 gettimeofday({1380364334, 982309}, NULL) = 0 <0.000013>
12:32:14.982342 gettimeofday({1380364334, 982355}, NULL) = 0 <0.000008>
12:32:14.982397 gettimeofday({1380364334, 982411}, NULL) = 0 <0.000009>
12:32:14.982438 gettimeofday({1380364334, 982451}, NULL) = 0 <0.000008>
12:32:14.982483 gettimeofday({1380364334, 982499}, NULL) = 0 <0.000012>
12:32:14.982528 gettimeofday({1380364334, 982540}, NULL) = 0 <0.000008>

Such entries went on and on and on. So apparently PHP-FPM had a problem getting the time of day.

The interesting part of this is that the call to gettimeofday goes through /dev/timedev which is not available in a standard OpenVZ container. So to see if that was actually the problem I just did the following:

mknod /dev/timedev c 15 0
chmod 644 /dev/timedev

The load on the server dropped immediately and has since been a very well behaved container.

Now the only thing to do is make sure that /dev/timedev is available every time the container starts. This is also not very difficult to remedy. From the Host node you will need to allow access to /dev/timedev

vzctl set CTID –devices c:15:0:r –save
vzctl exec CTID mknod /dev/timedev c 15 0
vzctl exec CTID chmod 644 /dev/timedev

Now you are set for the next restart of the container and PHP-FPM should not be causing any further problems.