Raam Dev » thoughts essays journal notes contact about subscribe rss

Posts Tagged: Web Hosting

How I Revamped My Web Hosting Business

During the past two months or so, I’ve pushed really hard to finish a project that I’ve been “working on” for the past year. The project was to rename, streamline, and solidify my web hosting business. This included registering the business as a trade name with the state, opening a business bank account, opening a post office box, designing a new website, and setting up and integrating the billing system into the website.

The hosting business originally started as a side-project — something I set up to host my own websites and those of friends and colleagues. I hadn’t anticipated the business growing and not putting much thought into setting it up properly from the start was a mistake.

As the number of hosting clients grew, I found it increasingly difficult to keep track of account balances, payments, contact information, account statuses, etc. I realized that I needed something that would automatically generate invoices and send them out, accept payments through my website, and handle new account signups.

I researched various billing systems and eventually settled with WHM.AutoPilot: It was relatively inexpensive and appeared to have everything I needed. However, after adding all my clients and reconciling the accounts, I struggled to get the system working just the way I wanted. There were many bugs and newer versions weren’t being released in a timely manner. It felt as though the billing software just made things more complicated rather than improving them.

All the while, my hosting business continued to grow. Despite bad accounting and being very unorganized, clients were continuing to roll in by word-of-mouth advertising. Every time a new client would sign up, I felt embarrassed that I didn’t have something more professional to present to them. I was beginning to dislike the thought of setting up new accounts!

That’s when I realized I really needed to streamline everything and make growth less of a burden. (Growth should be easy, not something you dread!) So almost exactly a year ago, I decided to change the name of the business to ActualWebSpace, open a bank account so clients could make checks payable to the business instead of my personal name, and get everything set up properly once and for all.

After researching billing systems once again, I decided on and purchased WHMCS. The developers seemed more “on top of things” and the community around the software appeared very active. It used a very simple PHP templating system that would make integrating the billing system into the website very simple.

So that I could offer domain registration and SSL certificates, I signed up for an eNom reseller account. WHMCS included full integration with eNom, so automating domains and SSL certificates was easy.

For the website, I decided to use WordPress as a back-end and design a WordPress theme from scratch. It was both the first time I had set up WordPress as a CMS and the first time I had designed a WordPress theme from scratch. While it extended the amount of time it took the launch the site, it was an invaluable learning experience.

Setting up the website was probably the most difficult part of the entire process for me. I’m a perfectionist and it’s difficult for me to create something and be happy with it. But, after much persistence, I discovered ways of getting out of my perfectionist state of mind and I made enormous progress in the past few weeks.

I launched the new website for ActualWebSpace yesterday. It has been almost a year in the making and it feels great to finally follow through with a project to the end. I’m going to use the lessons I learned to start, and finish, my next project (still deciding what that will be).

The biggest lesson I learned from this year-long project: When starting any kind of venture that has the potential to grow, set things up properly from the beginning. Plan for and anticipate growth instead of waiting until the growth begins to happen.

How Amazon’s EC2 Service was Born

Benjamin Black talks about how Amazon’s EC2 service was born. I’ve had some experience with EC2 and it’s really quite an impressive service. I think if the costs were slightly lower they would be putting a lot of VPS hosting providers out of business (or VPS hosting providers would be switching to EC2 and putting conventional data centers out of business).

Bounce-back Spam (Backscatter)

I really hate bounce-back spam! (I call it bounce-back spam, but the official name for it is Backscatter.) I’ve read, and been told by sysadmins, that there is not much that can be done about it. The Wikipedia page on bounce messages has a little section that explains why:

Excluding MDAs, all MTAs forward mails to another MTA. This next MTA is free to reject the mail with an SMTP error message like user unknown, over quota, etc. At this point the sending MTA has to inform the originator, or as RFC 5321 puts it:

If an SMTP server has accepted the task of relaying the mail and later finds that the destination is incorrect or that the mail cannot be delivered for some other reason, then it MUST construct an “undeliverable mail” notification message and send it to the originator of the undeliverable mail (as indicated by the reverse-path).

This rule is essential for SMTP: as the name says, it’s a simple protocol, it cannot reliably work if mail silently vanishes in black holes, so bounces are required to spot and fix problems.

Today, however, most email is spam, which usually utilizes forged Return-Paths. It is then often impossible for the MTA to inform the originator, and sending a bounce to the forged Return-Path would hit an innocent third party. This inherent flaw in today’s SMTP (without the deprecated source routes) is addressed by various proposals, most directly by BATV and SPF.

It looks like I’ll have to just deal with it. (I could set up filters and such, but then I might miss a real bounce-back and not know that my message didn’t go through!) I’m just grateful it comes in waves of a few hours every few weeks instead of non-stop! Has anyone else had to deal with this? If so, what did you do about it?

Backscatter Spam

WHM Whitelist to Exclude from Exim Sender Verify Callbacks

Sender verification is an important feature used by email servers to help prevent spam. When sender verification is enabled, the receiving email server checks to make sure the sender exists. Various email servers have different ways of handling this feature. Exim, for example, uses a mechanism called ‘sender callouts’ or ‘callbacks’. (When the sending server does not accept a verification request, it does not comply with RFC 2821.)

However, in the event that the network route from the receiving email server to the originating email server is broken (or a firewall blocks the connection), the result can be a bit confusing. The receiving email server treats a failed verification as a failed verification, regardless of whether or not it could even connect to the originating server. This means the email never comes through to the recipient. After all, as far as the email server knows, it’s spam.

