Odroid HC4 / NAS

Da sich mein Qnap NAS verabschiedet hat, war dies die Gelegenheit ein NAS selber zu bauen.

Anforderungen an Services

Ein NAS bietet heutzutage, nebst dem Speichern von Daten, diverse Services an. Folgendes möchte ich auch auf dem HC4 nutzen:

NAS-Strategie

Als erstes ist es eine gute Idee zu klären, was man mit dem NAS überhaupt erreichen möchte. Hier meine Kriterien:

  • Datenverlust: Die Daten sollen bestmöglich vor Verlust geschützt werden.
  • Verfügbarkeit: Die Daten können auch mal 1-2 Tage nicht verfügbar sein. Mehr als 2 Tage Ausfall sollten es aber nicht sein.

Massnahmen Datenverlust

  • Das NAS soll in einem RAID-1 Verbund laufen. Damit werden die Daten gespiegelt abgespeichert, so dass ein Festplatten-Ausfall einfach abgefedert werden kann.
  • Gleichzeitig werden die “Core-Daten” (alles ausser Musik, Filme etc.) regelmässig zusätzlich auf ein zweites Gerät gespeichert (rsync).

Massnahmen Verfügbarkeit

  • RAID-1 hilft hier ebenfalls, die Daten bleiben bei einem Ausfall einer der beiden Festplatten weiterhin verfügbar.
  • Es kann aber auch sein, dass die Hardware (SD-Karte oder HC4) ausfällt. Die SD-Karte klone ich zu diesem Zweck. So kann ich bei einem Ausfall die SD-Karte einfach austauschen. Beim HC4 wird es aber etwas schwieriger. Ich habe mir zwei HC4 Geräte besorgt. Bei einem Ausfall kann ich entsprechend auch den HC4 sofort ersetzen.

Hardware

Ich habe bereits mit dem Odroid HC2 sehr gute Erfahrungen gemacht. HC4 ist der Nachfolger und bietet neu mehr CPU Leistung, einen 64Bit Prozessor, 4Gb RAM, etc.

Das HC4 Gehäuse

Update 2024: Sie scheinen mittlerweile verstanden zu haben, dass das Originale Case nix bringt. Es gibt mittlerweile von odroid ein HC4 Case Kit, mit welchem man sich ein vernünftiges Case selber zusammenschrauben kann.

Das Gehäuse vom HC4 ist meines Erachtens nicht gelungen. Die Festplatten werden vertikal in den SATA-Anschluss des HC4 eingeschoben. Das ganze ist mir viel zu wackelig. “Serverschrank-Ready” ist dieses Ding so definitiv nicht. Auch frage ich mich, ob es sinnvoll ist, SATA Stecker so zu verwenden. Ich kann mir nicht vorstellen, dass die SATA Stecker des HC4 solide genug sind um häufiges wechseln von Festplatten zu überstehen:

Das SBC Case Builder Gehäuse

Ich drucke mir mit dem 3D Drucker, basierend auf dem Design von SBC Case Builder mein eigenes Gehäuse. Ziel soll es sein, ein Gehäuse zu produzieren, welches auch mit gutem Gewissen in einem Server- oder Netzwerkschrank platziert werden kann:

Der SBC-Build hat aber leider eine kleine Schwäche. Auf der einen Seite, wo sich das Board befindet, kann der Deckel nicht angeschraubt werden. Daraus resultiert, dass beim Stromanschluss ein Spalt von ca 2mm entsteht. Dem habe ich einfach mit einem Kabelbinder entgegengewirkt. Ist nicht schön, aber für den Serverschrankt tut es das allemal:

Alles in allem kann man den HC4 nun mit gutem Gewissen in den Serverschrank stellen:

  • Die Festplatten sind sehr gut fixiert und es wackelt rein gar nichts.
  • Der zweite Lüfter, den ich über den USB-Port betreibe, sorgt für zusätlich gute Belüftung.
  • Der Stock-Lüfter befindet sich übrigens unterhalb des HC4-Boards. Ein Lüfter wurde so montiert, dass er die Luft nach aussen bläst und einer zieht die Luft an.
  • Der Lüftungsregulierer erlaubt es die Touren des Lüfters einzustellen. Ich habe ihn auf ca. 50% eingestellt. Damit wird immer noch gut belüftet und der Lärmpegel hält sich in Grenzen. => Serverschrank-Ready.
  • Ist es schön? => NEIN 😀

Betriebssystem

Der HC4 bietet neu (im Gegensatz noch zum HC2) die Möglichkeit das Betriebssystem auf der SATA-Disk zu installieren. Hardkernel hat dafür den Petitboot Bootloader vorinstalliert. Dieser Bootloader ermöglicht den HC4 Start ohne eingelegte Disk oder SD-Karte. Anschliessend kann über netboot ein Betriebssystem direkt auf einer Disk installiert werden. Ich habe aber für die Installation das Image auf die SD Karte geschreiben und dabei folgende zwei Images getestet:

Die Ubuntu-Version stammt von Hardkernel und ist mit Petitboot kompatibel. Das bedeutet, dass das Betriebssystem (nach 10s wartezeit) von Petitboot erkannt und gebootet wird. Dieses Ubuntu könnte damit z.B. auf einer SATA SSD Disk installiert werden. Das Betriebssystem wird damit dann direkt von der SSD betrieben und nicht auf der SD-Karte.

Armbian hingegen wird von Petitboot nicht erkannt. bei Armbian muss Petitboot komplett entfernt werden. Mit gelöschtem Petitboot versucht der HC4 auf der SD-Karte ein Betriebssystem zu finden und startet dieses dann direkt. Dies hat den Vorteil, dass der Start sofort durchgeführt wird (ohne 10s) Wartezeit. Dafür aber auch den Nachteil, dass das Betriebssystem auf der SD-Karte liegt. SD-Karten sind bekanntlich nicht dafür geeignet ein Betriebssystem (mit vielen writes) zu betreiben.

Ich entscheide mich für eine Installation mit Armbian. Armbian ist leichtgewichtiger als die Hardkernel Ubuntu-Version und auf den HC4 abgestimmt. Armbian ist mir deswegen etwas sympatischer – ist aber eher ein Bauchentscheid als wirklich mit harten Fakten begründet…

Installation Armbian

# flash_eraseall /dev/mtd0
# flash_eraseall /dev/mtd1
# flash_eraseall /dev/mtd2
# flash_eraseall /dev/mtd3
    • => Dadurch wird der SPI-Flash-Speicher gelöscht und der HC4 startet ab sofort direkt von der SD Karte.
  • HC4 mit eingelegter Armbian SD-Karte starten
  • Installations-Anweisungen befolgen

Grund-Installation Armbian ist damit abgeschlossen

