How To - set up a NAS on an RPI using Ubuntu Server

Summary

Steps on how to configure a shared drive on Ubuntu Server 22.04 running on an RPI (Raspberry PI).

Assumptions

This assumes that you have setup Ubuntu Server 22.04 on the RPI see UBU Server 22.04 on a RPI. Ubuntu Desktop 22.04 should also work.

Note that Ubuntu 24.04 should also work as well.

It also assumes you have a USB based drive. I have tried this on these two:

  • WD7500GBPVT - a Western Digital 75OGB
  • Seagate FreeAgent Goflex - a Seagate 500GB

Neither of these is an SSD. It is better to use SSDs since there is no initial delay in connecting to the disk the clients. It is short, but annoying.

I selected exfat for the disk format. As best I can tell, this format works on Ubuntu, macOS and Windows. Other disk formats don't tend to work on Windows. The fat32 is okay, but it seems to limit the size of the segments on the disk drive you use.

Note that exfat does not support file permissions. That means that some linux and macOS based tools may need changes to accommodate it. Most work okay. For example, rsync is okay, but you can't use the "-a" option since it uses file permissions (which don't exist) to send or not a file.

Initial

  • set up an SSH connection to the RPI
  • ensure Ubuntu on the RPI is updated and upgraded
  • check that the drive does not contain any files you want to keep! The instructions below will format the drive and so all data will be destroyed.
  • ensure that the IP address used by the RPI is static. Set up your router to give the same IP address to your RPI always. Most commercial routers have this facility.

Set up the drive on the RPI

  • SSH into the RPI and set up the drive to automatically mount even after rebooting

  • install exfat utilities on the RPI

sudo apt install exfat-fuse exfatprogs
  • choose a USB port on the RPI. When you plug in the drive choose the same port every time. Some tools may use the USB port config to determine if this is a new or an existing drive, changing the port may confuse them.
# unplug the drive from the RPI
# run:
lsblk -o NAME,FSTYPE,SIZE,MOUNTPOINT,LABEL
# this shows the current set of mounted drives on the RPI
[snip]

# plug the drive into the RPI USB port.
# Note: my drive was previously used on a windows box and so had some NTFS partitions on it:
lsblk -o NAME,FSTYPE,SIZE,MOUNTPOINT,LABEL
   sda                  698.6G
├─sda1      ntfs       400M                                     Recovery
├─sda2      vfat       300M                                     ESP
├─sda3                 128M                                     
├─sda4      ntfs     677.2G                                     Acer
└─sda5      ntfs      20.6G                                     Push Button Reset
  • format the drive as an exfat
    • choose a name for it. I chose "wdusb" since this was the Western Digital USB drive.
    • Select the correct sdx name from the lsblk output above. In my case, the only drive on the RPI was "sda".
    • Note: if you choose the wrong drive from lsblk, you will format it and wipe out any content.
$ sudo mkfs.exfat -n wdusb /dev/sda
exfatprogs version : 1.2.2
Creating exFAT filesystem(/dev/sda, cluster size=131072)
[snip]
exFAT format complete!
  • create a partition in the drive. In this example, I've created 1 partition that uses the entire drive
$ sudo fdisk /dev/sda      # <-- use the name from above

Welcome to fdisk (util-linux 2.39.3).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

The device contains 'exfat' signature and it will be removed by a write command. See fdisk(8) man page and --wipe option for more details.

Command (m for help): n   # <--- add a new partition 
Partition type
   p   primary (0 primary, 0 extended, 4 free)
   e   extended (container for logical partitions)
Select (default p): p     # <--- make it a primary partition
Partition number (1-4, default 1): 1    # <--- select 1 or hit enter
First sector (2048-1465149163, default 2048):      # <--- hit enter
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-1465149163, default 1465149163):  # <--- hit enter 

Created a new partition 1 of type 'Linux' and of size 698.6 GiB.

Command (m for help): t   # <--- set the partition type
Selected partition 1
Hex code or alias (type L to list all): 7   # <--- use type 7 which is exFAT
Changed type of partition 'Linux' to 'HPFS/NTFS/exFAT'.

