- Build a DIY NAS
- OS drive: OpenMediaVault 6.0-16 on microSD card (cloned for backup)
- Data drive: RAID5 -> LUKS -> LVM2 -> EXT4 for read performance, failure safety and privacy
- Automatic unlocking of encrypted drive in a known network with Tang & Clevis
- Server should be able to do unattended shutdowns / reboots for energy saving
- Hardware
- Software
- Secure your server
- Administration
- Backup
TOC created with https://imthenachoman.github.io/nGitHubTOC/
See the official specifications at https://support.hpe.com/hpesc/public/docDisplay?docId=emr_na-c03793258#N1048F
- Intel Xeon E3-1220LV2 (17 W)
- 8 GB RAM
- 16 GB SanDisk A1 micro SD-card for OS (OS-drive on internal slot)
- 4 x 4 TB Western Digital Red Plus (data-drives on SATA slots)
- Get the firmware file SP99427.exe at https://support.hpe.com/connect/s/search
- Create USB-Key on Windows & boot server from it.
- Get the firmware file cp046467.exe at https://support.hpe.com/connect/s/search
- Connect the server at the iLO network interface
- Login into the iLO web interface via IPv6 (credentials on the sticker at the backside of the microserver)
- Upload new firmware and flash it.
- Get an ILO Advanced Key and enter it in the iLO web interface
- Install OpenWrt on your LTE modem / router if you can
- Set a static IP outside of dhcp range for your server machine in your router's web console
IPv4: 192.168.x.xxx Mac-address: xx:xx:xx:xx:xx:xx
- Get a real public IP from ISP for your LTE sim card (if it does not have one)
- Use a DDNS service to map a domain name to your changing IP
- Configure a DDNS client on your router: https://openwrt.org/docs/guide-user/services/ddns/client
- Install a tang server (tested with tang 6.1 on OpenWrt 21.02.0)
- Edit the xinetd config
vi /etc/xinetd.conf
- Add
service tangd { port = 8888 socket_type = stream wait = no user = root server = /usr/libexec/tangdw server_args = /usr/share/tang/cache log_on_success += USERID log_on_failure += USERID disable = no }
- Generate keys:
/usr/libexec/tangd-keygen /usr/share/tang/db /usr/libexec/tangd-update /usr/share/tang/db /usr/share/tang/cache service xinetd reload
- Check log
cat /var/log/tangd.log
- https://openwrt.org/
- https://github.com/latchset/tang
- https://moin.meidokon.net/furinkan/sysadmin/Clevis_and_Tang
- https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/security_hardening/configuring-automated-unlocking-of-encrypted-volumes-using-policy-based-decryption_security-hardening
This guide follows the documentation of OMV version 5.x since 6.x is still under development.
- Prepare two installation media: 1. ISO to boot from and 2. formated with ext4 to install to
- Installation: follow the official documentation at https://openmediavault.readthedocs.io/en/5.x/new_user_guide/newuserguide.html#amd64-64-bit-platforms
- Initial configuration of OMV: follow the official documentation at https://openmediavault.readthedocs.io/en/5.x/new_user_guide/newuserguide.html#initial-configuration
- Change the admin password
- Change auto logout time interval to 30 min:
System > Workbench > Auto logout
- Configure network interface:
Network > Interfaces > eth0
IPv4: 192.168.x.xxx Netmask: 255.255.255.0 Gateway: 192.168.x.xxx DNS-Server: 8.8.8.8 [x] wake on LAN
- Create a NAS user:
User Management > Users > + > nas_user
- Careful: adding/removing public ssh keys via the omv web console will change
sshd_config
!
- Generate & copy new public ssh key from the client machine to the NAS server
ssh-keygen -t ed25519 ssh-copy-id [email protected]
- Login via ssh
- Update OMV
sudo -i nano /etc/locale.gen locale-gen apt-get update && apt-get dist-upgrade -y && omv-upgrade -y
- Install additional packages
apt-get install -y screen htop
- Install omv-extras to have access to more plugins
wget -O - https://github.com/OpenMediaVault-Plugin-Developers/packages/raw/master/install | bash
- Install OMV plugins
- clam-av
- openmediavault-flashmemory
The following scheme is used for the data drives: RAID --> LUKS --> LVM --> ext4
.
- Having RAID as bottom layer has the advantage that a disk can be easily swapped in case of failure.
- Putting LUKS as second layer allows you to have only one password.
- Adding LVM as a third layer offers flexibility for future shrinking/extending.
- Wipe disks before doing anything else
haveged -n 0 | dd of=/dev/sd[abcd]
-
Create RAID array:
Storage > RAID Management > +
-
Save the RAID configuration
mdadm --detail --scan >> /etc/mdadm/mdadm.conf
-
Install
sudo apt install -y cryptsetup
-
Benchmark
cryptsetup benchmark
This gives 1555.8 MiB/s (encryption) and 1652.4 MiB/s (decryption) for aes-xts with 256b key.
-
Create a LUKS container
cryptsetup luksFormat --cipher aes-xts-plain64 --hash sha512 -s 512 /dev/md0
-
Show info
cryptsetup luksDump /dev/md0
-
Open the new LUKS container
cryptsetup luksOpen /dev/md0 crypt-raid
-
Find UUID of /dev/md0
blkid
-
Edit
/etc/crypttab
and addcrypt-raid UUID=xxxx none luks
-
Recreate initramfs
update-initramfs -u -k all
-
Change GRUB_TIMEOUT to 1s
nano /etc/default/grub update-grub
-
Purge old kernels
uname -r apt remove --purge linux-image-
- Specify md0 as physical volume (make sure dataalignment matches chunk size of RAID)
pvcreate --dataalignment=512 /dev/mapper/crypt-raid
- Create new volume group
vgcreate raid-vg /dev/mapper/crypt-raid
- Create logical volume that uses the whole free disk space
lvcreate -l 100%FREE --name mrm raid-vg
- Create EXT4 filesystem (this takes a while):
Storage > File Systems > + > Create > mrm-raid-vg, ext4
-
Install
sudo apt install -y clevis clevis-luks clevis-dracut
-
Check if the tang server is responding
echo hi | clevis encrypt tang '{"url": "192.168.x.xxx:8888"}' > hi.jwe
-
List and unbind existing binds
clevis luks list -d /dev/md0 clevis luks unbind -d /dev/md0 -s 1
-
Bind the device to tang
clevis luks bind -d /dev/md0 tang '{"url": "192.168.x.xxx:8888"}'
-
Update initial RAM filesystem using dracut
dracut -fv --regenerate-all
- https://superuser.com/questions/1193290/best-order-of-raid-lvm-and-luks
- https://github.com/gandalfb/openmediavault-full-disk-encryption
- https://thelinuxchronicles.blogspot.com/2014/04/encrypted-software-raid-5-on-debian.html
- https://github.com/latchset/clevis
- https://moin.meidokon.net/furinkan/sysadmin/Clevis_and_Tang
- Hard Disk Drive (HDD) bays 1 and 2 support 6.0 Gb/s = 750 MB/s SATA
- HDD bays 3 and 4 support 3.0 Gb/s = 375 MB/s SATA
- Testfile has ~32 GB
- Local copies
- Read:
dd if=/srv/disk-by-uid/share/testfile.tar.gz of=/dev/null bs=1M
- Write:
dd if=/dev/zero of=/srv/disk-by-uid/share/testfile_1.tar.gz bs=1M count=32000 conv=sync
- Read:
- Network (CIFS/NFS) via 1 Gb/s = 125 MB/s ethernet port
- Read:
dd if=/mnt/share/testfile.tar.gz of=/dev/null bs=1M
- Write:
dd if=/dev/zero of=/mnt/share/testfile_1.tar.gz bs=1M count=32000 conv=sync
- Read:
RAID5 | RAID5+LUKS+LVM | RAID5*+LUKS+LVM | RAID5 - NFS | RAID5 - CIFS | |
---|---|---|---|---|---|
Read | 356 MB/s | 350 MB/s | 375 MB/s | 86.30 MB/s | 85.3 MB/s |
Write | 336 MB/s | 368 MB/s | 368 MB/s | 43.60 MB/s | 87.8 MB/s |
*: with stripe_cache_size=8192
This is more or less the maximum performance the hardware controller allows since the RAID array uses all four HDD bays.
- https://louwrentius.com/zfs-performance-on-hp-proliant-microserver-gen8-g1610t.html
- https://superuser.com/questions/305716/bad-performance-with-linux-software-raid5-and-luks-encryption
```sh
sudo apt install -y libpam-pwquality
sudo cp --archive /etc/pam.d/common-password /etc/pam.d/common-password-COPY-$(date +"%Y%m%d%H%M%S")
sudo sed -i -r -e "s/^(password\s+requisite\s+pam_pwquality.so)(.*)$/# \1\2 # commented by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")\n\1 retry=3 minlen=10 difok=3 ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1 maxrepeat=3 gecoschec # added by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")/" /etc/pam.d/common-password
```
```sh
sudo apt install -y unattended-upgrades apt-listchanges apticron
nano /etc/apt/apt.conf.d/51myunattended-upgrades
```
```sh
// Enable the update/upgrade script (0=disable)
APT::Periodic::Enable "1";
// Do "apt-get update" automatically every n-days (0=disable)
APT::Periodic::Update-Package-Lists "1";
// Do "apt-get upgrade --download-only" every n-days (0=disable)
APT::Periodic::Download-Upgradeable-Packages "1";
// Do "apt-get autoclean" every n-days (0=disable)
APT::Periodic::AutocleanInterval "7";
// Send report mail to root
// 0: no report (or null string)
// 1: progress report (actually any string)
// 2: + command outputs (remove -qq, remove 2>/dev/null, add -d)
// 3: + trace on APT::Periodic::Verbose "2";
APT::Periodic::Unattended-Upgrade "1";
// Automatically upgrade packages from these
Unattended-Upgrade::Origins-Pattern {
"o=Debian,a=stable";
"o=Debian,a=stable-updates";
"origin=Debian,codename=${distro_codename},label=Debian-Security";
};
// You can specify your own packages to NOT automatically upgrade here
Unattended-Upgrade::Package-Blacklist {
};
// Run dpkg --force-confold --configure -a if a unclean dpkg state is detected to true to ensure that updates get installed even when the system got interrupted during a previous run
Unattended-Upgrade::AutoFixInterruptedDpkg "true";
//Perform the upgrade when the machine is running because we wont be shutting our server down often
Unattended-Upgrade::InstallOnShutdown "false";
// Send an email to this address with information about the packages upgraded.
Unattended-Upgrade::Mail "root";
// Always send an e-mail
Unattended-Upgrade::MailOnlyOnError "false";
// Remove all unused dependencies after the upgrade has finished
Unattended-Upgrade::Remove-Unused-Dependencies "true";
// Remove any new unused dependencies after the upgrade has finished
Unattended-Upgrade::Remove-New-Unused-Dependencies "true";
// Automatically reboot WITHOUT CONFIRMATION if the file /var/run/reboot-required is found after the upgrade.
Unattended-Upgrade::Automatic-Reboot "true";
// Automatically reboot even if users are logged in.
Unattended-Upgrade::Automatic-Reboot-WithUsers "true";
```
```sh
sudo unattended-upgrade -d --dry-run
```
- Create user group sudo (already present in Debian) & add users
sudo usermod -a -G sudo nas_user
- Create user group suusers & add users
sudo groupadd suusers sudo usermod -a -G suusers root sudo usermod -a -G suusers nas_user sudo dpkg-statoverride --update --add root suusers 4750 /bin/su
-
Careful: adding/removing public ssh keys via the omv web console will change
sshd_config
! -
Create SSH user group for AllowGroups (already present in Debian) & add users
sudo groupadd ssh sudo usermod -a -G ssh nas_user
-
Edit ssh settings
nano /etc/ssh/sshd_config sudo service sshd restart sudo sshd -T
-
Remove short moduli
sudo cp --archive /etc/ssh/moduli /etc/ssh/moduli-COPY-$(date +"%Y%m%d%H%M%S") sudo awk '$5 >= 3071' /etc/ssh/moduli | sudo tee /etc/ssh/moduli.tmp sudo mv /etc/ssh/moduli.tmp /etc/ssh/moduli
-
Firewall
sudo apt install -y ufw sudo ufw default deny outgoing comment 'deny all outgoing traffic' sudo ufw default deny incoming comment 'deny all incoming traffic' sudo ufw allow in 22/tcp comment 'allow incoming SSH' sudo ufw allow out 53 comment 'allow DNS calls out' sudo ufw allow out 123 comment 'allow NTP out' sudo ufw allow out http comment 'allow HTTP traffic out' sudo ufw allow in http comment 'allow HTTP traffic in' sudo ufw allow out https comment 'allow HTTPS traffic out' sudo ufw allow in https comment 'allow HTTPS traffic in' sudo ufw allow out 445/tcp comment 'allow SMB traffic out' sudo ufw allow in 445/tcp comment 'allow SMB traffic in' sudo ufw allow out 8888/tcp comment 'allow tang traffic out' sudo ufw allow in 8888/tcp comment 'allow tang traffic in' sudo ufw enable sudo ufw status
-
Iptables ntrusion detection with psad
sudo apt install -y psad sudo cp --archive /etc/psad/psad.conf /etc/psad/psad.conf-COPY-$(date +"%Y%m%d%H%M%S") nano /etc/psad/psad.conf sudo cp --archive /etc/ufw/before.rules /etc/ufw/before.rules-COPY-$(date +"%Y%m%d%H%M%S") sudo cp --archive /etc/ufw/before6.rules /etc/ufw/before6.rules-COPY-$(date +"%Y%m%d%H%M%S")
Add
# log all traffic so psad can analyze -A INPUT -j LOG --log-tcp-options --log-prefix "[IPTABLES] " -A FORWARD -j LOG --log-tcp-options --log-prefix "[IPTABLES] "
to
/etc/ufw/before.rules
and/etc/ufw/before6.rules
at the end of the file before COMMIT.sudo ufw reload sudo psad -R sudo psad --sig-update sudo psad -H sudo psad --fw-analyze sudo psad --Status
-
App intrusion detection with fail2ban
sudo apt install -y fail2ban sudo nano /etc/fail2ban/jail.local
Add
[DEFAULT] # the IP address range we want to ignore ignoreip = 127.0.0.1/8 [LAN SEGMENT] # who to send e-mail to destemail = [your e-mail] # who is the email from sender = [your e-mail] # since we're using exim4 to send emails mta = mail # get email alerts action = %(action_mwl)s
cat << EOF | sudo tee /etc/fail2ban/jail.d/ssh.local [sshd] enabled = true banaction = ufw port = ssh filter = sshd logpath = %(sshd_log)s maxretry = 5 EOF
sudo fail2ban-client start sudo fail2ban-client reload sudo fail2ban-client add sshd # This may fail on some systems if the sshd jail was added by default sudo fail2ban-client status sudo fail2baclevis luks unbind -d /dev/sda2 -s 1n-client status sshd
-
New shared folder:
Storage > Shared Folders > + > /dev/md0 > Everyone: read/write
-
SMB/CIFS service:
Services > SMB/CIFS > Shares > + >
withGuests allowed
-
Inherit ACLs
-
Inherit permissions
-
Extended attributes
-
Store DOS attributes
-
NFS service:
Services > NFS > Shares > + >
with- Client IP: 192.168.x.xxx
- Read/Write
-
Install cifs-utils on
sudo apt install -y cifs-utils
-
Credentials file
/root/.smbcredentials
username=nas_user password=yourpassword domain=WORKGROUP
sudo chmod 600 /root/.smbcredentials
-
Add a line to
/etc/fstab
//192.168.x.xxx/<share> /media/share cifs credentials=/root/.smbcredentials,uid=ubuntu_user,noperm,rw,vers=3.0 0 0
-
Create mount point
sudo mkdir /media/share
-
Mount
sudo mount -a
- Install NFS client
sudo apt-get install -y nfs-common
- Create mount point
sudo mkdir /media/share_nfs
- Mount
sudo mount 192.168.x.xxx:/<share> /media/share_nfs
- Implement a backup policy
- Create a backup of the OS drive
sudo dd if=/dev/sdcard of=~/Downloads/NAS/omv6_sdcard_backup.img bs=1M status=progress
- Test restoring it
sudo dd bs=4M if=~/Downloads/NAS/omv6_sdcard_backup.img of=/dev/sdb status=progress