Headless Virtual Machines – Virtualbox & phpVirtualBox on Ubuntu Server

Virtual Machines make life easier. In development they allow you to create completely destructible instances of machines within a few moments, giving you a safe place to execute that new code you’ve written or try out that new software package you’ve been reading lots about. Although Virtual Machines most certainly do have their place in Production enviroments, they don’t usually appear in small scale situations – from my experience.

Ever since I started “hacking” (messing with stuff, not breaking into stuff) I’ve always loved the concept of Virtual Machines, running an OS within my OS just seemed crazy, but I’ve always found it a burden to have to use clunky UI to manage them. My favourite of all of the Virtual Machines/Hypervisors has always been Virtualbox, with the main reason behind it being that it’s free and open source. As the years have passed, I’ve found myself administrating my Linux servers without any form of Desktop UI and simply through CLI, yet I never found a way to feed my hunger for Virtual Machines from a Terminal. That is until I discovered that VirtualBox can be easily managed from the CLI tools it comes with & phpvirtualbox.

This guide will show you how to set up a neat headless (no Desktop GUI) environment for running VM’s:

Requirements:

  • A Linux Server – This guide will assume you’re running Ubuntu
  • Apache/Nginx/Lighttpd
  • PHP 5.*

VirtualBox

First of all we need to install VirtualBox, preferably the latest version you can get hold of. If you’re repo’s don’t have a version close to 4.1.8 (latest at the time of writing this) grab a copy from the VirtualBox site. If you can’t tell which version is in the repo’s then I’d install the VirtualBox repos on the previously mentioned page (there’s a guide too). Once we’re ready, install:

sudo apt-get install virtualbox-4.1

After a few minutes (1.5Mb adsl connections means a fair few minutes for me) we are ready to go. From this point, you can manage Virtual Machines via two commands:

vboxmanage
vboxheadless

Next, I like to create a user to run Vbox, so I create a user called “vbox” and add it to the “vboxusers” group:

useradd -a vbox -g vboxusers

After which provide the credentials you’re asked for, yada yada yada.

phpVirtualBox

phpVirtualBox is a light-weight web interface for VirtualBox written in PHP (duh). It was designed to replicate the interface of VirtualBox, so things should look vaguely familiar. VirtualBox will have installed a service called “vboxweb-service”, this service provides XML data which can be used to read and modify your VM’s settings, make sure this service is running.

Get phpVirtualBox from here project’s home page and un-package it somewhere where your web server can get to it.

Within the folder you’ve extracted will be a file called ‘config.php-example’, open this file up via any text editor and look for the two lines where $username and $password are defined. These two values need to be the same as the vbox user’s details, so enter these in and save the file as config.php.

That should be it, navigate your web browser to the directory where you saved phpVirtualBox and login using “admin” x2. You can change the login details from the “File” menu once logged in.

Optional: Virtualbox Extension Pack

Although not needed, it may be useful for you to extend Virtualbox’s functionality with Oracle’s optional package, this package provides you with several pieces of functionality, must useful being USB2 support and RDP.

Grab the package from Virtualbox’s website here and store it somewhere near by. Once you’ve done so, run this command from cli:

sudo vboxmanage extpack install "file location for extpack"

And that’s it, that’s as far as this guide goes. As for using the phpVirtualbox interface as well as any errors you encounter, you’re on your own!

Linux Web Server – Security Basics

It’s getting easier and easier to set up and run your own web server these days. Popular service provider’s such as Rackspace, Amazon and VPS.net (UK based) make it incredibly quick and simple to set up your own server in the cloud within minutes. Once you’ve set up an account you will often find the ability to install a popular Linux distro with a basic LAMP set-up. Things that seem to be frequently overlooked by newer users however is security and optimisation, as these will not be set-up for you.

I will mention no specifics to what leads me to believe this, as doing so could alert the world to such sites I know to be at risk, but I know for a fact that there are a fair few servers that are remarkably vulnerable. This article/guide (your choice) will provide simple steps to ensure that your server isn’t compromised or taken down.

