QNAP TS-251+ would be an ideal choice for a personal NAS, but at €500.-, it’s expensive for my humble needs. Someday I might upgrade to one of these with all the bells and whistles, and may even have it run ZFS; just not today. For now, I’ve opted to build one from scratch at one-twelfth its cost.

Functional requirements:

  1. Low cost and tiny footprint
  2. Setup on an Apple Airport powered home router
  3. Secure personal cloud with access worldwide
  4. Very low power consumption1, so that it can stay alive by sharing a low capacity UPS with my wireless network router

I realised I could satisfy the above requirements by simply re-purposing my €40.- Raspberry Pi for this task. It took the following 3 workflows to get it working2:

1. Raspberry Pi setup

  1. Raspbian lite image installed
  2. Defaults changed
  3. SSH enabled with access via public key, and
  4. Hardened for security

2. Home router setup

  1. Pi’s local IP address reserved under Network tab → DHCP Reservations
  2. Port-forwarding set up under Network tab → Port Settings

3. DDNS setup

  1. DDNS records updated on service provider’s control panel to map a private domain I own
  2. Pi’s IP address setup to refresh periodically using Anacron3

NAS access

Currently set up to be accessible only via a shell on a custom port. For login, I run a command like below:

ssh <userid>@<privatedomain> -p <custom port>

But mostly, I use rsync to download or upload files (or folders), and git to push or pull code from my private repositories — since my NAS also functions as a private git server.

rsync -auvz -e 'ssh -p <custom port>' <userid>@<privatedomain>:/home/<userid>/d/somefile.pdf ./somefile.pdf

Unlike most NAS, my drives stay disconnected and need a human to connect it physically before I can mount a drive virtually and then access files on it — this is by design.4

NAS access from restricted networks

Occasionally, I have to deal with networks that restrict outgoing SSH connections. For this, I use Corkscrew to tunnel through https proxies via ports, e.g., 443, which restricted networks do not typically block to avoid service disruptions. So, if I use port 443 as an example to tunnel through a proxy, then the login command becomes:

ssh <userid>@<privatedomain> -D 443 -p <custom port>

Configuring is very simple, just add a config file to .ssh folder with the following details:

ProxyCommand /usr/local/bin/corkscrew <proxy server> 80 %h %p

Replace <proxy server> with the actual proxy address, and you’re good to go. For a select host, this can be as follows:

Host <privatedomain>
ProxyCommand /usr/local/bin/corkscrew <proxy server> 80 %h %p

When not needed to tunnel-through, I just rename config to _config to turn-off http(s) tunnelling.


The NAS is also mobile shell enabled — to allow roaming + intermittent connectivity.5 As mosh works over UDP, I had to allow a port range, and install iptables-persistent.

sudo iptables -I INPUT 1 -p udp --dport 60000:60100 -j ACCEPT
sudo service iptables save
sudo apt install iptables-persistent

Mosh makes you feel like you have super powers, no really! One would think it would be mindless to back-up a laptop on a bus travelling on rural roads with patchy cellular network to a raspberry-pi connected storage at home. And yet, I do exactly this and often on my 90min long evening commute.

  1. In a country where power fluctuates like flashing lights on a Christmas tree, the only way to stay alive during critical differential backup routines is to consume less power. 

  2. You’ll note that this is not a step-wise how-to post. Instead, I’m keeping it high-level with key steps that matter for a successful setup, and by which I mean some steps may require one to research and follow instructions elsewhere. 

  3. I use Anacron since I don’t necessarily find the need to keep the Pi accessible 24×7, but only on days I think I need access. Periodic update is needed for home internet connections with dynamically assigned IP addresses by ISPs. 

  4. Also to conserve power, I’ve turned off display power circuitry on the Pi by disabling HDMI (via /usr/bin/tvservice -o; -p would enable it again). 

  5. mosh is installed on both the client and the server.