Lüfter-Support aktivieren:

vi /etc/fancontrol

Inhalt einfügen:

INTERVAL=10
DEVPATH=hwmon0=devices/virtual/thermal/thermal_zone0 hwmon2=devices/platform/pwm-fan
DEVNAME=hwmon0=cpu_thermal hwmon2=pwmfan
FCTEMPS=hwmon2/pwm1=hwmon0/temp1_input
FCFANS= hwmon2/pwm1=hwmon2/fan1_input
MINTEMP=hwmon2/pwm1=50
MAXTEMP=hwmon2/pwm1=60
MINSTART=hwmon2/pwm1=20
MINSTOP=hwmon2/pwm1=28
MINPWM=hwmon2/pwm1=0
MAXPWM=hwmon2/pwm1=255

Restart fancontrol

sudo systemctl restart fancontrol

Wichtig: Wenn man den Kernel 5.15.x einsetzt, muss die Zeile FCFANS=hwmon2/pwm1=hwmon2/fan1_input entfernt werden.

Reboot Issue

Ein soft reboot (sudo reboot) funktionierte in diesem Zustand nicht. Die Lösung ist hier zu finden:

armbian-config ---> System -> Install -> Install/Update the bootloader on SPI/Flash

Danach bootet armbian sauber nach einem “sudo reboot”.

Wiederherstellen/Update Petitboot

Es besteht die Möglichkeit Petitboot zu aktualisieren bzw. über das gleiche Vorgehen, nach einer Löschung, wieder zu installieren.

Dafür stellt Hardkernel ein Image zur Vefügung:

  • Download aktuelles spiupdate-image unter http://ppa.linuxfactory.or.kr/images/petitboot/odroidhc4/ => Die heute aktuelle Version ist “spiupdate_odroidhc4_20201112.img”
  • Optional:
    • Download letzte Firmware “spiboot-20220317.img
    • Auf der geflashten SD-Karte das File “spiboot.img” durch die neue heruntergeladene Variante ersetzen. Das File muss natürlich nach spiboot.img umbenannt werden.
  • Den HC4 mit dieser SD-Karte booten. Das Firmware-Update wird automatisch durchgeführt.
Hint: Boot ohne Petitboot

Gut zu Wissen ist, dass der HC4 auch ohne das entfernen von Petitboot die Möglichkeit bietet ohne Petitboot zu starten. Dafür muss man einfach den schwarzen Reset-Knopf drücken und gleichzeitig den Stromstecker einstecken. Dann warten, bis der HC4 blau zu blinken beginnt. Damit startet HC4 ohne Petitboot. => Das ist aber natürlich für den täglichen Gebrauch nicht wirklich zu empfehlen.

Installation Festplatten / RAID1

Partition erstellen

Als erstes schliesse ich eine der beiden 8TB Festplatten an und boote das System neu. Nun eine Partition erstellen:

sudo fdisk /dev/sda
g

Dies erstellt eine gpt-Partitionstabelle und wir erhalten das Disk-Label (GUID) => Dieses notieren

  • Nun mit n eine Partition erstellen und alle vorgeschlagenen Standardwerte übernehmen.
  • Am Schluss mit w die Änderungen auf die Platte schreiben.
sudo fdisk -l
  • Zeigt nun die partitionierte Festplatte an
  • Filesystem erstellen

  • Wir erstellen ein Btrfs Filesystem, über welches dann Raid1 umgesetzt wird.
mkfs.btrfs /dev/sda1

Dies erstellt das Filesystem und weist eine UUID zu (UUID notieren).

Die notierten GUID und UUID habe ich mir mit einem P-Touch auf ein Label ausgedruckt und auf die Disk geklebt. Das ermöglicht im späteren Betrieb die Disk einwandfrei zu identifizieren.

Der Disk Identifier kann folgendermassen ermittelt werden

fdisk -l /dev/sda

Subvolumes einrichten

Btrfs unterstützt Subvolumes. Btrfs hat ein unabhängiges einhängbares Root-Verzeichnis für das Volume (Subvolume der obersten Ebene) und für jedes Subvolume. Ein Btrfs-Volume kann also mehr als einen einzelnen Dateibaum enthalten. Einen ganze Tree  von Dateibäumen enthalten. Ein Btrfs-Subvolume kann man sich als POSIX-Dateinamensraum vorstellen.

Es ist zum empfehlen Subvolumes für voneinander unabhängige Datenablagen zu verwenden (z.B. Backup, Filme, Musik, etc.)

Als erstes hängen wir das Btrfs Root-Subvolume ein:

sudo mount /dev/sda1 /mnt

Ich erstelle für mich ein Subvolume, welches alle Multimedia-Daten beinhalten soll (Filme, Musik, Bücher, etc.):

btrfs subvolume create /mnt/@backup

Nun das Root-Subvolume wieder aushängen

sudo umount /dev/sda1

Jetzt kann man das erstellte Subvolume direkt in das Filesystem einhängen:

sudo mkdir /mnt/multimedia
sudo vi /etc/fstab
/dev/sda1 /mnt/multimedia btrfs defaults,nofail,noatime,compress=zstd,subvol=@multimedia 0 0

Dieser fstab Eintrag kann anschliessend über die CLI gemountet werden

sudo mount /mnt/multimedia

Komplette Rechte auf /mnt/multimedia setzen

chmod 0777 /mnt/multimedia

Auf diese Art und Weise kann man so viele Subvolumes erstellen wie man eben braucht.

Raid1

Bis jetzt haben wir nur eine HDD installiert. Nachdem das Filesystem angelegt ist funktioniert (an dieser Stelle habe ich auch bereits Samba eingerichtet und getestet), setzen wir die zweite Disk (nach einem shutdown und anschliessendem Neustart) ein und erstellen das Raid1.

Hinweis 1: An dieser Stelle habe ich festgestellt, dass ich die erste HDD in Slot2 des HC4 gesteckt habe. Der SATA-Slot, der sich näher am Stromanschluss/Netzwerkanschluss befindet ist offensichtlich Slot Nr. 2 – Nach dem Restart hat nämlich die zweite HDD /dev/sda zugewiesen bekommen und wodurch dann natürlich das vorhin erstellte Btrfs Filesystem nicht mehr verfügbar war. Nach einem erneuten Stopp, wechsel der Festplatten und Neustart war dieses Problem behoben.

Hinweis 2: Bei der Einrichtung von Raid1 habe ich mich gefragt, ob es denn möglich ist, den Raid-level je nach subvolume zu setzen. Das ist offenbar nicht möglich. Btrfs scheint dies als Feature offen zu haben, es ist aber offenbar seit fast 10 Jahren nichts mehr in diese Richtung gegangen. Also: Nein. 🙂