Command (m for help): w   # <--- write partition table to disk and exit
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
  • check it was formatted with exfat:
# reformat it as exfat
$ sudo mkfs.exfat -n wdusb /dev/sda1

lsblk -o NAME,FSTYPE,SIZE,MOUNTPOINT,LABEL
$ lsblk -o NAME,FSTYPE,SIZE,MOUNTPOINT,LABEL
NAME        FSTYPE     SIZE MOUNTPOINT                          LABEL
[snip]
sda                  698.6G                                     
└─sda1      exfat    698.6G                                     wdusb   

mount the drive on the RPI

  • choose a directory on the RPI to mount the drive to. In this case I chose /wdusbnas
$ sudo mkdir /wdusbnas
$ sudo mount /dev/sda1 /wdusbnas

# try it out
$ cd  /wdusbnas
$ sudo touch hello.txt
$ ls -al
$ ll
total 132
drwxr-xr-x  2 root root 131072 Nov 17 15:38 ./
drwxr-xr-x 23 root root   4096 Nov 17 15:38 ../
-rwxr-xr-x  1 root root      0 Nov 17 15:31 hello.txt*
  • add the drive to /etc/fstab so it is mounted automatically at boot time and mounted with your user permissions
$ sudo blkid
[snip]
/dev/sda1: LABEL="wdusb" UUID="FFFB-6DA8" BLOCK_SIZE="512" TYPE="exfat"

# get your userid info; you need the id and the group id. 
$ id
uid=1002(arrizza) gid=1002(arrizza) groups=1002(arrizza), etc.

# add a new line to /etc/fstab
$ sudo nano /etc/fstab
UUID=FFFB-6DA8 /fastnas exfat defaults,uid=1002,gid=1002 0 0

# note:
#   * the UUID is the one from the blkid command
#   * the uid is the one from id command
#   * the gid is the one from the id command
 ```

* mount everything in the fstab

```bash
$ sudo mount -a

$ ls -al /wdusbnas/
total 132
drwxr-xr-x  2 arrizza arrizza 131072 Nov 17 15:43 ./
drwxr-xr-x 23 root    root      4096 Nov 17 15:38 ../
-rwxr-xr-x  1 arrizza arrizza      0 Nov 17 15:31 hello.txt*

# I added a couple words to hello.txt at this point
  • double check that it mounts after a reboot
$ sudo reboot

Broadcast message from root@rpi-02 on pts/1 (Sun 2024-11-17 15:44:46 MST):
The system will reboot now!

$ Connection to rpi-02 closed by remote host.   # <-- in my system, the RPI is rpi-02
Connection to rpi-02 closed.
$ ssh rpi-02
$ cd /wdusbnas/
$ ls -al
total 260
drwxr-xr-x  2 arrizza arrizza 131072 Aug 27 08:37 ./
drwxr-xr-x 23 root    root      4096 Nov 17 15:45 ../
-rwxr-xr-x  1 arrizza arrizza     14 Nov 17 15:44 hello.txt*   # <--- the 14 bytes is the content I added.

At this point, the drive is mounted automatically to the same directory whenever the RPI is rebooted.

setup samba on RPI

  • install samba
$ sudo apt install samba
  • configure samba to share the mounted USB drive
# create a share section at the bottom of the samba configuration file 
sudo nano /etc/samba/smb.conf

[wdusbnas]   # <--- call the share something unique in your network
    comment = WD USB drive
    path = /wdusbnas
    writeable=Yes
    create mask=0777
    directory mask=0777
    public=no

# restart the samba service to pick up these changes
sudo systemctl restart smbd.service nmbd.service
  • set up a samba userid and password to use
sudo smbpasswd -a a_userid  # <--- change this to something you can remember
# enter password here       # <--- use a password you can remember

# restart service
sudo systemctl restart smbd.service nmbd.service
  • double-check the IP address your router has statically allocated to your RPI
$ ip address
[snip]
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether d8:3a:dd:13:7e:f6 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.16/24 brd 10.0.0.255 scope global noprefixroute eth0

# Usually the driver is eth0. THe IP address is 10.0.0.16 

