Systemd Service – Startreihenfolge und warten auf Godot

Für meine  NAS Lösung habe ich ein Raid1, basierend auf btrfs eingesetzt. Services wie Video-Recording und die Bibliotheks-Software speichern dabei ihre Daten auf Mount-Verzeichnisse aus btrfs ab. Leider kam es vor, dass das Mounten der btrfs Verzeichnisse 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. Folgende Services waren bei mir betroffen:

  • /lib/systemd/system/mariadb.service (für shinobi)
  • /etc/systemd/system/calibre-server.service (für calibre)
  • /etc/systemd/system/cps.service (für calibre)
  • /etc/systemd/system/pm2-root.service (für shinobi)

Ich habe das gelöst, indem ich einen eigenes systemd Target definiert habe und besagte Services auf dieses Target, welches nach “multi-user.target” ausgeführt wird, gesetzt habe.

Und so geht das:

Erstelle ein eigenes Target

vi /etc/systemd/system/custom.target
[Unit]
Description=My Custom Target - um sicherzustellen, dass caliberdb cps und mariadb ganz am schluss starten
Requires=multi-user.target
After=multi-user.target
AllowIsolate=yes

Betroffene Systemd Services auf custom.target legen

Die betroffenen Services werden nun nach custom.target gelegt. Gleichzeitig habe ich eine “sleep” Phase eingebaut um dem btrfs mount sicher genügend zeit zu geben. Damit triggere ich den Start der Services schön nacheinander.

mariadb.service

vi /lib/systemd/system/mariadb.service
[Unit]
...
After=multi-user.target
...

[Install]
...
WantedBy=custom.target
...

[Service]
...
# Warte 120s
TimeoutStartSec=300
ExecStartPre=/bin/sleep 120
...

Services neu installieren

sudo systemctl disable mariadb.service 
sudo systemctl enable mariadb.service

calibre-server.service

vi /etc/systemd/system/calibre-server.service

## startup service
[Unit]
Description=calibre content server
After=multi-user.target

[Service]
...
TimeoutStartSec=300
ExecStartPre=/bin/sleep 140
...

[Install]
WantedBy=custom.target

Services neu installieren

sudo systemctl disable mariadb.service 
sudo systemctl enable mariadb.service

cps.service

vi /etc/systemd/system/cps.service
[Unit]
Description=Calibre-Web
After=multi-user.target

[Service]
...
TimeoutStartSec=300 
ExecStartPre=/bin/sleep 160
...

[Install]
WantedBy=custom.target

Services neu installieren

sudo systemctl disable mariadb.service 
sudo systemctl enable mariadb.service

pm2-root.service

vi /etc/systemd/system/pm2-root.service
[Unit]
...
After=multi-user.target
...

[Install]
WantedBy=custom.target

[Service]
..
TimeoutStartSec=300 
ExecStartPre=/bin/sleep 180
...

Services neu installieren

sudo systemctl disable mariadb.service 
sudo systemctl enable mariadb.service

Links

Calibre und Calibre-web auf HC4 mit armbian

Auf meinem HC4 NAS soll Calibre die Bibliotheksverwaltung meiner eBooks übernehmen. Hier wird die Installation beschrieben.

Seit Mitte 2022 ist die Version 6.0 von Calibre verfügbar, welche die ARM CPU Architektur unter Linux unterstützt. Es waren bisher zwar auch Debian-Pakete für Calibre verfügbar, diese waren aber meist veraltet. Calibre empfielt explizit, keine Distro-Pakete einzusetzen und statdessen ihren Installer zu verwenden.

Installation

Notwendige Pakages installieren

  • python ≥ 3.3 => armbian liefert bereits 3.10 mit.
  • xdg-utils
  • wget => wget bereits auf armbian installiert.
  • xz-utils
  • libegl1
  • libopengl0
sudo apt-get install xdg-utils
sudo apt-get install xz-utils
sudo apt-get install libegl1
sudo apt-get install libopengl0

