Alpine Linux: Home NAS Setup 1.0
BEGIN IMPORTANT NOTE
This guide is superseeded, please refer to this guide instead. This is only for archival purposes.
END IMPORTANT NOTE
This guide assumes the following:
- Alpine Linux installed with "sys" method on your target system.
- During installation select OpenSSH for ssh server.
- You have at least two other hard drives that are the same size.
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
.
TIP: You can also delete users with deluser siblinga
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.
Enable Community repo
Open /etc/apk/repositories with text editor
Uncomment 3rd line URL ending with /community
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:
sudo apk add mandoc 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
Warning: This will clear any data on the drives
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
sudo reboot
Reboot is required after setting.
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
Warning: This will wipe all data on drive
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 filesystem show /dev/sd*1
btrfs: Mounting
With a multi-device file system you can mount any device part of RAID for the mount command.
sudo mount /dev/sd*1 /mnt
And check the mount with:
sudo btrfs filesystem 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:
sudo 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
- 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 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.
BTRFS maintenance
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
- 2021-01-02: Document published.
- 2020-04-23: Add cron tutorial.
- 2019-10-27: Add file permissions, chroot SFTP, hostname, DHCP.
- 2019-10-07: Add SSH, btrfs filesystem and RAID 1, and Samba.
- 2019-10-06: Document started.