Tuesday, June 3, 2014

Setting Up My New Home Server

This post contains a substantial amount of geekery; you have been warned.

As I've written previously, I'm using my own server for reading feeds using Tiny Tiny RSS. I also set up file sharing and synchronization between my computers using Owncloud(1). I started last year by installing Ubuntu in a virtual machine on my seven years-old desktop. Canvas, our internet provider, offers a fixed public IP address for a moderate fee, and that lets me access the server from anywhere.

At first I just used the server for tt-rss and copying files between computers. But now I use it for all kinds of stuff. For instance, the Owncloud Android app automatically copies pictures I take with my phone directly to my server. I use the server to synchronize all the research papers I have in Zotero. I'm moving my Git repositories to it. And I can run octave, R, Python and so on on my tablet from anywhere using SSH.

I plan to move my calendar to it and to make a small website as well. I now depend on this server every day, and it's clear that I can't keep using my old desktop for this any longer. It's old and unreliable. It's also big, noisy and uses a lot of power. I need a dedicated machine.

Last month I got a Intel NUC DN2820FYK, a very small form-factor, low power machine. It's small, around 12cm square and about 5cm high, and draws only around 10W. You need to add memory and a hard drive yourself, but that was commendably easy; if you can use a screwdriver you can certainly add the parts you need. I added 8GB memory(2) but chose a slow 5400rpm notebook hard disk. It's cheaper and quieter than faster disks, and the machine will mostly be limited by network speed anyway.

After a quick BIOS update(3) I installed Ubuntu Server 14.04. It installs without any trouble. Full-disk encryption is now available by default, but I skipped that; encryption makes sense on a laptop that you might lose or have stolen, but this server will sit quietly at home. Nobody is going to have direct access to the machine so encryption doesn't feel very necessary.

The Intel NUC sitting atop my old desktop. The NUC is faster, has more memory and larger storage. It also has bluetooth and wifi; it's tiny in comparison to the old machine and almost completely silent. I'm still using the old machine for my film scanner, though.  

It's pretty straightforward to install tt-rss and Owncloud on Ubuntu, but there are a few wrinkles to the process so I thought I'd post it here. Any line that starts with "$" below is a command to run on the command line(4).

Both Owncloud and tt-rss need a database and a web server. I choose to install Postgres and Lighttp. Postgres is mature, stable and efficient. Lighttpd is, as its name implies, a lot more lightweight than Apache, and is commendably straightforward to configure and maintain.

First install the database and web server, along with php and a couple of useful tools:

    $ sudo apt-get install lighttpd php5-cgi php5-curl php5-gd php5-pgsql postgresql openssl bzip2 wget

Owncloud is available in the Ubuntu repository but it's an older version. Better to use the Owncloud official packages. We add the repository and get the key:

    $ sudo sh -c "echo 'deb http://download.opensuse.org/repositories/isv:/Owncloud:/community/xUbuntu_14.04/ /' >> /etc/apt/sources.list.d/owncloud.list"
    $ wget http://download.opensuse.org/repositories/isv:Owncloud:community/xUbuntu_14.04/Release.key
    $ sudo apt-key add - < Release.key

The newest version of Tiny Tiny RSS is also available in a separate repository:

    $ sudo add-apt-repository ppa:webupd8team/tt-rss
    $ sudo apt-get update


Install the package:

    $ sudo apt-get install owncloud

You may want to increase the maximum upload sizes for scripts in /etc/php5/cgi/php.ini. Set something like

    upload_max_filesize = 20M
    max_file_uploads = 50 
    post_max_size = 20M

Set up Postgres. First, run the postgres client psql as user postgres:

    $ sudo -u postgres psql postgres

Use the \password postgres command to set a new password for the user. Create an "owncloud" database user (write down the password!) and create the database:

    $ sudo -u postgres createuser --no-createdb --pwprompt --no-superuser --no-createrole owncloud_user
    $ sudo -u postgres createdb --owner=owncloud_user --template=template0 --encoding='UNICODE' owncloud_db
    $ sudo -u postgres psql --command='GRANT ALL PRIVILEGES ON DATABASE owncloud_db TO owncloud_user;'

Set up lighttpd to serve the Owncloud app. Owncloud is already installed under /var/www/owncloud. We want to make sure people can't access the underlying data directly. Edit /etc/lighttpd/lighttpd.conf, and add:

    $HTTP["url"] =~ "^/owncloud/data/" { url.access-deny = ("") }
    $HTTP["url"] =~ "^/owncloud($|/)" { dir-listing.activate = "disable" }

Enable a couple of web server modules:

    $ sudo lighty-enable-mod fastcgi fastcgi-php
    $ sudo service lighttpd restart

