Saturday, April 30, 2016

OwnCloud server on Raspberry Pi 3

<- Raspberry Pi as Classroom Server and Digital Pet

Encouraged by the performance of running a basic wiki engine on the new Raspberry Pi 3, we can try a more resource intensive service. OwnCloud is a popular web based file-sharing solution, similar to Google drive or Dropbox. Reports of running OwnCloud on the original Raspberry Pi have generally been discouraging for performance reasons.

We continue using the same lightweight web server setup from the last tutorial. Although not really recommended, we are using sqlite instead of a server based database, primarily out of simplicity and to minimize the amount of services we need to run within the tight memory constraints of the Raspberry Pi.

The basic installation of the ownCloud server is as simple as downloading the desired version and moving it to a path in the web server root directory:

$ sudo wget
$ sudo tar xvf owncloud-8.2.3.tar.bz2 
$ sudo mv owncloud /var/www/
$ sudo chown -R www-data:www-data /var/www/owncloud

OwnCloud requires a series of additional PHP modules which we can install with

sudo apt-get install openssl ssl-cert php5-cli php5-sqlite php5-gd php5-common php5-cgi php-pear 
 php-apc curl libapr1 libtool curl libcurl4-openssl-dev php-xml-parser php5-dev php5-gd 

OwnCloud requires https enabled, which most easily can be done by adding/uncommenting the following at the beginning of the server section in /etc/nginx/sites-available/default:

listen 80 default_server;
listen [::]:80 default_server;

# SSL configuration
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
# Self signed certs generated by the ssl-cert package
# Don't use them in a production server!
include snippets/snakeoil.conf;

This is using a self-signed certificate to assert the identity of the server, which most browsers will block with a security warning. This could be avoided by obtaining a certificate from one of the certification authorities trusted by the browser, but such certificates can only be obtained for the identity of a public fully qualified domain name and not for an ad-hoc self defined name in .local.

In order to enable support for the ownCloud installation in /var/www/owncloud add the following additional location section at the end of the main server section in /etc/nginx/sites-available/default:

