Cheap, homemade NAS with Raspberry Pi

2024-05-21, 17:53:18

This is a very simple, cheap and quick way to get networked storage at home. It should not cost more than €120 for all the components (assuming you've got a network you can plug it into). It also offers more flexibility than a commercial NAS, because you can install any software you want on it. And if you already use the Raspberry Pi for something else, you can just add this to it and not worry about an extra device you need power, networking, space and maintenance for.

A Raspberry Pi is already 4-bay since it has 4 USB ports. You can use a hub for more drives, since no HDD will use the full potential of USB 3.0. Just keep in mind you need an adapter for each.

However, for large-scale use, this method should be done with a different type of computer, not a Raspberry Pi.

I assume you know some things about GNU/Linux, SSH, and networking. This guide is not for that; if you don't know these things read some material when you need it.

If you think this is for you, keep reading.

Materials

My setup

Total: €221. Now, this is not the cheapest setup. I use that Pi for other things as well. You can certainly have a cheaper setup:

Low-cost setup

Total: €113, with drive included!

What about a "real" NAS?

Cheapest NAS I could find is €180! It is 1-bay and has 1GB of RAM. It doesn't do anything else, it doesn't use standard protocols, it runs a proprietary OS, it's bulkier and much more expensive. (The brand is Synology.)

No, it doesn't come with drives. Using the same drive as above, it would reach €230.

Well, it's plug-and-play but that makes it much more restricted. Also, it does have a warranty and professional support. However, it's not the kind of NAS a business would use either.

Setup (skip if you already have the computer set up)

  1. Flash your microSD card. Raspberry Pi recommends their own (free) software, Choose an OS without a GUI: Raspberry Pi OS Lite, Ubuntu enable SSH and preset the Wi-Fi settings if you're going

  2. Put the card in the computer, plug in the network and start it.

  3. Find out the IP address of the computer. You can use your router's web interface, or a network Now is a good time to set up a static IP address for the computer, forward its ports dynamic DNS if you want to access it from the internet. YDNS is a imple and free service for that. Their official client is also free software.

  4. Connect to your server via SSH. On GNU/Linux or Macintosh you can use the preinstalled ssh On Windows, you can use PuTTY.

  5. Set a root password with sudo passwd. Then su.

  6. Update the system with apt update && apt -y upgrade.

Set up the drives

You must edit the /etc/fstab to automatically mount the drives on boot. If you know how to do this, you can do it yourself. For the rest of the tutorial the mount point will be /storage.

  1. Turn off the computer and plug in the drive(s).

  2. Turn on the computer.

  3. lsblk to find the drive(s). They should be /dev/sd followed by a letter. For now we'll

  4. Find the drive's UUID with blkid /dev/sdX1.

  5. Add the drive to the /etc/fstab as such:

    =00000000-0000-0000-0000-000000000000 /storage ext4 defaults 0 2

Replace the UUID with the one you found and, if you want, the mount point (/storage in this case) with another one, and the filesystem to match the one you formatted the drive with. Change the last column to 0 to disable fsck for that drive.

  1. mkdir /storage to create the mount point.

  2. Reboot.

Give each user their private directory

We'll mirror the home layout. However, we won't move the existing home directories, because then users can't use the SD card, and you may have some other apps to run on the server that you want to be separate from the mass storage.

Write a systemd service to create the directories on boot. Give it a name inside /etc/systemd/system/, like /etc/systemd/system/setup_storage_dirs.service

[Unit]
Description=Update private user storage spaces

[Service]
Type=oneshot
ExecStart=/usr/bin/python3 /usr/local/bin/setup_storage_dirs.py

[Install]
WantedBy=multi-user.target

And the script /usr/local/bin/setup_storage_dirs.py:

#!/bin/python3

import os
import subprocess
from pathlib import Path

homes = Path("/home").glob("*")
storage_path = Path("/storage")   # change this if you changed the mount point

for home in homes:
   if home.is_dir():
       user = home.name
       storage = storage_path/user
       bound = home/"Storage"    # change this if you'd like a different name
       if not storage.exists():
           os.makedirs(storage)
           os.chown(storage, home.stat().st_uid, home.stat().st_gid)
           os.chmod(storage, 0o700)
       if not bound.is_dir():
           os.makedirs(bound)
           os.chown(bound, home.stat().st_uid, home.stat().st_gid)
           os.chmod(bound, 0o700)
       
       # Using bind mounts; some file managers don't like symlinks
       subprocess.run(["mount", "--bind", str(storage), str(bound)])

Reboot. Now each user has a private directory on your drive at ~/Storage. You can add more users; each will get their own directory only they can access.

Using the server

This guide does not cover setting up sharing protocols. However, we will use SFTP (FTP over SSH) because it's plug-and-play, the speed difference is negligible, it integrates with system users, it's native (works in the system file manager, no web needed) and, last but not least, it's encrypted.

Since you set up the OS to use SSH, you can use SFTP. All file managers can connect to SFTP servers, except for Windows Explorer, in which case you can use WinSCP. This is not my problem, it's Microsoft's problem. Even the preinstalled file manager on Samsung phones can use an SFTP add-on. Not like Next"cloud"¹ is more integrated.

If you want to mount it there is the sshfs program as well. This is useful if you don't like GUI file managers or want easier access to the files.

SFTP in the terminal

sftp -oPort=22 user@server

If you use port 22, you can omit the oPort option. The commands are identical to the ones in the classic ftp client.

SSHFS

sshfs user@server:/storage/user ~/server

Second argument is the "mount point". If you want to unmount it:

fusermount -u ~/server

SFTP in the file manager

Graphically, you can access SFTP by typing sftp://user@server in the address bar (works in most cases) or by finding an option to connect to a server.

Nemo (GNU/Linux)

File > Connect to server > select type SSH

Material Files (Android)

Menu > Add storage > SFTP server

Amaze (Android)

Plus button > Cloud connection > SCP/SFTP Connection

Windows

Windows Explorer doesn't natively support SFTP. WinSCP is a good client for it, and it's free software.

Samsung phone file manager (Android)

Storage space section > Network storage space > Update the app when prompted > Plus > SFTP server