🧭 deepwest

Alpine Linux: Home NAS Setup

Published on 2021-01-02

This guide assumes the following:

Adding administrator accounts

Start by adding any users who will be administrating the NAS:

adduser mea -G wheel
adduser siblinga -G wheel

In my case I will simply add an "a" on the end to differentiate them from the normal accounts. We are also adding them to the wheel group, which will give our admin users greater access to the system, such as privilege escalation with sudo.

We separate the users so we can limit the normal accounts access to the NAS system files.

Next create a group for our normal users:

addgroup nas

Setting up sudo

It is now time to setup sudo, and give elevated privileges to our administrator accounts.

First install the sudo software and documentation using Alpine's package manager:

apk add sudo sudo-doc

In order for this to have any effect, we will edit the sudoers file using the command: visudo.

Keep in mind this will open in the vi text editor, if you aren't comfortable with this editor and would prefer nano, type :q to exit. Install nano with sudo apk add nano and run visudo with EDITOR=/usr/bin/nano visudo.

When in the editor find the line that says "User privilege specification". Next find the command to allow all users part of the wheel group to use sudo.

It should look something like this:

# %wheel   ALL=(ALL:ALL) ALL

By default in Alpine Linux it is "commented out" by default, so that it isn't active. Make it active by removing the #:

%wheel   ALL=(ALL:ALL) ALL

In the config file there is also a variation without password, in the interest of security, I would advise against enabling that.

Save and exit the editor. And logout of the root account using the exit command.

Next login into one of the accounts that you added to the wheel group. You should test sudo with sudo -v, if the output is empty, then you have sudo access.

We should now disallow login to the root account, otherwise the root account will be an easy target for attackers:

sudo passwd -l root

SSH

In order to remotely access the NAS we need to have SSH enabled. Thankfully Alpine Linux setup asks you to install a ssh server (this guide uses the OpenSSH server). If not then you could install with: sudo apk add openssh openssh-doc.

On the NAS execute the command: ip a, and in the output find your ethernet interface (usually formatted like enp3s0). Then find the IP address, mine looked like: inet 192.168.1.100/24. Note that the /24 part is not part of the IP address.

From another computer connected to the same local network execute the ssh command, make sure to replace mea with your relevant admin account, and replace the IP address with the IP from the command above.

ssh mea@192.168.1.100

A script for making normal users

To easily add NAS users, I have made a script. It will add system and Samba accounts if they don't exist, then ask you to set passwords for both. Don't worry about Samba right now, we will get that setup later.

For now lets get the script installed:

Create a new file with your preferred text editor (in this case I use vi)

sudo vi /usr/local/bin/nas-user

Once opened, copy and paste the following script:

#!/bin/sh
user=$1

# Fail script if not root
if [ "$(id -u)" != "0" ]; then
    printf "ERROR: Must be run as root \n"
    printf "Try running 'sudo nas-user' \n"
    return 2
fi

if [ "$user" == "" ]
then
    printf "ERROR: Username not provided \n"
    printf "Expected: 'nas-user [username]' \n"
    return 1
else
    # Try to add a Unix user with no password and part of nas group
    # Then set password with passwd command.
    adduser $user -D -G nas 1&> /dev/null || true && \
    passwd $user && \

    # Do the same with Samba
    smbpasswd -a $user && \
    return 0
fi

Now give it execute permissions:

sudo chmod +x /usr/local/bin/nas-user

The script won't work right now, as we don't have Samba installed. We will worry about this later.

Manual Pages

In case you get stuck we will be installing the documentation alongside the required software. In order to view these docs we need a program called man installed:

sudo apk add man man-pages

Now to get help for sudo type: man sudo. Of course substitute sudo with another program you need help with.

Partition the hard drives

Since fdisk cannot partition anything larger then 2TB you should install and use GNU Parted instead.

sudo apk add parted parted-doc

Make sure to only partition the drives you intend to store the data on. I tend to have a 120GB SSD purely for the operating system, while having multiple 3TB HDD's for data storage. Take into account your hard-drive setup while going through these steps.

List the available hard drives using parted:

sudo parted -l

Determine one of the disks that will be used for storage. Make note of the disk names (usually formatted as /dev/sd* for SATA disks.), We now need to partition them, please note this will DESTROY any data on the drive(s):

sudo parted /dev/sd*

Replace /dev/sd* with the relevant disk drive you intend to format.

Set the label to "gpt":

mklabel gpt

Set the units to whatever is relevant to your disk. For example I have two 3TB hard drives, so I will set the units to "TB":

unit TB

Make a primary partition that takes all of the drive.

For example from 0% (the start) to 100% (the end):

mkpart primary 0% 100%

Alternatively, you could use the exact size:

mkpart primary 0.00TB 3.00TB