Set up cron (that's a scheduling service) to periodically run various Owncloud housekeeping tasks:

    $ crontab -u www-data -e 

and add this line (it tells cron to run the "cron.php" script every 15 minutes):

    */15  *  *  *  * /usr/bin/php -f /var/www/owncloud/cron.php

This should give you a basic installation already. But we want to make things a little more secure. We'll access tt-rss and serve our files with an encrypted connection using https rather than http. We'll need an SSL certificate and prevent access to Owncloud from ordinary http connections. We're not setting up a public service so we can sign the certificate ourselves. We'll do this as root.

    $ sudo bash
    $ mkdir -p /etc/lighttpd/certs
    $ cd /etc/lighttpd/certs
    $ openssl req -new -x509 -keyout lighttpd.pem -out lighttpd.pem -days 1095 -nodes

Fill in nonsense info or leave blank; it doesn't much matter since we're not going to have a public certificate. Change permissions:

    $ chmod 400 lighttpd.pem

Edit /var/www/owncloud/config/config.php and add to trusted_domains:

    'trusted_domains' => 
 array ('[your public URL, if any]', '[your ip address]'),

and set

    'forcessl' => true,

Edit /etc/lighttpd/lighttpd.conf again, and add:

    $SERVER["socket"] == ":443" {
 ssl.engine = "enable"
 ssl.pemfile = "/etc/lighttpd/certs/lighttpd.pem"

 ssl.use-sslv2 = "disable"
 ssl.cipher-list = "TLSv1+HIGH !SSLv2 RC4+MEDIUM !aNULL !eNULL !3DES @STRENGTH"

That should do it. Now you should be able to access Owncloud using https://yourserver/owncloud but not using http://yoursever/owncloud. When you first create your user, be sure to mark the "advanced" check box and choose Postgres as your database.

Tiny Tiny RSS

tt-rss is really easy to set up, but we need to fix one problem with database access. First, install tt-rss:

    $ sudo apt-get install tt-rss

The installation will ask you a few questions about things like your database and webserver. The setup will partially fail, and the reason is that Postgres by default won't give access to tt-rss. Edit /etc/postgresql/9.3/main/pg_hba.conf and look for a line that looks like this:

    # "local" is for Unix domain socket connections only
    local   all             all                 peer

Change "peer" to "md5" and you're done. Restart the database with sudo service postgresql restart

We want tt-rss to refresh the feed list automatically. Edit /etc/default/tt-rss and change the "disabled" parameter:

    set "DISABLED=0"

Then start the update service:

    $ sudo service tt-rss start

Finally, we want to force tt-rss to use SSL encryption. Add the following to /etc/lighttpd/lighttpd.conf:

    $HTTP["scheme"] == "http" {
 $HTTP["host"] =~ ".*" {
     url.redirect = ("^/tt-rss/.*" => "https://%0$0")

It basically says that if someone tries to access the server with http, for any host name, and if the URL contains "tt-rss", then redirect the request to an encrypted https connection instead.

This setup works admirably so far. The machine itself takes up no space, and it's so quiet I can't hear it even when sitting right next to it. Tiny Tiny RSS has worked just fine ever since I started using it almost a year ago, and Owncloud seems to be reliable and fast.

The Owncloud client is still basic and lacks some needed features — you can't easily exclude a particular folder on the server from synchronization for instance — but it uses the standard WebDAV protocol so you can use any client, your browser or even the file manager to access files on your server. Owncloud is a smooth, mostly painless way to have my stuff accessible from anywhere, and the Intel NUC is a good little machine to run it.

#1 It's similar to, say, Dropbox or Google Drive. But my data is not moved across continents and to different legal jurisdictions whenever I copy something, and I have control over the server where the data sits. I am responsible for keeping the server up and running; on the other hand, I won't get caught flat-footed when an online service is suddenly shut down.

#2 You can never be too rich, too beautiful or have too much memory.

#3 Put the recovery BIOS FY0032.BIO from here onto a USB stick then reboot into the BIOS setup. In the BIOS update function, select the file on the stick. Easy.

#4 This is a server without a screen or keyboard so I log in remotely and use the command line. But if you want, you can of course start a desktop and use the graphical tools to set things up.


phu said...

Just thought I'd suggest nginx rather than lighttpd. I don't know if it's still the case, but it used to be that the latter had some pretty significant memory leakage issues; that situation persisted for long enough that I just stopped checking and stuck with the former. I use it on a lot of production sites, originally with fastCGI on PHP projects but now with uWSGI for Python, and it's very nice. Pleasant and concise configuration, too.

Jan Moren said...

I actually tried with nginx at first. But I never got it to work properly; I very much disagree about it being pleasant to configure.

I haven't seen any memory leaks with lighttpd so far.