setup up a client Windows connection

  • open Windows Explorer
  • in the left pane, right click on "Network"
  • click "Map network drive..."
  • set the "Drive" to whatever is good for you. Mine was "X:"
  • In the "Folder" enter "\10.0.0.16\wdusbnas" i.e. the ip address of the RPI and the share name from the smb.conf file
  • select on "Reconnect at sign-in". On subsequent mappings, you won't have to enter your userid/password
  • click "Finish"
  • get dlgbox "Enter network credentials"
  • in "User name" enter the user id you entered for smbpasswd above
  • in "Password" enter the password you entered for smbpasswd above
  • click "OK"

To test:

  • create a file x:\win.txt using notepad, enter some text
  • ssh into the RPI
$ ls -al /wdusbnas
total 388
drwxr-xr-x  2 arrizza arrizza 131072 Nov 17 17:46 ./
drwxr-xr-x 23 root    root      4096 Nov 17 17:25 ../
-rwxr-xr-x  1 arrizza arrizza     19 Nov 17 17:24 hello.txt*
-rwxr-xr-x  1 arrizza arrizza     12 Nov 17 17:45 win.txt*

$ cat /wdusbnas/win.txt
# you should see the text you entered above

setup up a client Ubuntu connection

From Ubuntu desktop:

  • open Nautilus File Manager
  • click on "+ Other Locations"
  • Your RPI should be there e.g. "RPI-02"
  • click on "RPI-02"
  • There should be two names: "print$" and "wdusbnas"
  • click on "wdusbnas"
  • dlgbox "Authentication Required"
  • click "Registered User"
  • in "Username" enter the user id you entered for smbpasswd above
  • in "Domain" the default is "WORKGROUP" and that is the default in smb.conf on the RPI
  • in "Password" enter the password you entered for smbpasswd above
  • click on "Connect"

You should see the "hello.txt" and "win.txt".

  • click on the 3 vertical dots, click on "Open in terminal"
$ ls -al
total 1
drwx------ 1 arrizza arrizza  0 Nov 17 17:48 .
dr-x------ 4 arrizza arrizza  0 Oct 16 16:50 ..
-rwx------ 1 arrizza arrizza 19 Nov 17 17:24 hello.txt
-rwx------ 1 arrizza arrizza 14 Nov 17 17:48 win.txt

$ nano ubu.txt
# add some text
  • go to RPI and cat ~/wdusbnas/ubu.txt, should see the text you entered.
  • go to windows and open ubu.txt, should see the text you entered.

setup up a client macOS connection

From macOS:

  • open Finder
  • click on "Go" in menu
  • click "Connect to Server..."
  • in "Server Address" click on down-arrow to see list of network shares
  • click on smb://RPI-02...
  • when "wdusbnas" shows up, click on OK

To access it from the command line, open a terminal:

$ ls /Volumes
# the wdusbnas should be visible

$ ln -s /Volumes/wdusbnas ~/wdusbnas
$ cd ~
$ ls -al wdusbnas
lrwxr-xr-x  1 arrizza  staff    17B Nov 17 18:28 wdusbnas -> /Volumes/wdusbnas
$ cd wdusbnas
$ ls -al
total 1568
drwx------  1 arrizza  staff    16K Nov 17 18:20 .
drwxr-xr-x  5 root     wheel   160B Nov 17 18:26 ..
-rwx------@ 1 arrizza  staff   6.0K Nov 17 18:19 .DS_Store
-rwx------  1 arrizza  staff   4.0K Nov 17 18:04 ._.DS_Store
-rwx------  1 arrizza  staff   4.0K Nov 17 18:20 ._win.txt
-rwx------  1 arrizza  staff    19B Nov 17 17:24 hello.txt
-rwx------  1 arrizza  staff    16B Nov 17 17:58 ubu.txt
-rwx------@ 1 arrizza  staff    14B Nov 17 17:48 win.txt

$ nano macos.txt
# add some text
  • go to RPI and cat ~/wdusbnas/macos.txt, should see the text you entered.
  • go to windows and open macos.txt, should see the text you entered.
  • go to Ubuntu and open macos.txt, should see the text you entered.

- John Arrizza