Linux NAS Server
Teil I: Installation und grundlegender Aufbau
Inhalt
- Einleitung
- Platten partitionieren
- Linux redundant installieren
- NAS-Storage vorbereiten
- «nasvg» und «bckvg» synchron halten
- Starten und Stoppen des NAS
1. Einleitung
Immer mehr Geräte zum Abspielen von Musik, Videos, etc. Doch der lokale Speicher der Geräte reicht nicht aus, um alles aufzunehmen, auf das man so zugreifen möchte. Die laut propagierte Lösung ist die Wolke irgendwo da draußen. Wir wollen uns in einem zunächst dreiteiligen Kurs aber unser eigenes NAS mit Linux-Bordmitteln bauen.
Im ersten Teil geht es um den grundsätzlichen Aufbau eines Linux-Systems als NAS. Dabei wollen wir zwei Dinge erreichen
- Verschlüsselte NAS Volumes - dies hilft gegen Datenpreisgabe, falls der NAS-Server gestohlen werden sollte. Ein verschlüsselter Zugriff wird dadurch nicht ersetzt!
- Redundanz gegen Datenverlust durch Harwareausfälle - hier vor allem der Festplatte
2. Platten partitionieren
Als Beispiel soll ein System mit zwei großen Festplatten dienen - sda und sdb. Hier zeigt sich Linux flexibel - so können wir die Platten partitioneren und insgesamt 4 Volume Groups anlegen - zwei für's System und zwei für's NAS. Die Partitionierung würde dann etwa so aussehen:
# fdisk -l Disk /dev/sda: 1500.3 GB, 1500301910016 bytes 255 heads, 63 sectors/track, 182401 cylinders, total 2930277168 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x000c9d55 Device Boot Start End Blocks Id System /dev/sda1 2048 526335 262144 83 Linux /dev/sda2 526336 134744063 67108864 8e Linux LVM /dev/sda3 134744064 2930277167 1397766552 5 Extended /dev/sda5 134746112 2930277167 1397765528 8e Linux LVM Disk /dev/sdb: 1500.3 GB, 1500301910016 bytes 255 heads, 63 sectors/track, 182401 cylinders, total 2930277168 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x46ba1a6d Device Boot Start End Blocks Id System /dev/sdb1 2048 526335 262144 83 Linux /dev/sdb2 526336 134744063 67108864 8e Linux LVM /dev/sdb3 134744064 2930277167 1397766552 5 Extended /dev/sdb5 134746112 2930277167 1397765528 8e Linux LVM
Auf den beiden kleinen Partitionen legen wir dann die System Volume Groups an - eine auf der wir unser Linux installieren und eine auf der wir eine Kopie des Systems anlegen. Wenn eine Platte ausfällt, können wir von der zweiten booten.
# pvcreate /dev/sda2 # vgcreate sysvg /dev/sda2 # pvcreate /dev/sdb2 # vgcreate altsysvg /dev/sdb2
3. Linux redundant installieren
Aus Performance- und Flexibilitätsgründen habe ich mich entschieden, die Partitionen nicht zu spiegeln wie z.B. im Artikel Slackware 13.1 mit Software Raid und LVM beschrieben, sondern das Betriebssystem auf die erste Platte zu installieren und dann einen Klon auf der zweiten Platte anzulegen. Neben der Performancesteigerung ergibt sich dadurch auch die Möglichkeit eines OS Updates auf der einen Platte, während auf der zweiten Platte immer noch die alte Installation als Fallback zur Verfügung steht - ähnlich der AIX-Methode der Alternate Disk Installation.
Die Installation auf die sysvg geschieht mit der Installations-CD der gewählten Linux-Distribution und soll nicht Gegenstand dieses Artikels sein.
Klonen der sysvg auf die altsysvg
Sobald Linux installiert und grundlegend konfiguriert ist, können wir die sysvg klonen. Dazu werden zunächst in der altsysvg
die gleichen LVs angelegt wie in der sysvg, also z.B.
nas# lvs | grep -w sysvg local sysvg -wi-ao-- 5.00g opt sysvg -wi-ao-- 5.00g root sysvg -wi-ao-- 5.00g swap sysvg -wi-ao-- 8.00g usr sysvg -wi-ao-- 15.00g var sysvg -wi-ao-- 5.00g nas# lvcreate -L 5G -n local altsysvg nas# lvcreate -L 5G -n opt altsysvg nas# lvcreate -L 5G -n root altsysvg nas# lvcreate -L 8G -n swap altsysvg nas# lvcreate -L 15G -n usr altsysvg nas# lvcreate -L 5G -n var altsysvg
Die angelegten Dateisysteme werden dann eingehängt:
nas# mkdir /.altroot nas# mount /dev/altsysvg/root /.altroot nas# mount /dev/altsysvg/usr /.altsys/usr
und so weiter. Zusätzlich muss /dev/sdb1 unter /.altroot/boot eingeghängt werden:
nas# mount /dev/sdb1 /.altroot/boot
Um keine Pseudodateien zu kopieren muss auch das aktuelle System noch einmal an anderer Stelle eingehängt werden:
nas# mkdir /.root nas# mount /dev/sysvg/root /.root nas# mount /dev/sysvg/usr /.sys/usr
und so weiter. Auch hier /boot nicht vergessen:
nas# mount /dev/sda1 /.root/boot
Dann können wir mit rsync einen Klon anlegen:
nas# rsync -avz --delete /.root/ /.altroot
Diesen rsync können wir grundsätzlich immer wieder laufen lassen, um das System synchron zu halten. Allerdings sollten wir dabei die nächsten Schritte im Auge behalten:
Alternate Boot ermöglichen
Damit von der altsysvg auch gebootet werden kann, muss die /etc/fstab nach dem rsync angepasst werden, also etwa
nas# cat /etc/fstab | sed -e 's%/sysvg%/altsysvg%' -e 's%/sda%/sdb%' > /.altroot/etc/fstab
Danach muss das initrd für die alternative Installation neu geschrieben werden - unter Slackware ginge das ungefähr so:
nas# chroot /.altroot altnas# mkinitrd -c -f ext4 -r /dev/altsysvg/root -m usbhid:ehci-hcd:xhci-hcd:mbcache:jbd2:ext4 -L -u -o /boot/initrd.gz altnas# exit nas# _
In der /etc/lilo.conf bzw. /etc/grub.conf müssen beide Linux-Systeme eingetragen sein. Falls Sie LILO benutzen, muss der Bootlader auch auf beide Platten geschrieben werden:
nas# lilo -b /dev/sda nas# lilo -b /dev/sdb
Für GRUB ist ein solcher Schritt nicht nötig.
4. NAS-Storage vorbereiten
Die Linux-Systempartitionen haben wir nicht verschlüsselt. Hier liegen keine sensiblen Daten. Anders sieht es mit den NAS Volumina selbst aus, diese wollen wir nicht nur redundant auslegen sondern auch verschlüsseln. Wie das geht, wurde im Artikel Festplatte verschlüsseln eingehend erläutert, hier nur die Kurzfassung für unser Beispiel-Setup:
nas# dd if=/dev/urandom of=/dev/sda5 nas# root# cryptsetup -s 256 -y luksFormat /dev/sda5 nas# root# cryptsetup luksDump /dev/sda5 nas# root# cryptsetup luksOpen /dev/md3 crypt0 nas# dd if=/dev/urandom of=/dev/sdb5 nas# root# cryptsetup -s 256 -y luksFormat /dev/sdb5 nas# root# cryptsetup luksDump /dev/sdb5 nas# root# cryptsetup luksOpen /dev/sdb5 crypt1
Auf den verschlüsselten Devices werden dann die Daten Volume Groups angelegt:
nas# pvcreate /dev/mapper/crypt0 nas# vgcreate nasvg /dev/mapper/crypt0 nas# pvcreate /dev/mapper/crypt1 nas# vgcreate bckvg /dev/mapper/crypt1
In der nasvg werden dann die NAS-Volumina angelegt. Beispielhaft legen wir einmal 5 Volumina an:
nas# lvcreate -L 40.00G -n sda5lv01 nasvg nas# lvcreate -L 100.00G -n sda5lv02 nasvg nas# lvcreate -L 70.00G -n sda5lv03 nasvg nas# lvcreate -L 30.00G -n sda5lv04 nasvg nas# lvcreate -L 10.00G -n sda5lv05 nasvg
Analog die Backup Volumina in der bckvg:
nas# lvcreate -L 40.00G -n sdb5lv01 bckvg nas# lvcreate -L 100.00G -n sdb5lv02 bckvg nas# lvcreate -L 70.00G -n sdb5lv03 bckvg nas# lvcreate -L 30.00G -n sdb5lv04 bckvg nas# lvcreate -L 10.00G -n sdb5lv05 bckvg
Auf allen LVs (NAS Volumina und Backup Volumina) legen wir Dateisysteme an, also etwa
nas# mkfs.ext4 -m 0 -O resize_inode /dev/nasvg/sda5lv01
und so weiter.
In der /etc/fstab verankern wir die Volumina wie folgt:
# NAS Volumes
/dev/nasvg/sda5lv01 /export/diska/vol01 ext4 noauto 0 0 /dev/nasvg/sda5lv02 /export/diska/vol02 ext4 noauto 0 0 /dev/nasvg/sda5lv03 /export/diska/vol03 ext4 noauto 0 0 /dev/nasvg/sda5lv04 /export/diska/vol04 ext4 noauto 0 0 /dev/nasvg/sda5lv05 /export/diska/vol05 ext4 noauto 0 0# Backup Volumes
/dev/bckvg/sdb5lv01 /var/nas/.snapshots/diska/vol01 ext4 noauto 0 0 /dev/bckvg/sdb5lv02 /var/nas/.snapshots/diska/vol02 ext4 noauto 0 0 /dev/bckvg/sdb5lv03 /var/nas/.snapshots/diska/vol03 ext4 noauto 0 0 /dev/bckvg/sdb5lv04 /var/nas/.snapshots/diska/vol04 ext4 noauto 0 0 /dev/bckvg/sdb5lv05 /var/nas/.snapshots/diska/vol05 ext4 noauto 0 0
Man beachte, dass die verschlüsselten NAS-Volumina nicht automatisch eingehängt werden (noauto
)
5. «nasvg» und «bckvg» synchron halten
Wie eingangs erläutert, soll Datensicherheit nicht durch eine Plattenspiegelung sondern durch eine inaktive Kopie gewährleistet werden. Der Vorteil liegt unter Linux eindeutig in der Performance, doch es gibt noch einen positiven Nebeneffekt. Die Kopie ist auch eine Art Backup, denn eine versehentlich gelöschte Datei ist auf der Kopie -ganz im Gegensatz zum Spiegel- noxh vorhanden. Diesem Umstand wird im folgenden Skript noch einmal gesondert Rechnung getragen.
Damit eine Kopie wirklich Sicherheit gegen Datenverlust bietet, muss sie regelmäßig aktualisiert werden. Dazun installieren wir folgendes Skript:
#!/bin/bash
#
# purpose: sync active nas volumes to passive disk
# (c) aml, 2013-01-12
# Defaults:
# =========
delete=""# Names:
# ======
ACTVG=nasvg PASVG=bckvg ACTMNT=/export PASMNT=/var/nas/.snapshots# Helper functions
#=================
fskip() { if [ "$skip" = "fs" ] then echo "skipping filesystem »$afs«...." elif [ "$skip" = "dir" ] then echo "skipping folder »$dir«....." fi }# Delete removed files from backup only if requested
# ==================================================
if [ "$1" = "-d" ] then delete="--delete" fi# get list of volumes to be backed up
# ===================================
VOLUMELIST=$(lvs | awk -v avg="$ACTVG" '$2 == avg {print $1}') for avol in $VOLUMELIST do afs=$(mount | sed -e "s%/dev/mapper/$ACTVG-%/dev/$ACTVG/%" | awk -v vol=/dev/$ACTVG/$avol '($1 == vol) {print $3}') bfs=$(echo $afs | sed -e "s%^$ACTMNT%$PASMNT%") echo "$(date +%Y/%m/%d-%H:%M): $afs -> $bfs"# if backup volume not mounted, do it now
mount | grep $bfs >/dev/null 2>&1 ; RC=$? [ "$RC" = "0" ] || { mount $bfs || { skip=fs fskip ; continue ; } ; } for dir in $(ls $afs | grep -v lost+found) do cwd=$PWD cd $afs# if dir does not exist yet on backup volume, create it!
[ -x "$bfs/$dir" ] || { mkdir "$bfs/$dir" || { skip=dir fskip ; continue ; } ; }# start sync process
rsync -auvz $delete $afs/"$dir"/ $bfs/"$dir" cd $cwd done umount $bfs done
Das Skript könnte z.B. in der crontab verankert werden, um einmal täglich zu laufen, z.B.:
30 13 * * * /usr/local/sbin/syncjob >> /var/adm/nassync.log 2>&1
Man beachte, dass dieses Skript auf den Backup Volumina Dateien nicht löscht, die auf dem NAS schon gelöscht wurden. Dies ist eine Versicherung gegen versehentliches Löschen,
führt aber dazu, dass auf lange Sicht die Backup Volumina voll laufen. Deshalb kann das Skript von Zeit zu Zeit manuell mit der Option »-d« aufgerufen werden, um die
Backup Volumina zu bereinigen.
6. Starten und Stoppen des NAS
Der NAS-Server hat typischerweise keine Ein- und Ausgabegeräte, weshalb er ohne Administrator-Interaktion hochfahren soll. Die verschlüsselten NAS-Volumina können dann aber nicht automatisch eingehängt werden - sie benötigen eine manuelle Passworteingabe. Deshalb starten wir das eigentliche NAS über eine ssh-Session. Ein bisschen erinnert das an Novells Netware-Fileserver, die anfangs ein DOS starteten. Der Fileserver wurde dann manuell vom DOS-Prompt mit
> server
hochgefahren.
Wir installieren dazu ein Skript nas mit dem das NAS im SysV-Stil hoch- und heruntergefahren werden kann:
#!/bin/bash
#
# start/stop NAS volumes
nasstart() { echo "decrypting your NAS devices...." cryptsetup luksOpen /dev/sda5 crypt0 cryptsetup luksOpen /dev/sdb5 crypt1 echo "opening primary volume group..." vgchange -a y nasvg echo "opening backup volume group..." vgchange -a y bckvg echo "mounting volumes...." lvs | awk '$2 ~ /^nasvg$/ {print "fsck -C -a /dev/nasvg/"$1" && mount -v /dev/nasvg/"$1}' | sh sh /etc/init.d/nfs-server start sh /etc/init.d/samba start } nasstop() { echo "stopping NFS exports..." exportfs -u -a echo "unmounting backup volumes...." for vol in $(mount | awk '$3 ~ /^\/\.snapshots/ {print $3}') do umount $vol done echo "unmounting primary volumes..." for vol in $(mount | awk '$3 ~ /^\/export/ {print $3}') do umount $vol done sleep 5 echo "closing volume groups..." vgchange -an bckvg vgchange -an nasvg sleep 5 echo "encrypting your NAS devices..." cryptsetup luksClose crypt0 cryptsetup luksClose crypt1 } case $1 in start) nasstart ;; stop) nasstop ;; *) echo "Usage $(basename $0) { start | stop }" esac
Im Skript bitte beachten, dass der Aufruf zum Start des NFS-Servers und des Samba-Servers sich von Distribution zu Distribution unterscheiden kann. Da das Skript die NFS- und Samba-Server startet, sollte überdies sicher gestellt werden, dass diese Dienste nicht bereits vom Boot-Prozess gestartet werden.
Weitere Artikel zum Thema bei unixwerk
- Teil II: Dynamischer Zugriff auf NAS mit dem Automounter
- Teil III: Einrichung eines Samba-Servers für den Windows-Zugriff