fdisk verrät mir, wie die neue Festplatte erkannt wurde:

sudo fdisk -l

In meinem Falle ist die neue HDD das Device /dev/sdb.

Nun wird für diese HDD (/dev/sdb) ebenfalls eine gpt-Partition und eine Partition über die gesamte Platte erstellt siehe hier.

Nun teilen wir btrfs mit, dass die neue Platte als Raid-1 Verbund zur ersten Platte verwendet werden soll. Dafür hängen wir alle gemounteten subvolumes erst aus.

sudo umount /mnt/<subvolumes>

Nun hängen wir die gesamte erste Festplatte ein

sudo mount /dev/sda1 /mnt

btrfs die neue Festplatte bekannt machen

sudo btrfs device add /dev/sdb1 /mnt

/dev/sdb in einen Raid1-Verbund aufnehmen. Erklärung:

  • -mconvert= Option, ein neues Profil “raid1” auf die Metadaten des Diskarrays anzuwenden
  • -dconvert = Neues Profil “raid1” auf die Nutzdaten des Diskarrays zu legen
# sudo btrfs balance start -dconvert=raid1 -mconvert=raid1 /mnt
# Done, had to relocate 5 out of 5 chunks

Damit wurde der Raid1 Verbund erstellt. Wenn die zweite HDD  (wie bei mir zu Testzwecken) kleiner als die erste HDD ist, dann wird der Gesamtspeicherplatz neu maimal die Grösse der kleineren Festplatte betragen. Was bei mir auch so korrekt funktioniert hat.

Nun die ganze Festplatte wieder aushängen und die zuvor angelegten subvolumes einhängen (z.B. durch reboot, so dass die fstab Einträge geladen werden).

sudo umount /mnt
sudo reboot

Test / weitere Befehle

Überblick über das Raid

# btrfs fi usage /mnt/<subvolume>

Overall:
Device size: 14.55TiB
Device allocated: 10.06GiB
Device unallocated: 14.54TiB
Device missing: 0.00B
Used: 4.51GiB
Free (estimated): 7.27TiB (min: 7.27TiB)
Free (statfs, df): 7.27TiB
Data ratio: 2.00
Metadata ratio: 2.00
Global reserve: 6.11MiB (used: 0.00B)
Multiple profiles: no

Data,RAID1: Size:3.00GiB, Used:2.25GiB (74.92%)
/dev/sda1 3.00GiB
/dev/sdb1 3.00GiB

Metadata,RAID1: Size:2.00GiB, Used:8.55MiB (0.42%)
/dev/sda1 2.00GiB
/dev/sdb1 2.00GiB

System,RAID1: Size:32.00MiB, Used:16.00KiB (0.05%)
/dev/sda1 32.00MiB
/dev/sdb1 32.00MiB

Unallocated:
/dev/sda1 7.27TiB
/dev/sdb1 7.27TiB

Prüfen der Devices

sudo btrfs fi show /mnt/<subvolume>

Label: none uuid: 0edb47d3-ea4a-4667-b609-223212ec41b1
Total devices 2 FS bytes used 2.26GiB
devid 1 size 7.28TiB used 5.03GiB path /dev/sda1
devid 2 size 7.28TiB used 5.03GiB path /dev/sdb1

Raid 1 – Festplattenwechel

Es ist eine Frage der Zeit, bis eine Festplatte den Geist aufgeben wird. Da wir ein Raid1 haben, sollte dies kein grossen Problem darstellen. Ob das aber funktioniert, muss getestet werden.

Das Vorgehen

  1. System herunterfahren
  2. Defekte HDD entfernen und stattdessen neue HDD in den Slot stecken.
    Als Simulation ersetzte ich die zweite (kleinere) HDD nun mit einer neuen gleichgrossen HDD (8TB)
  3. System hochfahren.
    Nach dem reboot wurden die subvolumes, wie erwartet, nicht mehr gemountet. Ich habe aber auch nirgends einen Hinweis erhalten, dass es ein Problem mit BTRFS gibt (auch nicht in dmesg). An dieser Stelle kann man über fdisk die Devices identifizieren.

    sudo fdisk -l

    Anhand der auf der HDD gekenntzeichneten GUID stelle ich fest, dass die noch funktionierende HDD als /dev/sda und die neue als /dev/sdb erkannt wurde.

  4. RAID im degraded mode mounten.
    Damit die noch funktionierende Festplatte eingehängt werden kann, muss das Raid mit der Option -o degraded eingehängt werden

    sudo mkdir /mnt/temp
    sudo mount -o degraded /dev/sda1 /mnt/temp

    Nun kann überprüft werden, welche Festplatte fehlt (in diesem Falle ID2):

    # sudo btrfs device usage /mnt/temp
    
    /dev/sda1, ID: 1
    Device size: 7.28TiB
    Device slack: 3.50KiB
    Data,RAID1: 3.00GiB
    Metadata,RAID1: 1.00GiB
    System,RAID1: 32.00MiB
    Unallocated: 7.27TiB
    
    missing, ID: 2
    Device size: 0.00B
    Device slack: 0.00B
    Data,RAID1: 3.00GiB
    Metadata,RAID1: 1.00GiB
    System,RAID1: 32.00MiB
    Unallocated: 1.81TiB
  5. Die neue Festplatte partitionieren
    Die neue Festplatte (hier /dev/sdb) muss nun wie her beschrieben partitioniert werden.
  6. RAID wiederherstellen (`btrfs replace`).
    Nun kann die neue Festtplatte in den Raid1 Verbund aufgenommen werden. Hier wird das vermisste Device mit der ID 2, welches sich an /dev/sdb1 in das Raid1, welches an /mnt/temp eingebunden wurde, aufgenommen (siehe auch btrfs Doku).

    sudo btrfs replace start 2 /dev/sdb1 /mnt/temp

    Der replace-Prozess wird im Hintergrund durchgeführt. Das kann einige Stunden dauern. Der Status des replace kann folgendermassen abgerufen werden

    sudo btrfs replace status /mnt/temp/

    Sobald der replace-Prozess beendet wurde (zu überprüfen mit status) kann die neue disk angezeigt werden:

    # sudo btrfs device usage /mnt/temp
    
    /dev/sda1, ID: 1
    Device size: 7.28TiB
    Device slack: 3.50KiB
    Data,single: 3.00GiB
    Data,RAID1: 3.00GiB
    Metadata,single: 2.00GiB
    Metadata,RAID1: 1.00GiB
    System,single: 64.00MiB
    System,RAID1: 32.00MiB
    Unallocated: 7.27TiB
    
    /dev/sdb1, ID: 2
    Device size: 7.28TiB
    Device slack: 5.46TiB
    Data,RAID1: 3.00GiB
    Metadata,RAID1: 1.00GiB
    System,RAID1: 32.00MiB
    Unallocated: 1.81TiB
  7. Jetzt die Redundaz wieder herstellen
    # sudo btrfs balance start -dconvert=raid1,soft -mconvert=raid1,soft /mnt/temp
    # Done, had to relocate 7 out of 12 chunks
  8. System rebooten