Nun kann Calibre über das installer-Skript installiert werden. Ich führe eine isolierte Installation durch und installiere Calibre auf einem eigens dafür eingerichteten Platz auf der HDD:

wget -nv -O- https://download.calibre-ebook.com/linux-installer.sh | sh /dev/stdin install_dir=/mnt/program_data/calibre-bin isolated=y

Damit ist Calibre unter /mnt/program_data/calibre-bin installiert. Calibre ist eine Desktop Anwendung, welche über eine Server-Komponente verfügt. Logischerweise kann Calibre selber nicht gestartet werden, da wir ja einen headless Server einsetzen. Folgender Aufruf führt entsprechend zu einem Fehler:

/mnt/program_data/calibre-bin/calibre/calibre

Um die Server-Komponente starten zu können, müssen noch einige Schritte getan werden:

cd /mnt/program_data/calibre-bin
mkdir mkdir calibre-library
cd calibre-library

irgend ein eBook herunterladen

wget http://www.gutenberg.org/ebooks/46.kindle.noimages -O christmascarol.mobi

Das Buch der Calibre-db hinzufügen:

cd /mnt/program_data/calibre-bin/calibre
./calibredb add /mnt/program_data/calibre-bin/calibre-library/*.mobi --with-library /mnt/program_data/calibre-bin/calibre-library/Calibre

Damit wurde eine Calibre Library unter /mnt/program_data/calibre-bin/calibre-library/Calibre erstellt und gleichzeitig das Buch hinzugefügt.

Nun kann der Calibre-Server gestartet werden. Da ich den Standart-Port 8080 breits verwende, weise ich über den Parameter –port den Port 8081 zu:

cd /mnt/program_data/calibre-bin/calibre
./calibre-server --port 8081  /mnt/program_data/calibre-bin/calibre-library/Calibre

Nun, da der Server läuft, kann man das Web-Interface aufrufen:

http://192.168.x.xxx:8081

Service erstellen

Achtung: Dieser Service soll nach dem mounten der btrfs Shares durchgeführt werden. Es ist daher nötig, die Reihenfolge der Services zu beeinflussen. Hier habe ich beschrieben wie ich das konkret umgesetzt habe.

sudo vi /etc/systemd/system/calibre-server.service
## startup service
[Unit]
Description=calibre content server
After=runlevel4.target => eigenes Target siehe https://www.dev-metal.ch/?p=1913

[Service]
Type=simple
User=xxx
Group=<Gruppe, welche Schreibzugriff auf /mnt/multimedia/books hat>
ExecStart=/mnt/program_data/calibre-bin/calibre/calibre-server --port 8081 /mnt/program_data/calibre-bin/calibre-library/Calibre --enable-local-write

[Install]
WantedBy=multi-user.target  => eigenes Target siehe https://www.dev-metal.ch/?p=1913
sudo systemctl enable calibre-server
sudo service calibre-server start

Ab sofort wird Calibre-Server als Service beim System-Boot mit gestartet.

Die Bücherbilbiothek Calibre hinzufügen

Ich verfüge bereits über sehr viele eBooks, welches sich unter /mnt/multimeda/books befinden. Dies können nun der Calibre-DB hinzugefügt werden:

./calibredb add /mnt/multimedia/books/ -r --with-library http://localhost:8081#Calibre

Zu beachten ist hier, dass für den library-pfad die lokale http URL verwendet wird. Dies ist nötig, weil calibredb ansonsten den Aufruf bei laufendem Server nicht erlaubt. Da wir den Service mit –enable-local-write gestartet haben, kann calibredb über die lokale URL (localhost) dennoch direkte Bücher hinzufügen.

Im weiteren werden hier die Bücher von /mnt/multimedia/books nach Calibre kopiert.

Automatisch Bücher der Bibliothek hinzufügen

Es gäbe die Möglichkeit einen “Listener-Ordner” zu definieren, über welchem calibredb dann jeweils Bücher direkt importiert. Dann müssten die bücher nur in diesen Ordner kopiert werden und diese würden dann automatisch nach Calibre eingelesen: https://www.digitalocean.com/community/tutorials/how-to-create-a-calibre-ebook-server-on-ubuntu-20-04#step-6-mdash-optional-automatically-adding-books-to-your-calibre-library

Dies verwende ich aber (mal bis auf weiteres) nicht, da Bücher auch elegant über die Weboberfläche von Calibre oder Calibre-Web hochgeladen werden können.

Calibre-web

Das Standard- Web-Interface von Calibre ist zwar zu gebrauchen, aber sicher nicht “state of the art”. Es gibt ein Projekt “Calibre-Web“, welches ein schöneres Interface für die Verwaltung einer Calibre Datenbank bietet (https://github.com/janeczku/calibre-web/wiki/Manual-installation):

sudo apt install python3-pip python3-venv python3-dev

Installations-Verzeichnis erstellen:

mkdir /mnt/program_data/calibre-bin/calibre-web
cd /mnt/program_data/calibre-bin/calibre-web

Virtuelle Umgebung für calibre-web in ordner venv erstellen

python3 -m venv venv

Calibreweb in virutelle Umgebung installieren:

cd /mnt/program_data/calibre-bin/calibre-web
./venv/bin/python3 -m pip install calibreweb

Calibre-Web starten

./venv/bin/python3 -m calibreweb

URL öffnen

http://192.168.x.x:8083

Login

Default admin login:
Username: admin
Password: admin123

Calibre Datenbank konfigurieren

Calibre-Web Konfig Files

Alle Konfig-Files (settings database, logfiles) befinden sich unter

cd /homes/[username]/.calibre-web

zusätzlichen Konfig-Files (für gdrive,  gmail, etc.) sind dort zu konfigurieren.

Calibre-Web als Service installieren

Siehe https://github.com/janeczku/calibre-web/wiki/Setup-Service-on-Linux#start-calibre-web-as-service-under-linux-with-systemd

Achtung: Dieser Service soll nach dem mounten der btrfs Shares durchgeführt werden. Es ist daher nötig, die Reihenfolge der Services zu beeinflussen. Hier habe ich beschrieben wie ich das konkret umgesetzt habe.

Service File erstellen

sudo vi /etc/systemd/system/cps.service
[Unit]
Description=Calibre-Web
After=runlevel4.target => eigenes Target. Siehe https://www.dev-metal.ch/?p=1913

[Service]
Type=simple
User=ralwet
ExecStart=/mnt/program_data/calibre-bin/calibre-web/venv/bin/python3 -m calibreweb

[Install]
WantedBy=multi-user.target => eigenes Target. Siehe https://www.dev-metal.ch/?p=1913

Service aktivieren

sudo systemctl enable cps.service

Service starten

sudo service cps status

Gut zu wissen:

Installations-Pfad

Hier wird die Installation über den pip paket-manager durchgeführt. Wenn man wissen will, wo calibre-web effektiv installiert ist:

/mnt/program_data/calibre-bin/calibre-web/venv/bin/pip show calibreweb

Name: calibreweb
Version: 0.6.19
Summary: Web app for browsing, reading and downloading eBooks stored in a Calibre database.
Home-page: https://github.com/janeczku/calibre-web
Author: @OzzieIsaacs
Author-email: Ozzie.Fernandez.Isaacs@googlemail.com
License: GPLv3+
Location: /mnt/program_data/calibre-bin/calibre-web/venv/lib/python3.10/site-packages
Requires: advocate, APScheduler, Babel, backports-abc, chardet, Flask, Flask-Babel, Flask-Login, Flask-Principal, flask-wtf, iso-639, lxml, PyPDF3, pytz, requests, SQLAlchemy, tornado, unidecode, Wand, werkzeug
Required-by:
Security-Header

Der Security-Header kann hier angepasst werden. => Man muss aber wissen was man tut… 😉

vi /mnt/program_data/calibre-bin/calibre-web/venv/lib/python3.10/site-packages/calibreweb/cps/web.py

@app.after_request
def add_security_headers(resp):
# csp = "default-src 'self'"
# csp += ''.join([' ' + host for host in config.config_trustedhosts.strip().split(',')])
# csp += " 'unsafe-inline' 'unsafe-eval'; font-src 'self' data:; img-src 'self' "
# if request.path.startswith("/author/") and config.config_use_goodreads:
# csp += "images.gr-assets.com i.gr-assets.com s.gr-assets.com"
# csp += " data:"
# resp.headers['Content-Security-Policy'] = csp
# if request.endpoint == "edit-book.show_edit_book" or config.config_use_google_drive:
# resp.headers['Content-Security-Policy'] += " *"
# elif request.endpoint == "web.read_book":
# resp.headers['Content-Security-Policy'] += " blob:;style-src-elem 'self' blob: 'unsafe-inline';"
# resp.headers['X-Content-Type-Options'] = 'nosniff'
# resp.headers['X-Frame-Options'] = 'SAMEORIGIN'
# resp.headers['X-XSS-Protection'] = '1; mode=block'
# resp.headers['Strict-Transport-Security'] = 'max-age=31536000;'
return resp

 

Links

 

OpnSense Multicast: Miele XGW3000 / WLAN Tockner in unterschiedlichem Subnet

Ich verwende einen Miele XGW3000 als Zigbee Gateway, welches im LAN (192.168.20.x) angeschlossen ist (fixe IP über DHCP). Gleichzeitig betreibe ich ein WLAN Netz (192.168.30.x). Die beiden Netze sind über zwei Ports an der OpnSense Firewall angeschlossen (LAN/WLAN Interface). Am WLAN ist der Trockner verbunden (fixe IP über DHCP). Das XGW3000 erkennt über Multicast die WLAN Geräte. Da Mulitcast aber auf das Netz-Segment beschränkt ist, findet der XGW3000 aus dem LAN den Trockner im WLAN natürlich nicht.

Hier beschreibe ich, wie ich die Verbindung doch noch hinbekommen habe:

  1. Installation Plugin “UDP Broadcast Relay”
  2. Konfiguration Plugin (Services>UDP Broadcast Relay). Die Multicast-Adresse sowie den Port habe ich mittels Wireshark ausgelesen.
  3. Firewall
    1. LAN
    2. WLAN
  4. NAT > Outbound

Wichtige Anmerkung

Diese “sehr offen” Firewall Rules habe ich nur temporär gesetzt bzw. nach dem erfolgreichen XGW3000 Scan wieder deaktiviert. Denn wenn der XGW3000 das Gerät bzw. die IP Adresse aus dem anderen Subnet mal gefunden hat, bleibt die Verbindung bestehen (weil die IP bekannt ist). Deswegen macht es auch Sinn, dem Gerät eine fixe IP Adresse (über DHCP) zu vergeben.

Schlussendlich habe ich dann nur noch eine Firewall-Rule aktiv, welche die direkte 1:1 Kommunikation zwischen den beiden Geräten erlaubt.

 

 

Rasperry Pi SD Karte klonen

Es gibt verschiedene Wege eine SD Karte für den Raspi zu klonen. Dabei haben sich für mich zwei mögliche Wege bewährt:

  1. Image mit einem Card-Reader auf den PC Speichern und dann wieder vom PC auf eine neue SD Karte oder
  2. Den Card-Reader mit neuer SD-Karte direkt an den Raspi anschliessen und aus dem laufenden Betrieb ein Clone erstellen.

Klone aus dem laufenden Betrieb

  • Raspi mit angeschlossenem Card-Reader (inkl. darin enthaltener neuer SD Karte) starten
  • Anschliessend https://github.com/billw2/rpi-clone installieren
  • $ git clone https://github.com/billw2/rpi-clone.git 
    $ cd rpi-clone
    $ sudo cp rpi-clone rpi-clone-setup /usr/local/sbin

Nun mit

sudo rpi-clone <zielllaufwerk> => z.B. sudo rpi-clone sdf

ein Clone erstellen.

Dies hat den schönen nebenefekt, dass man den Clone auch direkt auf eine kleinere Karte schreiben kann, sofern der genutzte Speicher im Ursprungslaufwerk die Kapazität des Ziellaufwerks nicht übersteigt.

Hint Passwort

Beim letzten Clone hat es das Passwort des Sudo-Users “zerstört” bzw. ich konnte mich auf der geklonten SD Karte nicht anmelden. Hiermit kann man das Passwort reseten (Ich habe Methode 3 benutzt): https://forums.raspberrypi.com/viewtopic.php?t=319398

Image der SD Karte auf PC speichern

Device-Name herausfinden

lsblk -p

=> /dev/sdf

Dump SD Karte in Image File

sudo dd bs=4M if=[SD CARD DEVICE NAME] of=[IMAGE FILE NAME] conv=fsync

sudo dd bs=4M if=/dev/sdf of=~/Downloads/raspi_image.img conv=fsync

Image auf neue SD Karte schreiben

sudo dd bs=4M if=[IMAGE FILE NAME] of=[SD CARD DEVICE NAME] conv=fsync

sudo dd bs=4M if=~/Downloads/raspi_image.img of=/dev/sdf conv=fsync

 

Links

How to clone your Raspberry PI SD card in Linux

Bash Scripting: Existieren aktuelle Files in einem Ordner?

Ich verwende seit einiger Zeit Shinobi als Video-Recorder für meine Kameras. Die Installation habe ich hier beschreiben.

Problem

Nun kam es einmal vor, dass Shinobi die Aufnahmen ungeplant gestoppt hat. Damit ich dies schneller bemerke habe ich mir ein Bash-Script gezimmert.

Anforderungen:

  • Skript soll regelmässig überprüfen ob sich in den Video-Verzeichnissen aktuelle Aufnahmen befinden.
  • Falls sich keine aktuellen Aufnahmen darin befinden, soll eine Pushover Nachricht ausgelöst werden.

Umsetzung

Folgendes Script überprüft vordefinierte Verzeichnisse und sendet eine Pushover-Nachricht, falls sich in den Verzeichnissen keine aktuellen Files befinden.

Für das versenden der pushover Nachricht wird das Script von https://github.com/akusei/pushover-bash verwendet.

#!/bin/bash

#***********************************************************************************************
#**
#** Dieses Script überprüft ob sich aktuelle Video-Files in den dafür vorgesehenen Verzeichnissen
#** befindet.
#**
#***********************************************************************************************

#***********************
# Variablen
#***********************
notOlderThan="10" # die Files dürfen nicht älter als diese Variable (in minuten) sein
sourcepath="/home/xxx/checkVideosAvailable/"
paths=( "${sourcepath}videos" "${sourcepath}videos2" "${sourcepath}videos3") # Die zu überprüfenden Verzeichnisse (Array)
pushover_App_Key="xxxxx" #Pushover API Key
pushover_User_Key="xxxxx" #Pushover User Key
out=$(mktemp /tmp/message.XXXXXXXX) #Temp-File zum Aufbereiten der Pushover-Nachricht
timestampLocation="./timestamp" #Pfad und Name zum timestamp File, welches für die Überprüfung des alters gebraucht wird.


#***********************
# Logik
#***********************
filesExists=true

# Erstelle ein File "timestamp" mit einem Timestamp "jetzt - $notOlderThan min". 
# Dieses File wird anschliessend verwendet um über den "find" Befehl das Alter der Files vergleichen zu können. 
date --date="-$notOlderThan minutes" +"%Y%m%d%H%M" | xargs touch $timestampLocation -mt

#iteriere über die paths und überprüfe ob sich darin Files befinden, welche jünger als $notOlderThan bzw. das File $timestampLocation sind 
for i in "${paths[@]}"
do
#echo "Testing $i" >> "$out"
# Suche Files, welche neuer als das erstellte timestamp-file sind.
if test "`find $i/. -newer $timestampLocation -type f`"
then
echo "Aktuelle Video-Files existieren in $i"
else
filesExists=false
echo "Es existieren keine aktuellen Video-Files in \n $i"
fi
done

if [ "$filesExists" = false ] ; 
then
echo "Sende Pushover Nachricht"
cat "$out" | xargs -0 -I XX ./pushover.sh -t $pushover_App_Key -u $pushover_User_Key -m XX
fi

# Entferne die temp Files
rm "$out"
rm $timestampLocation

Installation auf HC4

Das obige bash-Script inkl. Pushover Bashscript in ein Verzeichnis schreiben (z.B. nach /home/xxxx/checkVideosAvailable/ )

cronjob

Das Script soll als cron-job jede Stunde laufen.

sudo -s
crontab -e
-------------
45 * * * * /bin/bash /home/xxx/checkVideosAvailable/checkVideosAvailable.sh > /dev/null 2>&1

Synchronisation HC4 NAS nach Qnap TS-109

Hier habe ich beschrieben, wie man einen rsync-job von eine Thecus NAS nach Qnap TS-109 einrichten kann. Mittlerweile ist mein Thecus NAS Geschichte. Stattdessen läuft das NAS, basierend auf einem Odroid HC4 in meinen 4 Wänden.

Das HC4 NAS verfügt zwar über ein Raid1. Aber die wichtigsten Daten sollen 1:1 noch auf ein weiteres Backup NAS (TS-109) kopiert werden.

Damit Rsync funktioniert muss ein Gerät als Server und eines als Client agieren. Dabei stellt der Client als Initiator eine Verbindung zum Server her und lädt Files herunter oder transferiert Files zum Server.

HC4 NAS (Rsync Server)

Das HC4 wird als RSYNC Server installiert (im Sinne eines Dienstes):

sudo apt-get install rsync

Nach der Installation von rsync müssen zwei Dateien erstellt werden.

Konfigurations-Datei

sudo vi /etc/rsyncd.conf

Diese mit folgendem Inhalt befüllen:

pid file = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
log file = /var/log/rsync.log
#hosts allow = 192.168.2.254:255.255.255.0
hosts allow = 192.168.1.101

[testData]
path = /mnt/test123
comment = RSYNC FILES
read only = true
timeout = 300
uid = sys
gid = nogroup
#auth users = rsync1
#secrets file = /etc/rsyncd.secrets

Der rsync-Zugriff erfolgt in diesem Falle über den user “sys”. Hier kann ein beliebiger User konfiguriert werden. Es ist aber wichtig, dass dieser User auch entsprechende Rechte auf dem lokalen Ordner (/mnt/test123) besitzt. Es können beliebig viele solcher “rsync-shares” erstellt werden. Es ist damit auch möglich nur einzelne Unterverzeichnisse zu synchen:

auth users
Hier kommen die Benutzer, die Zugriff auf dieses Modul haben werden. Diese Benutzer müssen nicht unbedingt auf dem System vorhanden sein. Dies sind rsync-Benutzer, die in der Secrets-Datei aufgeführt sein sollten, die in der nächsten Zeile der Konfigurationsdatei beschrieben wird.

secrets-Datei
Das ist die Datei, in der die rsync-Benutzer erstellt werden und die für den Rsync-Server zum Lesen verfügbar ist.

Secrets-Datei

Wenn man die Autentifizierung anwenden möchte, muss entsprechend noch die Secrets-Datei erstellt werden.

Die Secrets-Datei wird in /etc mit dem Namen rsyncd.secrets erstellt und enthält die Paare aus Benutzernamen und Passwort, welche von rsync geprüft werden.

sudo vi /etc/rsyncd.secrets

Mit folgendem Inhalt befüllen

 rsinc1:beispielPassword

Wie wir sehen, ist das Passwort direkt als Text und unverschlüsselt abgelegt. Deswegen ist es eine gute Idee nach Erstellung dieses Files den Zugriff nur noch für Root zu erlauben:

sudo chmod 0640 /etc/rsyncd.secrets

Starten des Rsync-Server Dienstes

sudo rsync --daemon

Es folgt keine weitere Meldung von rsync. Man kann aber überprüfen, ob der rsync daemon läuft:

ps -ef | grep rsync-----
root 821310 1 0 17:23 ? 00:00:00 rsync --daemon

Auch das Log bestätigt, dass alles ok ist:

$ tail /var/log/rsync.log
2022/09/22 17:23:20 [821310] rsyncd version 3.2.3 starting, listening on port 873

RSYNC beim Booten starten

sudo systemctl enable rsync

Zusätzlich:
Dieser Service soll nach dem mounten der btrfs Shares durchgeführt werden. Deswegen setze ich das “After Target” auf “After=runlevel4.target”

sudo vi /etc/systemd/system/multi-user.target.wants/rsync.service

...
After=runlevel4.target
...

Qnap TS-109 (Rsync Client)

Das Qnap TS-109 ist das Zielgerägt bzw. das “target” wohin die Dateien aus dem HC4 kopiert werden sollen.  Es initiiert in der Rolle als “Client” eine Verbindung zum Rsync Server und kopiert anschliessend die Daten:

  • Login über das Qnap TS-109 Webinterface
  • Erstellen der Zielverzeichnisse. z.B. “BackupHC4/test123”, etc.
  • Das Qnap TS-109 liefert bereits ein SSH-Login Plugin mit. Dieses aktivieren.
  • Login über SSH
  • Das Qnap TS-109 liefert ebenfalls bereits rsync out of the box mit.
  • Nun können auf dem Qnap TS-109 rsync Befehle gegen das HC4 ausgeführt werden.
    Folgender Befehl kopiert alle Daten aus dem HC4 Source-Verzeichnis /mnt/test123 in das Qnap TS-109 Zielverzeichnis /share/HDA_DATA/BackupHC4/test123/.
    Parameter delete = gelöschte Dateien werden auch in der Sicherung gelöscht
    Parameter stats = zeigt einen ausführlicheren Report am Ende einer Übertragung an.
rsync -a --delete --stats hc4IP::testData /share/HDA_DATA/BackupHC4/ralwet_data

Backup automatisieren

Nun, da rsync funktioniert ist es Zeit das ganze automatisiert, in regelmässigen Zeitabständen auszuführen.

  • copy_all.sh File unter /mnt/HDA_ROOT erstellen
cd /mnt/HDA_ROOT
vi copy_all.sh

Script:

#!/bin/sh
#
# called by cron to backup the HC4 NAS to the Qnap TS-109 via rsync
echo "start backup via rsync : `date`"
echo "syncing folder : test"
rsync -a --delete --stats hc4IP::testData /share/HDA_DATA/BackupHC4/ralwet_data
echo "end backup via rsync : `date`"
echo "+++++++++++++++++++++++++++++++++++++++++++++++++"

File ausführbar machen

chmod +x copy_all.sh

Nun die crontab des Qnap TS-109 anpassen (“crontab -l” listet die aktuellen Einträge auf)

vi /etc/config/crontab

folgenden Eintrag hinzfügen. Das Script wird nun jeden Sonntag um 1:00 Uhr ausgeführt. Die Logdatei wird in das Root-Verzeichnis des Backups geschrieben.

0 1 * * 0 /mnt/HDA_ROOT/copy_all.sh >> /share/HDA_DATA/BackupHC4/rsync.log 2>&1

crontab neu laden

crontab /etc/config/crontab

cron restarten

/etc/init.d/crond.sh restart

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

OpnSense – Geo IP Blockierung

Aktuell könnte es Sinn machen, gewisse Regionen auf der Firewall gleich direkt zu blockieren. Dies kann man mit OpnSense sehr elegant lösen:

  • Erstelle einen Alias mit Typ “GeoIp”:
    Erstelle eine Floating-Rule auf der Firewall: