The other day I switch all my web sites from a shared hosting provider to VPS hosting at Linode. There are thousands of Linux VPS providers, the most famous of which is Rackspace because of all their television commercials, but within the developer community Slicehost (now a subsidiary of Rackspace) and Linode are the two that really stand out. I am not writing a VPS primer here, so if you are unsure what a VPS is then this article is probably not for you, but basically a VPS is like having your own dedicated server (which can be extremely expensive), except that it is much cheaper since you are actually sharing hardware resources with other virtual servers.
If you just want a web site or two and do not consider yourself a technical person, programmer, or system administrator, then shared hosting is all you will probably need. If, however, you are technically proficient, and you have a large number of web sites, and/or they get a lot of traffic, or have special server-based functionality (such as running cron jobs, which by the way you can stop reading if you do know what a cron job is), if you are running it as a business, or if you just want more control over everything, then you should consider a VPS or dedicated server. Also, if you are not familiar with or comfortable with the Linux command line, Linux administration, basic Linux security (ssh, iptables, etc.), and Apache administration (if you plan to use Apache as your web server), then having your own VPS is probably not for you. Otherwise, having your own VPS (or VPSs) can easily satisfy all your web hosting needs with much better performance, optimization, customization, and configurable than any shared hosting solution could possible provide.
Before I could begin I had to decide which VPS provider I wanted to use. For me it came down to choosing between Slicehost and Linode, both which are great choices. Ultimately, it boiled down to cost: a VPS “slice” from Slicehost with 1GB of memory, 40 GB of disk space, and 600 GB of bandwidth was $70 a month, while a 1 GB “node” from Linode (with a little less bandwidth and disk space) was $40 a month. Also, this article shows Linode as having the highest processing horsepower of the various VPSs that were compared. More for less always wins in my book.
As a side note, “step 0” for me was actually to transfer all my domains from my current domain registrar (which was a GoDaddy reseller) to Namecheap.com (an eNom reseller). I liked their simpler interface much better, and while they still had some up-sell, it was not as flagrantly in-your-face and constantly annoying like GoDaddy’s. Plus, and this was huge for me, they had 1 year free on their WhoisGuard (which legally obscures registration details from the WhoIs listings) on all domains, after which it’s about $1.60 a year per domain (in bulk), while GoDaddy’s would cost about x10 more. That’s a no-brainer too. Basically, if you want to register or transfer your domains to a registrar that doesn’t suck, go with Namecheap.com.
Now, back to our regularly scheduled article on Linode. When you create an account with Linode you have to select what VPS plan you want. Currently, Linode offers VPS nodes ranging from 512MB up to 4 GB of memory, and various increments in between. I came close to getting the 1 GB node, but chose the 768MB node instead. While this may not sound like much memory for a web server, it was plenty for my needs: my server is still only 5% utilized with some spikes every now and then. The great thing about VPS hosting is that you can always upgrade your node, add more memory, more storage, more bandwidth, etc., as your needs grow. You can also create more servers, so if you needed 3 VPS servers (i.e., a web server, a file server, and a database server), you can easily create and manage them as your needs change or business grows.
I started off creating a basic Ubuntu 10.04 server image, but quickly deleted it when I realized that I could install a pre-built LAMP (Linux, Apache, MySQL, PHP) stack with basic security already installed from Linode’s library of StackScripts. I chose to create my server image from the Ubuntu 10.04 LTS and ‘LAMP & Basic Firewall’ StackScript which installs MySQL, Postfix (for sending mail), Apache2, PHP, iptables with a basic but good configuration, ssh, and fail2ban. It also restricts logins to ssh via public key authorization (that is, no password but only public key/private key “handshake”) and disables the ability for root to login directly via ssh. Regardless of whether or not you use the same StackScript to create your Linode node, this is the minimal security measures you should take on any publicly accessible Linux server. When you install from this StackScript it will ask you for one or more ssh keys, which you should generate on the computer (or computers) from which you plan to “ssh into” your server. If you do not know how to do this, I’m sorry but this is not an ssh primer–just Google search it.
Anyway, what it boils down to is this: with a VPS, you are responsible for securing your server. Failing to do so will get you hacked (and quickly). A secure Linux server must have, at minimal:
- SSH for login, no root login, and no password login, and only allow logins via ssh public key for keys set in the ~/.ssh/authorized_keys list.
- Recommended to move ssh login port from 22 to something obscure, but not really necessary if you secure ssh as above.
- Iptables for blocking all ports other than the few ports you need open (80, 443, 22 or whatever you change it to for ssh login).
- Fail2ban for added security to block anyone attempting to hack into the server.
- Install php5-suhosin if you have PHP sites, if its not already installed (which it might be).
- Do not run FTP: just use an FTP client that supports FTP via SSH tunnel (i.e., FTPS).
- Do not open the SQL port to access your MySQL server remotely, instead just tunnel in via SSH (MySQL Workbench easiy supports this).
- Never, ever grant any folder anywhere 777 access (open read, write, execute access) for any reason no matter how tempting it might be to get a web page or script working. No, not ever. Never. I repeat: never.
- All your passwords, especially your Linode manager password, need to be very strong: like 10 characters or more with numbers, letters, capital letters, and special characters.
That should make your server “secure enough” to avoid being cracked by bots, script-kiddies, sweatshop hackers, and such, but no security can absolutely perfect. Be mindful of the fact that a determined malicious intruder will find a way in, and so you should always maintain one or more up-to-date backups of your system. In fact, Linode offers an excellent server backup and restore service, which I am also now using, although it is an additional fee.
Once you create your basic server image, you should explore the Linode Manager. From within the Linode Manager, if you go to the Remote Access tab, you can click “Launch Lish Ajax Console” to bring up a remote virtual console of your server. You should really only use this in emergencies or to load new ssh keys into the ~/.ssh/authorized_keys files. All real work should be done through a real ssh console login. The Linode Manager also allows you to manage your DNS records if you choose to use Linode’s nameservers. I did, simply because I like their no-nonsense DNS interface, but this is certainly not necessary. Either way, you will need to point your domain’s A record to the IP address of your Linode server.
Then you just need to ssh to your server to login:
ssh firstname.lastname@example.org (if you have a different port than 22, add -p [your ssh port])
If the private key on your computer matches the public key stored in the~/.ssh/authorized_keys file, then you will be automatically logged in–no password needed (and much more secure).
The first thing you should do is run apt-get update and apt-get upgrade to make sure you have the latest versions of all software. To run any root command as a non-root user you must prefix the command with sudo (superuser do), i.e., sudo apt-get upgrade. You will then be prompted for the root password, which you should have created when you installed the image and which should of course be a nice secure password. You will not be asked for the password every time you run a sudo command, but it will ask for it again from time to time.
Next, for a LAMP server, make sure all php modules that you think you might need are installed (this might be more than you need):
apt-get install php5 php-pear php5-mysql php5-suhosin libapache2-mod-php5 php5-common php5-curl php5-dev php5-gd php5-idn php-pear php5-imagick php5-imap php5-mcrypt php5-memcache php5-mhash php5-ming php5-mysql php5-pspell php5-recode php5-snmp php5-sqlite php5-tidy php5-xmlrpc php5-xsl
You should also enable the apache modules for URL rewite and SSI if you want them:
sudo a2enmod rewrite
sudo a2enmod include
You will also need to set your server’s timezone to whatever you prefer (by default it is GMT) and change the hostname of your server to your primary domain name:
sudo dpkg-reconfigure tzdata
If it is not already installed, you should install logrotate as well. This will keep your log files from getting huge by rotating them daily, weekly, or monthly (depending on the configuration) and compressing old log file. A definite must have!
sudo apt-get install logrotate
I also wanted a program to generate daily web stats, and chose awstats for this purpose (there are others). In preperation I made sure these packages were installed…
sudo apt-get install libnet-xwhois-perl libnet-dns-perl libnet-ip-perl libgeo-ipfree-perl
Then I installed awstats:
sudo apt-get install awstats
Configuring awstats and setting it up to run daily (or hourly) cron jobs to generate reports is a little complicated, so you can read these articles here (it is a Slicehost article, yes, but it still applies to Linode–just skip down to the configuration bit).
Fail2Ban should already be setup (if you used the StackScript I suggested) to ban users who attempt to crack your ssh login, but you can and should configure it further. I configured mine to have a longer ban period, permanent in some cases, to ban known hacker bots, and also to watch for and ban any attempts to get into phpmyadmin (which I do not and will not install, for security reasons), and other admin backends. Read these for more information:
I also added denyhosts as a further precaution, but it might be redundant when fail2ban is installed.
sudo apt-get install denyhosts
While some may consider it controversial, I went the extra step to specifically block all IP address ranges for several countries where the majority of hacking attempts originate, namely, China, Russia, Nigeria, and some others, adding their IP ranges to the iptables like so:
/sbin/iptables -A INPUT -p tcp -s 22.214.171.124/15 -j DROP
You can get a full list by country here.
This is controversial because it means no one in any of these countries will be able to access your web sites. If that matters to you, don’t do this. However, if your audience does not encompass these countries, it can mitigate some attacks–especially denial of service attacks.
Once you load the list, run:
sudo iptables-save > iptables.conf
It will be saved until you reboot. Whenever you reboot you will need to run this, although I’m sure that can be automated:
sudo iptables-restore < /etc/firewall.conf
You should also configure the Apache web server for your needs and for all your sites. This is not a tutorial for that, but I did discover that Apache will default to the first site listed in /etc/apache2/sites-enabled if there is no site under sites-enabled that match the domain, such as for wildcard subdomians. To fix that you should always name your default site (which should be a blank site or the default apache welcome site) 000-default, rather than just default.
The final item I would like to mention is that you probably don’t want to host your own mail server. You will need Postfix installed so your sites can send out email, but you certainly don’t want to go to all the trouble, and added security risks, of installing and managing Courier IMAP, SpamAssassin, ClamAV, SASL, TLS, and SquirrelMail. Instead, I chose to just use Google Apps (the free version) for all my domains that need mail. This works great, and is all I need. Your mileage may vary, of course, but it should be sufficient in most cases.
Well, that is all I have to say on setting up a Linode server. I think Linode is fantastic, and far superior to shared hosting (at least if you are technically proficient). This wasn’t a tutorial, but it should at least get you started in the right direction and help you create your check-list of things to do (or perhaps give you some idea of how much work will be involved). If you want to give it a shot, go ahead and sign up for Linode today. And yes, that is a referral link–go ahead and click it if you plan to sign up to give me some good referral credit!