Nach dem reboot ist das Raid1 mit der neuen Festplatte wieder hergestellt und alle subvolumes sollten wieder korrekt gemountet sein.

Raid1 vergrössern

Die alte Festplatte hatte in meinem Falle eine Grössen von 2TB, die neue Festplatte hat eine Grösse von 8TB. Damit habe ich 2x 8TB verbaut. Das Raid1 hat aber zu diesem Zeitpunkt immer noch die Grösse der früheren kleineren Festplatte. Wir müssen also nun noch die Grösse des Raids auf den maximal verfügbaren Speicher anheben. Dies geschieht über den resize Befehl:

Dazu muss das Raid wieder als gesamtes unter /mnt/temp gemountet werden und alle subvolumes ausgehängt sein.

sudo umount /mnt/<subvolumes>
sudo mount /dev/sda1 /mnt/temp

Hier müssen wir nun Device ID 2 auf deren maximal verfügbare Grösse vergrössern

# sudo btrfs filesystem resize 2:max /mnt/temp
Resize device id 2 (/dev/sdb1) from 1.82TiB to max

Nun zeigt btrfs device usage auch für das Device 2 die korrekte Grössen an (unallocated):

#sudo btrfs device usage /mnt/temp

/dev/sda1, ID: 1
Device size: 7.28TiB
Device slack: 3.50KiB
Data,RAID1: 3.00GiB
Metadata,RAID1: 2.00GiB
System,RAID1: 32.00MiB
Unallocated: 7.27TiB

/dev/sdb1, ID: 2
Device size: 7.28TiB
Device slack: 3.50KiB
Data,RAID1: 3.00GiB
Metadata,RAID1: 2.00GiB
System,RAID1: 32.00MiB
Unallocated: 7.27TiB

Damit stehen nun die gesamten 8TB als Raid zur Verfügung.

Über diesen Prozess kann übrigens das Raid durch neuere grössere Festplatten ersetzt werden. Der HC4 unterstütz bis zu 12 TB grosse Festplatten. Es besteht also noch Luft nach oben 🙂

Btrfs Wartung

Damit das Btrfs-Filesystem gut “in Schuss” bleibt, ist es notwendig etwas in die Wartung dessen zu investieren.  Wartungsaufgaben können mit dieser Script-Sammlung automatisiert werden (Scrubben, Ausbalancieren, Trimmen oder Defragmentieren).

Installation btrfsmaintenance

sudo apt-get update
sudo apt-get install btrfsmaintenance

Dies installiert btrfsmaintenance

  • Skripte unter /usr/share/btrfsmaintenance
  • Konfig-File unter /etc/default/btrfsmaintenance

Anpassen Konfig-File

sudo vi /etc/default/btrfsmaintenance

=> Setze auto um alle btfrs subvolumes abzudecken.
BTRFS_BALANCE_MOUNTPOINTS="auto"
BTRFS_SCRUB_MOUNTPOINTS="auto"

Installieren der cron-job Skripte.

sudo /usr/share/btrfsmaintenance/btrfsmaintenance-refresh-cron.sh
Refresh script btrfs-scrub.sh for monthly
Refresh script btrfs-defrag.sh for none
Refresh script btrfs-balance.sh for weekly
Refresh script btrfs-trim.sh for none

Samba

Damit das NAS Files im Netzwerk bereitstellen kann, benötigt es natürlich den entsprechenden Dienst. Mit Armbian könnten wir hier natürlich aus den vollen schöpfen. Aber ich begnüge mich mit Samba:

sudo apt-get install samba

Die einzelnen subvolumes sollen mittles Samba im Netzwerk verfügbar gemacht werden. Pro Subvolume muss entsprechend ein Linux-User erstellt werden, der sich aber nicht am System selber anmelden kann:

sudo useradd -s /bin/false multimedia
sudo smbpasswd -a multimedia

Gruppe erstellen und user multimedia zuweisen

sudo groupadd multimedia
sudo usermod -a -G multimedia multimedia

Nun die Samba Konfiguration durchführen

sudo mv /etc/samba/smb.conf /etc/samba/smb.orig
sudo vi /etc/samba/smb.conf

Inhalt

[global]
workgroup = WORKGROUP
server string = %h server (Samba, HC4_NAS)
security = user
map to guest = never

[multimedia]
path = /mnt/multimedia
public = yes
writable = yes
comment = hc4 nas: multimedia share
printable = no
guest ok = no
force group = multimedia
valid users = multimedia
create mask = 0660
directory mask = 0770

Nun Samba Dienste neu starten. Anschliessend steht das Sama-Share ‘multimedia’ zur Verfügung:

sudo systemctl restart smbd.service
sudo systemctl restart nmbd.service

Das Share kann nun z.B. unter Ubuntu in Dateibrowser mit

smb://<ip>/multimedia/

unter Verwendung des Users ‘multimedia’ & Passwort verbunden werden.

FTP Server

HC4 soll auch einen FTP Server bereitstellen. Ich installier dafür PureFTPd. Die Installation habe ich hier bereits einmal beschrieben.

Video-Überwachung

Für die Video Überwachung setzte ich Shinoi ein. Die Installation wird hier beschrieben.

Bibliotheksverwaltung für eReader

Für die Bibliotheksverwaltung setze ich Calibre ein. Hier wird die Installation beschrieben.

Fazit

Wenig überraschend lassen sich alle Services eines Standard-NAS nachbauen.

Daten-Transfer Performance

Das Kopieren von sehr grossen Files (20 à ca. 10GB) oder auch gleichzeitig vielen kleineren Files ( 300 à 10MB) ergeben eine Durchschnittsgeschwindigkeit von 55-57MB/s. Damit befinden wir uns in dem, für die eingesetzten HDDs, erwarteten Rahmen. Hardkernel verspricht beim Einsatz von SSDs Werte von bis zu 100MB/s. Wer das notwendige Budget hat => go4it 😉

Festplattenwechsel

Ein Festplattenwechsel hat ohne Probleme und ohne Datenverlust funktioniert.

Performance allgemein

Die Performance des HC4 reicht für die von mir eingesetzten Services locker aus. Für die Video-Überwachung habe ich 4 Neztwerk-Kameras installiert, welche alle durchwegs im recording Modus laufen, also Daueraufnahmen machen und gleichzeitig den Stream auch noch an diverse Clients weiterleiten. Trotzdem läuft der HC4 ziemlich unbeeindruckt auf rund 5-10% CPU und ca 20% RAM-Auslastung. Die Temperaturen belaufen sich auf rund 55°C (CPU) und 45°C (Storage).

Systemd Startreihenfolge der Services

Nach einigen Monaten Laufzeit ist aufgefallen, dass das System öfters nach einem Reboot nicht mehr korrekt funktioniert hat. Zum einen musste ich die korrektur des “Reboot Issues” wieder durchführen. Diese Anpassung ging wohl nach einem apt-get upgrade verloren.

Das andere Problem war dass das Mounten der btrfs Verzeichnisse teilweise länger dauerte, als das starten der systemd Services. Das führte zur unschönen Situation, dass das System nach einem Reboot im Status “degraded” hängen blieb, weil benötigte Verzeichnisse noch nicht gemountet waren. Hier habe ich beschrieben, wie ich diese Problematik gelöst habe.

Links

Pure-FTP Server auf Ubuntu Server installieren

Pure-FTP ist ein einfach zu installierender und sicherer FTP-Server. Er lässt sich jedoch nicht wie sonst gewohnt über ein Konfig-File konfigurieren. Vielmehr wird der Server (pureftpd) über ein Wrapper-Script aufgerufen, welches dem Server die Konfigurations-Parameter direkt beim Aufruf des Prozesses mitreicht. Die Konfiguration kann aber trotzdem recht einfach durchgeführt werden. Im Verzeichnis

/etc/pure-ftpd/conf

können “One-Liner” Files erstellt werden, welche vom Wrapper-Script gelesen und als Parameter verwendet werden. Siehe dazu weiter unten die Konfiguration.

Das Wrapper-Script wird hier genauer beschreiben: https://manpages.debian.org/experimental/pure-ftpd-common/pure-ftpd-wrapper.8.en.html

Um zu überprüfen, welche Option aus dem Wrapper-Script gesetzt wurden:

pure-ftpd-wrapper --show-options

Installation

Während der Installation wird nebst dem installieren des Packete auch eine Gruppe “ftpgroup” und einen User “ftpuser” erstellt. Das Home-Verzeichnis von “ftpuser” wird das Root-Verzeichnis für alle virtuellen ftpuser sein. “ftpuser” dient zukünftig als Profil für alle virtuellen User (beim erstellen eines virutellen Users wird auf diesen ftpuser verwiesen).

sudo apt-get install pure-ftpd

sudo groupadd ftpgroup

sudo mkdir /home/ftpuser

sudo useradd -g ftpgroup -d /dev/null -s /bin/false ftpuser
=> useradd: Warning: missing or non-executable shell '/etc': Warnung ist ok

sudo chown -R ftpuser:ftpgroup /home/ftpuser

Die Grundinstallation ist damit abgeschlossen. Nun kann sicher jeder Linux-User bereits einloggen, wobei das entsprechende Home-Verzeichnis als FTP-Root Verzeichnis verwendet wird. Das ganze ist in diesem Zustand auch noch nicht sehr sicher, da sich die User im gesamten Tree des Servers bewegen dürfen (kein chroot, etc.).

Konfiguration

Jedes File in

/etc/pure-ftpd/conf/

entspricht einem Parameter, wobei das File dem Parameter und der Inhalt des Files dem Wert des Parameters entspricht. Verwendet wird die ausgeschriebene Variante der Parameter. Die möglichen Parameter können mit

pure-ftpd --help

aufgelistet werden.

Ich verwende folgende Konfiguration

sudo bash
echo yes > /etc/pure-ftpd/conf/ChrootEveryone
echo yes > /etc/pure-ftpd/conf/NoAnonymous
echo no > /etc/pure-ftpd/conf/PAMAuthentication
echo no > /etc/pure-ftpd/conf/UnixAuthentication 
echo yes > /etc/pure-ftpd/conf/IPV4Only
echo /etc/pure-ftpd/pureftpd.pdb > /etc/pure-ftpd/conf/PureDB

Da wir als Authentifizierung die PureDB nutzen wollen muss noch ein symbolischer Link gesetzt werden:

cd /etc/pure-ftpd/auth
sudo ln -s ../conf/PureDB 50pure

Weiter mögliche Konfigurations-Varianten:

echo yes > /etc/pure-ftpd/conf/ProhibitDotFilesWrite
echo yes > /etc/pure-ftpd/conf/ProhibitDotFilesRead
echo 50 > /etc/pure-ftpd/conf/MaxClientsNumber
echo 10 > /etc/pure-ftpd/conf/MaxClientsPerIP
echo no > /etc/pure-ftpd/conf/VerboseLog
echo yes > /etc/pure-ftpd/conf/DisplayDotFiles
echo no > /etc/pure-ftpd/conf/AnonymousOnly
echo /etc/pure-ftpd/pureftpd.pdb > /etc/pure-ftpd/conf/PureDB
echo yes > /etc/pure-ftpd/conf/NoChmod
echo 15 > /etc/pure-ftpd/conf/MaxIdleTime
echo 2000 8 > /etc/pure-ftpd/conf/LimitRecursion
echo yes > /etc/pure-ftpd/conf/AntiWarez
echo no > /etc/pure-ftpd/conf/AnonymousCanCreateDirs
echo 4 > /etc/pure-ftpd/conf/MaxLoad
echo no > /etc/pure-ftpd/conf/AllowUserFXP
echo no > /etc/pure-ftpd/conf/AllowAnonymousFXP
echo no > /etc/pure-ftpd/conf/AutoRename
echo yes > /etc/pure-ftpd/conf/AnonymousCantUpload
echo yes > /etc/pure-ftpd/conf/BrokenClientsCompatibility
echo ,21 > /etc/pure-ftpd/conf/Bind
echo yes > /etc/pure-ftpd/conf/Daemonize

Virtuelle User

  • Erstelle einen User-Home-Verzeichnis (Für jeden Benutzer kann ein solches Verzeichnis erstellt werden)
    sudo mkdir /home/ftpuser/<username>
    
  • Auf dem FTP-Verzeichnis die Rechte setzen:
    sudo chown -R ftpuser:ftpgroup /home/ftpuser
    
  • Den Virtuellen User beim FTP-Server anlegen
    sudo pure-pw useradd $USERNAME -u ftpuser -d /home/ftpuser/$USERNAME
    
  • Damit Pure-FTP den neuen Benutzer mitbekommt, muss die Pure-FTP DB neu erstellen werden:
    sudo pure-pw mkdb

