Wednesday, 23 July 2014

RaspberryPi Webserver: install & configure

The low power consumption of the RaspberryPi means that it wont run up a huge electricity bill if left on all the time.


So its a good candidate for a webserver, either as part of your home automation system, or just for experimentation.


This post describes how I configured a Raspberry Pi using a light-weight web server application.

I'll start by discussing the principle before moving on to describe how I did it.

In the beginning


Although the RaspberryPi was developed to meet the needs of young people, and jump-start the next generation of Computer Scientists, to me its just a technical playground.

Do I need a web server hanging on the internet?

I don't know. But I'd like to experiment with one, just for the hell of it!

I also have this woolly notion that I might like to be able to touch my Android phone and turn the lights on and off in our bird box...from anywhere in the world!

So what's the Plan?


The plan is to build a Raspberry Pi web server and connect it to our home network.

With the Pi web server linked up like this:-

Pi Webserver with local access only


...I can access my personal web pages simply by pointing the browser on my laptop or phone to the web servers local IP address and port number.

So assuming my Raspberry Pi has an IP address of: 192.168.0.77 and I've used port 9080 for the web server, I point the browser at: http://192.168.0.77:9080/ to view the default page.

But if I want to access my web server from outside the relative safety of my local network, I'll need to punch another hole in my firewall like this:-

Pi web server: internet access


...which I can do by re-configuring my router, allowing me to access my web server using my internet IP address + port: http://123.45.67.89:9080/

I think I should be able to safely remote into my Pi via the local network using VNC or RDP. But to safely remote into my Pi from the internet, I need to use SSH and open up a second port (22) to the outside world.

How to configure


I started with a new Raspbian install and entered:-

sudo raspi-config
Note: all commands like this one, in this font are entered in the terminal
I didn't change the default user (pi) but I did change to a complicated (safer) password. I also enabled SSH, changed the host name (...well I don't want 6 Pi computers called raspberrypi) and made the usual hash-up of trying to select the correct keyboard & locale.

At some point I updated/upgraded the software and did a firmware upgrade:-

sudo apt-get update
sudo apt-get upgrade
sudo rpi-update

As this system will be headless once the initial configuration has been completed, I also added RDP so I can use a GUI interface in addition to SSH:-

sudo apt-get install xrdp

The next step is to install the light-weight webserver lighttpd (a.k.a. Lighty):-

sudo apt-get install lighttpd

The server-side scripting language PHP looks like fun, so I've installed that too:-

sudo apt-get install php5-common php5-cgi php5

The fastcgi-php module should be enabled to allow the webserver to handle PHP:-

sudo lighty-enable-mod fastcgi-php

You should see a message about enabling changes, so do this:-

sudo service lighttpd force-reload

Your new web directory /var/www is currently owned by root, so change owner and group to www-data:-

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

You want to be able to edit web files as user "pi" so add the pi user to the www-data group:-

sudo usermod -a -G www-data pi

Now you just need read-write-execute permissions:-

sudo chmod ug=rwx /var/www

So if you are following this, you are almost ready to access the default web page locally by using a suitable LAN address.

The final step is to tell the web server which port to use. I also wanted a second web-site, so I created a new folder on the Pi: /var/www/sec, and in the lighttpd config file: /etc/lighttpd/lighttpd.conf I added a few extra lines:-

server.document-root        = "/var/www"
server.upload-dirs          = ( "/var/cache/lighttpd/uploads" )
server.errorlog             = "/var/log/lighttpd/error.log"
server.pid-file             = "/var/run/lighttpd.pid"
server.username             = "www-data"
server.groupname            = "www-data"
server.port                 = 9080

$SERVER["socket"]==":9090"{
server.document-root        = "/var/www/sec"
}


...so now, after a system reboot, I can access the primary site as:-

http://192.168.0.77:9080/

...where I can see the default home page...
...and the secondary site as:-

http://192.168.0.77:9090/


Headless access


As mentioned, I have installed xrdp so that I can remote access the Pi using Remmina on Linux as a graphical session (or if you must use Windows, you can use Remote Desktop Connection).

I think this should be safe, but DO check this out for yourself. I can only remote-in this way over the local network, not via the internet.

I thought it might not be safe to enable any folder shares, so I cannot move files between the Pi and my laptop over my network.

However, by using SSH (secure shell) and SCP (secure copy) I can safely transfer files and also remotely access the Pi locally or via the internet. (Again, on Windows use can use Putty and pscp.exe).

Punching a hole in the wall


Details of how to open up your firewall and do "port-forwarding" vary by router model and type, so please refer to this website.

For my Netgear router it is simply a matter of:-
  1. adding a Custom Service to the Services table (i.e specify Type=TCP, port number=9080 & giving it a name or ID)
  2. include this "Inbound Service" in the Firewall Rule list (specifying service id & Pi local IP address).
  3. repeating this process for the second port (9090)
  4. if you need SSH access over the internet, open port 22 using the same approach

My IP address keeps changing


My service provider (Plusnet) uses DHCP, so my internet IP address changes if I reboot the router, and for other unspecified conditions. This is not a huge problem at the moment as I just make a note of the current address when I want to play with the web server.

There are (at least) 2 ways to overcome this:-
  1. ask your ISP for a static IP address (this is not the best approach)
  2. sign up to a DNS service. I haven't used one, but Duck DNS is free and seems to have a good reputation.

Conclusion


Well, it's a start. In a subsequent post, I will discuss how to create a WebSocket using Tornado, which should give near-real-time two way communication between my Android phone and RaspberryPi.

No comments:

Post a Comment