Batten down the hatches

Firewalls were created for a reason, to close off unused ports and prevent Brute Force attacks. Now, for different servers I have different methods of closing off connections. For live servers I would recommend using iptables. There’s no great explanation to follow iptables, it is simply a tool which allows you to specify which ports you wish to close and leave open. I won’t go into details about obtaining iptables, but it will most likely be in your distro’s repos (apt-get install iptables, yum install iptables etc etc). The command can be used directly from CLI, however and commands you enter will be lost upon a reboot, as such I would suggest writing a script. The code below is an example of what runs on one machine that I use:

#!/bin/bash
# Flush all current rules from iptables, useful if running script without reboot
 iptables -F

# Allow all connections from trusted IP Addresses

iptables -A INPUT -s (ipaddress here) -j ACCEPT # Home
iptables -A INPUT -s (ipaddress here) -j ACCEPT # Friend's house
iptables -A INPUT -s (ipaddress here) -j ACCEPT # Other random static IP

# Open Services Here

iptables -A INPUT -p tcp --dport 80 -j ACCEPT # Your web server, Nginx, Apache, lighttpd etc
iptables -A INPUT -p icmp --icmp-type 8 -s 0/0 -m state --state  NEW,ESTABLISHED,RELATED -j ACCEPT # Ping

# Block anything else inbound, but allow all outbound connections

iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# Set access for localhost

iptables -A INPUT -i lo -j ACCEPT

# Accept packets belonging to established and related connections

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Save settings

iptables-save

# List rules

iptables -L

Now we have our script ready (assuming you’ve edited it to meet your needs) save it somewhere on your server. The process for making a script run on boot differs between Linux Distros, I mainly use Debian & Ubuntu so I assume you are too, if not try searching for some info.

Open up /etc/rc.local:

sudo nano /etc/rc.local

Once opened, add the following line before “exit 0″:

sh *location to script*

That’s it, sorted. However iptables won’t be too useful if you’re non a Dynamic IP address as you can’t predict what address you will have at a specific time. Although I do have a static IP address, I do find it useful to have one box that I can connect to at all times (which I don’t allow access to any of my other machines). To secure this machine, I use Fail2Ban.

Fail2Ban

Unlike iptables, where a connection is refused outright, Fail2Ban will allow a user only a limited number of chances to connect to your services. For example, you could allow a user only 3 chances of getting the login correct for SSH, if they cannot they get added to the Jail (via iptables).

Installation should be fairly straight-forward, I can’t vouch for this one being in your repo’s but it seems to be in Ubuntu! Once installed, locate your config file (usually /etc/fail2ban/jail.conf). I can’t be bothered to explain how this config file works, as it is fairly self-explanatory. One thing I must mention about Fail2Ban is that on reboot of your server, the record of banned IP’s will be lost! This is a rather large anoyance, one that I will attempt to resolve in another article shortly.

P.S This was going to also include optimisation information for your web server, this will branch off into another guide.

Automated Snapshot Backups for Linux – Quick and simple

I’m sharing with you today my extremely simple snapshot script, that I run via a cron everyday. Although there may be apps out there that can do this for you, I prefer to opt for simplicity and write something myself.

What is Rsync?

Rsync is an application that allows you to sync directories locally or over networks. It allows for incremental updates to files, meaning that you can save time/bandwidth when making backups. Very useful!

What’s a Hard Link?

A hard link is essentially a name that links to data in the filesystem. Think about it this way, you have a file called crumbs.html, “crumbs.html” is essentially a name/hard link to the raw data that is stored within the file system. Within Linux it’s possible to create multiple links/names to the same raw data, resulting in the appearance of multiple files that take up no additional space. Each file the file-system contains a counter for how many hard-links point to it’s data, if this count reaches zero than the raw data can be written over (it’s deleted essentially).

How it’s going to work / The Code

In my machine I have two 2TB drives, the first one stores all of my data in the format and structure that I wish. The second drive, contains all of my backup data, sorted into folders (month/day/).

The concept is to sync all of the first drive’s data over to a directory on the second drive. Once this has completed, we created a hard-link copy of this folder, which acts as our snapshot.

#!/bin/bash

rsync -avh --delete /source/ /backup-location/latest/

cd /backup-location/
mkdir -p `date +%Y`/`date +%B`/`date +%d`/

cp -al /media/backup-2/latest/ /media/backup-2/`date +%Y`/`date +%B`/`date +%d`/

Encountered Questions

Why not use Symlinks moto?
Symlinks are useful for creating links to directories, however they create links based on the filename/hard link rather than the raw data itself. Hopefully the diagrams below help you spot the difference:

This is a Hard Link example
Hard Link
Symbolic Link
Symbolic Link
Nginx, php-fpm and MySQL under Ubuntu/Debian

Due to the popularity of the original guide on my old site, I thought it may be worth going over this topic again. Throughout this guide you will need to enter commands via terminal/cli, as such I will assume that you have root user (or sudo) permissions.

Since the last guide that I wrote, the Ubuntu repos have been updated to include PHP5.3. This is great news as PHP-FPM is bundled with this package.

Optional: If you are using an old version of Ubuntu (older than 11.04) or Debian (older than 6) then I would recommend adding the .dotdeb repositories to Aptitude. Now, please bear in mind that I have encountered problems with their repository, in particular version dependency when upgrading MySQL, if you’re on a recent version of Ubuntu/Debian you don’t need this. You can find instructions on their website, alternatively you can simply bash the following into terminal/cli:

echo -e "deb http://php53.dotdeb.org oldstable all \n deb-src http://php53.dotdeb.org oldstable all"
> /etc/apt/sources.list.d/dotdeb.list

Followed by:

wget http://www.dotdeb.org/dotdeb.gpg
cat dotdeb.gpg | sudo apt-key add -

Now to reload the aptitude’s repository cache:

apt-get update

The .dotdeb repository has miscellaneous packages used for other apps too, so we should ensure everything is up to date.

apt-get upgrade

And we’re done, now on to the rest of the guide.

Nginx

To start off with we’re going to install Nginx:

apt-get install nginx

Fairly simple, right? Well yeah, all we need to do now is to tell configure Nginx to your environment:

nano /etc/nginx/sites-available/default

In all honesty, the majority of this file is untidy and isn’t strictly needed. Unfortunately explaining all the options myself would take forever, as such take a look at Nginx’s docs if you need more help.

Personally I would suggest deleting the contents of this file and replacing with my nice template:

server {
        server_name motomotomd.co.uk; # Change to your domain name
        root /home/matt/sites/moto/htdocs; # Change to the location of your site
        index index.html index.htm index.php; # Feel free to add any file extensions

        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to index.html
                try_files $uri $uri/ /index.html;
        }

        #Pass .php files off to php-fpm
        location ~ \.php$ {
                fastcgi_pass 127.0.0.1:9000;
                fastcgi_index index.php;
                include fastcgi_params;
        }
}

Now to restart Nginx to load the changes we’ve made:

service nginx restart

Your pages should load now, unless they’re php obviously, as we haven’t installed it yet.

MySQL

Nothing too difficult to do here:
apt-get install mysql-server phpmyadmin

(phpmyadmin isn’t required, but I use it all the time, feel free to remove it).

I normally use phpmyadmin to create my users because I’m lazy. You will need to log in the first time using root user details.

And erm… that’s it.

PHP

Nothing too difficult here either:

apt-get install php5-fpm

Now I can’t be sure what packages you need, but if you do need additional packages just install them like normal, for example GD Library:

apt-get install php5-gd

php-fpm runs like a service/daemon on your machine and can be controlled as so:

service php5-fpm restart

I have noticed that at times you’d expect for php-fpm to be automatically restarted, such as when installing additional php packages, it doesn’t, so make a note of the above.

That’s it, you should now be ready to go. Obviously this guide isn’t a complete noobie guide and does expect you to know what you’re doing from here. If you need any more info, please feel free to get in touch (using the form above) and I’ll write you a guide or add to this one.