Ich verwende auf meinem FTP Server softlinks zu weiteren Verzeichnissen/Datenablagen. Normalerweise verbietet PureFTPd die Weiterleitung an “symlinks”. Man kann dies aber auch explizit erlauben. Dies aber nicht wie (von mir) erwartet über ein Konfig-File “virtualchroot”. Dafür muss man folgende Anpassung machen:

sudo vi /etc/default/pure-ftpd-common

=> VIRTUALCHROOT=true

Anschliessend erlaubt PureFTPd das Weiterleiten an Symlinks.

TLS / SSL

  • TLS/SSL-Support aktivieren und Zertifikat erstellen:
    /etc/pure-ftpd/conf# apt-get install openssl
    /etc/pure-ftpd/conf# echo 1 > TLS
    /etc/pure-ftpd/conf# openssl req -x509 -nodes -newkey rsa:1024 -keyout /etc/ssl/private/pure-ftpd.pem -out /etc/ssl/private/pure-ftpd.pem
    Generating a 1024 bit RSA private key
    .
    .
    .
    /etc/pure-ftpd/conf# chmod 600 /etc/ssl/private/pure-ftpd.pem

pureadmin

Fuer Pure-FTP existiert ein GUI fuer die Administration. Hierfuer einfach das Packet pureadmin installieren.

User-Administration über Konsole

Siehe dazu: https://download.pureftpd.org/pub/pure-ftpd/doc/README.Virtual-Users

Wichtig: nach allen User-Änderungen immer die DB neu generieren:

sudo pure-pw mkdb

Benutzer-Management

View a User

sudo pure-pw show $USERNAME

Change a User’s Password

sudo pure-pw passwd $USERNAME -m

Update an Existing User

sudo pure-pw usermod $USERNAME $OPTIONS -m

Deleting a User

sudo pure-pw userdel $USERNAME -m

Listing All Users

sudo pure-pw list

Update the User/Password Database Manually

sudo pure-pw mkdb

Managing the Pure-FTP Server

Start Pure-FTPd Server

sudo service pure-ftpd start

Stop Pure-FTPD
Note: This does not disconnect active users.

sudo service pure-ftpd stop

Disconnect All Active Users Immediately

sudo killall pure-ftpd

Pure-FTPd Status

sudo service pure-ftpd status

Restart Pure-FTPd

sudo service pure-ftpd restart

View Server Activity

sudo pure-ftpwho

 

Pure-FTPd deinstallieren

sudo service pure-ftpd stop
sudo apt-get autoremove pure-ftpd
sudo apt-get purge pure-ftpd
sudo rm -r /etc/pure-ftpd
sudo userdel ftpuser
sudo groupdel ftpgroup

Links

https://linux.die.net/man/8/pure-ftpd

https://www.laub-home.de/wiki/Ubuntu_%26_Debian_Linux_-_Installation_Pure-FTP

https://help.ubuntu.com/community/PureFTP

Install Pure-FTPd Ubuntu – How we do it

Let’s encrypt

letsencrypt ist eine Zertifizierungsstelle, welche es erlaubt Zertifikate vollautomatisch und GRATIS zu generieren. Damit entfällt endlich die müsahme manuelle Erstellung von Zertifikaten. Und so geht es:

Ich installiere letsencrypt auf einem Ubuntu 16.04 System mit installiertem Apache:

    1. Letsencrypt installieren
      sudo apt install letsencrypt python-letsencrypt-apache
    2. Zertifikat generieren
      Bevors mit dem Zertifikate erstellen losgeht, muss ich zuerst den Apache-Dienst stoppen, weil letsencryp einen standalone Server auf port 80 verwendet:

      sudo service apache2 stop

      Nun generiere ich das Zertifikat mit “certonly”. Damit modifiziert mir letsencrypt nicht das Apache-Config File. Dieses möchte ich selber modifizieren… Für jede Domain kann dieser Befehl wiederholt werden:

      sudo letsencrypt certonly --agree-tos --email postmaster@yourdomain.ch -d www.yourdomain.ch

      Und voilà:

      IMPORTANT NOTES:
       - Congratulations! Your certificate and chain have been saved at
         /etc/letsencrypt/live/nextcloud.domain.ch/fullchain.pem. Your cert
         will expire on 2017-01-23. To obtain a new version of the
         certificate in the future, simply run Let's Encrypt again.
       - Some rewrite rules copied from /etc/apache2/conf-
         enabled/nextcloud.conf were disabled in the vhost for your HTTPS
         site located at /etc/apache2/conf-enabled/nextcloud-le-ssl.conf
         because they have the potential to create redirection loops.
      

      Nun den Apache wieder starten:

      sudo service apache2 start
    3. Das Script erstellt vollautomatisch die benötigten Zertifikate und legt diese ab unter
      /etc/letsencrypt/live/your.domain.zz/

      Das Zertifikat kann nun am conf-File des Apachen eingetragen werden

      SSLCertificateKeyFile /etc/letsencrypt/live/your.domain.zz/privkey.pem
      SSLCertificateFile /etc/letsencrypt/live/your.domain.zz/cert.pem
      SSLCertificateChainFile /etc/letsencrypt/live/your.domain.zz/chain.pem

    Renewal

    Letsencrypt stellt Zertifikate aus, welche 90 Tage gültig sind. Es wird empfohlen, dass alle 60 Tage ein renewal durchgeführt wird. Dies kann am einfachsten über einen cron-job erledigt werden, der monatlich ausgeführt wird:

    sudo vi /etc/cron.monthly/letsencrypt-renew
    #!/bin/bash
       echo "Stop Apache2 Service"
       service apache2 stop
       echo "Renew letsencrypt certificates"
       letsencrypt --standalone renew
       echo "Restart Apache2 Service"
       service apache2 start
    exit 0
    sudo chmod +x /etc/cron.monthly/letsencrypt-renew

     

Löschen

Mal erstellte Zertifikate, welche nicht mehr benötigt werden, können gelöscht werden:

sudo letsencrypt delete -d xx.domain.xx

 

docker / docker-compose Befehle

Container stoppen

docker-compose down

Container aktualisieren

docker-compose down
docker-compose pull
docker-compose up -d

Volumes anzeigen / löschen

Achtung! Dies entfernt einerseits die Container, aber inklusive die statischen Files bzw. Volumes (wordpress_files & db_data)

docker volume ls                # Listet alle Docker-Volumes auf
docker-compose down ––volumes   # löscht ein Container inkl. Volumes (!)

Aktive Containers anzeigen

docker container ls              # Listet alle aktiven container auf

Bash eines Containers öffnen

Es ist möglich über den Docker-Host auf eine Container-Bash zuzugreifen.
Syntax:

docker exec -i -t <docker-id> /bin/bash

Docker Logs anzeigen

