This note explains how to set up a cheap Raid 1 NAS with an Odroid or Rasbperry board and two USB-harddisks using OpenMediaVault. Only very cheap and largely available hardware components are used. When very high availability is required it is recommended to hold available a second Oroid/Rasbperry board with a mirrored SD-card containing the NAS operating system. In this way the system has no single point of failure.
1. Hardware
Any Rasbperry like development board will do as long as Armbian supports it. I prefer Odroid-C2 over Rasbperry 3 because of the better performance, larger memory (2GB) and Gigabit-Ethernet. As neither Odroid-C2 nor Rasbperry-3 have USB3 ports cheap USB2 hard-disks will do perfectly.
-
1 Odroid-C2
-
1 SD-card UHS Speed Class 1 (U1), 4GB
-
1 USB 2 or USB 3 hard-disk containing your data, e.g. films, photos …
-
1 empty USB 2 or USB 3 hard-disk with the same size or bigger.
For optimal speed it is recommended to use the separated USB host port for the second HDD via USB OTG host port on C2.
-
1 Rasbperry 3
-
1 SD-card Class 10, 4GB
-
1 USB 2 or USB 3 hard-disk containing your data, e.g. films, photos …
-
1 empty USB 2 or USB 3 hard-disk with the same size or bigger.
Note
|
You can connect up to 5 USB2 disks as the Odroid-C2 has 5 USB2 ports. For very high availability you might also want to buy a second spare Odroid/Rasbperry with a second mirrored SD-card as instant replacement. |
Designed as a project for my students I installed all devices in a 3€ paint-bucket. This is how it looks like without cover.
2. Copy Debian 9 on a micro SD card and initial setup
I recommend the Armbian distribution because it has good hardware support and is available for wide range of Rasbperry-like boards.
See also the official documentation.
2.1. Download image
Download: Odroid C2 – Armbian or Alternative version
2.2. Copy image on SD-card
> apt-get install p7zip > mkdir tmp; cd tmp > 7z x Armbian_5.47_Odroidc2_Debian_stretch_default_3.16.57.7z > dd if=Armbian_5.47_Odroidc2_Debian_stretch_default_3.16.57.img of=/dev/mmcblk0 bs=8M
[1]
Insert the SD-card in your Odroid or Rasbperry and power-on.
2.3. Login
Login as root on console or via SSH and use password 1234. Change default password. I will call it "<naspassword>" later.
2.4. Console stuff
> apt-get update > apt-get upgrade > dpkg-reconfigure tzdata > apt-get install mc aptitude cryptsetup keyboard-configuration > dpkg-reconfigure keyboard-configuration > service keyboard-setup restart > update-initramfs -u
3. Install OpenMediaVault
3.1. Armbian’s configuration tool
Armbian comes with a configuration tool armbian-config
automating the
installation of OpenMediaVault.
> armbian-config
In the ncurses-application choose: Software
→ Softy
→ OMV
for
OpenMediaVault.
An alternative setup guide can be found here.
3.2. Manual install
The following section shows how to install OpenMediaVault manually.
-
Set up link to OVM repositiory
Create the file
/etc/apt/sources.list.d/openmediavault.list
with the following content:deb http://packages.openmediavault.org/public arrakis main # deb http://downloads.sourceforge.net/project/openmediavault/packages arrakis main ## Uncomment the following line to add software from the proposed repository. # deb http://packages.openmediavault.org/public arrakis-proposed main # deb http://downloads.sourceforge.net/project/openmediavault/packages arrakis-proposed main ## This software is not part of OpenMediaVault, but is offered by third-party ## developers as a service to OpenMediaVault users. # deb http://packages.openmediavault.org/public arrakis partner # deb http://downloads.sourceforge.net/project/openmediavault/packages arrakis partner
-
Set up your keys
> wget -O - http://packages.openmediavault.org/public/archive.key | apt-key add -
-
Install
> apt-get update > apt-get install openmediavault openmediavault-keyring > omv-initsystem
-
Install ovmextras (optional)
> wget http://omv-extras.org/openmediavault-omvextrasorg_latest_all4.deb > dpkg -i openmediavault-omvextrasorg_latest_all4.deb > apt-get update
-
Reboot
WarningIn order to reconnect via slogin
you need to enable SSH in the OpenmediaVault Web-GUIServices → SSH → Enable
> reboot
3.3. Login in
> firefox https://bucketnas.lan # <- replace with your NAS ip here
-
username = admin
-
password = openmediavault
> slogin -l root bucketnas.lan # <- replace with your NAS ip here
-
username = root
-
password = <naspassword>
3.4. Install the Luksencryption plugin (recommended)
The openmediavault-luksencryption
plugin is very handy to lock or unlock
the encryption layer.
Install in console:
> apt-get install openmediavault-luksencryption
or Web-GUI:
openmediavault web-gui -> System -> Plugins -> openmediavault-luksencryption
3.5. Install plugins (optional)
Interesting modules:
> apt-get install openmediavault-webdav openmediavault-minidlna
[2]
3.6. Enable ssl/tls connections (https:…)
Open Web-GUI and
openmediavault web-gui -> System -> Certificats -> ssl -> add -> create
openmediavault web-gui -> General Settings -> Web administration -> secure connection
then enable SSL/TLS and choose the above created certificate.
3.7. Change passwords
-
Web-GUI-adminstrator password
firefox https://bucketnas.lan # <- replace with your NAS ip here
Username: admin, initial password: openmediavault
OpenMediaVault -> General Settings -> Web Administrator Password
-
Root password
> slogin -l root bucketnas.lan # <- replace with your NAS ip here
Initial password is: odroid
> passwd
4. Create an empty Raid 1 and copy your data
4.1. Prepare an empty degraded Raid 1 with one disk
-
Create partition on empty disk
It is highly recommended to pre-partition the disks to be used in the array. Since most RAID users are selecting HDDs >2 TB, GPT partition tables are required and recommended. Disks are easily partitioned using gptfdisk.
-
After created, the partition type should be assigned hex code
FD00
. -
If a larger disk array is employed, consider assigning disk labels or partition labels to make it easier to identify an individual disk later.
-
Creating partitions that are of the same size on each of the devices is preferred.
-
A good tip is to leave approx 100 MB at the end of the device when partitioning. See below for rationale.
WarningIt is also possible to create a RAID directly on the raw disks (without partitions), but not recommended because it can cause problems when swapping a failed disk. When replacing a failed disk of a RAID, the new disk has to be exactly the same size as the failed disk or bigger — otherwise the array recreation process will not work. Even hard drives of the same manufacturer and model can have small size differences. By leaving a little space at the end of the disk unallocated one can compensate for the size differences between drives, which makes choosing a replacement drive model easier. Therefore, it is good practice to leave about 100 MB of unallocated space at the end of the disk. [3]
> fdisk /dev/sdb
-
-
Create empty degraded Raid 1
> mdadm --create /dev/md1 --level=1 --raid-devices=2 missing /dev/sdb1
[4]
-
Create encryption layer on top of our Raid
> cryptsetup -v luksFormat /dev/md1
-
Open encryption layer
cryptsetup luksOpen /dev/md1 md1-crypt Enter passphrase for /dev/md1
-
Create filesystem
> mkfs.ext4 /dev/mapper/md1-crypt
-
Mount this disk as destination disk
> mkdir /mnt/raid1 > mount -t ext4 /dev/mapper/md1-crypt /mnt/raid1
4.2. Copy your data onto the new disk
-
Mount disk with existing data
> mkdir /mnt/from > mount -t ext4 /dev/sda1 /mnt/from
-
Copy
> cd /mnt/from > cp -vur * /mnt/raid1
Figure 2. Copying -
Unmount
> umount /mnt/from > umount /mnt/raid1
-
Create /etc/fstab entry
Mount the Raid via the Web-GUI. It will leave an entry in
/etc/fstab
[5]. From now on the filesystem should be mounted automatically as soon as you decrypt.
4.3. Prepare a second empty disk
After having checked that all your data is well copied on your (still degraded) Raid 1, the original disk is now free and you can use it to complete your Raid 1.
Partition /dev/sda1
:
Warning
|
This deletes the content of /dev/sda1 . Make sure that all your
data was previously correctly copied on /dev/raid1 !
|
Important
|
The new partition /dev/sda1 must have exactly the same size
than /dev/sdb1 (or bigger).
|
> fdisk /dev/sda
[6]
4.4. Recover and sync
-
Start sync
> mdadm --add-spare /dev/md1 /dev/sda1 > mdadm --readwrite /dev/md1 > cat /proc/mdstat Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10] md1 : active raid1 sdb1[2] sda1[0] 2929928640 blocks super 1.2 [2/1] [U_] [=>...................] recovery = 5.4% (160290304/2929928640) finish=2286.7min speed=20185K/sec bitmap: 0/22 pages [0KB], 65536KB chunk
As you can see on the following screenshot the synchronisation of 1.36 TB takes 19h and the speed is approx. 20MB/sec which is a very good value for writing USB 2 disks.
Encryption does not have any impact on the speed with our chosen hardware.
5. Start and stop the system
5.1. Stop
Login as root:
> shutdown
5.2. Start
In order to populate the internal OpenMediaVault database propertly, you must mount the filesystem once using the OVM’s webgui in the following order:
-
Assemble Raid
OpenMediaVault -> Storage -> Software RAID
-
Decrypt
OpenMediaVault -> Storage -> Encryption
-
Mount file system
OpenMediaVault -> Storage -> File Systems
-
Select folders to share
OpenMediaVault -> Storage -> Shared Folders
From now on, you can use the shell to automate the above process when you restart the system. Make sure to always reference the same mount point that was generated automatically by OVM in step 3.
5.3. Sample shell start session
The following shell log shows how to start the system after reboot.
root@bucketnas:~/bin# mdadm --detail --scan
root@bucketnas:~/bin#
root@bucketnas:~/bin# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 2.7T 0 disk
└─sda1 8:1 0 2.7T 0 part
sdb 8:16 0 2.7T 0 disk
└─sdb1 8:17 0 2.7T 0 part
root@bucketnas:~/bin# mdadm -A /dev/md1 /dev/sda1 /dev/sdb1
mdadm: /dev/md1 has been started with 2 drives.
root@bucketnas:~/bin# mdadm --detail --scan
ARRAY /dev/md1 metadata=... name=bucketnas:1 UUID=0ed40ecb-4c61-41d2-b3a3-f62892324db8/
root@bucketnas:~/bin# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 2.7T 0 disk
└─sda1 8:1 0 2.7T 0 part
└─md1 9:1 0 2.7T 0 raid1
sdb 8:16 0 2.7T 0 disk
└─sdb1 8:17 0 2.7T 0 part
└─md1 9:1 0 2.7T 0 raid1
root@bucketnas:~/bin# cryptsetup open --type luks /dev/md1 md1-crypt
Enter passphrase for /dev/md1:
root@bucketnas:~/bin# ls /dev/mapper
control md1-crypt
# Replace the mount point `/srv/dev-disk-by-uuid-0ed40e...` with the one that was generated by OMV during the first mount via GUI.
root@bucketnas:~/bin# mount -t ext4 -o rw,noexec,relatime /dev/mapper/md1-crypt /srv/dev-disk-by-uuid-0ed40ecb-4c61-41d2-b3a3-f62892324db8/
root@bucketnas:~/bin# mount |grep mapper
/dev/mapper/md1-crypt on /srv/dev-disk-by-uuid-0ed40ecb-4c61-41d2-b3a3-f62892324db8 type ext4 (rw,noexec,relatime)
root@bucketnas:~/bin# service minidlna restart
5.4. Sample session: close filesystem
root@bucketnas:~/bin# cryptsetup close md1-crypt
Device md1-crypt is still in use.
root@bucketnas:~/bin# cryptsetup status md1-crypt
/dev/mapper/md1-crypt is active and is in use.
type: LUKS2
cipher: ...
keysize: ...
key location: ...
device: /dev/md1
sector size: ...
offset: ... sectors
size: ... sectors
mode: read/write
root@bucketnas:~/bin# mount | grep /dev/mapper
/dev/mapper/md1-crypt on /srv/dev-disk-by-uuid-0ed40ecb-4c61-41d2-b3a3-f62892324db8 type ext4 (rw,relatime,jqfmt=vfsv0,usrjquota=aquota.user,grpjquota=aquota.group)
root@bucketnas:~/bin# umount /dev/mapper/md1-crypt
root@bucketnas:~/bin# mount | grep /dev/mapper
root@bucketnas:~/bin#
root@bucketnas:~/bin# cryptsetup close md1-crypt
root@bucketnas:~/bin# cryptsetup status md1-crypt
/dev/mapper/md1-crypt is inactive.
Raids are reboot resitant. There is usually no need to stop them. The following is documented for completeness. Omit!
root@bucketnas:~/bin# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 2.7T 0 disk
└─sda1 8:1 0 2.7T 0 part
└─md1 9:1 0 2.7T 0 raid1
sdb 8:16 0 2.7T 0 disk
└─sdb1 8:17 0 2.7T 0 part
└─md1 9:1 0 2.7T 0 raid1
root@bucketnas:~/bin# mdadm --detail --scan
ARRAY /dev/md1 metadata=... name=bucketnas:1 UUID=b1feed48:13bd99ea:dc0c4ffb:69680134
root@bucketnas:~/bin# mdadm -S /dev/md1
mdadm: stopped /dev/md1
root@bucketnas:~/bin# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 2.7T 0 disk
└─sda1 8:1 0 2.7T 0 part
sdb 8:16 0 2.7T 0 disk
└─sdb1 8:17 0 2.7T 0 part
root@bucketnas:~/bin# mdadm --detail --scan
root@bucketnas:~/bin#
5.5. Sample startscript
This script resides on your NAS.
If you want to call it from your client, adapt it using ssh
and sshpass
.
#!/bin/sh
# setup decryption layer (will prompt for passwd)
cryptsetup open --type luks $(ls /dev/md*|head -n 1) md1-crypt
# mount filesystem
mount -t ext4 -o rw,noexec,relatime,data=ordered,jqfmt=vfsv0,usrjquota=aquota.user,grpjquota=aquota.group /dev/mapper/md1-crypt /srv/dev-disk-by-uuid-0ed40ecb-4c61-41d2-b3a3-f62892324db8
# restart services
service minidlna restart
# create log directory, otherwise service will not start
mkdir -p /var/log/nginx
service nginx restart
5.6. Troubleshooting
5.6.1. Logical volume is not available
- Problem
-
One Raid member device is a logical volume and it is not available.
> lvdisplay --- Logical volume --- LV Path /dev/vg-sdb1-sdc1/lv-combined LV Name lv-combined VG Name vg-sdb1-sdc1 LV Write Access read/write LV Status NOT available LV Size 2.73 TiB Current LE 715347 Segments 2 Allocation inherit Read ahead sectors auto
> lvchange -aay
or if link to device is available
> lvchange -ay /dev/vg-sdb1-sdc1/lv-combined
--- Logical volume --- LV Path /dev/vg-sdb1-sdc1/lv-combined LV Name lv-combined VG Name vg-sdb1-sdc1 LV Write Access read/write LV Status available # open 0 LV Size 2.73 TiB Current LE 715347 Segments 2 Allocation inherit Read ahead sectors auto - currently set to 256 Block device 252:0
5.6.2. Only one Raid member is started
- Problem
-
Raid starts degraded and you see and error message like
/dev/md1 has been started with 1 drive (out of 2)
.-
Check the member devices.
> mdadm -E /dev/sdb1 sdb1: Magic : a92b4efc Version : 1.2 Feature Map : 0x1 Super Offset : 8 sectors Unused Space : before=262056 sectors, after=1152 sectors State : clean Internal Bitmap : 8 sectors from superblock Update Time : Tue Aug 16 20:52:39 2016 Bad Block Log : 512 entries available at offset 72 sectors Checksum : 7c33262b - correct Events : 64894
> mdadm -E /dev/sda1 sda1: Magic : a92b4efc Version : 1.2 Feature Map : 0x1 Super Offset : 8 sectors Unused Space : before=262056 sectors, after=8 sectors State : clean Internal Bitmap : 8 sectors from superblock Update Time : Tue Aug 16 23:00:46 2016 Bad Block Log : 512 entries available at offset 72 sectors Checksum : 8c9eaaac - correct Events : 64898
-
Stop Raid.
> umount /dev/mapper/md1-crypt > cryptsetup close md1-crypt > mdadm -S /dev/md1 mdadm: stopped /dev/md1
-
Check Raid status.
> mdadm -D /dev/md1 /dev/md1: Version : Raid Level : raid0 Total Devices : 0 State : inactive
-
Assemble the members.
> mdadm -A /dev/md1 /dev/sda1 /dev/sdb1 mdadm: /dev/md1 has been started with 1 drive (out of 2).
-
Add the missing device.
> mdadm /dev/md1 --add /dev/sdb1 mdadm: re-added /dev/sdb1
-
Check Raid status.
> mdadm -D /dev/md1 /dev/md1: Version : 1.2 Raid Level : raid1 State : active Active Devices : 2 Working Devices : 2 Failed Devices : 0 Spare Devices : 0 Events : 163202 Number Major Minor RaidDevice State 2 8 17 0 spare rebuilding /dev/sdb1 1 8 1 1 active sync /dev/sda1
-
If the above does not help try
> mdadm --stop /dev/md1 > mdadm --assemble --run --force --update=resync /dev/md1 /dev/sda1 /dev/sdb1 > mdadm --readwrite /dev/md1
A detailed explanation can be found in this article.
6. Secure your NAS with a firewall
To protect your BucketNas a firewall is recommended. My preferred configuration method is using the Uncomplicated firewall (UFW) configuration tool, because it configures IPv4 and IPv6 in one go.
6.1. Firewall configuration with UFW
The Uncomplicated firewall (UFW) is a configuration tool that abstracts a big deal of firewall complexity. Learn more here: An Introduction to Uncomplicated Firewall (UFW)
Install UFW:
> apt-get install ufw
Most services bring their own ufw configuration, Minidlna doesn’t. We have
to add one. Create a file /etc/ufw/applications.d/minidlna
with
the following content:
[Minidlna] title=Media server description=MiniDLNA is server software with the aim of being fully compliant with DLNA/UPnP clients. The MiniDNLA daemon serves media files (music, pictures, and video) to clients on a network. ports=1900/udp|8200/tcp
Activate ufw-profiles:
> ufw allow Minidlna > ufw allow OpenSSH > ufw allow Samba > ufw allow "Nginx Full" > ufw enable
Check activation. Below you see the expected results:
> ufw status verbose Status: active Logging: on (low) Default: deny (incoming), allow (outgoing), disabled (routed) New profiles: skip To Action From -- ------ ---- 1900/udp (Minidlna) ALLOW IN Anywhere 8200/tcp (Minidlna) ALLOW IN Anywhere 22/tcp (OpenSSH) ALLOW IN Anywhere 137,138/udp (Samba) ALLOW IN Anywhere 139,445/tcp (Samba) ALLOW IN Anywhere 80,443/tcp (Nginx Full) ALLOW IN Anywhere 1900/udp (Minidlna (v6)) ALLOW IN Anywhere (v6) 8200/tcp (Minidlna (v6)) ALLOW IN Anywhere (v6) 22/tcp (OpenSSH (v6)) ALLOW IN Anywhere (v6) 137,138/udp (Samba (v6)) ALLOW IN Anywhere (v6) 139,445/tcp (Samba (v6)) ALLOW IN Anywhere (v6) 80,443/tcp (Nginx Full (v6)) ALLOW IN Anywhere (v6)
6.2. Firewall configuration with OMV
Alternatively you can configure your firewall rule by rule in OpenMediaVault:
OpenMediaVault -> System -> Network -> Firewall
A good template including other services can be found in this forum.
Below you find my sample settings for IPv4.
Add similar rules for IPv6 or add a REJECT from everywhere rule to disable IPv6.
7. Install a DNLA/UPnP media server on your NAS (optional)
OpenMediaVault has management modules for many common protocols e.g. FTP, NFS, RSync, SMB/CIFS, SNMP, SSH and TFTP.
In order to set up a media server you may want to install the the minidnla-plugin
> apt-get install openmediavault-minidlna
Do not change the default settings, just define some shares on the tab
OpenMediaVault -> Services -> DNLA -> Shares
and enable the server:
OpenMediaVault -> Services -> DNLA -> Settings -> Enable
8. Set up a video/music player client (optional)
8.1. Windows 10 and Android
The Windows 10 Media Player and Yaacc application for Android can connect without any further configuration.
8.2. Debian
I recommend the vlc media-player.
vlc -> local network -> Universal Plug'n'Play
It may take a minute until MiniDNLA appears in the main window. Please be patient.
8.2.1. Firewall configuration
A simple firewall configuration tool is gufw
.
> apt-get install gufw
The following could be a good start:
To | Action | From |
---|---|---|
8200/tcp |
ALLOW |
Anywhere |
1900/udp |
ALLOW |
Anywhere |
8200/tcp |
ALLOW |
Anywhere (v6) |
1900/udp |
ALLOW |
Anywhere (v6) |