Saturday, 7 November 2015

Raspberry Pi Cloud Server

I've decided to use a Raspberry Pi as a cloud server, I'm going to install Raspbian on it, setup a couple of hard drives as an lvm and install owncloud. There were a few issues with lvm with the drives not mounting at boot time, I've come up with a workaround. But more of that later.

We'll start by writing the image to an SD card first, you can get the image from here. I'm using Linux here so your method of writing the image to an SD card will be different depending on your OS.

In Linux you use the dd command, in this case the SD card is appearing as /dev/sdg when I connect it to my deskstop, you can find out by type dmesg after connecting it.

Once you've identified the correct device use the following command, the version of raspbian may be different than the one I've shown and please make sure you are using the correct device or you may write the image to an Ipod which is what I did originally.

sudo dd bs=4M if=2015-09-24-raspbian-jessie.img of=/dev/sdg

Once it's finished writing, put the card into the Raspberry Pi and give it some electric.

You should be able to look at the connected devices on your router to find out it's IP address. Once you have login to it with ssh pi@ or whatever IP address it shows, the password is raspberry.

One you login, enter the command sudo raspi-config for the configuration utility.

You should get the screen shown above, go down to advanced options and select update, once that's completed select Expand Filesystem so that it fills the card. Then, I'm going to boot options and I'm going to select the top option to boot to a text console and require a login. Next we go to Internationalisation Options and select your country. Then we go back to advanced options and select hostname, I'm changing mine to Andromeda because I can. And then finally back to Advanced Options to make sure that ssh starts on boot. Once you've done all that, go to finish to write the changes and reboot.

Once it's rebooted, log back in and now it's time to add another user with the command:

sudo adduser username 

Followed by:

sudo adduser username sudo

If this is the same as the username on your desktop it means you won't have to enter your username everytime you want to connect and you can run commands as root with that user. Logout as pi and log back in as your user.

Now, it's time to update it and setup the external hard drives, 

sudo apt-get update
sudo apt-get upgrade

Then we install lvm so we can pool some hard drives together.

sudo apt-get install lvm2

Now plug in your external drives, I've got a 1Tb drive and a 512Mb drive showing up as /dev/sda and /dev/sdb.

We need to partition them now with the command:

sudo fdisk /dev/sda 

Use whatever device your drive is showing as.

To delete any existing partitions we type "d", then "n" to create a new one, then "p" for primary, press enter on the next 3 screens to accept the defaults and then type "t" followed by "8e" to identify the drive as an lvm partition. Finally type "w" to write the information to the drive and quit, we then need to do the same for the other drive or drives.

Now we prepare the partitions with:

sudo pvcreate /dev/sda1 /dev/sdb1

Now we create a "Volume Group" with the command:

sudo vgcreate owncloud /dev/sda1 /dev/sdb1

Now we give all the drive space to the volume with:

sudo lvcreate -l 100%FREE -n owncloudlv owncloud

This creates a device called /dev/owncloud/owncloudlv

Next it's time to create the filesystem with the command:

sudo mkfs.ext4 /dev/owncloud/owncloudlv

Now we can create the mount point for the volume, as this is going to be used as storage for my cloud server, I'm going to mount it at /var/www. So first we create the mount point with:

sudo mkdir /var/www

Then we mount it with 

sudo mount /dev/owncloud/owncloudlv /var/www

Normally at this point we can add the UUID of the device to fstab to get the drive starting up at boot time, but there appears to be an issue with the OS here in that the lvm service won't start automatically. I've come up with a not very elegant workaround which is to use the rc.local file to start the service and mount the drive when it boots. So we edit the file with:

sudo nano /etc/rc.local

And at the end of the file above  "exit" we need to add the following:

## Stuff to make the lvm run on startup
service lvm2 start
sleep 10
/sbin/vgchange -a y
sleep 10
mount /dev/owncloud/owncloudlv /mnt/www
sleep 10
service apache2 restart

## End of stuff

The apache2 line will just give an error at the moment until Apache is installed, it needs to be restarted after mounting the drive. I don't know if the sleep options are really needed but they are there to give the drives time to spin up.

We now make sure that the file is executable with:

sudo chmod +x /etc/rc.local