Wenn Docker-Containers im “detached-mode” (-d) laufen, werden keine Logs angezeigt. Die Logs können folgendermassen sichtbar gemacht werden:

# Zeigt das Log
docker logs <ContainerName/ContainerID>  
# Zeigt das laufende Log (tail -f)
docker logs --follow <ContainerName/ContainerID>
# Zeigt  die letzen 2500 Zeilen des Logs
docker logs --tail 2500 <ContainerName/ContainerID>
# Zeigt das Log seit dem 28.12.2018 10:00
docker logs --since 2018-12-28T10:00 ContainerName/ContainerID

Auch docker-compose bietet die Möglichkeit auf die Docker-Logs zuzugreifen:

docker-compose logs <service-name>

Entferne nicht benutzte Docker Images

Folgender Befehl entfernt alle aktuell nicht benutzen Images und Volumes

docker system prune

 

WordPress Container auf Docker

Dieser Blog-Eintrag beschreibt, wie man auf WordPress auf einem Docker-Host installieren und damit mehrere WordPress-Instanzen auf einem Host betreiben kann.
Ich betreibe die Docker-Container hinter einem Proxy-Server, der aber nicht als Container läuft. Der Proxy-Server leitet die HTTPS-Requests an die entsprechenden Docker-Container weiter.

Dieser Beitrag setzt ein vorinstalliertes Photon 3.0 inkl. Docker und Docker-Compose voraus. Siehe hier.

Die Docker-Container können über diverse Befehle gemanaged werden. Siehe dazu eine kleine Übersicht hier.

WordPress installieren

Wir installieren WordPress mit Hilfe von Docker Compose. Dazu erstellen wir ein template:

mkdir wordpress
cd wordpress
vi docker-compose.yml

Im yml-Script erstellen wir eine WordPress- inkl. DB-Instanz.

WordPress-Instanz

  • Die WordPress-Instanz hat eine Abhängigkeit zur DB.
  • Die WordPress-Files werden unter /var/www/html abgelegt
  • der Host-Port 80 wird zur wordpress-Instanz port 80 weitergeleitet (“80:80”)
  • Die DB ist über Port 3306 anzusprechen (WORDPRESS_DB_HOST: db:3306)
  • Der DB-User ist wordpress (WORDPRESS_DB_USER: wordpress)
  • Das DB-Passowort ist zu setzen: WORDPRESS_DB_PASSWORD: <wordpress_db_password>

DB-Instanz

  • Die DB-Files werden hier abgelegt: db_data:/var/lib/mysql
  • Passort setzen: MYSQL_ROOT_PASSWORD: <mysql root password>
  • Datenbank definieren: MYSQL_DATABASE: wordpress
  • User definieren: MYSQL_USER <wordpress>
  • DB-Passwort setzen: MYSQL_PASSWORD: (wordpress db password)
version: '3.3' services:

wordpress:
   depends_on:
     - db
   image: wordpress:latest
   volumes:
     - wordpress_files:/var/www/html
   ports:
     - "8080:80"
   restart: always
   environment:
     WORDPRESS_DB_HOST: db:3306
     WORDPRESS_DB_USER: wordpress
     WORDPRESS_DB_PASSWORD: (wordpress_db_password)

db:
   image: mysql:5.7
   command: '--default-authentication-plugin=mysql_native_password'
   volumes:
     - db_data:/var/lib/mysql
   restart: always
   environment:
     MYSQL_ROOT_PASSWORD: (mysql root password)
     MYSQL_DATABASE: wordpress
     MYSQL_USER: wordpress
     MYSQL_PASSWORD: (wordpress db password)
   volumes:
     wordpress_files:
     db_data:

 

Die letzten beiden Linien restellen lokale Verzeichnisse auf dem Photon-Host. Hier werden die WordPress- und SQL-Files abgespeichert. Diese Files überleben somit, wenn der container zerstört und neu generiert wird.

Die Volumes werden unter

cd /var/lib/docker/volumes

erstellt und bleiben bestehen. Dies solange bis die Volumes mittels

docker-compose down -v

zerstört werden.

WordPress Container starten

Nun kann der Container einfach gestartet werden. Dank Docker Compose braucht man nur noch einen Befehl. Docker Compose erkennt automatisch das YAML im aktuellen Verzeichnis, durchläuft die Konfiguration und startet die Container-Anwendung:

docker-compose up -d

Den Prozess kann man anzeigen lassen

docker ps

Nun ist über http://<ip>:8080 auf die WordPress-Instanz zugegriffen werden.

WordPress Container mit SSL erweitern

Das so bereitgestellte Container-Image bietet WordPress “out-of-the-Box” über Port 80 an. Port 443 ist nicht aktiviert. Man geht dabei davon aus, dass die Verschlüsselung (https) eine zusätzliche, neue Funktion darstellt und damit über einen weiteren Container abzubilden ist. Dazu kann ein Proxy-Container aufgebaut werden, für den es auch bereits fertige Docker-Images gibt. Architektonisch mag das Sinn machen.

Ich möchte das aber nicht so umsetzen. Ich betreibe bereits einen Proxy-Server und dieser soll auch so weiter beibehalten werden. Ich verzichte also auf einen Proxy-Container und erweitere das WordPress-Image durch die SSL-Funktionalität. Damit das geht, muss ich das docker-compose.yml bzw. die WordPress-Container Beschreibung erweitern.

Als erstes erstelle ich ein zusätzliches File