Then use the print command to check the disk. And quit once you are finished.

Repeat the partition process on all drives that you intend to use for data.

btrfs File-system + RAID 1

In my system I use RAID 1 + btrfs on my NAS hard drives. RAID 1 gives me fallback if one drive physically fails, and the btrfs file-system gives me protection against data corruption. Using RAID 1 alone will not protect you from things like bit rot, and btrfs on it's own won't protect you from a drive dying. But using both systems together is solid. Keep in mind that although btrfs works very well with RAID 1, other RAID levels are not yet stable and use of them could result in data loss.

Your NAS setup should have at least two hard drives with the same size. You should not try and use hard drives with different sizes in a RAID 1 array, since RAID 1 works by mirroring the data to the second drive.

First add btrfs to the modules file (you need run that from a root shell with sudo su). And then install btrfs-progs, which are the tools needed to configure btrfs.

sudo su
echo btrfs >> /etc/modules
exit
sudo apk add btrfs-progs btrfs-progs-doc

btrfs: Create OpenRC service

We need the command btrfs device scan to run at startup so our btrfs drives can be initialised.

In order to do this you need to create /etc/init.d/btrfs-scan with a text editor with sudo, once opened insert the following in the file:

#!/sbin/openrc-run

name="btrfs-scan"

depend() {
  before localmount
}

start() {
  /sbin/btrfs device scan
}

Once the file has been saved, you will need to mark it as executable, and then set to run at boot:

sudo chmod +x /etc/init.d/btrfs-scan
sudo rc-update add btrfs-scan boot

btrfs: Create file-system

Use the mkfs.btrfs command to create a btrfs RAID 1 file-system. -d raid1 means all data will be stored in RAID 1, and -m raid1 means that all metadata will be stored in RAID 1. Remember to replace /dev/sd*1 with your relevant drives.

sudo mkfs.btrfs -d raid1 -m raid1 -f /dev/sd*1 /dev/sd*1
sudo btrfs device scan

Once done you can now check with sudo btrfs file-system show /dev/sd*1

btrfs: Mounting

With a multi-device file system you can mount any device in the FS for the mount command.

sudo mount /dev/sd*1 /mnt

And check the mount with:

sudo btrfs file-system show /mnt

btrfs: Setting up fstab

fstab will enable automatic drive mount on startup.

Just like with mounting you can choose to mount any device in the array and it will mount all other devices. Choose one of the devices and find out what it's UUID is:

blkid /dev/sd*1

Now edit /etc/fstab with your text editor of choice. Create a new line, which we will use for our new entry.

Begin with the UUID of your device:

UUID=[insert uuid here]

You will now need to use the Tab key to move to the next column.

The second column specifies the mount point, for my system I mount at /mnt but you could choose a different location:

/mnt

Third column specifies the file system:

btrfs

Forth column are for options, we use the defaults:

defaults

The last column you just need to type:

0 0

What you have just entered should look something like:

UUID=ba219394-9940-4bf5-be8a-5d466e177504       /mnt    btrfs   defaults        0 0

Now you should reboot to verify that it works: sudo reboot

btrfs: Sources

https://www.cyberciti.biz/faq/linux-btrfs-fstab-entry-to-mount-filesystem-at-startup/

File structure

Now that our btrfs device is mounted, we should create some folders for our users to create files underneath:

sudo mkdir /mnt/Photos
sudo mkdir /mnt/Documents
sudo mkdir /mnt/Public

File permissions

An important step for making sure your users can read/write in certain directories. In this guide we have created a btrfs device and have mounted it under /mnt. Created some example folders under /mnt. And we've made a group called nas for our normal users.

Right now root has ownership of all example folders, meaning that our users won't have access. Before we correct that we should ensure all folder have correct permissions.

Make sure the containing folder /mnt is owned by root:

sudo chown root:root /mnt/

Then, make sure that the permissions on /mnt give the owner (the root user) full access but gives the group and others read and execute permissions only:

sudo chmod 755 /mnt/

Now we will set the nas group onto all of the sub-folders:

sudo chgrp -R nas /mnt/*

Notice the -R option, this means that it will recursively apply this setting onto all of the sub-folders. Be careful with this option!

Let's lock down the permissions by giving root and our group r(ead) w(rite) x(execute) permissions, and giving anyone else no permission:

sudo chmod -R 770 /mnt/*

This will make sure all sub-folders belong to the nas group, and then gives those in the group full access to the files.

If at any point you want to check the file permissions simply use cd to move directories and ls -l to list the files/directories and show owner/group and the permissions.

The permissions are represented as drwxrwxrwx. The d stands for directory, and only appears when the item is a folder. The r stands for read, the w stands for write, and the x stands for execute. These are duplicated 3 times to show the permissions for different users and groups. The first set is for our owner, the second is for the group, and the third is for others (Which is anyone, who doesn't fall into either owner or group).

The set of three numbers in the chmod command represent the permissions for all three groups. The first number is for the owner, the second for the group, and third for anyone else. 7 means full access, 0 means no permission. You can work out what other numbers mean by adding up any of these three numbers:

read = 4
write = 2
execute = 1

So to give someone read and execute permission the number would be 5.

Besides that you should see root nas next to all of the sub-folders. The first is the owner which is root and the group is set to nas, both root and nas have full permission.

File permissions: Sources

Set the hostname

To make it easier to access your NAS, we will set a hostname and a domain: nas.local. The first part is the hostname, second part the domain. You can change the hostname, but you should keep the domain as "local" since that is convention for local network devices.

To change the hostname edit the /etc/hostname file with a text editor using sudo. Clear whatever name in that file and replace it with the new hostname.domainname scheme.

Use the command hostname to print the current hostname of your NAS.

Hostname: Zeroconf with avahi

In order for other computers to discover your NAS through Zeroconf you should setup avahi

Start by installing avahi and dbus:

sudo apk add avahi avahi-doc dbus dbus-doc

Open /etc/init.d/avahi-daemon in a text editor and ensure that under depend(), hostname is listed next to `need'. E.g:

depend() {
        before netmount nfsmount
        use net
        need dbus hostname
}

If hostname isn't listed as a needed dependency, then upon boot, the system will advertise the hostname none instead of the desired name.

Add avahi-daemon to boot:

sudo rc-update add avahi-daemon boot

Reserve DHCP

Next you will have to reserve an address in your router. The default router management IP address should be in the documentation provided with your router. Otherwise use a search engine to find information about your router.

Type this IP address into a web browser.

On the NAS use the command ip a to view network interfaces. More then likely your interface will be called "eth0" (or similar) although if you use WiFi or have two network cards installed, this might be different. Most OS's will have a "loopback" interface beginning with "lo", don't use that one.

In your router use the MAC Address found from the ip a command, and then allocate it an IP address within the same subnet as your router. In my case my router is 192.168.1.1 so I give my NAS 192.168.1.100.

Subnets will be explained later on, but most home equipment uses a subnet of 255.255.255.0 (or /24). This means that you only change the forth number when assigning IP addresses to devices. Keep in mind that 254 is the highest you can go for a particular number.

Once set, your NAS will get the same IP address each time it comes on the network.

Samba

Microsoft's SMB is a well supported protocol for network shares. Samba is an open-source implementation of SMB for Unix-like systems.

Install Samba:

sudo apk add samba samba-doc

We can now use the user setup script we installed at the beginning of this document. Create any user you will need:

sudo nas-user me
sudo nas-user sibling
sudo nas-user mother
sudo nas-user father

This will create both a Unix and Samba account with the same name. You will need to enter your password 4 times. It will also sometimes look like no input was detected, but it is working, just invisibly.

We now need to edit the Samba config file, located at /etc/samba/smb.conf. You should make a backup of it with sudo cp /etc/samba/smb.conf ~. Open this file with a text editor and lets get underway...

The text file is quite huge and shows many example configuration settings, most are commented out (meaning they are inactive by putting a symbol at the beginning of the line). You should completely delete what is in the file for simplicity sake.

Defining a share is simple, just put the name you want (anything except for "global") between two square brackets. Underneath it is where you add configuration options.

For the purposes of a simple home NAS, here is the config that I use:

[global]
        server string = nas
        server role = standalone server
        hosts allow = 192.168.1.0/24
        hosts deny = 0.0.0.0/0
        force group = nas
        inherit permissions = yes
        force create mode = 0750
        force directory mode = 0770
        client min protocol = SMB3

[Share]
        comment = Files shared will all users.
        path = /mnt
        valid users = @nas
        read only = no
[Public]
        comment = Read-only for guests
        path = /mnt/Public
        read only = yes
        guest ok = yes
        map to guest = Bad User

hosts allow and deny is an important one, as it will limit the IP address range that can access your home network. Make sure to change the network address for "hosts allow" so that it matches the subnet used by your router. From what is set above, the NAS will allow anyone connecting from 192.168.1.1 to 192.168.1.254, and deny anything else.

Keep in mind that there are a number of private address ranges, and your router could be using any of the following:

10.0.0.0 - 10.255.255.255
172.16.0.0 - 172.31.255.255
192.168.0.0 - 192.168.255.255

Most home networks should have the subnets at /24 (can also be represented as 255.255.255.0), so working out the network address is a simple as replacing the last character with a 0.

If in doubt, use a subnet calculator! Alpine Linux has one called sipcalc, installed with apk. Simply give it the IP and subnet mask from inside your routers management site: sipcalc 192.168.1.1 255.255.255.0 and it will provide information about the subnet. The network address and CIDR notation is what you put in hosts allow.

Now is a good time to try and simplify your home network (if need be) to prevent confusion. You really only need one device functioning as a router. Most new gear gives you a setting to put the device in "Bridge mode" (whereby the router functions are disabled and the device acts like a dumb access point). I would suggest enabling bridge mode on any other router or managed switch that isn't your main.

Back to the smb.conf:

The various "force" options will enforce permissions on any new file uploaded. Refer to the "File Permissions" section for more details.

The minimum protocol will prevent clients from using an older version of SMB. You might want to change this to SMB2 if you still have Windows 7 PCs.

I have added "@nas" to the valid users, the @ symbol tells Samba to allow any user from that group. This is why it is essential to have the same SMB and UNIX usernames.

I have also made a read-only group for guests that will allow access to anything in the "Public" folder. This is useful for setting up things like Kodi, without having to store a password.

For detailed information on any samba option, refer to the man page man smb.conf, or the web.

Finally, set the samba service to start on boot and then start for current session:

sudo rc-update add samba
sudo rc-service samba start

Cronjobs

We want to run certain maintenance tasks consistently and automatically. Cron is perfect for this. We specify a time for a script to be run, and cron will run it at the specified time.

First we need to start crond and set it to startup on boot:

sudo rc-update add crond
sudo rc-service crond start

By default scripts in the folder /etc/periodic/daily will run everyday at 2am. If you are not planning on having the NAS on 24/7, you can change this to a better time by running sudo crontab -e. By default Alpine Linux gives you hourly, daily, weekly etc. folders, all the scripts in these folders will be run at the set time each hour/day/week. In our entry for the daily period, you can see that it is set to run at the 2nd hour (2am in the morning):

# min   hour    day     month   weekday command
0       2       *       *       *       run-parts /etc/periodic/daily

Using 24hour time we can change this to be (for example) 6:30PM in the evening:

# min   hour    day     month   weekday command
30      18      *       *       *       run-parts /etc/periodic/daily

Save and quit once you are happy.

The first script we'll write is one to automatically update all Alpine Linux packages:

sudo vi /etc/periodic/daily/package-update

#!/bin/sh

/sbin/apk update && /sbin/apk upgrade

Now use sudo chmod a+x /path/to/script to make your script(s) executable.

Use sudo run-parts --test /etc/periodic/[foldername] to reveal what scripts will run.


2. Client-side

SMB

Now that we have our SMB share setup, it is time to access it from our computers.

On Windows, head to file explorer and add a Network location from "My PC". The address will look like:

\\nas.local\share

On Linux, most file managers will allow access through an address bar, or an option titled "other locations" or "connect to server" or "network". Note: Some Linux distros won't pre-install gvfs-smb which is required. Once connected, there should be a way to bookmark to the sidebar. The address to connect will look like:

smb://nas.local/share

Type username and password, set the workgroup to "WORKGROUP" if needed. You can also choose to save the credentials for faster login.

On Linux thumbnails might not display for photos. Check your file manager settings for thumbnails options, most will only display them on local files by default.

There are some drawbacks to using the share through the file manager on Linux. Some other options include adding details to /etc/fstab so that it will mount on boot, or using sudo mount.cifs to mount it. KDE users can also take a look at SMB4k.

SSHFS

Another way to access the NAS is to use SSHFS, it will mount SFTP sites as network drives. I would still recommend SMB over SFTP/SSHFS though.

For Linux-based PCs the GNOME Files app should have this available from the "Other Locations" tab. If you setup avahi, then it should automatically appear in the list. otherwise enter sftp://192.168.1.100 or sftp://nas.local to connect.

Windows requires the installation of sshfs-win in order to connect via the SFTP protocol. But it is best to use SMB on Windows instead.


3. Optional

Chroot SFTP

Begin by opening the SSH config file: /etc/ssh/sshd_config with a text editor in through sudo

Find the following line:

Subsystem sftp /usr/lib/ssh/sftp-server

Comment this command out by adding a # to the beginning of the line, like this:

#Subsystem sftp /usr/lib/ssh/sftp-server

Then below this line add the following command in the old ones place:

Subsystem sftp internal-sftp

Then at the very bottom of the file we need to create rules for our nas group. Here is an example:

Match Group nas
        ChrootDirectory /mnt
        ForceCommand internal-sftp

Afterwards save the file, now restart the service using sudo rc-service sshd restart or restart the NAS.

Now whenever your normal users go to login to SFTP, they will be limited to the /mnt directory. Or in other words /mnt becomes the root folder for these users

chroot: Sources

https://linuxize.com/post/how-to-set-up-sftp-chroot-jail/

4. Changelog