location ^~ /owncloud {
  # set max upload size
  client_max_body_size 512M;
  fastcgi_buffers 64 4K;

  # Disable gzip to avoid the removal of the ETag header
  gzip off;

  # Uncomment if your server is build with the ngx_pagespeed module
  # This module is currently not supported.
  #pagespeed off;

  index index.php;

  error_page 403 /owncloud/core/templates/403.php;
  error_page 404 /owncloud/core/templates/404.php;

  location ~ ^/owncloud/(build|tests|config|lib|3rdparty|templates|data)/ {
   deny all;

  location ~ ^/owncloud/(?:\.|autotest|occ|issue|indie|db_|console) {
   deny all;

  rewrite ^/owncloud/remote/(.*) /owncloud/remote.php last;
  rewrite ^/owncloud/core/doc/([^\/]+)(?:$|/) /owncloud/core/doc/$1/index.html;

  try_files $uri $uri/ =404;

  location ~ \.php(?:$|/) {
   fastcgi_split_path_info ^(.+\.php)(/.+)$;
   include fastcgi_params;
   fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
   fastcgi_param PATH_INFO $fastcgi_path_info;
   fastcgi_param HTTPS on;
   fastcgi_param modHeadersAvailable true; #Avoid sending the security headers twice
   #fastcgi_pass php-handler;
   fastcgi_pass unix:/var/run/php5-fpm.sock;
   fastcgi_intercept_errors on;

  # Adding the cache control header for js and css files
  # Make sure it is BELOW the location ~ \.php(?:$|/) { block
  location ~* \.(?:css|js)$ {
   add_header Cache-Control "public, max-age=7200";
   # Add headers to serve security related headers
   # Before enabling Strict-Transport-Security headers please read into this topic first.
   # add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;";
   add_header X-Content-Type-Options nosniff;
   add_header X-Frame-Options "SAMEORIGIN";
   add_header X-XSS-Protection "1; mode=block";
   add_header X-Robots-Tag none;
   # Optional: Don't log access to assets
   access_log off;

  # Optional: Don't log access to other assets
  location ~* \.(?:jpg|jpeg|gif|bmp|ico|png|swf|svg)$ {
   access_log off;

After restarting the server with sudo /etc/init.d/nginx restart. The use the browser to navigate to http://raspberrypi.local/owncloud/ and follow the instructions for database setup (use Sqlite) and creating and admin account.

After that, log in as the admin user and use the admin settings in the upper right part of the screen to add new users and continue configuring the server settings.

For a single user setup, this very basic installation of ownCloud is surprisingly usable for file sharing for at least a small number of files.

Thursday, April 21, 2016

Raspberry Pi as Classroom Server and Digital Pet

With the new Raspberry Pi 3 just out and presumably much faster than the original, I wanted to try again how well it would hold up as a really small scale server for hosting web applications.

Over the last few years, Raspberry Pi had mostly made its mark in the maker community as a small low-power embedded computer.

Even the official Raspbian image is now available in a "lite" version, optimized for headless servers. It now has out of the box IPv6 as well as the avahi daemon enabled, making the changes described in this earlier tutorial no longer necessary. Installing a Raspberry Pi server is now easier than ever: copy image to a flash card, plug into any network (including direct tethering) and connect to it under its default name : ssh pi@raspberrypi.local. The hostname can easily be changed when running sudo raspi-config along with other settings (extend filesystem, change GPU memory allocation etc.).

Back to the original education use-case, a Raspberry Pi is quiet and low-power enough that it could be used as an always on micro-server in the classroom as a sharing platform and to give students a taste of what it means to run "mission critical" IT infrastructure themselves.

The oldest, most basic, most lightweight but also most flexible platform for managing and collaboratively authoring web based documents is a wiki. Wikis impose almost no restrictions on the structure, except consisting of a series of inter-linked pages. Pages or sections can be edited easily in place using a simplified markup syntax for formatting and structure. Wikipedia, the most famous of wikis, is still one of the most popular sites on the Internet today and demonstrates the power and flexibility of the wiki model.

Among the man wiki engines, one that is frequently recommended as being particularly lightweight and suitable for Raspberry Pi is DokuWiki. It uses plain-text files for its storage backend, not needing an additional database, it is simple to install and configure and the UI looks reasonably up to date.

In order to host the DokuWiki engine written in PHP, we need a lightweight web server with fast PHP execution. For another tutorial, we have used lighttpd as a small footprint web server, this time we are trying out nginx another highly resource efficient web server that is somewhat more widely adopted.

First to install the missing packages for nginx with fast PHP support:

sudo apt-get install nginx php5-fpm php5-cli php5-mcrypt php5-gd

The download the latest version of the DokuWiki distribution and install it in a "wiki" subdirectory under the default document root tree of the server:

$ wget -O dokuwiki.tgz
$ tar xzf dokuwiki.tgz
$ sudo mv dokuwiki-2015-08-10a /var/www/wiki
$ sudo chown -R www-data:www-data /var/www/wiki

Then we edit the default host config of the nginx web server

sudo vi /etc/nginx/sites-available/default 

and insert the following configuration:

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    root /var/www;

    # Add index.php to the list if you are using PHP
    index index.html index.htm index.php docu.php;

    server_name _;

    location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to displaying a 404.
        try_files $uri $uri/ =404;

    #Remember to comment the below out when you're installing, and uncomment it when done.
    #location ~ ^/wiki/(data/|conf/|bin/|inc/|install.php) { deny all; }

    location ~ \.php$ {
        try_files $uri $uri/ /doku.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param REDIRECT_STATUS 200;
        fastcgi_pass unix:/var/run/php5-fpm.sock;

and after each configuration change, restart the web server:

sudo /etc/init.d/nginx restart

To initialize the wiki, point a browser at http://raspberrypi.local/wiki/install.php and answer the settings questions on the web form.

For the most simplicity we could choose full public mode for reading and editing, but seeing who has made which changes in the revision history might also be useful for a classroom setting and encourage some level responsibility and accountability on behalf of the students. In this case, we choose public for read and authenticated users for editing as well as the checkbox to allow users to register themselves.

After finishing setup, we use the newly created admin user to log in, and choose the Admin function from the top right and choose "Configuration Manager" from the list to uncheck the box "Autogenerate passwords" under authentication and save. Since we do not have email service set up, this requires the user to enter a password at registration time rather than trying to send an auto-generated one by email. Then we can comment out the corresponding line in the web-server config above to block access to the wiki-engine internals.

On the Raspberry Pi 3 the wiki is surprisingly snappy and responsive and indeed a long way from the slow response times of the earlier version of the hardware. It seems that Raspberry Pi has now reached a level of performance that is quite usable in a small scale setting.

Depending on the expected volume of content created on the wiki (especially uploaded attachment and media files), the flash-card should be sufficiently large or an external USB disk should be mounted - however an external USB drive might increase noise and power consumption.

Students could use the wiki to create their own homepages, collaborate on projects or share media projects they have created. Being able to experiment with a permissive and open platform in a protected setting (i.e. not on the Internet) can help to teach the basis of respectful interaction in a virtual environment.