vi wordpress/wp-init.sh
!/usr/bin/env bash
apt-get update
apt-get install -y --no-install-recommends ssl-cert
rm -r /var/lib/apt/lists/*
a2enmod ssl
a2dissite 000-default.conf
a2ensite apache2-vhosts.conf
docker-entrypoint.sh apache2-foreground

Dieses Bash-Script soll bei jedem Starten des Containers ausgeführt werden. Mittels diesem Script wird
– SSL nachinstalliert
– Die Default Konfig “000-default.conf” auf dem Apachen entfernt und stattdessen
– eine neue Konfig “apache2-vhosts.conf” installiert.
– Anschliessend wird der Apache neu gestartet.

Damit das Script funktioniert braucht es noch eine Apache-Config. Diese Config wird in den WordPress-Container gemappt und beim Container-Start aktiviert. Damit kann ich von ausserhalb des Containers, die Apache-Config manipulieren:

vi wordpress/apache2-vhosts.conf
NameVirtualHost * 
<VirtualHost *:443> 
   ServerName domain.ch 
   DocumentRoot /var/www/html/ 
   DirectoryIndex index.php 
   Options -Indexes 
   SSLEngine On 
   SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem 
   SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key 
   SSLCACertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem 
</VirtualHost>

Nun ist das das docker-compose.yml zu erweitern (siehe die markierten Erweiterungen):

version: '3.3'
   services:
   wordpress:
     depends_on:
       - db_node
     image: wordpress:latest
     volumes:
       - wordpress_files:/var/www/html
       - ./wp-init.sh:/usr/local/bin/apache2-custom.sh
       - ./apache2-vhosts.conf:/etc/apache2/sites-available/apache2-vhosts.conf
     ports:
       - "8080:80"
       - "8443:443"
     restart: always
     environment:
       WORDPRESS_DB_HOST: db_node:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD: (wordpress db password)
     container_name: wordpress_web
     command: "bash -c apache2-custom.sh"

   db_node:
     image: mysql:5.7
     command: '--default-authentication-plugin=mysql_native_password'
     volumes:
       - db_data:/var/lib/mysql
     ports:
       - 6601:3306
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: (wordpress root password)
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: (wordpress db password)
     container_name: wordpress_db
     volumes:
       wordpress_files:
       db_data:

Wie man sieht wird
– das wp-init.sh Skript in den Container gemappt
– Die Apache-Config apache2-vhosts.conf in den Container gemappt.
– Der Container um den Port 8443 erweitert, der Container-Intern auf 443 routet und
– Das Commando “bash -c apache2-custom.sh” bei starten ausgeführt.

Damit startet der Container ab sofort mit aktiviertem SSL und der Apache-Container kann über das File apache2-vhosts.conf konfiguriert werden.

Reverse Proxy

Auf dem Reverse-Proxy wird nun einfach eine Reverse-Rule für den Container eingeführt. Der Reverse-Proxy leitet die HTTPS-Anfragen intern an den Container-Host mit Port 8443 weiter. Diese kann so aussehen:

<VirtualHost serverIp:80> 
ServerAdmin info@domain.ch 
ServerName www.domain.ch 
ServerAlias domain.ch 
RewriteEngine on 
ReWriteCond %{SERVER_PORT} !^443$ RewriteRule ^/(.*) https://www.domain.ch/$1 [NC,R,L] 
</VirtualHost>

<VirtualHost serverIp:443> 
ServerAdmin info@domain.ch 
ServerName www.domain.ch 

#aktiviert SSL Unterstuetzung 
SSLEngine On 
SSLProxyEngine on 
SSLProxyVerify none 
SSLProxyCheckPeerCN off 
SSLProxyCheckPeerName off 
SSLProxyCheckPeerExpire off 

SSLCertificateKeyFile /etc/letsencrypt/live/www.domain.ch/privkey.pem 
SSLCertificateFile /etc/letsencrypt/live/www.domain.ch/cert.pem 
SSLCertificateChainFile /etc/letsencrypt/live/www.domain.ch/chain.pem 

# Regeln zum umleiten auf den internen Server 
ProxyPreserveHost On 
ProxyRequests Off 
ProxyPass / https://www.domain.ch:8443/ 
ProxyPassReverse / https://www.domain.ch:8443/ 

RequestHeader unset Accept-Encoding 

ErrorLog /var/log/apache2/error.log 

# Possible values include: debug, info, notice, warn, error, crit, 
# alert, emerg. 
LogLevel warn 

CustomLog /var/log/apache2/access.log combined 
ServerSignature On 
</VirtualHost>

SMTP auf WordPress-Container

Ich betreibe einen eigenen Mailserver. Ich stellte rasch fest, dass WordPress keine Mails über diesen Server versenden kann. Dies, weil das WordPress-Image einerseits grundsätzlich keinen SMTP-Agent mit dabei hat und andererseits mein Mailserver auch nicht aus dem Container heraus erreichbar war:

Um das Problem zu lösen habe ich mir einfach das Plugin “WP Mail SMTP” installiert. Dieses erweitert WordPress um die Mailfunktion. Das Connectivity-Problem konnte ich mit einer einfach Erweiterung von /etc/hosts lösen:

192.168.xx.xx    mx.domain.ch

Man beachte, dass ich die interne IP des Mailservers verwende.

Damit diese Erweiterung auch bei einem neuen Create des Containers übernommen wird, muss wordpress/wp-init.sh noch modifiziert werden:

#!/usr/bin/env bash

# modify /etc/hosts with mx.intelli.ch
cat >> /etc/hosts <<-EOF

/* mx.intelli.ch */
192.168.xx.xx    mx.domain.ch
EOF

apt-get update
apt-get install -y  --no-install-recommends ssl-cert   # SSL
rm -r /var/lib/apt/lists/*

a2enmod ssl
a2dissite 000-default.conf
a2ensite apache2-vhosts.conf

# finally execute default command
docker-entrypoint.sh apache2-foreground

Links

Linux Datei-Rechte

GruppeUserGroupOthers
Rechtr w xr – xr – –
Wertung4 2 14 0 14 0 0
Mode (Octal)754
Recht Mode (Octal)
0
–x 1
-w- 2
-wx 3
r– 4
r-x 5
rw- 6
rwx 7

Debian sudo: Benutzer für sudo berechtigen

Erscheint die Fehlermeldung

username is not in the sudoers file. This incident will be reported.

hat der aktuelle Benutzer kein Recht, sudo zu nutzen. Das heißt, er ist nicht in einer Benutzergruppe, welche ihm die Nutzung dieser Funktion gestattet.

In der Standardkonfiguration haben der Benutzer “root” und die Benutzergruppe “sudo” Zugriff auf die gleichnamige Funktion sudo. Es gibt auch hinreichend viele Tutorials, welche sich mit der Thematik befassen, einem Benutzer das Recht zu geben, sudo zu nutzen. Diese sind jedoch meiner Meinung nach umständlicher.

Umständliche Variante

Diese nutzen das Programm visudo, welches von sudo ebenfalls mitgeliefert wird. Damit öffnet sich die Konfigurationsdatei von sudo und man kann mit der richtigen Syntax Benutzer oder Benutzergruppen hinzufügen, um ihnen das Nutzen von sudo zu erlauben.

Für den Benutzer “test” sähe das z.B. folgendermaßen aus:

test ALL=(ALL) ALL

Für die Benutzergruppe “test” sähe das dagegen folgendermaßen aus:

%test ALL=(ALL) ALL

Einfache Variante

Da jedoch bereits die Gruppe “sudo” das Recht hat, sudo zu nutzen, kann man auch einfach diese nutzen. Hierzu muss man den Benutzer lediglich dieser Gruppe hinzufügen:

usermod -a -G sudo test

Nach dem nächsten Login per SSH können dann der jeweilige Benutzer bzw. Benutzer der jeweiligen Benutzergruppe sudo problemlos nutzen und erhalten nicht mehr die Fehlermeldung “username is not in the sudoers file. This incident will be reported.”.