Alpine Linux: Home NAS Setup 2.0
BEGIN IMPORTANT NOTE
This guide is superseeded, please refer to this guide instead. This is only for archival purposes.
END IMPORTANT NOTE
Welcome to my guide on setting up a NAS or file server using the lightweight Alpine Linux distro. This setup is designed to work with two dedicated internal HDDs and a small SSD for booting the operating system.
Unlike the previous guide, this setup does not utilize btrfs or RAID. Instead, we will opt for two separate EXT4 file systems, with one drive serving as a backup. The emphasis here is on creating an incremental backup system rather than relying solely on mirroring with RAID. RAID can provide performance gains and convenience when a disk fails, but it is not a foolproof backup system.
By avoiding RAID, we may experience a decrease in read performance when accessing two different files simultaneously. However, we gain a more robust backup solution that allows us to go back in time, depending on our configuration.
While editing system files in the terminal, you will need a text editor. For beginners, we recommend using the nano
text editor. Although it is not installed by default, you can easily add it by running apk add nano
. Many system files will require elevated privileges, and for this, we will set up a tool called doas
.
It's important to note that our system uses doas to elevate privileges, rather than the commonly used sudo command. Keep this in mind if you ever refer to other online guides.
Throughout this guide, you will need to edit various text files on the file system. If you choose to use nano
as your text editor, you can edit these files by running doas nano /etc/example-file
.
This guide assumes the following:
- You have already installed Alpine Linux version 3.16+ using the "sys" method on your target system.
- Select DHCP network setting on the installer.
- During installation, you selected OpenSSH to install the SSH server.
- You have at least two additional hard drives (preferably the same size).
To begin, log into the NAS directly using the root account and the password you set during the setup. Connect a keyboard and monitor to access the system.
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 doas
.
If the user that you want to add as admin already exists, just simply add them to the wheel group with adduser <user> wheel
.
You can also delete users with deluser siblinga
Setting up doas
Now, let's set up doas
to grant elevated privileges to our administrator accounts.
First install the doas
software and documentation using Alpine's package manager:
apk update
apk add doas doas-doc
Next, using your preferred text editor, open the file /etc/doas.d/doas.conf
:
nano /etc/doas.d/doas.conf
Add a new line to the file:
permit persist :wheel
Save the changes and exit the text editor.
Now, log out of the root account using the exit
command.
Next, log in to one of the accounts that you added to the wheel
group. You can test doas
using the following command:
doas apk update
To enhance security, it is recommended to disallow direct login to the root account. This helps protect the root account from being an easy target for attackers. To disable root login, run the following command:
doas passwd -l root
SSH
o remotely access the NAS, we need to enable SSH. Fortunately, during the Alpine Linux setup, you were asked to install an SSH server (this guide uses OpenSSH server). If you didn't install it during setup, you can do so by running the following command:
doas apk add openssh openssh-doc
Make sure sshd service is enabled and started:
doas rc-update add sshd
doas rc-service sshd start
To determine the IP address of your NAS on the network, run the following command on the NAS itself:
ip a
Look for your Ethernet interface in the output (usually formatted like enp3s0
). Find the IP address associated with it. For example, the output might include a line like this: 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, you can use the ssh
command to connect to the NAS. Replace mea
with the relevant admin account username, and replace the IP address with the IP you obtained in the previous step:
ssh mea@192.168.1.100
This command establishes an SSH connection to the NAS using the specified admin account and IP address.
Normal Users
Create a group for our normal users:
addgroup nas
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:
doas nano /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 'doas 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:
doas 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.
Enable Community repo
Open /etc/apk/repositories
with text editor. You then need to uncomment line containing a URL ending with /community
You can do this by removing the hash (#
) symbol at the beginning of the relevant line. Here is an example of what mine looks like:
#/media/sdb/apks
http://mirror.lagoon.nc/alpine/v3.16/main
http://mirror.lagoon.nc/alpine/v3.16/community
#http://mirror.lagoon.nc/alpine/edge/main
#http://mirror.lagoon.nc/alpine/edge/community
#http://mirror.lagoon.nc/alpine/edge/testing
Ignore the repositories with /alpine/edge/
. These are the very latest packages, and don't play well with the stable versions of Alpine Linux.
Now execute
apk update
apk upgrade
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:
doas apk add mandoc man-pages
Now to get help for any program you run (e.g. doas) type: man doas
.
Partition the hard drives
This guide will get the NAS hard drives up and running. If you already have the drives setup from a previous NAS, you should skip the partitioning step.
Install parted
Since fdisk
cannot partition anything larger then 2TB you should install and use GNU Parted instead:
doas 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:
doas 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):
doas parted /dev/sd*
Replace /dev/sd*
with the relevant disk drive you intend to format.
Set the label to "gpt":
mklabel gpt
Make a primary partition that takes all of the drive.
For example from 0% (the start) to 100% (the end):
mkpart primary 0% 100%
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. Note that executing doas parted -l
again might show old information until the new file system is created.
File system
When you execute the doas parted -l
command, note the disk: e.g. /dev/sd*
and the partition number, since we only created one partition on these drives, there will only be one. this will then come together to make the full drive as Linux understands it: /dev/sd*1
doas mkfs.ext4 -L NAS_2022 /dev/sd*1
doas mkfs.ext4 -L BACKUP_2022 /dev/sd*1
reboot
doas mkdir /mnt/nas
doas mkdir /mnt/backup
Make sure the /dev/sd*1
matches from the file system creation phase.
View UUID, Labels, and Block device:
doas blkid
Using the information from this command, we will edit the fstab file, so these partitions are automatically mounted on boot.
Edit /etc/fstab
with your text editor of choice. We will need to create two new lines.
Column by column press the Tab key to jump to the next column
LABEL=NAS_2022 /mnt/nas ext4 defaults 0 0
LABEL=BACKUP_2022 /mnt/backup ext4 defaults 0 0
The second column specifies the mount point, for my system I mount at /mnt
but you could choose a different location:
Third column specifies the file system:
Forth column are for options, we use the defaults:
The last column are options which we leave default at 0 0
Now you should verify that it works:
doas mount -a
File structure
Now that our btrfs device is mounted, we should create some folders for our users to create files underneath:
doas mkdir -p /mnt/nas/files/Documents
doas mkdir -p /mnt/nas/files/Media
doas mkdir -p /mnt/nas/files/Photos
doas mkdir -p /mnt/nas/files/Projects
File permissions
An important step for making sure your users can read/write in certain directories.
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.
Setting permissions can be dangerous, so make sure to copy exactly!
Make sure the containing folder files
is owned by root
:
doas chown root:root /mnt/nas/files/
Then, make sure that the permissions on /mnt/nas/files
give the owner (the root user) full access but gives the group and others read and execute permissions only:
doas chmod 755 /mnt/nas/files
Now we will set the nas
group onto all of the sub-folders:
doas chgrp -R nas /mnt/nas/files/*
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:
doas chmod -R 770 /mnt/nas/files/*
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
- Linuxcommand.org: Permissions - An explanation of Unix file permissions.
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 doas
. 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
:
doas 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:
doas 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:
doas 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:
doas nas-user me
doas nas-user sibling
doas nas-user mother
doas 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 doas 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
force group = nas
inherit permissions = yes
force create mode = 0750
force directory mode = 0770
client min protocol = SMB3
map to guest = Bad User
[Share]
comment = Files shared will all users.
path = /mnt/nas/files
valid users = @nas
guest ok = no
read only = no
[Public]
comment = Read-only access to media without an account.
path = /mnt/nas/files/Media
read only = yes
guest ok = yes
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 "Media" 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:
doas rc-update add samba
doas 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 make sure crond is running, and set has been set to startup on boot:
doas rc-update add crond
doas 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 doas 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.
Backup
For our backups we will be using the incredible Borg Backup. We can use this to take daily snapshots of the NAS. Borg is deduplicating, so it won't store two copies of files from different days, which will save on hard disk space.
Borg also won't immediately delete files just because they were deleted on the NAS.
We start by installing:
doas apk add borgbackup borgbackup-docs
Borg must be run as root, so we must prepend doas
to each borg command. Each function of borg is broken down into different sub-commands. To initialise a repo we type doas borg init
, to create a new backup state doas borg create
, and so on. Then after call the sub-command, you give any options, and then the location of the backup repo.
Borg has very good documentation, which I suggest you read here
Setting up the backup
We will create a new backup repository on the backup drive:
doas borg init --encryption none /mnt/backup/borgbackup-nas
Create the first backup called "First":
doas borg create --list --stats /mnt/backup/borgbackup-nas::First /mnt/nas/files/
Automatic backups
Let's setup automatic backups. First create a script using any text editor you want:
doas vi /etc/periodic/daily/borgbackup.sh
Paste the following script:
#!/bin/sh
export TIME=$(date '+%Y-%m-%d %H:%M')
export BORG_REPO="/mnt/backup/borgbackup-nas"
echo "Starting Backup"
/usr/bin/borg create ::"Auto $TIME" /mnt/nas/files/
echo "Pruning Backup"
/usr/bin/borg prune -v --list --keep-daily=14 --keep-monthly=12
echo "Compacting Backup"
/usr/bin/borg compact
In the pruning stage, I have set it to keep the last 14 days of backups, and the last 12 months. In other words you'll be able to get back to a state from any day within two weeks, or the last backup for each month of the last year.
Set permissions to allow execute using chmod, and check that the script will run:
doas chmod a+x /etc/periodic/daily/package-update.sh
doas run-parts --test /etc/periodic/daily
View info about backups
It is a very good idea to frequently check that backups are successfully being ran.
Get a list of all current backup states in the repository:
doas borg list /mnt/backup/borgbackup-nas/
View all the files of a particular backup state:
doas borg list /mnt/backup/borgbackup-nas::"Auto 2022-05-07 18:30"
Make sure to replace "Auto 2022-05-07 18:30" with the relevant backup name.
View info about the backup repository:
doas borg info /mnt/backup/borgbackup-nas/
View info about particular backup:
doas borg info /mnt/backup/borgbackup-nas::"Auto 2022-05-07 18:30"
More info can simply be viewed by running borg
. you can also get help in regards to a single command (e.g. create) by running borg help create
. The Borg backup website is also very helpful.
Checking backups
Please reference the documentation on borgbackup website:
Restore backup
First list all the archives:
doas borg list /mnt/backup/borgbackup-nas
You'll likely want to restore from the latest backup.
To extract to a new drive. You'll want to use a command like this:
doas borg extract /mnt/backup/borgbackup-nas::"Auto 2022-07-08 18:30"
BE WARNED: borg extract will always extract to your current directory. Make sure you mount the new drive and then use the cd
command to change to the new drive.
Watch out for permissions. Use doas su
to change to a root shell, if you are getting permissions issues when navigating the extracted backup.
The full path including mnt/nas
will be restored, so use the following to fix it:
doas mv mnt/nas/files .
This will move the files
folder back to where it was before you can now safely delete mnt/nas
. But DON'T delete: /mnt/nas
that's the real full path to your NAS's hard drive!
Make sure to reread this guide checking permissions, and file paths in Samba etc.
There are some other things you can do, like only doing a partial restore. Please read the documentation for more info:
Keep system up-to-date
The first script we'll write is one to automatically update all Alpine Linux packages:
doas vi /etc/periodic/daily/package-update.sh
#!/bin/sh
/sbin/apk update && /sbin/apk upgrade
Set permissions to allow execute using chmod, and check that the script will run:
doas chmod a+x /etc/periodic/daily/package-update.sh
doas run-parts --test /etc/periodic/daily
Other Tools
These are some other tools I use every now and again that I suggest get installed.
doas apk add tmux tmux-doc ncurses-terminfo rsync rsync-doc sipcalc
Microcode
To keep the processor up-to-date, it is suggested to install microcode for your CPU:
Intel:
doas add intel-ucode
AMD:
doas add amd-ucode
Upgrading Alpine Linux
News about Alpine versions are published on the website.
edit /etc/apk/repositories
doas apk update
doas apk upgrade --available
doas sync
doas reboot
More detailed instructions on the wiki
Note about IP Addresses
In this tutorial I have been using IP addresses in the 192.168.1.0 range. When setting IP addresses, make sure to follow the subnet of the router. Your router could be using any of the following in these ranges:
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.
Login to your router and view the Network or LAN settings. Take note of the IP address and subnet mask. The math behind subnets can be tricky so use a subnet calculator, plenty online, and Alpine Linux has one called sipcalc
installed with apk
. Simply give it the IP and subnet mask from your routers management page, e.g. sipcalc 192.168.1.1 255.255.255.0
and it will provide information about the subnet.
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.
Backup to an external NTFS drive
In cases where Windows users might need access to data in-case of emergency. It's a good idea to store a backup on external hard-drives with the Microsoft NTFS file system.
We won't discuss formatting the drive on the NAS. That should be done in Windows, since it's best at doing that. Instead we will plug the drive directly into the NAS, mount it, and do a backup on the NAS.
Optional: Tmux
When you run commands over SSH, you must keep the terminal open on the PC you ran them from. Using tmux allows us to execute a long running command on the remote NAS, and then disconnect our PC. You'll need to install tmux and terminfo as mentioned in "Other Tools" section. You may also need to install a *-extra-terminfo
package if tmux doesn't like your terminal program.
Start new tmux session called backup:
tmux new -s "backup"
To detach from the tmux session press Ctrl+B
to put it into command mode, then press: D
. You can then close your SSH session, with the backup still running on the NAS.
To attach again type:
tmux attach -t "backup"
Mount drive
First get a list of attached hard drives:
doas parted -l
Find your external drive making note of it's location (e.g. /dev/sd*), and partition number in the list.
Next create a mount point in /mnt:
doas mkdir /mnt/external1
Install NTFS driver:
doas apk add ntfs-3g
Mount the drive, in this example we mount the 1st partition of whatever /dev/ device is your external drive:
doas mount.ntfs-3g /dev/sd*1 /mnt/external1/
Confirm by viewing all mounts:
df -h
Run the following rsync
command:
doas rsync -a --progress "/mnt/nas/files/" "/mnt/external1" --delete
Make sure you are inside tmux if you want to close the remote session on your PC.
Note how /mnt/nas/files/
has a leading slash, but /mnt/external1
doesn't. The leading slash means copy anything under files
, but not the files
folder itself. Slashes in rsync are significant, so make sure to follow above.
The --delete
option will delete any files in the backup that were deleted on the NAS. --progress
will show us progress.
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". Once connected, there should be a way to bookmark to the sidebar. The address to connect will look like:
smb://nas.local/share
Note: Some Linux distros won't pre-install gvfs-smb
, which is required to connect. KDE users should make sure kio-extras
is installed.
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 doas mount.cifs
to mount it. KDE users can also take a look at SMB4k.
Changelog
- 2023-02-21: Removed hosts allow/deny from smb.conf, added section on IP addresses.
- 2022-07-10: Document published.
- 2022-04-24: Document started.