One of my hosting clients was experiencing this “lost email” problem and a quick grep at /var/log/exim_mainlog confirmed the problem (hosts and IPs changed for obvious reasons):


2008-11-17 15:02:27 [30121] H=relay1.example.com (qsv-spam1.example.com) [67.26.151.59]:36752 I=[69.161.211.25]:25 sender verify defer for : could not connect to customer.example.com [163.112.75.15]: Connection timed out
2008-11-17 15:02:27 [30121] H=relay1.example.com (qsv-spam1.example.com) [67.26.151.59]:36752 I=[69.161.211.25]:25 F=<administrator@customer.example.com> temporarily rejected RCPT <raam@mydomain.com>: Could not complete sender verify callout
2008-11-17 15:02:27 [30120] H=relay1.example.com (qsv-spam1.example.com) [67.26.151.59]:36751 I=[69.161.211.25]:25 incomplete transaction (RSET) from <administrator@customer.example.com>

As you can see, the email server was unable to connect to customer.example.com to verify the existence of the sender (administrator@customer.example.com). This doesn’t mean the sending server doesn’t verify callbacks, but rather that the network connection from my server to the sending server could not be established.

Most of the stuff I found online related to solving this problem on a server running WHM (here and here) explain how to modify exim.conf to add special whitelist rules. Luckily, my server is running WHM 11.23.2 and has a whitelist option that makes it really easy to exclude a particular IP address from sender verification without any manual changes to exim.conf:

1. Click Service Configuration -> Exim Configuration Editor
2. Under Access Lists, find “Whitelist: Bypass all SMTP time recipient/sender/spam/relay checks” and click [EDIT]
3. Add the IP address for the sending server for which you wish to skip sender verification (as the note at the bottom explains, hosts cannot be used in this list)
4. Click Save
5. Click Save again near the bottom of the Exim Configuration Editor page

That’s it! Now any emails from that IP that were failing to come through because of a sender verification failure will come through without a problem (again, you can watch /var/log/exim_mainlog to confirm).

Switching to suPHP; What a Mess!

When one of my users reported problems deleting files he had uploaded using a PHP script, I quickly discovered all the files being uploaded were owned by the user running the web server: nobody. This meant only the root user could delete those files.

Apache suEXEC is commonly used to resolve this problem. It allows Apache to run as the user who owns the domain being accessed. This way, files created by PHP would be owned by the user owning the site instead of the default nobody user.

However, Apache suEXEC only works if you’re using CGI as the PHP handler. The PHP5 handler on my server was set to use CGI, but I have PHP4 configured as the default PHP version and it was configured to use DSO. When I tried changing PHP4 to use CGI as the handler, most of the domains on my server displayed this:

Warning: Unexpected character in input: ‘’ (ASCII=15) state=1 in /usr/local/cpanel/cgi-sys/php4 on line 772
Warning: Unexpected character in input: ‘ in /usr/local/cpanel/cgi-sys/php4 on line 772
Warning: Unexpected character in input: ‘ in /usr/local/cpanel/cgi-sys/php4 on line 772
Warning: Unexpected character in input: ‘ in /usr/local/cpanel/cgi-sys/php4 on line 772
Parse error: syntax error, unexpected T_STRING in /usr/local/cpanel/cgi-sys/php4 on line 772

OK, that looks like a problem with cPanel. I don’t have time to debug cPanel’s problems.

suPHP, like suEXEC, is used to run Apache as the user who owns the domain. I decided to try recompiling Apache and PHP with suPHP enabled to see if that would fix the problem.

File Ownership Hell

suPHP worked, except now the sites using PHP sessions were trying to access stored session data in /tmp/ that was owned by the user nobody! So I deleted all the session data and that allowed the PHP sites to create new session data with file ownership of the user owning the domain.

But then I tried accessing my WordPress admin page and started getting permission denied errors in /wp-content/cache/. Same problem: the cache files that had been created before I enabled suPHP were owned by the user nobody and now the user who owns my domain couldn’t access them. A quick chown -R raamdev:raamdev /wp-content/cache/ fixed that problem.

Yeah, I could simply chown -R [user]:[user] /home/[user] for each of the users on the server, but there’s something about running a recursive command on files I’ve never seen, and know nothing about, that makes me uncomfortable.

More suPHP Limitations

I was beginning to worry that this was going to be more difficult than simply enabling suPHP and I wondered how many other sites I’m hosting could have similar problems. I tried accessing one of the high priority sites I’m hosting and discovered it was broken and displaying an “Internal Server Error”.

After a little research, I discovered that you cannot use php_value directives in .htaccess files with suPHP. The .htaccess file included with (created by?) Joomla! contained this at the bottom:

#Fix Register Globals
php_flag register_globals off

I already knew register_globals was turned off in the global PHP configuration, so I simply commented out that line and the site started working again.

Conclusion

It was at this point that I concluded it was too risky to just blindly enable suPHP while hosting over 50 domains, many of which I am not at all familiar with what’s being used or hosted. I will need to take the time to carefully crawl through all the sites making sure their .htaccess files don’t contain anything that might disrupt suPHP and then confirm all the sites are still working properly.

Lesson learned: Setup suPHP before you’re hosting 50+ domains.

Where in the world is Raam?

Join the Facebook Community

Raam Dev » thoughts essays journal notes contact about subscribe rss

Powered by WordPress and other Open Source Software
Uncopyright by Raam Dev