Give it a reboot to make sure it all works

Now it's time to install owncloud

We begin by installing php:

sudo apt-get install php5 php5-dev php-pear php5-gd php5-mysql php5-curl

Then we change the config file:

sudo nano /etc/php5/cli/php.ini

Under the resource limits section we need to change the maximum execution time to 120:

max_execution_time = 120

Then under Module Settings we need to change the time zone settings, in my case I'm the UK so I'm going to change it to:

date,timezone = Europe/London

Make sure you remove the ";" from the start of the line.

There are other options depending on where you live, you can find these here.

Let's install mysql, during the process you will be asked to make a password, if you are going to give access outside of your local network this needs to be a strong one.

sudo apt-get install mysql-server-5.5

Just a few more applications now with:

sudo apt-get install mysql-client-5.5 libmysqlclient-dev apache2 libapache2-mod-php5

And then we need to edit the config file with:

sudo nano /etc/php5/apache2/php.ini

We then need to change these settings

memory_limit =  -1
max_execution_time = 120 
date.timezone =  Europe/London

Now it's time to install and configure the ownCloud server, let's make the directory structure first.

sudo mkdir /var/www/owncloud

Next we make sure ssl is installed and configured correctly:

sudo apt-get install openssl

sudo a2enmod ssl
sudo a2enmod php5
sudo a2enmod rewrite
sudo mkdir -p /etc/apache2/ssl

sudo openssl req -new -x509 -days 365 -nodes -out /etc/apache2/ssl/owncloud.pem -keyout /etc/apache2/ssl/owncloud.key

Time now to edit the apache config file.

sudo nano /etc/apache2/sites-enabled/owncloud.conf

Paste all this into the file,  replacing the IP address in the file with your the IP address of your server:

#### Redirect to port 443 ###
RewriteEngine on
ReWriteCond %{SERVER_PORT} !^443$
RewriteRule ^/(.*) https://%{HTTP_HOST}/$1 [NC,R,L]
#### End of Redirection configuration ###
DocumentRoot /var/www/owncloud/
<Directory /var/www/owncloud>
    Options Indexes FollowSymLinks MultiViews
    AllowOverride All
    Require all granted
####Configuration for SSL #####
SSLEngine on
SSLCertificateFile /etc/apache2/ssl/owncloud.pem
SSLCertificateKeyFile /etc/apache2/ssl/owncloud.key
#### End of SSL Configuration ####
DocumentRoot /var/www/owncloud/
<Directory /var/www/owncloud>
    Options Indexes FollowSymLinks MultiViews
    AllowOverride All
    Require all granted

Now let's download the ownCloud setup file

sudo -i
cd /var/www/owncloud
sudo wget

Time to set some permissions with:

sudo chmod 0777 -R -v /var/www


sudo chown www-data:www-data -R /var/www

And now we configure owncloud itself by connecting with a web browser to:

Replace the IP address with the one for your server.

If you get any error messages just go back and rerun the permissions again.

Once this is all done, forward on port 443 from your router to the raspberry pi so you can get access from the outside world.

That's it, you will get some certificate error messages from your browser and the ownCloud clients.

We've not quite finished with the little machine, one last thing I want to do is to have this update noip with my ip address.

Back to the command line with:
cd ~/
mkdir noip
cd noip
tar vzxf noip-duc-linux.tar.gz
cd noip-2.1.9-1/

Check the name of the folder first to make sure that it's not a different version.
sudo make
sudo make install

Now we want to make this run on startup, we do this with:

sudo nano /etc/init.d/noip

Paste the following onto it

#! /bin/sh
# /etc/init.d/noip 

# Provides:          noip
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Simple script to start a program at boot
# Description:       A simple script from which will start / stop a program a boot / shutdown.

# If you want a command to always run, put it here

# Carry out specific functions when asked to by the system
case "$1" in
    echo "Starting noip"
    # run application you want to start
    echo "Stopping noip"
    # kill application you want to stop
    killall noip2
    echo "Usage: /etc/init.d/noip {start|stop}"
    exit 1

exit 0

Then, make it executable and run on startup with the following commands:

sudo chmod 755 /etc/init.d/noip

sudo update-rc.d noip defaults

Now reboot, and that's it all nice and working.